mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-31 11:35:24 +01:00
Refer to playlists by ID rather than index in the tabbar, so they can be moved around
This commit is contained in:
parent
a274f8cbfc
commit
119c6fbd6e
@ -233,7 +233,7 @@ void Player::PlayPause() {
|
||||
|
||||
case Engine::Empty:
|
||||
case Engine::Idle: {
|
||||
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||
playlists_->SetActivePlaylist(playlists_->current_id());
|
||||
if (playlists_->active()->rowCount() == 0)
|
||||
break;
|
||||
|
||||
|
@ -78,7 +78,7 @@ void PlaylistContainer::ClearFilter() {
|
||||
void PlaylistContainer::SetManager(PlaylistManager *manager) {
|
||||
manager_ = manager;
|
||||
|
||||
connect(ui_->tab_bar, SIGNAL(currentChanged(int)),
|
||||
connect(ui_->tab_bar, SIGNAL(CurrentIdChanged(int)),
|
||||
manager, SLOT(SetCurrentPlaylist(int)));
|
||||
connect(ui_->tab_bar, SIGNAL(Rename(int,QString)),
|
||||
manager, SLOT(Rename(int,QString)));
|
||||
@ -103,8 +103,8 @@ void PlaylistContainer::SetViewModel(Playlist* playlist) {
|
||||
playlist->IgnoreSorting(false);
|
||||
|
||||
// Ensure that tab is current
|
||||
if (ui_->tab_bar->currentIndex() != manager_->current_index())
|
||||
ui_->tab_bar->setCurrentIndex(manager_->current_index());
|
||||
if (ui_->tab_bar->current_id() != manager_->current_id())
|
||||
ui_->tab_bar->set_current_id(manager_->current_id());
|
||||
|
||||
// Sort out the undo/redo actions
|
||||
delete undo_;
|
||||
@ -142,25 +142,26 @@ void PlaylistContainer::UpdateActiveIcon(const QIcon& icon) {
|
||||
|
||||
// Set our icon
|
||||
if (!icon.isNull())
|
||||
ui_->tab_bar->setTabIcon(manager_->active_index(), icon);
|
||||
ui_->tab_bar->set_icon_by_id(manager_->active_id(), icon);
|
||||
}
|
||||
|
||||
void PlaylistContainer::PlaylistAdded(int index, const QString &name) {
|
||||
ui_->tab_bar->insertTab(index, name);
|
||||
void PlaylistContainer::PlaylistAdded(int id, const QString &name) {
|
||||
int index = ui_->tab_bar->count();
|
||||
ui_->tab_bar->InsertTab(id, index, name);
|
||||
|
||||
// Are we startup up, should we select this tab?
|
||||
if (starting_up_ && settings_.value("current_playlist", 0).toInt() == index) {
|
||||
if (starting_up_ && settings_.value("current_playlist", 0).toInt() == id) {
|
||||
starting_up_ = false;
|
||||
ui_->tab_bar->setCurrentIndex(index);
|
||||
ui_->tab_bar->set_current_id(id);
|
||||
}
|
||||
}
|
||||
|
||||
void PlaylistContainer::PlaylistRemoved(int index) {
|
||||
ui_->tab_bar->removeTab(index);
|
||||
void PlaylistContainer::PlaylistRemoved(int id) {
|
||||
ui_->tab_bar->RemoveTab(id);
|
||||
}
|
||||
|
||||
void PlaylistContainer::PlaylistRenamed(int index, const QString &new_name) {
|
||||
ui_->tab_bar->setTabText(index, new_name);
|
||||
void PlaylistContainer::PlaylistRenamed(int id, const QString &new_name) {
|
||||
ui_->tab_bar->set_text_by_id(id, new_name);
|
||||
}
|
||||
|
||||
void PlaylistContainer::NewPlaylist() {
|
||||
@ -185,5 +186,5 @@ void PlaylistContainer::Save() {
|
||||
if (starting_up_)
|
||||
return;
|
||||
|
||||
settings_.setValue("current_playlist", ui_->tab_bar->currentIndex());
|
||||
settings_.setValue("current_playlist", ui_->tab_bar->current_id());
|
||||
}
|
||||
|
@ -28,6 +28,12 @@ PlaylistManager::PlaylistManager(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
PlaylistManager::~PlaylistManager() {
|
||||
foreach (const Data& data, playlists_.values()) {
|
||||
delete data.p;
|
||||
}
|
||||
}
|
||||
|
||||
void PlaylistManager::Init(LibraryBackend* library_backend,
|
||||
PlaylistBackend* playlist_backend,
|
||||
PlaylistSequence* sequence) {
|
||||
@ -52,16 +58,15 @@ Playlist* PlaylistManager::AddPlaylist(int id, const QString& name) {
|
||||
connect(ret, SIGNAL(PlaylistChanged()), SIGNAL(PlaylistChanged()));
|
||||
connect(ret, SIGNAL(EditingFinished(QModelIndex)), SIGNAL(EditingFinished(QModelIndex)));
|
||||
|
||||
playlists_ << Data(ret, name);
|
||||
playlists_[id] = Data(ret, name);
|
||||
|
||||
int index = playlists_.count() - 1;
|
||||
emit PlaylistAdded(index, name);
|
||||
emit PlaylistAdded(id, name);
|
||||
|
||||
if (current_ == -1) {
|
||||
SetCurrentPlaylist(index);
|
||||
SetCurrentPlaylist(id);
|
||||
}
|
||||
if (active_ == -1) {
|
||||
SetActivePlaylist(index);
|
||||
SetActivePlaylist(id);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -74,60 +79,64 @@ void PlaylistManager::New(const QString& name) {
|
||||
qFatal("Couldn't create playlist");
|
||||
|
||||
AddPlaylist(id, name);
|
||||
SetCurrentPlaylist(playlists_.count() - 1);
|
||||
SetCurrentPlaylist(id);
|
||||
}
|
||||
|
||||
void PlaylistManager::Load(const QString& filename) {
|
||||
|
||||
}
|
||||
|
||||
void PlaylistManager::Save(int index, const QString& filename) {
|
||||
Q_ASSERT(index >= 0 && index < playlists_.count());
|
||||
void PlaylistManager::Save(int id, const QString& filename) {
|
||||
Q_ASSERT(playlists_.contains(id));
|
||||
}
|
||||
|
||||
void PlaylistManager::Rename(int index, const QString& new_name) {
|
||||
Q_ASSERT(index >= 0 && index < playlists_.count());
|
||||
void PlaylistManager::Rename(int id, const QString& new_name) {
|
||||
Q_ASSERT(playlists_.contains(id));
|
||||
|
||||
playlist_backend_->RenamePlaylist(playlist(index)->id(), new_name);
|
||||
playlists_[index].name = new_name;
|
||||
playlist_backend_->RenamePlaylist(id, new_name);
|
||||
playlists_[id].name = new_name;
|
||||
|
||||
emit PlaylistRenamed(index, new_name);
|
||||
emit PlaylistRenamed(id, new_name);
|
||||
}
|
||||
|
||||
void PlaylistManager::Remove(int index) {
|
||||
Q_ASSERT(index >= 0 && index < playlists_.count());
|
||||
void PlaylistManager::Remove(int id) {
|
||||
Q_ASSERT(playlists_.contains(id));
|
||||
|
||||
// Won't allow removing the last playlist
|
||||
if (playlists_.count() <= 1)
|
||||
return;
|
||||
|
||||
playlist_backend_->RemovePlaylist(playlist(index)->id());
|
||||
playlist_backend_->RemovePlaylist(id);
|
||||
|
||||
if (index == active_)
|
||||
SetActivePlaylist(qMax(0, index-1));
|
||||
if (index == current_)
|
||||
SetCurrentPlaylist(qMax(0, index-1));
|
||||
playlists_.takeAt(index);
|
||||
int next_id = playlists_.constBegin()->p->id();
|
||||
|
||||
emit PlaylistRemoved(index);
|
||||
if (id == active_)
|
||||
SetActivePlaylist(next_id);
|
||||
if (id == current_)
|
||||
SetCurrentPlaylist(next_id);
|
||||
|
||||
Data data = playlists_.take(id);
|
||||
delete data.p;
|
||||
|
||||
emit PlaylistRemoved(id);
|
||||
}
|
||||
|
||||
void PlaylistManager::SetCurrentPlaylist(int index) {
|
||||
Q_ASSERT(index >= 0 && index < playlists_.count());
|
||||
current_ = index;
|
||||
void PlaylistManager::SetCurrentPlaylist(int id) {
|
||||
Q_ASSERT(playlists_.contains(id));
|
||||
current_ = id;
|
||||
emit CurrentChanged(current());
|
||||
}
|
||||
|
||||
void PlaylistManager::SetActivePlaylist(int index) {
|
||||
Q_ASSERT(index >= 0 && index < playlists_.count());
|
||||
void PlaylistManager::SetActivePlaylist(int id) {
|
||||
Q_ASSERT(playlists_.contains(id));
|
||||
|
||||
// Kinda a hack: unset the current item from the old active playlist before
|
||||
// setting the new one
|
||||
if (active_ != -1)
|
||||
active()->set_current_index(-1);
|
||||
|
||||
active_ = index;
|
||||
emit ActiveChanged(current());
|
||||
active_ = id;
|
||||
emit ActiveChanged(active());
|
||||
}
|
||||
|
||||
void PlaylistManager::ClearCurrent() {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define PLAYLISTMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
class LibraryBackend;
|
||||
class Playlist;
|
||||
@ -33,13 +34,14 @@ class PlaylistManager : public QObject {
|
||||
|
||||
public:
|
||||
PlaylistManager(QObject *parent = 0);
|
||||
~PlaylistManager();
|
||||
|
||||
int current_index() const { return current_; }
|
||||
int active_index() const { return active_; }
|
||||
int current_id() const { return current_; }
|
||||
int active_id() const { return active_; }
|
||||
|
||||
Playlist* playlist(int index) const { return playlists_[index].p; }
|
||||
Playlist* current() const { return playlist(current_index()); }
|
||||
Playlist* active() const { return playlist(active_index()); }
|
||||
Playlist* playlist(int id) const { return playlists_[id].p; }
|
||||
Playlist* current() const { return playlist(current_id()); }
|
||||
Playlist* active() const { return playlist(active_id()); }
|
||||
|
||||
QString name(int index) const { return playlists_[index].name; }
|
||||
|
||||
@ -53,12 +55,13 @@ public:
|
||||
public slots:
|
||||
void New(const QString& name);
|
||||
void Load(const QString& filename);
|
||||
void Save(int index, const QString& filename);
|
||||
void Rename(int index, const QString& new_name);
|
||||
void Remove(int index);
|
||||
void Save(int id, const QString& filename);
|
||||
void Rename(int id, const QString& new_name);
|
||||
void Remove(int id);
|
||||
|
||||
void SetCurrentPlaylist(int index);
|
||||
void SetActivePlaylist(int index);
|
||||
void SetCurrentPlaylist(int id);
|
||||
void SetActivePlaylist(int id);
|
||||
void SetActiveToCurrent() { SetActivePlaylist(current_id()); }
|
||||
|
||||
// Convenience slots that defer to either current() or active()
|
||||
void ClearCurrent();
|
||||
@ -69,9 +72,9 @@ public slots:
|
||||
void SetActiveStreamMetadata(const QUrl& url, const Song& song);
|
||||
|
||||
signals:
|
||||
void PlaylistAdded(int index, const QString& name);
|
||||
void PlaylistRemoved(int index);
|
||||
void PlaylistRenamed(int index, const QString& new_name);
|
||||
void PlaylistAdded(int id, const QString& name);
|
||||
void PlaylistRemoved(int id);
|
||||
void PlaylistRenamed(int id, const QString& new_name);
|
||||
void CurrentChanged(Playlist* new_playlist);
|
||||
void ActiveChanged(Playlist* new_playlist);
|
||||
|
||||
@ -85,7 +88,7 @@ private:
|
||||
|
||||
private:
|
||||
struct Data {
|
||||
Data(Playlist* _p, const QString& _name) : p(_p), name(_name) {}
|
||||
Data(Playlist* _p = NULL, const QString& _name = QString()) : p(_p), name(_name) {}
|
||||
Playlist* p;
|
||||
QString name;
|
||||
};
|
||||
@ -94,7 +97,9 @@ private:
|
||||
LibraryBackend* library_backend_;
|
||||
PlaylistSequence* sequence_;
|
||||
|
||||
QList<Data> playlists_;
|
||||
// key = id
|
||||
QMap<int, Data> playlists_;
|
||||
|
||||
int current_;
|
||||
int active_;
|
||||
};
|
||||
|
@ -24,11 +24,14 @@
|
||||
PlaylistTabBar::PlaylistTabBar(QWidget *parent)
|
||||
: QTabBar(parent),
|
||||
menu_(new QMenu(this)),
|
||||
menu_index_(-1)
|
||||
menu_index_(-1),
|
||||
suppress_current_changed_(false)
|
||||
{
|
||||
rename_ = menu_->addAction(IconLoader::Load("edit-rename"), tr("Rename playlist"), this, SLOT(Rename()));
|
||||
remove_ = menu_->addAction(IconLoader::Load("list-remove"), tr("Remove playlist"), this, SLOT(Remove()));
|
||||
menu_->addSeparator();
|
||||
|
||||
connect(this, SIGNAL(currentChanged(int)), this, SLOT(CurrentIndexChanged(int)));
|
||||
}
|
||||
|
||||
void PlaylistTabBar::SetActions(
|
||||
@ -67,3 +70,50 @@ void PlaylistTabBar::Remove() {
|
||||
|
||||
emit Remove(menu_index_);
|
||||
}
|
||||
|
||||
int PlaylistTabBar::current_id() const {
|
||||
if (currentIndex() == -1)
|
||||
return -1;
|
||||
return tabData(currentIndex()).toInt();
|
||||
}
|
||||
|
||||
|
||||
int PlaylistTabBar::index_of(int id) const {
|
||||
for (int i=0 ; i<count() ; ++i) {
|
||||
if (tabData(i).toInt() == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void PlaylistTabBar::set_current_id(int id) {
|
||||
setCurrentIndex(index_of(id));
|
||||
}
|
||||
|
||||
void PlaylistTabBar::set_icon_by_id(int id, const QIcon &icon) {
|
||||
setTabIcon(index_of(id), icon);
|
||||
}
|
||||
|
||||
void PlaylistTabBar::RemoveTab(int id) {
|
||||
removeTab(index_of(id));
|
||||
}
|
||||
|
||||
void PlaylistTabBar::set_text_by_id(int id, const QString &text) {
|
||||
setTabText(index_of(id), text);
|
||||
}
|
||||
|
||||
void PlaylistTabBar::CurrentIndexChanged(int index) {
|
||||
if (!suppress_current_changed_)
|
||||
emit CurrentIdChanged(tabData(index).toInt());
|
||||
}
|
||||
|
||||
void PlaylistTabBar::InsertTab(int id, int index, const QString& text) {
|
||||
suppress_current_changed_ = true;
|
||||
insertTab(index, text);
|
||||
setTabData(index, id);
|
||||
suppress_current_changed_ = false;
|
||||
|
||||
if (currentIndex() == index)
|
||||
emit CurrentIdChanged(id);
|
||||
}
|
||||
|
@ -30,11 +30,26 @@ public:
|
||||
void SetActions(QAction* new_playlist, QAction* save_playlist,
|
||||
QAction* load_playlist);
|
||||
|
||||
// We use IDs to refer to tabs so the tabs can be moved around (and their
|
||||
// indexes change).
|
||||
int index_of(int id) const;
|
||||
int current_id() const;
|
||||
|
||||
// Utility functions that use IDs rather than indexes
|
||||
void set_current_id(int id);
|
||||
void set_icon_by_id(int id, const QIcon& icon);
|
||||
void set_text_by_id(int id, const QString& text);
|
||||
|
||||
void RemoveTab(int id);
|
||||
void InsertTab(int id, int index, const QString& text);
|
||||
|
||||
signals:
|
||||
void Rename(int index, const QString& name);
|
||||
void Remove(int index);
|
||||
void CurrentIdChanged(int id);
|
||||
void Rename(int id, const QString& name);
|
||||
void Remove(int id);
|
||||
|
||||
private slots:
|
||||
void CurrentIndexChanged(int index);
|
||||
void Rename();
|
||||
void Remove();
|
||||
|
||||
@ -46,6 +61,8 @@ private:
|
||||
int menu_index_;
|
||||
QAction* rename_;
|
||||
QAction* remove_;
|
||||
|
||||
bool suppress_current_changed_;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTTABBAR_H
|
||||
|
@ -479,7 +479,7 @@ void MainWindow::AddFilesToPlaylist(bool clear_first, const QList<QUrl>& urls) {
|
||||
QModelIndex playlist_index = playlists_->current()->InsertPaths(urls);
|
||||
|
||||
if (playlist_index.isValid() && player_->GetState() != Engine::Playing) {
|
||||
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||
playlists_->SetActiveToCurrent();
|
||||
player_->PlayAt(playlist_index.row(), Engine::First, true);
|
||||
}
|
||||
}
|
||||
@ -570,7 +570,7 @@ void MainWindow::PlayIndex(const QModelIndex& index) {
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||
playlists_->SetActiveToCurrent();
|
||||
player_->PlayAt(index.row(), Engine::Manual, true);
|
||||
}
|
||||
|
||||
@ -598,7 +598,7 @@ void MainWindow::AddLibraryItemToPlaylist(bool clear_first, const QModelIndex& i
|
||||
library_->model()->GetChildSongs(idx));
|
||||
|
||||
if (first_song.isValid() && player_->GetState() != Engine::Playing) {
|
||||
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||
playlists_->SetActiveToCurrent();
|
||||
player_->PlayAt(first_song.row(), Engine::First, true);
|
||||
}
|
||||
}
|
||||
@ -716,7 +716,7 @@ void MainWindow::RadioDoubleClick(const QModelIndex& index) {
|
||||
|
||||
QModelIndex first_song = playlists_->current()->index(0, 0);
|
||||
if (first_song.isValid() && player_->GetState() != Engine::Playing) {
|
||||
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||
playlists_->SetActiveToCurrent();
|
||||
player_->PlayAt(first_song.row(), Engine::First, true);
|
||||
}
|
||||
}
|
||||
@ -726,7 +726,7 @@ void MainWindow::InsertRadioItem(RadioItem* item) {
|
||||
QList<RadioItem*>() << item);
|
||||
|
||||
if (first_song.isValid() && player_->GetState() != Engine::Playing) {
|
||||
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||
playlists_->SetActiveToCurrent();
|
||||
player_->PlayAt(first_song.row(), Engine::First, true);
|
||||
}
|
||||
}
|
||||
@ -735,7 +735,7 @@ void MainWindow::InsertRadioItems(const PlaylistItemList& items) {
|
||||
QModelIndex first_song = playlists_->current()->InsertItems(items);
|
||||
|
||||
if (first_song.isValid() && player_->GetState() != Engine::Playing) {
|
||||
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||
playlists_->SetActiveToCurrent();
|
||||
player_->PlayAt(first_song.row(), Engine::First, true);
|
||||
}
|
||||
}
|
||||
@ -808,7 +808,7 @@ void MainWindow::PlaylistPlay() {
|
||||
if (playlists_->current()->current_index() == playlist_menu_index_.row()) {
|
||||
player_->PlayPause();
|
||||
} else {
|
||||
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||
playlists_->SetActiveToCurrent();
|
||||
player_->PlayAt(playlist_menu_index_.row(), Engine::Manual, true);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user