diff --git a/src/glue/CMakeLists.txt b/src/glue/CMakeLists.txt index dd9c86537..2e345008c 100644 --- a/src/glue/CMakeLists.txt +++ b/src/glue/CMakeLists.txt @@ -3,6 +3,7 @@ set(GLUE_SOURCES ./query/GetPlaylistQuery.cpp ./query/CategoryListQuery.cpp ./query/CategoryTrackListQuery.cpp + ./query/DeletePlaylistQuery.cpp ./query/NowPlayingTrackListQuery.cpp ./query/SavePlaylistQuery.cpp ./query/SearchTrackListQuery.cpp diff --git a/src/glue/query/DeletePlaylistQuery.cpp b/src/glue/query/DeletePlaylistQuery.cpp new file mode 100644 index 000000000..b2271ed02 --- /dev/null +++ b/src/glue/query/DeletePlaylistQuery.cpp @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007-2016 musikcube team +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the author nor the names of other contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#include "DeletePlaylistQuery.h" + +#include +#include + +using namespace musik::core; +using namespace musik::core::query; +using namespace musik::core::db; +using namespace musik::glue; + +static std::string DELETE_PLAYLIST_TRACKS_QUERY = + "DELETE FROM playlist_tracks WHERE playlist_id=?;"; + +static std::string DELETE_PLAYLIST_QUERY = + "DELETE FROM playlists WHERE id=?;"; + +DeletePlaylistQuery::DeletePlaylistQuery(const DBID playlistId) { + this->playlistId = playlistId; +} + +DeletePlaylistQuery::~DeletePlaylistQuery() { +} + +bool DeletePlaylistQuery::OnRun(musik::core::db::Connection &db) { + ScopedTransaction transaction(db); + + /* create playlist */ + Statement deleteTracks(DELETE_PLAYLIST_TRACKS_QUERY.c_str(), db); + deleteTracks.BindInt(0, this->playlistId); + + if (deleteTracks.Step() == db::Error) { + transaction.Cancel(); + return false; + } + + /* add tracks to playlist */ + Statement deletePlaylist(DELETE_PLAYLIST_QUERY.c_str(), db); + deletePlaylist.BindInt(0, this->playlistId); + + if (deletePlaylist.Step() == db::Error) { + transaction.Cancel(); + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/glue/query/DeletePlaylistQuery.h b/src/glue/query/DeletePlaylistQuery.h new file mode 100644 index 000000000..99ea950a8 --- /dev/null +++ b/src/glue/query/DeletePlaylistQuery.h @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007-2016 musikcube team +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the author nor the names of other contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +namespace musik { + namespace glue { + class DeletePlaylistQuery : public musik::core::query::QueryBase { + public: + DeletePlaylistQuery(const DBID playlistId); + virtual ~DeletePlaylistQuery(); + + virtual std::string Name() { return "DeletePlaylistQuery"; } + + protected: + virtual bool OnRun(musik::core::db::Connection &db); + + private: + DBID playlistId; + }; + } +} diff --git a/src/musikbox/app/layout/NowPlayingLayout.cpp b/src/musikbox/app/layout/NowPlayingLayout.cpp index 6b2e5ccbc..84fcc6593 100755 --- a/src/musikbox/app/layout/NowPlayingLayout.cpp +++ b/src/musikbox/app/layout/NowPlayingLayout.cpp @@ -229,7 +229,7 @@ bool NowPlayingLayout::KeyPress(const std::string& key) { PlayQueueOverlays::ShowRenamePlaylistOverlay(this->library); return true; } - else if (key == "M-d") { + else if (key == "M-x") { PlayQueueOverlays::ShowDeletePlaylistOverlay(this->library); return true; } diff --git a/src/musikbox/app/overlay/PlayQueueOverlays.cpp b/src/musikbox/app/overlay/PlayQueueOverlays.cpp index 2edcfbfb6..7cbe0a760 100644 --- a/src/musikbox/app/overlay/PlayQueueOverlays.cpp +++ b/src/musikbox/app/overlay/PlayQueueOverlays.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -108,6 +109,91 @@ static void showPlaylistListOverlay( cursespp::App::Overlays().Push(dialog); } +static void confirmOverwritePlaylist( + musik::core::ILibraryPtr library, + const std::string& playlistName, + const DBID playlistId, + std::shared_ptr tracks) +{ + std::shared_ptr dialog(new DialogOverlay()); + + (*dialog) + .SetTitle("musikbox") + .SetMessage("are you sure you want to overwrite the playlist '" + playlistName + "'?") + .AddButton("^[", "ESC", "no") + .AddButton( + "KEY_ENTER", + "ENTER", + "yes", + [library, playlistId, tracks](const std::string& str) { + library->Enqueue(SavePlaylistQuery::Replace(playlistId, tracks)); + }); + + App::Overlays().Push(dialog); +} + +static void createNewPlaylist( + std::shared_ptr tracks, + musik::core::ILibraryPtr library) +{ + std::shared_ptr dialog(new InputOverlay()); + + dialog->SetTitle("playlist name") + .SetWidth(DEFAULT_OVERLAY_WIDTH) + .SetText("") + .SetInputAcceptedCallback( + [tracks, library](const std::string& name) { + if (name.size()) { + library->Enqueue(SavePlaylistQuery::Save(name, tracks)); + } + }); + + cursespp::App::Overlays().Push(dialog); +} + +static void renamePlaylist( + musik::core::ILibraryPtr library, + const DBID playlistId, + const std::string& oldName) +{ + std::shared_ptr dialog(new InputOverlay()); + + dialog->SetTitle("new playlist name") + .SetWidth(DEFAULT_OVERLAY_WIDTH) + .SetText(oldName) + .SetInputAcceptedCallback( + [library, playlistId](const std::string& name) { + if (name.size()) { + library->Enqueue(SavePlaylistQuery::Rename(playlistId, name)); + } + }); + + cursespp::App::Overlays().Push(dialog); +} + +static void confirmDeletePlaylist( + musik::core::ILibraryPtr library, + const std::string& playlistName, + const DBID playlistId) +{ + std::shared_ptr dialog(new DialogOverlay()); + + (*dialog) + .SetTitle("musikbox") + .SetMessage("are you sure you want to delete '" + playlistName + "'?") + .AddButton("^[", "ESC", "no") + .AddButton( + "KEY_ENTER", + "ENTER", + "yes", + [library, playlistId](const std::string& str) { + library->Enqueue(std::shared_ptr( + new DeletePlaylistQuery(playlistId))); + }); + + App::Overlays().Push(dialog); +} + PlayQueueOverlays::PlayQueueOverlays() { } @@ -225,48 +311,6 @@ void PlayQueueOverlays::ShowLoadPlaylistOverlay( }); } -static void createNewPlaylist( - std::shared_ptr tracks, - musik::core::ILibraryPtr library) -{ - std::shared_ptr dialog(new InputOverlay()); - - dialog->SetTitle("playlist name") - .SetWidth(DEFAULT_OVERLAY_WIDTH) - .SetText("") - .SetInputAcceptedCallback( - [tracks, library](const std::string& name) { - if (name.size()) { - library->Enqueue(SavePlaylistQuery::Save(name, tracks)); - } - }); - - cursespp::App::Overlays().Push(dialog); -} - -static void confirmOverwritePlaylist( - musik::core::ILibraryPtr library, - const std::string& playlistName, - const DBID playlistId, - std::shared_ptr tracks) -{ - std::shared_ptr dialog(new DialogOverlay()); - - (*dialog) - .SetTitle("musikbox") - .SetMessage("are you sure you want to overwrite the playlist '" + playlistName + "'?") - .AddButton("^[", "ESC", "no") - .AddButton( - "KEY_ENTER", - "ENTER", - "yes", - [library, playlistId, tracks](const std::string& str) { - library->Enqueue(SavePlaylistQuery::Replace(playlistId, tracks)); - }); - - App::Overlays().Push(dialog); -} - void PlayQueueOverlays::ShowSavePlaylistOverlay( musik::core::audio::PlaybackService& playback, musik::core::ILibraryPtr library) @@ -299,26 +343,6 @@ void PlayQueueOverlays::ShowSavePlaylistOverlay( }); } -static void renamePlaylist( - musik::core::ILibraryPtr library, - const DBID playlistId, - const std::string& oldName) -{ - std::shared_ptr dialog(new InputOverlay()); - - dialog->SetTitle("new playlist name") - .SetWidth(DEFAULT_OVERLAY_WIDTH) - .SetText(oldName) - .SetInputAcceptedCallback( - [library, playlistId](const std::string& name) { - if (name.size()) { - library->Enqueue(SavePlaylistQuery::Rename(playlistId, name)); - } - }); - - cursespp::App::Overlays().Push(dialog); -} - void PlayQueueOverlays::ShowRenamePlaylistOverlay(musik::core::ILibraryPtr library) { std::shared_ptr query = queryPlaylists(library); auto result = query->GetResult(); @@ -340,5 +364,22 @@ void PlayQueueOverlays::ShowRenamePlaylistOverlay(musik::core::ILibraryPtr libra } void PlayQueueOverlays::ShowDeletePlaylistOverlay(musik::core::ILibraryPtr library) { - /* stubbed */ + std::shared_ptr query = queryPlaylists(library); + auto result = query->GetResult(); + + std::shared_ptr adapter(new Adapter()); + adapter->SetSelectable(true); + addPlaylistsToAdapter(adapter, result); + + showPlaylistListOverlay( + "delete playlist", + adapter, + [library, result] + (cursespp::IScrollAdapterPtr adapter, size_t index) { + if (index != ListWindow::NO_SELECTION) { + DBID playlistId = (*result)[index]->id; + std::string playlistName = (*result)[index]->displayValue; + confirmDeletePlaylist(library, playlistName, playlistId); + } + }); } \ No newline at end of file