From 1ea70b085fdd180f3233cdbdb16f770a442e81af Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sun, 5 Jun 2022 11:58:53 +0200 Subject: [PATCH] Context: Remove albums --- src/CMakeLists.txt | 4 - src/context/contextalbumsmodel.cpp | 390 ------------------------ src/context/contextalbumsmodel.h | 111 ------- src/context/contextalbumsview.cpp | 434 --------------------------- src/context/contextalbumsview.h | 137 --------- src/context/contextview.cpp | 70 +---- src/context/contextview.h | 7 - src/core/mainwindow.cpp | 2 - src/settings/contextsettingspage.cpp | 2 - src/settings/contextsettingspage.h | 1 - src/settings/contextsettingspage.ui | 10 - 11 files changed, 3 insertions(+), 1165 deletions(-) delete mode 100644 src/context/contextalbumsmodel.cpp delete mode 100644 src/context/contextalbumsmodel.h delete mode 100644 src/context/contextalbumsview.cpp delete mode 100644 src/context/contextalbumsview.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b5c38e731..194e9b159 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,8 +60,6 @@ set(SOURCES context/contextview.cpp context/contextalbum.cpp - context/contextalbumsmodel.cpp - context/contextalbumsview.cpp collection/collection.cpp collection/collectionmodel.cpp @@ -299,8 +297,6 @@ set(HEADERS context/contextview.h context/contextalbum.h - context/contextalbumsmodel.h - context/contextalbumsview.h collection/collection.h collection/collectionmodel.h diff --git a/src/context/contextalbumsmodel.cpp b/src/context/contextalbumsmodel.cpp deleted file mode 100644 index 22c5acc4c..000000000 --- a/src/context/contextalbumsmodel.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Strawberry Music Player - * This code was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2013-2021, Jonas Kvinge - * - * Strawberry 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 3 of the License, or - * (at your option) any later version. - * - * Strawberry is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Strawberry. If not, see . - * - */ - -#include "config.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/application.h" -#include "core/database.h" -#include "core/iconloader.h" -#include "collection/collectionquery.h" -#include "collection/collectionbackend.h" -#include "collection/collectionmodel.h" -#include "collection/collectionitem.h" -#include "playlist/playlistmanager.h" -#include "playlist/songmimedata.h" -#include "covermanager/albumcoverloader.h" -#include "covermanager/albumcoverloaderoptions.h" -#include "covermanager/albumcoverloaderresult.h" - -#include "contextalbumsmodel.h" - -const int ContextAlbumsModel::kPrettyCoverSize = 32; - -ContextAlbumsModel::ContextAlbumsModel(CollectionBackend *backend, Application *app, QObject *parent) - : SimpleTreeModel(new CollectionItem(this), parent), - backend_(backend), - app_(app), - album_icon_(IconLoader::Load("cdcase")) { - - root_->lazy_loaded = true; - - cover_loader_options_.get_image_data_ = false; - cover_loader_options_.scale_output_image_ = true; - cover_loader_options_.pad_output_image_ = true; - cover_loader_options_.desired_height_ = kPrettyCoverSize; - - QObject::connect(app_->album_cover_loader(), &AlbumCoverLoader::AlbumCoverLoaded, this, &ContextAlbumsModel::AlbumCoverLoaded); - - QIcon nocover = IconLoader::Load("cdcase"); - QList nocover_sizes = nocover.availableSizes(); - no_cover_icon_ = nocover.pixmap(nocover_sizes.last()).scaled(kPrettyCoverSize, kPrettyCoverSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); - -} - -ContextAlbumsModel::~ContextAlbumsModel() { delete root_; } - -void ContextAlbumsModel::AddSongs(const SongList &songs) { - - for (const Song &song : songs) { - if (song_nodes_.contains(song.id())) continue; - QString key = CollectionModel::ContainerKey(CollectionModel::GroupBy_Album, song); - CollectionItem *container = nullptr; - if (container_nodes_.contains(key)) { - container = container_nodes_[key]; - } - else { - container = ItemFromSong(CollectionItem::Type_Container, true, root_, song, 0); - container_nodes_.insert(key, container); - } - song_nodes_[song.id()] = ItemFromSong(CollectionItem::Type_Song, true, container, song, -1); - } - -} - -QString ContextAlbumsModel::AlbumIconPixmapCacheKey(const QModelIndex &idx) { - - QStringList path; - QModelIndex index_copy(idx); - while (index_copy.isValid()) { - path.prepend(index_copy.data().toString()); - index_copy = index_copy.parent(); - } - return "contextalbumsart:" + path.join("/"); - -} - -QVariant ContextAlbumsModel::AlbumIcon(const QModelIndex &idx) { - - CollectionItem *item = IndexToItem(idx); - if (!item) return no_cover_icon_; - - // Check the cache for a pixmap we already loaded. - const QString cache_key = AlbumIconPixmapCacheKey(idx); - - QPixmap cached_pixmap; - if (QPixmapCache::find(cache_key, &cached_pixmap)) { - return cached_pixmap; - } - - // Maybe we're loading a pixmap already? - if (pending_cache_keys_.contains(cache_key)) { - return no_cover_icon_; - } - - // No art is cached and we're not loading it already. Load art for the first song in the album. - SongList songs = GetChildSongs(idx); - if (!songs.isEmpty()) { - const quint64 id = app_->album_cover_loader()->LoadImageAsync(cover_loader_options_, songs.first()); - pending_art_.insert(id, ItemAndCacheKey(item, cache_key)); - pending_cache_keys_.insert(cache_key); - } - - return no_cover_icon_; - -} - -void ContextAlbumsModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result) { - - if (!pending_art_.contains(id)) return; - - ItemAndCacheKey item_and_cache_key = pending_art_.take(id); - - CollectionItem *item = item_and_cache_key.first; - if (!item) return; - - const QString &cache_key = item_and_cache_key.second; - if (pending_cache_keys_.contains(cache_key)) { - pending_cache_keys_.remove(cache_key); - } - - // Insert this image in the cache. - if (!result.success || result.image_scaled.isNull() || result.type == AlbumCoverLoaderResult::Type_ManuallyUnset) { - // Set the no_cover image so we don't continually try to load art. - QPixmapCache::insert(cache_key, no_cover_icon_); - } - else { - QPixmap image_pixmap; - image_pixmap = QPixmap::fromImage(result.image_scaled); - QPixmapCache::insert(cache_key, image_pixmap); - } - - const QModelIndex idx = ItemToIndex(item); - - emit dataChanged(idx, idx); - -} - -QVariant ContextAlbumsModel::data(const QModelIndex &idx, int role) const { - - const CollectionItem *item = IndexToItem(idx); - - if (role == Qt::DecorationRole && item->type == CollectionItem::Type_Container && item->container_level == 0) { - return const_cast(this)->AlbumIcon(idx); - } - - return data(item, role); - -} - -QVariant ContextAlbumsModel::data(const CollectionItem *item, int role) const { - - switch (role) { - case Qt::DisplayRole: - case Qt::ToolTipRole: - return item->DisplayText(); - - case Qt::DecorationRole: - switch (item->type) { - case CollectionItem::Type_Container: - if (item->type == CollectionItem::Type_Container && item->container_level == 0) { return album_icon_; } - break; - default: - break; - } - break; - - case Role_Type: - return item->type; - - case Role_ContainerType: - return item->type; - - case Role_Key: - return item->key; - - case Role_Artist: - return item->metadata.artist(); - - case Role_Editable: - if (item->type == CollectionItem::Type_Container) { - // if we have even one non editable item as a child, we ourselves are not available for edit - if (!item->children.isEmpty()) { - for (CollectionItem *child : item->children) { - if (!data(child, role).toBool()) { - return false; - } - } - return true; - } - else { - return false; - } - } - else if (item->type == CollectionItem::Type_Song) { - return item->metadata.IsEditable(); - } - else { - return false; - } - - case Role_SortText: - return item->SortText(); - - default: - return QVariant(); - } - - return QVariant(); - -} - -void ContextAlbumsModel::Reset() { - - for (QMap::const_iterator it = container_nodes_.constBegin(); it != container_nodes_.constEnd(); ++it) { - const QString cache_key = AlbumIconPixmapCacheKey(ItemToIndex(it.value())); - QPixmapCache::remove(cache_key); - } - - beginResetModel(); - delete root_; - song_nodes_.clear(); - container_nodes_.clear(); - pending_art_.clear(); - pending_cache_keys_.clear(); - - root_ = new CollectionItem(this); - root_->lazy_loaded = true; - endResetModel(); - -} - -CollectionItem *ContextAlbumsModel::ItemFromSong(CollectionItem::Type item_type, const bool signal, CollectionItem *parent, const Song &s, const int container_level) { - - if (signal) beginInsertRows(ItemToIndex(parent), static_cast(parent->children.count()), static_cast(parent->children.count())); - - CollectionItem *item = new CollectionItem(item_type, parent); - item->container_level = container_level; - item->lazy_loaded = true; - - if (item_type == CollectionItem::Type_Container) { - item->key = CollectionModel::ContainerKey(CollectionModel::GroupBy_Album, s); - item->display_text = CollectionModel::TextOrUnknown(s.album()); - item->sort_text = CollectionModel::SortTextForArtist(s.album()); - } - else { - item->key = s.album() + " " + s.title(); - item->display_text = CollectionModel::TextOrUnknown(s.title()); - item->sort_text = CollectionModel::SortTextForSong(s); - item->metadata = s; - } - - if (signal) endInsertRows(); - - return item; - -} - -Qt::ItemFlags ContextAlbumsModel::flags(const QModelIndex &idx) const { - - switch (IndexToItem(idx)->type) { - case CollectionItem::Type_Song: - case CollectionItem::Type_Container: - return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; - case CollectionItem::Type_Root: - case CollectionItem::Type_LoadingIndicator: - default: - return Qt::ItemIsEnabled; - } - -} - -QStringList ContextAlbumsModel::mimeTypes() const { - return QStringList() << "text/uri-list"; -} - -QMimeData *ContextAlbumsModel::mimeData(const QModelIndexList &indexes) const { - - if (indexes.isEmpty()) return nullptr; - - SongMimeData *data = new SongMimeData; - QList urls; - QSet song_ids; - - data->backend = backend_; - - for (const QModelIndex &idx : indexes) { - GetChildSongs(IndexToItem(idx), &urls, &data->songs, &song_ids); - } - - data->setUrls(urls); - data->name_for_new_playlist_ = PlaylistManager::GetNameForNewPlaylist(data->songs); - - return data; - -} - -bool ContextAlbumsModel::CompareItems(const CollectionItem *a, const CollectionItem *b) const { - - QVariant left(data(a, ContextAlbumsModel::Role_SortText)); - QVariant right(data(b, ContextAlbumsModel::Role_SortText)); - -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (left.metaType().id() == QMetaType::Int) -#else - if (left.type() == QVariant::Int) -#endif - return left.toInt() < right.toInt(); - else return left.toString() < right.toString(); - -} - -void ContextAlbumsModel::GetChildSongs(CollectionItem *item, QList *urls, SongList *songs, QSet *song_ids) const { - - switch (item->type) { - case CollectionItem::Type_Container:{ - - QList children = item->children; - std::sort(children.begin(), children.end(), std::bind(&ContextAlbumsModel::CompareItems, this, std::placeholders::_1, std::placeholders::_2)); - - for (CollectionItem *child : children) { - GetChildSongs(child, urls, songs, song_ids); - } - break; - } - - case CollectionItem::Type_Song: - urls->append(item->metadata.url()); - if (!song_ids->contains(item->metadata.id())) { - songs->append(item->metadata); - song_ids->insert(item->metadata.id()); - } - break; - - default: - break; - } - -} - -SongList ContextAlbumsModel::GetChildSongs(const QModelIndexList &indexes) const { - - QList dontcare; - SongList ret; - QSet song_ids; - - for (const QModelIndex &idx : indexes) { - GetChildSongs(IndexToItem(idx), &dontcare, &ret, &song_ids); - } - return ret; - -} - -SongList ContextAlbumsModel::GetChildSongs(const QModelIndex &idx) const { - return GetChildSongs(QModelIndexList() << idx); -} diff --git a/src/context/contextalbumsmodel.h b/src/context/contextalbumsmodel.h deleted file mode 100644 index 5d3543bf5..000000000 --- a/src/context/contextalbumsmodel.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Strawberry Music Player - * This code was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2013-2021, Jonas Kvinge - * - * Strawberry 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 3 of the License, or - * (at your option) any later version. - * - * Strawberry is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Strawberry. If not, see . - * - */ - -#ifndef CONTEXTALBUMSMODEL_H -#define CONTEXTALBUMSMODEL_H - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/simpletreemodel.h" -#include "core/song.h" -#include "collection/collectionquery.h" -#include "collection/collectionitem.h" -#include "covermanager/albumcoverloaderoptions.h" -#include "covermanager/albumcoverloaderresult.h" - -class QMimeData; - -class Application; -class CollectionBackend; -class CollectionItem; - -class ContextAlbumsModel : public SimpleTreeModel { - Q_OBJECT - - public: - explicit ContextAlbumsModel(CollectionBackend *backend, Application *app, QObject *parent = nullptr); - ~ContextAlbumsModel() override; - - static const int kPrettyCoverSize; - - enum Role { - Role_Type = Qt::UserRole + 1, - Role_ContainerType, - Role_SortText, - Role_Key, - Role_Artist, - Role_Editable, - LastRole - }; - - void GetChildSongs(CollectionItem *item, QList *urls, SongList *songs, QSet *song_ids) const; - SongList GetChildSongs(const QModelIndex &idx) const; - SongList GetChildSongs(const QModelIndexList &indexes) const; - - QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override; - Qt::ItemFlags flags(const QModelIndex &idx) const override; - QStringList mimeTypes() const override; - QMimeData *mimeData(const QModelIndexList &indexes) const override; - - void Reset(); - void AddSongs(const SongList &songs); - - private slots: - void AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderResult &result); - - private: - CollectionItem *ItemFromSong(CollectionItem::Type item_type, const bool signal, CollectionItem *parent, const Song &s, const int container_level); - - static QString AlbumIconPixmapCacheKey(const QModelIndex &idx); - QVariant AlbumIcon(const QModelIndex &idx); - QVariant data(const CollectionItem *item, int role) const; - bool CompareItems(const CollectionItem *a, const CollectionItem *b) const; - - private: - CollectionBackend *backend_; - Application *app_; - QueryOptions query_options_; - QMap container_nodes_; - QMap song_nodes_; - QIcon album_icon_; - QPixmap no_cover_icon_; - AlbumCoverLoaderOptions cover_loader_options_; - typedef QPair ItemAndCacheKey; - QMap pending_art_; - QSet pending_cache_keys_; -}; - -#endif // CONTEXTALBUMSMODEL_H diff --git a/src/context/contextalbumsview.cpp b/src/context/contextalbumsview.cpp deleted file mode 100644 index 33dee66c3..000000000 --- a/src/context/contextalbumsview.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Strawberry Music Player - * This code was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2013-2021, Jonas Kvinge - * - * Strawberry 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 3 of the License, or - * (at your option) any later version. - * - * Strawberry is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Strawberry. If not, see . - * - */ - -#include "config.h" - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/application.h" -#include "core/iconloader.h" -#include "core/mimedata.h" -#include "core/utilities.h" -#include "collection/collectiondirectorymodel.h" -#include "collection/collectionmodel.h" -#include "collection/collectionitem.h" -#ifndef Q_OS_WIN -# include "device/devicemanager.h" -# include "device/devicestatefiltermodel.h" -#endif -#include "dialogs/edittagdialog.h" -#include "organize/organizedialog.h" - -#include "contextalbumsmodel.h" -#include "contextalbumsview.h" - -ContextItemDelegate::ContextItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {} - -bool ContextItemDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &idx) { - - return true; - - Q_UNUSED(option); - - if (!event || !view) return false; - - QString text = displayText(idx.data(), QLocale::system()); - - if (text.isEmpty() || !event) return false; - - switch (event->type()) { - case QEvent::ToolTip: { - - QSize real_text = sizeHint(option, idx); - QRect displayed_text = view->visualRect(idx); - bool is_elided = displayed_text.width() < real_text.width(); - - if (is_elided) { - QToolTip::showText(event->globalPos(), text, view); - } - else if (idx.data(Qt::ToolTipRole).isValid()) { - // If the item has a tooltip text, display it - QString tooltip_text = idx.data(Qt::ToolTipRole).toString(); - QToolTip::showText(event->globalPos(), tooltip_text, view); - } - else { - // in case that another text was previously displayed - QToolTip::hideText(); - } - return true; - } - - case QEvent::QueryWhatsThis: - return true; - - case QEvent::WhatsThis: - QWhatsThis::showText(event->globalPos(), text, view); - return true; - - default: - break; - } - return false; - -} - -ContextAlbumsView::ContextAlbumsView(QWidget *parent) - : AutoExpandingTreeView(parent), - app_(nullptr), - context_menu_(nullptr), - load_(nullptr), - add_to_playlist_(nullptr), - add_to_playlist_enqueue_(nullptr), - open_in_new_playlist_(nullptr), - organize_(nullptr), -#ifndef Q_OS_WIN - copy_to_device_(nullptr), -#endif - edit_track_(nullptr), - edit_tracks_(nullptr), - show_in_browser_(nullptr), - is_in_keyboard_search_(false), - model_(nullptr) { - - setStyleSheet("border: none;"); - - setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); - setItemDelegate(new ContextItemDelegate(this)); - setAttribute(Qt::WA_MacShowFocusRect, false); - setHeaderHidden(true); - setAllColumnsShowFocus(true); - setDragEnabled(true); - setDragDropMode(QAbstractItemView::DragOnly); - setSelectionMode(QAbstractItemView::ExtendedSelection); - SetAddOnDoubleClick(false); - -} - -ContextAlbumsView::~ContextAlbumsView() = default; - -void ContextAlbumsView::SaveFocus() { - - QModelIndex current = currentIndex(); - QVariant type = model()->data(current, ContextAlbumsModel::Role_Type); - if (!type.isValid() || !(type.toInt() == CollectionItem::Type_Song || type.toInt() == CollectionItem::Type_Container || type.toInt() == CollectionItem::Type_Divider)) { - return; - } - - last_selected_path_.clear(); - last_selected_song_ = Song(); - last_selected_container_ = QString(); - - switch (type.toInt()) { - case CollectionItem::Type_Song: { - QModelIndex index = current; - SongList songs = model_->GetChildSongs(index); - if (!songs.isEmpty()) { - last_selected_song_ = songs.last(); - } - break; - } - - case CollectionItem::Type_Container: - case CollectionItem::Type_Divider: { - break; - } - - default: - return; - } - - SaveContainerPath(current); - -} - -void ContextAlbumsView::SaveContainerPath(const QModelIndex &child) { - - QModelIndex current = model()->parent(child); - QVariant type = model()->data(current, ContextAlbumsModel::Role_Type); - if (!type.isValid() || !(type.toInt() == CollectionItem::Type_Container || type.toInt() == CollectionItem::Type_Divider)) { - return; - } - - QString text = model()->data(current, ContextAlbumsModel::Role_SortText).toString(); - last_selected_path_ << text; - SaveContainerPath(current); - -} - -void ContextAlbumsView::RestoreFocus() { - - if (last_selected_container_.isEmpty() && last_selected_song_.url().isEmpty()) { - return; - } - RestoreLevelFocus(); - -} - -bool ContextAlbumsView::RestoreLevelFocus(const QModelIndex &parent) { - - if (model()->canFetchMore(parent)) { - model()->fetchMore(parent); - } - int rows = model()->rowCount(parent); - for (int i = 0; i < rows; i++) { - QModelIndex current = model()->index(i, 0, parent); - QVariant type = model()->data(current, ContextAlbumsModel::Role_Type); - switch (type.toInt()) { - case CollectionItem::Type_Song: - if (!last_selected_song_.url().isEmpty()) { - QModelIndex index = qobject_cast(model())->mapToSource(current); - const SongList songs = model_->GetChildSongs(index); - if (std::any_of(songs.begin(), songs.end(), [this](const Song &song) { return song == last_selected_song_; })) { - setCurrentIndex(current); - return true; - } - } - break; - } - } - return false; - -} - -void ContextAlbumsView::Init(Application *app) { - - app_ = app; - - model_ = new ContextAlbumsModel(app_->collection_backend(), app_, this); - model_->Reset(); - - setModel(model_); - - QObject::connect(model_, &ContextAlbumsModel::modelAboutToBeReset, this, &ContextAlbumsView::SaveFocus); - QObject::connect(model_, &ContextAlbumsModel::modelReset, this, &ContextAlbumsView::RestoreFocus); - -} - -void ContextAlbumsView::paintEvent(QPaintEvent *event) { - QTreeView::paintEvent(event); -} - -void ContextAlbumsView::mouseReleaseEvent(QMouseEvent *e) { - QTreeView::mouseReleaseEvent(e); -} - -void ContextAlbumsView::contextMenuEvent(QContextMenuEvent *e) { - - if (!context_menu_) { - context_menu_ = new QMenu(this); - - add_to_playlist_ = context_menu_->addAction(IconLoader::Load("media-playback-start"), tr("Append to current playlist"), this, &ContextAlbumsView::AddToPlaylist); - load_ = context_menu_->addAction(IconLoader::Load("media-playback-start"), tr("Replace current playlist"), this, &ContextAlbumsView::Load); - open_in_new_playlist_ = context_menu_->addAction(IconLoader::Load("document-new"), tr("Open in new playlist"), this, &ContextAlbumsView::OpenInNewPlaylist); - - context_menu_->addSeparator(); - add_to_playlist_enqueue_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue track"), this, &ContextAlbumsView::AddToPlaylistEnqueue); - - context_menu_->addSeparator(); - organize_ = context_menu_->addAction(IconLoader::Load("edit-copy"), tr("Organize files..."), this, &ContextAlbumsView::Organize); -#ifndef Q_OS_WIN - copy_to_device_ = context_menu_->addAction(IconLoader::Load("device"), tr("Copy to device..."), this, &ContextAlbumsView::CopyToDevice); -#endif - - context_menu_->addSeparator(); - edit_track_ = context_menu_->addAction(IconLoader::Load("edit-rename"), tr("Edit track information..."), this, &ContextAlbumsView::EditTracks); - edit_tracks_ = context_menu_->addAction(IconLoader::Load("edit-rename"), tr("Edit tracks information..."), this, &ContextAlbumsView::EditTracks); - show_in_browser_ = context_menu_->addAction(IconLoader::Load("document-open-folder"), tr("Show in file browser..."), this, &ContextAlbumsView::ShowInBrowser); - - context_menu_->addSeparator(); - -#ifndef Q_OS_WIN - copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0); - QObject::connect(app_->device_manager()->connected_devices_model(), &DeviceStateFilterModel::IsEmptyChanged, copy_to_device_, &QAction::setDisabled); -#endif - - } - - context_menu_index_ = indexAt(e->pos()); - if (!context_menu_index_.isValid()) return; - QModelIndexList selected_indexes = selectionModel()->selectedRows(); - - int regular_elements = 0; - int regular_editable = 0; - - for (const QModelIndex &idx : selected_indexes) { - regular_elements++; - if (model_->data(idx, ContextAlbumsModel::Role_Editable).toBool()) { - regular_editable++; - } - } - - // TODO: check if custom plugin actions should be enabled / visible - const int songs_selected = regular_elements; - const bool regular_elements_only = songs_selected == regular_elements && regular_elements > 0; - - // in all modes - load_->setEnabled(songs_selected > 0); - add_to_playlist_->setEnabled(songs_selected > 0); - open_in_new_playlist_->setEnabled(songs_selected > 0); - add_to_playlist_enqueue_->setEnabled(songs_selected > 0); - - // if neither edit_track not edit_tracks are available, we show disabled edit_track element - edit_track_->setVisible(regular_editable <= 1); - edit_track_->setEnabled(regular_editable == 1); - - organize_->setVisible(regular_elements_only); -#ifndef Q_OS_WIN - copy_to_device_->setVisible(regular_elements_only); -#endif - - // only when all selected items are editable - organize_->setEnabled(regular_elements == regular_editable); -#ifndef Q_OS_WIN - copy_to_device_->setEnabled(regular_elements == regular_editable); -#endif - - context_menu_->popup(e->globalPos()); - -} - -void ContextAlbumsView::Load() { - - QMimeData *q_mimedata = model()->mimeData(selectedIndexes()); - if (MimeData *mimedata = qobject_cast(q_mimedata)) { - mimedata->clear_first_ = true; - } - emit AddToPlaylistSignal(q_mimedata); - -} - -void ContextAlbumsView::AddToPlaylist() { - - emit AddToPlaylistSignal(model()->mimeData(selectedIndexes())); - -} - -void ContextAlbumsView::AddToPlaylistEnqueue() { - - QMimeData *q_mimedata = model()->mimeData(selectedIndexes()); - if (MimeData *mimedata = qobject_cast(q_mimedata)) { - mimedata->enqueue_now_ = true; - } - emit AddToPlaylistSignal(q_mimedata); - -} - -void ContextAlbumsView::OpenInNewPlaylist() { - - QMimeData *q_mimedata = model()->mimeData(selectedIndexes()); - if (MimeData *mimedata = qobject_cast(q_mimedata)) { - mimedata->open_in_new_playlist_ = true; - } - emit AddToPlaylistSignal(q_mimedata); - -} - -void ContextAlbumsView::scrollTo(const QModelIndex &idx, ScrollHint hint) { - - if (is_in_keyboard_search_) { - QTreeView::scrollTo(idx, QAbstractItemView::PositionAtTop); - } - else { - QTreeView::scrollTo(idx, hint); - } - -} - -SongList ContextAlbumsView::GetSelectedSongs() const { - QModelIndexList selected_indexes = selectionModel()->selectedRows(); - return model_->GetChildSongs(selected_indexes); -} - -void ContextAlbumsView::Organize() { - - if (!organize_dialog_) { - organize_dialog_ = std::make_unique(app_->task_manager(), app_->collection_backend(), this); - } - - organize_dialog_->SetDestinationModel(app_->collection_model()->directory_model()); - organize_dialog_->SetCopy(false); - if (organize_dialog_->SetSongs(GetSelectedSongs())) { - organize_dialog_->show(); - } - else { - QMessageBox::warning(this, tr("Error"), tr("None of the selected songs were suitable for copying to a device")); - } - -} - -void ContextAlbumsView::EditTracks() { - - if (!edit_tag_dialog_) { - edit_tag_dialog_ = std::make_unique(app_, this); - } - edit_tag_dialog_->SetSongs(GetSelectedSongs()); - edit_tag_dialog_->show(); - -} - -void ContextAlbumsView::CopyToDevice() { -#ifndef Q_OS_WIN - if (!organize_dialog_) { - organize_dialog_ = std::make_unique(app_->task_manager(), nullptr, this); - } - - organize_dialog_->SetDestinationModel(app_->device_manager()->connected_devices_model(), true); - organize_dialog_->SetCopy(true); - organize_dialog_->SetSongs(GetSelectedSongs()); - organize_dialog_->show(); -#endif -} - -void ContextAlbumsView::ShowInBrowser() const { - - const SongList songs = GetSelectedSongs(); - QList urls; - urls.reserve(songs.count()); - for (const Song &song : songs) { - urls << song.url(); - } - - Utilities::OpenInFileBrowser(urls); - -} diff --git a/src/context/contextalbumsview.h b/src/context/contextalbumsview.h deleted file mode 100644 index 94e49b938..000000000 --- a/src/context/contextalbumsview.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Strawberry Music Player - * This code was part of Clementine. - * Copyright 2010, David Sansome - * Copyright 2013-2021, Jonas Kvinge - * - * Strawberry 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 3 of the License, or - * (at your option) any later version. - * - * Strawberry is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Strawberry. If not, see . - * - */ - -#ifndef CONTEXTALBUMSVIEW_H -#define CONTEXTALBUMSVIEW_H - -#include "config.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "core/song.h" -#include "widgets/autoexpandingtreeview.h" - -class QWidget; -class QMenu; -class QAction; -class QContextMenuEvent; -class QHelpEvent; -class QMouseEvent; -class QPaintEvent; - -class Application; -class ContextAlbumsModel; -class EditTagDialog; -class OrganizeDialog; - -class ContextItemDelegate : public QStyledItemDelegate { - Q_OBJECT - - public: - explicit ContextItemDelegate(QObject *parent); - - public slots: - bool helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option, const QModelIndex &idx) override; -}; - -class ContextAlbumsView : public AutoExpandingTreeView { - Q_OBJECT - - public: - explicit ContextAlbumsView(QWidget *parent = nullptr); - ~ContextAlbumsView() override; - - // Returns Songs currently selected in the collection view. - // Please note that the selection is recursive meaning that if for example an album is selected this will return all of it's songs. - SongList GetSelectedSongs() const; - - void Init(Application *app); - - // QTreeView - void scrollTo(const QModelIndex &idx, ScrollHint hint = EnsureVisible) override; - - ContextAlbumsModel *albums_model() { return model_; } - - public slots: - void SaveFocus(); - void RestoreFocus(); - - protected: - // QWidget - void paintEvent(QPaintEvent *event) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void contextMenuEvent(QContextMenuEvent *e) override; - - private slots: - void Load(); - void AddToPlaylist(); - void AddToPlaylistEnqueue(); - void OpenInNewPlaylist(); - void Organize(); - void CopyToDevice(); - void EditTracks(); - void ShowInBrowser() const; - - private: - void RecheckIsEmpty(); - bool RestoreLevelFocus(const QModelIndex &parent = QModelIndex()); - void SaveContainerPath(const QModelIndex &child); - - private: - Application *app_; - - QMenu *context_menu_; - QModelIndex context_menu_index_; - QAction *load_; - QAction *add_to_playlist_; - QAction *add_to_playlist_enqueue_; - QAction *open_in_new_playlist_; - QAction *organize_; -#ifndef Q_OS_WIN - QAction *copy_to_device_; -#endif - QAction *edit_track_; - QAction *edit_tracks_; - QAction *show_in_browser_; - - std::unique_ptr organize_dialog_; - std::unique_ptr edit_tag_dialog_; - - bool is_in_keyboard_search_; - - // Save focus - Song last_selected_song_; - QString last_selected_container_; - QSet last_selected_path_; - - ContextAlbumsModel *model_; - -}; - -#endif // CONTEXTALBUMSVIEW_H diff --git a/src/context/contextview.cpp b/src/context/contextview.cpp index f9ad7959c..1e2053ab4 100644 --- a/src/context/contextview.cpp +++ b/src/context/contextview.cpp @@ -68,8 +68,6 @@ #include "contextview.h" #include "contextalbum.h" -#include "contextalbumsmodel.h" -#include "contextalbumsview.h" ContextView::ContextView(QWidget *parent) : QWidget(parent), @@ -81,7 +79,6 @@ ContextView::ContextView(QWidget *parent) action_show_album_(nullptr), action_show_data_(nullptr), action_show_output_(nullptr), - action_show_albums_(nullptr), action_show_lyrics_(nullptr), action_search_lyrics_(nullptr), layout_container_(new QVBoxLayout()), @@ -101,12 +98,9 @@ ContextView::ContextView(QWidget *parent) widget_play_output_(new QWidget(this)), layout_play_data_(new QGridLayout()), layout_play_output_(new QGridLayout()), - label_play_albums_(new QLabel(this)), textedit_play_lyrics_(new ResizableTextEdit(this)), - widget_albums_(new ContextAlbumsView(this)), spacer_play_output_(new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed)), spacer_play_data_(new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed)), - spacer_play_albums_(new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed)), spacer_play_bottom_(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Minimum)), label_filetype_title_(new QLabel(this)), label_length_title_(new QLabel(this)), @@ -246,18 +240,11 @@ ContextView::ContextView(QWidget *parent) textedit_play_lyrics_->setFrameShape(QFrame::NoFrame); textedit_play_lyrics_->hide(); - widget_albums_->hide(); - label_play_albums_->setWordWrap(true); - label_play_albums_->hide(); - layout_play_->setContentsMargins(0, 0, 0, 0); layout_play_->addWidget(widget_play_output_); layout_play_->addSpacerItem(spacer_play_output_); layout_play_->addWidget(widget_play_data_); layout_play_->addSpacerItem(spacer_play_data_); - layout_play_->addWidget(label_play_albums_); - layout_play_->addWidget(widget_albums_); - layout_play_->addSpacerItem(spacer_play_albums_); layout_play_->addWidget(textedit_play_lyrics_); layout_play_->addSpacerItem(spacer_play_bottom_); @@ -267,8 +254,7 @@ ContextView::ContextView(QWidget *parent) << label_length_title_ << label_samplerate_title_ << label_bitdepth_title_ - << label_bitrate_title_ - << label_play_albums_; + << label_bitrate_title_; labels_play_data_ << label_engine_icon_ << label_engine_ @@ -278,8 +264,7 @@ ContextView::ContextView(QWidget *parent) << label_length_ << label_samplerate_ << label_bitdepth_ - << label_bitrate_ - << label_play_albums_; + << label_bitrate_; labels_play_all_ = labels_play_ << labels_play_data_; @@ -296,7 +281,6 @@ void ContextView::Init(Application *app, CollectionView *collectionview, AlbumCo album_cover_choice_controller_ = album_cover_choice_controller; widget_album_->Init(this, album_cover_choice_controller_); - widget_albums_->Init(app_); lyrics_fetcher_ = new LyricsFetcher(app_->lyrics_providers(), this); QObject::connect(collectionview_, &CollectionView::TotalSongCountUpdated_, this, &ContextView::UpdateNoSong); @@ -322,10 +306,6 @@ void ContextView::AddActions() { action_show_output_->setCheckable(true); action_show_output_->setChecked(true); - action_show_albums_ = new QAction(tr("Show albums by artist"), this); - action_show_albums_->setCheckable(true); - action_show_albums_->setChecked(false); - action_show_lyrics_ = new QAction(tr("Show song lyrics"), this); action_show_lyrics_->setCheckable(true); action_show_lyrics_->setChecked(true); @@ -337,17 +317,15 @@ void ContextView::AddActions() { menu_options_->addAction(action_show_album_); menu_options_->addAction(action_show_data_); menu_options_->addAction(action_show_output_); - menu_options_->addAction(action_show_albums_); menu_options_->addAction(action_show_lyrics_); menu_options_->addAction(action_search_lyrics_); menu_options_->addSeparator(); ReloadSettings(); - QObject::connect(action_show_album_, &QAction::triggered, this, &ContextView::ActionShowAlbums); + QObject::connect(action_show_album_, &QAction::triggered, this, &ContextView::ActionShowAlbum); QObject::connect(action_show_data_, &QAction::triggered, this, &ContextView::ActionShowData); QObject::connect(action_show_output_, &QAction::triggered, this, &ContextView::ActionShowOutput); - QObject::connect(action_show_albums_, &QAction::triggered, this, &ContextView::ActionShowAlbums); QObject::connect(action_show_lyrics_, &QAction::triggered, this, &ContextView::ActionShowLyrics); QObject::connect(action_search_lyrics_, &QAction::triggered, this, &ContextView::ActionSearchLyrics); @@ -362,7 +340,6 @@ void ContextView::ReloadSettings() { action_show_album_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ALBUM], true).toBool()); action_show_data_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::TECHNICAL_DATA], false).toBool()); action_show_output_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ENGINE_AND_DEVICE], false).toBool()); - action_show_albums_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ALBUMS_BY_ARTIST], false).toBool()); action_show_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::SONG_LYRICS], true).toBool()); action_search_lyrics_->setChecked(s.value(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::SEARCH_LYRICS], true).toBool()); font_headline_ = s.value("font_headline", font().family()).toString(); @@ -476,7 +453,6 @@ void ContextView::UpdateFonts() { for (QTextEdit *e : textedit_play_) { e->setStyleSheet(font_style); } - label_play_albums_->setStyleSheet(QString("background-color: #3DADE8; color: rgb(255, 255, 255); font: %1pt \"%2\"; font-weight: regular;").arg(font_size_normal_).arg(font_normal_)); } @@ -596,35 +572,6 @@ void ContextView::SetSong() { spacer_play_output_->changeSize(0, 0, QSizePolicy::Fixed); } - if (action_show_albums_->isChecked() && song_prev_.artist() != song_playing_.artist()) { - CollectionBackend::AlbumList albumlist; - widget_albums_->albums_model()->Reset(); - albumlist = app_->collection_backend()->GetAlbumsByArtist(song_playing_.effective_albumartist()); - if (albumlist.count() > 1) { - label_play_albums_->show(); - widget_albums_->show(); - label_play_albums_->setText("" + tr("Albums by %1").arg(song_playing_.effective_albumartist().toHtmlEscaped()) + ""); - for (const CollectionBackend::Album &album : albumlist) { - SongList songs = app_->collection_backend()->GetAlbumSongs(song_playing_.effective_albumartist(), album.album); - widget_albums_->albums_model()->AddSongs(songs); - } - spacer_play_albums_->changeSize(20, 10, QSizePolicy::Fixed); - } - else { - label_play_albums_->hide(); - widget_albums_->hide(); - label_play_albums_->clear(); - spacer_play_albums_->changeSize(0, 0, QSizePolicy::Fixed); - } - } - else if (!action_show_albums_->isChecked()) { - label_play_albums_->hide(); - widget_albums_->hide(); - label_play_albums_->clear(); - widget_albums_->albums_model()->Reset(); - spacer_play_albums_->changeSize(0, 0, QSizePolicy::Fixed); - } - if (action_show_lyrics_->isChecked() && !lyrics_.isEmpty()) { textedit_play_lyrics_->setText(lyrics_); textedit_play_lyrics_->show(); @@ -794,17 +741,6 @@ void ContextView::ActionShowOutput() { } -void ContextView::ActionShowAlbums() { - - QSettings s; - s.beginGroup(ContextSettingsPage::kSettingsGroup); - s.setValue(ContextSettingsPage::kSettingsGroupEnable[ContextSettingsPage::ContextSettingsOrder::ALBUMS_BY_ARTIST], action_show_albums_->isChecked()); - s.endGroup(); - song_prev_ = Song(); - if (song_playing_.is_valid()) SetSong(); - -} - void ContextView::ActionShowLyrics() { QSettings s; diff --git a/src/context/contextview.h b/src/context/contextview.h index db5987a75..bcf35d869 100644 --- a/src/context/contextview.h +++ b/src/context/contextview.h @@ -49,7 +49,6 @@ class ResizableTextEdit; class Application; class CollectionView; class AlbumCoverChoiceController; -class ContextAlbumsView; class LyricsFetcher; class ContextView : public QWidget { @@ -61,7 +60,6 @@ class ContextView : public QWidget { void Init(Application *app, CollectionView *collectionview, AlbumCoverChoiceController *album_cover_choice_controller); ContextAlbum *album_widget() const { return widget_album_; } - ContextAlbumsView *albums_widget() const { return widget_albums_; } bool album_enabled() const { return action_show_album_->isChecked(); } Song song_playing() const { return song_playing_; } @@ -88,7 +86,6 @@ class ContextView : public QWidget { void ActionShowAlbum(); void ActionShowData(); void ActionShowOutput(); - void ActionShowAlbums(); void ActionShowLyrics(); void ActionSearchLyrics(); void UpdateNoSong(); @@ -113,7 +110,6 @@ class ContextView : public QWidget { QAction *action_show_album_; QAction *action_show_data_; QAction *action_show_output_; - QAction *action_show_albums_; QAction *action_show_lyrics_; QAction *action_search_lyrics_; @@ -134,13 +130,10 @@ class ContextView : public QWidget { QWidget *widget_play_output_; QGridLayout *layout_play_data_; QGridLayout *layout_play_output_; - QLabel *label_play_albums_; ResizableTextEdit *textedit_play_lyrics_; - ContextAlbumsView *widget_albums_; QSpacerItem *spacer_play_output_; QSpacerItem *spacer_play_data_; - QSpacerItem *spacer_play_albums_; QSpacerItem *spacer_play_bottom_; QLabel *label_filetype_title_; diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp index 5b9269dfb..da5f1e191 100644 --- a/src/core/mainwindow.cpp +++ b/src/core/mainwindow.cpp @@ -120,7 +120,6 @@ #include "widgets/trackslider.h" #include "osd/osdbase.h" #include "context/contextview.h" -#include "context/contextalbumsview.h" #include "collection/collection.h" #include "collection/collectionbackend.h" #include "collection/collectiondirectorymodel.h" @@ -833,7 +832,6 @@ MainWindow::MainWindow(Application *app, std::shared_ptr tray_ic QObject::connect(this, &MainWindow::AlbumCoverReady, context_view_, &ContextView::AlbumCoverLoaded); QObject::connect(this, &MainWindow::SearchCoverInProgress, context_view_->album_widget(), &ContextAlbum::SearchCoverInProgress); QObject::connect(context_view_, &ContextView::AlbumEnabledChanged, this, &MainWindow::TabSwitched); - QObject::connect(context_view_->albums_widget(), &ContextAlbumsView::AddToPlaylistSignal, this, &MainWindow::AddToPlaylist); // Analyzer QObject::connect(ui_->analyzer, &AnalyzerContainer::WheelEvent, this, &MainWindow::VolumeWheelEvent); diff --git a/src/settings/contextsettingspage.cpp b/src/settings/contextsettingspage.cpp index f1f7e0f26..52496a1d8 100644 --- a/src/settings/contextsettingspage.cpp +++ b/src/settings/contextsettingspage.cpp @@ -52,7 +52,6 @@ const char *ContextSettingsPage::kSettingsGroupEnable[ContextSettingsOrder::NELE "AlbumEnable", "EngineAndDeviceEnable", "TechnicalDataEnable", - "AlbumsByArtistEnable", "SongLyricsEnable", "SearchCoverEnable", "SearchLyricsEnable", @@ -70,7 +69,6 @@ ContextSettingsPage::ContextSettingsPage(SettingsDialog *dialog, QWidget *parent checkboxes_[ContextSettingsOrder::ALBUM] = ui_->checkbox_album; checkboxes_[ContextSettingsOrder::ENGINE_AND_DEVICE] = ui_->checkbox_engine_device; checkboxes_[ContextSettingsOrder::TECHNICAL_DATA] = ui_->checkbox_technical_data; - checkboxes_[ContextSettingsOrder::ALBUMS_BY_ARTIST] = ui_->checkbox_albums; checkboxes_[ContextSettingsOrder::SONG_LYRICS] = ui_->checkbox_song_lyrics; checkboxes_[ContextSettingsOrder::SEARCH_COVER] = ui_->checkbox_search_cover; checkboxes_[ContextSettingsOrder::SEARCH_LYRICS] = ui_->checkbox_search_lyrics; diff --git a/src/settings/contextsettingspage.h b/src/settings/contextsettingspage.h index d1504c0c7..fcec562e1 100644 --- a/src/settings/contextsettingspage.h +++ b/src/settings/contextsettingspage.h @@ -46,7 +46,6 @@ class ContextSettingsPage : public SettingsPage { ALBUM, ENGINE_AND_DEVICE, TECHNICAL_DATA, - ALBUMS_BY_ARTIST, SONG_LYRICS, SEARCH_COVER, SEARCH_LYRICS, diff --git a/src/settings/contextsettingspage.ui b/src/settings/contextsettingspage.ui index 4a8e593a9..bd1d2aec7 100644 --- a/src/settings/contextsettingspage.ui +++ b/src/settings/contextsettingspage.ui @@ -170,16 +170,6 @@ - - - - Albums by Artist - - - false - - -