parent
9b14df6b27
commit
653a35496d
@ -169,6 +169,7 @@ set(SOURCES
|
|||||||
dialogs/trackselectiondialog.cpp
|
dialogs/trackselectiondialog.cpp
|
||||||
dialogs/addstreamdialog.cpp
|
dialogs/addstreamdialog.cpp
|
||||||
dialogs/userpassdialog.cpp
|
dialogs/userpassdialog.cpp
|
||||||
|
dialogs/deleteconfirmationdialog.cpp
|
||||||
|
|
||||||
widgets/autoexpandingtreeview.cpp
|
widgets/autoexpandingtreeview.cpp
|
||||||
widgets/busyindicator.cpp
|
widgets/busyindicator.cpp
|
||||||
@ -367,6 +368,7 @@ set(HEADERS
|
|||||||
dialogs/trackselectiondialog.h
|
dialogs/trackselectiondialog.h
|
||||||
dialogs/addstreamdialog.h
|
dialogs/addstreamdialog.h
|
||||||
dialogs/userpassdialog.h
|
dialogs/userpassdialog.h
|
||||||
|
dialogs/deleteconfirmationdialog.h
|
||||||
|
|
||||||
widgets/autoexpandingtreeview.h
|
widgets/autoexpandingtreeview.h
|
||||||
widgets/busyindicator.h
|
widgets/busyindicator.h
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "core/iconloader.h"
|
#include "core/iconloader.h"
|
||||||
#include "core/mimedata.h"
|
#include "core/mimedata.h"
|
||||||
#include "core/utilities.h"
|
#include "core/utilities.h"
|
||||||
|
#include "core/deletefiles.h"
|
||||||
#include "collection.h"
|
#include "collection.h"
|
||||||
#include "collectionbackend.h"
|
#include "collectionbackend.h"
|
||||||
#include "collectiondirectorymodel.h"
|
#include "collectiondirectorymodel.h"
|
||||||
@ -61,7 +62,9 @@
|
|||||||
# include "device/devicestatefiltermodel.h"
|
# include "device/devicestatefiltermodel.h"
|
||||||
#endif
|
#endif
|
||||||
#include "dialogs/edittagdialog.h"
|
#include "dialogs/edittagdialog.h"
|
||||||
|
#include "dialogs/deleteconfirmationdialog.h"
|
||||||
#include "organize/organizedialog.h"
|
#include "organize/organizedialog.h"
|
||||||
|
#include "organize/organizeerrordialog.h"
|
||||||
#include "settings/collectionsettingspage.h"
|
#include "settings/collectionsettingspage.h"
|
||||||
|
|
||||||
CollectionView::CollectionView(QWidget *parent)
|
CollectionView::CollectionView(QWidget *parent)
|
||||||
@ -73,7 +76,23 @@ CollectionView::CollectionView(QWidget *parent)
|
|||||||
total_album_count_(-1),
|
total_album_count_(-1),
|
||||||
nomusic_(":/pictures/nomusic.png"),
|
nomusic_(":/pictures/nomusic.png"),
|
||||||
context_menu_(nullptr),
|
context_menu_(nullptr),
|
||||||
is_in_keyboard_search_(false)
|
action_load_(nullptr),
|
||||||
|
action_add_to_playlist_(nullptr),
|
||||||
|
action_add_to_playlist_enqueue_(nullptr),
|
||||||
|
action_add_to_playlist_enqueue_next_(nullptr),
|
||||||
|
action_open_in_new_playlist_(nullptr),
|
||||||
|
action_organize_(nullptr),
|
||||||
|
#ifndef Q_OS_WIN
|
||||||
|
action_copy_to_device_(nullptr),
|
||||||
|
#endif
|
||||||
|
action_edit_track_(nullptr),
|
||||||
|
action_edit_tracks_(nullptr),
|
||||||
|
action_rescan_songs_(nullptr),
|
||||||
|
action_show_in_browser_(nullptr),
|
||||||
|
action_show_in_various_(nullptr),
|
||||||
|
action_no_show_in_various_(nullptr),
|
||||||
|
is_in_keyboard_search_(false),
|
||||||
|
delete_files_(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
setItemDelegate(new CollectionItemDelegate(this));
|
setItemDelegate(new CollectionItemDelegate(this));
|
||||||
@ -211,6 +230,8 @@ void CollectionView::ReloadSettings() {
|
|||||||
app_->collection_model()->set_show_dividers(settings.value("show_dividers", true).toBool());
|
app_->collection_model()->set_show_dividers(settings.value("show_dividers", true).toBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete_files_ = settings.value("delete_files", false).toBool();
|
||||||
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -316,41 +337,41 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) {
|
|||||||
|
|
||||||
if (!context_menu_) {
|
if (!context_menu_) {
|
||||||
context_menu_ = new QMenu(this);
|
context_menu_ = new QMenu(this);
|
||||||
add_to_playlist_ = context_menu_->addAction(IconLoader::Load("media-playback-start"), tr("Append to current playlist"), this, SLOT(AddToPlaylist()));
|
action_add_to_playlist_ = context_menu_->addAction(IconLoader::Load("media-playback-start"), tr("Append to current playlist"), this, SLOT(AddToPlaylist()));
|
||||||
load_ = context_menu_->addAction(IconLoader::Load("media-playback-start"), tr("Replace current playlist"), this, SLOT(Load()));
|
action_load_ = context_menu_->addAction(IconLoader::Load("media-playback-start"), tr("Replace current playlist"), this, SLOT(Load()));
|
||||||
open_in_new_playlist_ = context_menu_->addAction(IconLoader::Load("document-new"), tr("Open in new playlist"), this, SLOT(OpenInNewPlaylist()));
|
action_open_in_new_playlist_ = context_menu_->addAction(IconLoader::Load("document-new"), tr("Open in new playlist"), this, SLOT(OpenInNewPlaylist()));
|
||||||
|
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
add_to_playlist_enqueue_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue track"), this, SLOT(AddToPlaylistEnqueue()));
|
action_add_to_playlist_enqueue_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue track"), this, SLOT(AddToPlaylistEnqueue()));
|
||||||
add_to_playlist_enqueue_next_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue to play next"), this, SLOT(AddToPlaylistEnqueueNext()));
|
action_add_to_playlist_enqueue_next_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue to play next"), this, SLOT(AddToPlaylistEnqueueNext()));
|
||||||
|
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
organize_ = context_menu_->addAction(IconLoader::Load("edit-copy"), tr("Organize files..."), this, SLOT(Organize()));
|
action_organize_ = context_menu_->addAction(IconLoader::Load("edit-copy"), tr("Organize files..."), this, SLOT(Organize()));
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
copy_to_device_ = context_menu_->addAction(IconLoader::Load("device"), tr("Copy to device..."), this, SLOT(CopyToDevice()));
|
action_copy_to_device_ = context_menu_->addAction(IconLoader::Load("device"), tr("Copy to device..."), this, SLOT(CopyToDevice()));
|
||||||
#endif
|
#endif
|
||||||
//delete_ = context_menu_->addAction(IconLoader::Load("edit-delete"), tr("Delete from disk..."), this, SLOT(Delete()));
|
action_delete_files_ = context_menu_->addAction(IconLoader::Load("edit-delete"), tr("Delete from disk..."), this, SLOT(Delete()));
|
||||||
|
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
edit_track_ = context_menu_->addAction(IconLoader::Load("edit-rename"), tr("Edit track information..."), this, SLOT(EditTracks()));
|
action_edit_track_ = context_menu_->addAction(IconLoader::Load("edit-rename"), tr("Edit track information..."), this, SLOT(EditTracks()));
|
||||||
edit_tracks_ = context_menu_->addAction(IconLoader::Load("edit-rename"), tr("Edit tracks information..."), this, SLOT(EditTracks()));
|
action_edit_tracks_ = context_menu_->addAction(IconLoader::Load("edit-rename"), tr("Edit tracks information..."), this, SLOT(EditTracks()));
|
||||||
show_in_browser_ = context_menu_->addAction(IconLoader::Load("document-open-folder"), tr("Show in file browser..."), this, SLOT(ShowInBrowser()));
|
action_show_in_browser_ = context_menu_->addAction(IconLoader::Load("document-open-folder"), tr("Show in file browser..."), this, SLOT(ShowInBrowser()));
|
||||||
|
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
|
|
||||||
rescan_songs_ = context_menu_->addAction(tr("Rescan song(s)"), this, SLOT(RescanSongs()));
|
action_rescan_songs_ = context_menu_->addAction(tr("Rescan song(s)"), this, SLOT(RescanSongs()));
|
||||||
|
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
show_in_various_ = context_menu_->addAction( tr("Show in various artists"), this, SLOT(ShowInVarious()));
|
action_show_in_various_ = context_menu_->addAction( tr("Show in various artists"), this, SLOT(ShowInVarious()));
|
||||||
no_show_in_various_ = context_menu_->addAction( tr("Don't show in various artists"), this, SLOT(NoShowInVarious()));
|
action_no_show_in_various_ = context_menu_->addAction( tr("Don't show in various artists"), this, SLOT(NoShowInVarious()));
|
||||||
|
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
|
|
||||||
context_menu_->addMenu(filter_->menu());
|
context_menu_->addMenu(filter_->menu());
|
||||||
|
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0);
|
action_copy_to_device_->setDisabled(app_->device_manager()->connected_devices_model()->rowCount() == 0);
|
||||||
connect(app_->device_manager()->connected_devices_model(), SIGNAL(IsEmptyChanged(bool)), copy_to_device_, SLOT(setDisabled(bool)));
|
connect(app_->device_manager()->connected_devices_model(), SIGNAL(IsEmptyChanged(bool)), action_copy_to_device_, SLOT(setDisabled(bool)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -376,34 +397,45 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) {
|
|||||||
const bool regular_elements_only = songs_selected == regular_elements && regular_elements > 0;
|
const bool regular_elements_only = songs_selected == regular_elements && regular_elements > 0;
|
||||||
|
|
||||||
// in all modes
|
// in all modes
|
||||||
load_->setEnabled(songs_selected > 0);
|
action_load_->setEnabled(songs_selected > 0);
|
||||||
add_to_playlist_->setEnabled(songs_selected > 0);
|
action_add_to_playlist_->setEnabled(songs_selected > 0);
|
||||||
open_in_new_playlist_->setEnabled(songs_selected > 0);
|
action_open_in_new_playlist_->setEnabled(songs_selected > 0);
|
||||||
add_to_playlist_enqueue_->setEnabled(songs_selected > 0);
|
action_add_to_playlist_enqueue_->setEnabled(songs_selected > 0);
|
||||||
|
|
||||||
// if neither edit_track not edit_tracks are available, we show disabled edit_track element
|
// if neither edit_track not edit_tracks are available, we show disabled edit_track element
|
||||||
edit_track_->setVisible(regular_editable == 1);
|
action_edit_track_->setVisible(regular_editable == 1);
|
||||||
edit_track_->setEnabled(regular_editable == 1);
|
action_edit_track_->setEnabled(regular_editable == 1);
|
||||||
edit_tracks_->setVisible(regular_editable > 1);
|
action_edit_tracks_->setVisible(regular_editable > 1);
|
||||||
edit_tracks_->setEnabled(regular_editable > 1);
|
action_edit_tracks_->setEnabled(regular_editable > 1);
|
||||||
|
|
||||||
rescan_songs_->setVisible(regular_editable > 0);
|
action_rescan_songs_->setVisible(regular_editable > 0);
|
||||||
rescan_songs_->setEnabled(regular_editable > 0);
|
action_rescan_songs_->setEnabled(regular_editable > 0);
|
||||||
|
|
||||||
organize_->setVisible(regular_elements == regular_editable);
|
action_organize_->setVisible(regular_elements == regular_editable);
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
copy_to_device_->setVisible(regular_elements == regular_editable);
|
action_copy_to_device_->setVisible(regular_elements == regular_editable);
|
||||||
#endif
|
#endif
|
||||||
//delete_->setVisible(regular_elements_only);
|
|
||||||
show_in_various_->setVisible(regular_elements_only);
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
no_show_in_various_->setVisible(regular_elements_only);
|
action_delete_files_->setVisible(regular_elements == regular_editable && delete_files_);
|
||||||
|
#else
|
||||||
|
action_delete_files_->setVisible(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
action_show_in_various_->setVisible(regular_elements_only);
|
||||||
|
action_no_show_in_various_->setVisible(regular_elements_only);
|
||||||
|
|
||||||
// only when all selected items are editable
|
// only when all selected items are editable
|
||||||
organize_->setEnabled(regular_elements == regular_editable);
|
action_organize_->setEnabled(regular_elements == regular_editable);
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
copy_to_device_->setEnabled(regular_elements == regular_editable);
|
action_copy_to_device_->setEnabled(regular_elements == regular_editable);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
|
action_delete_files_->setEnabled(regular_elements == regular_editable && delete_files_);
|
||||||
|
#else
|
||||||
|
action_delete_files_->setEnabled(false);
|
||||||
#endif
|
#endif
|
||||||
//delete_->setEnabled(regular_elements == regular_editable);
|
|
||||||
|
|
||||||
context_menu_->popup(e->globalPos());
|
context_menu_->popup(e->globalPos());
|
||||||
|
|
||||||
@ -619,3 +651,33 @@ int CollectionView::TotalArtists() {
|
|||||||
int CollectionView::TotalAlbums() {
|
int CollectionView::TotalAlbums() {
|
||||||
return total_album_count_;
|
return total_album_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CollectionView::Delete() {
|
||||||
|
|
||||||
|
if (!delete_files_) return;
|
||||||
|
|
||||||
|
SongList selected_songs = GetSelectedSongs();
|
||||||
|
QStringList files;
|
||||||
|
for (const Song &song : selected_songs) {
|
||||||
|
files << song.url().toString();
|
||||||
|
}
|
||||||
|
if (DeleteConfirmationDialog::warning(files) != QDialogButtonBox::Yes) return;
|
||||||
|
|
||||||
|
// We can cheat and always take the storage of the first directory, since they'll all be FilesystemMusicStorage in a collection and deleting doesn't check the actual directory.
|
||||||
|
std::shared_ptr<MusicStorage> storage = app_->collection_model()->directory_model()->index(0, 0).data(MusicStorage::Role_Storage).value<std::shared_ptr<MusicStorage>>();
|
||||||
|
|
||||||
|
DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, true);
|
||||||
|
connect(delete_files, SIGNAL(Finished(SongList)), SLOT(DeleteFinished(SongList)));
|
||||||
|
delete_files->Start(selected_songs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectionView::DeleteFilesFinished(const SongList &songs_with_errors) {
|
||||||
|
|
||||||
|
if (songs_with_errors.isEmpty()) return;
|
||||||
|
|
||||||
|
OrganizeErrorDialog *dialog = new OrganizeErrorDialog(this);
|
||||||
|
dialog->Show(OrganizeErrorDialog::Type_Delete, songs_with_errors);
|
||||||
|
// It deletes itself when the user closes it
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -109,6 +109,8 @@ class CollectionView : public AutoExpandingTreeView {
|
|||||||
void ShowInBrowser();
|
void ShowInBrowser();
|
||||||
void ShowInVarious();
|
void ShowInVarious();
|
||||||
void NoShowInVarious();
|
void NoShowInVarious();
|
||||||
|
void Delete();
|
||||||
|
void DeleteFilesFinished(const SongList &songs_with_errors);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RecheckIsEmpty();
|
void RecheckIsEmpty();
|
||||||
@ -128,27 +130,28 @@ class CollectionView : public AutoExpandingTreeView {
|
|||||||
|
|
||||||
QMenu *context_menu_;
|
QMenu *context_menu_;
|
||||||
QModelIndex context_menu_index_;
|
QModelIndex context_menu_index_;
|
||||||
QAction *load_;
|
QAction *action_load_;
|
||||||
QAction *add_to_playlist_;
|
QAction *action_add_to_playlist_;
|
||||||
QAction *add_to_playlist_enqueue_;
|
QAction *action_add_to_playlist_enqueue_;
|
||||||
QAction *add_to_playlist_enqueue_next_;
|
QAction *action_add_to_playlist_enqueue_next_;
|
||||||
QAction *open_in_new_playlist_;
|
QAction *action_open_in_new_playlist_;
|
||||||
QAction *organize_;
|
QAction *action_organize_;
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
QAction *copy_to_device_;
|
QAction *action_copy_to_device_;
|
||||||
#endif
|
#endif
|
||||||
QAction *delete_;
|
QAction *action_edit_track_;
|
||||||
QAction *edit_track_;
|
QAction *action_edit_tracks_;
|
||||||
QAction *edit_tracks_;
|
QAction *action_rescan_songs_;
|
||||||
QAction *rescan_songs_;
|
QAction *action_show_in_browser_;
|
||||||
QAction *show_in_browser_;
|
QAction *action_show_in_various_;
|
||||||
QAction *show_in_various_;
|
QAction *action_no_show_in_various_;
|
||||||
QAction *no_show_in_various_;
|
QAction *action_delete_files_;
|
||||||
|
|
||||||
std::unique_ptr<OrganizeDialog> organize_dialog_;
|
std::unique_ptr<OrganizeDialog> organize_dialog_;
|
||||||
std::unique_ptr<EditTagDialog> edit_tag_dialog_;
|
std::unique_ptr<EditTagDialog> edit_tag_dialog_;
|
||||||
|
|
||||||
bool is_in_keyboard_search_;
|
bool is_in_keyboard_search_;
|
||||||
|
bool delete_files_;
|
||||||
|
|
||||||
// Save focus
|
// Save focus
|
||||||
Song last_selected_song_;
|
Song last_selected_song_;
|
||||||
|
@ -34,10 +34,11 @@
|
|||||||
|
|
||||||
const int DeleteFiles::kBatchSize = 50;
|
const int DeleteFiles::kBatchSize = 50;
|
||||||
|
|
||||||
DeleteFiles::DeleteFiles(TaskManager *task_manager, std::shared_ptr<MusicStorage> storage)
|
DeleteFiles::DeleteFiles(TaskManager *task_manager, std::shared_ptr<MusicStorage> storage, const bool use_trash)
|
||||||
: thread_(nullptr),
|
: thread_(nullptr),
|
||||||
task_manager_(task_manager),
|
task_manager_(task_manager),
|
||||||
storage_(storage),
|
storage_(storage),
|
||||||
|
use_trash_(use_trash),
|
||||||
started_(false),
|
started_(false),
|
||||||
task_id_(0),
|
task_id_(0),
|
||||||
progress_(0) {
|
progress_(0) {
|
||||||
@ -112,6 +113,7 @@ void DeleteFiles::ProcessSomeFiles() {
|
|||||||
|
|
||||||
MusicStorage::DeleteJob job;
|
MusicStorage::DeleteJob job;
|
||||||
job.metadata_ = song;
|
job.metadata_ = song;
|
||||||
|
job.use_trash_ = use_trash_;
|
||||||
|
|
||||||
if (!storage_->DeleteFromStorage(job)) {
|
if (!storage_->DeleteFromStorage(job)) {
|
||||||
songs_with_errors_ << song;
|
songs_with_errors_ << song;
|
||||||
|
@ -38,7 +38,7 @@ class DeleteFiles : public QObject {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DeleteFiles(TaskManager *task_manager, std::shared_ptr<MusicStorage> storage);
|
explicit DeleteFiles(TaskManager *task_manager, std::shared_ptr<MusicStorage> storage, const bool use_trash);
|
||||||
~DeleteFiles() override;
|
~DeleteFiles() override;
|
||||||
|
|
||||||
static const int kBatchSize;
|
static const int kBatchSize;
|
||||||
@ -59,6 +59,7 @@ signals:
|
|||||||
std::shared_ptr<MusicStorage> storage_;
|
std::shared_ptr<MusicStorage> storage_;
|
||||||
|
|
||||||
SongList songs_;
|
SongList songs_;
|
||||||
|
bool use_trash_;
|
||||||
|
|
||||||
bool started_;
|
bool started_;
|
||||||
|
|
||||||
|
@ -108,6 +108,17 @@ bool FilesystemMusicStorage::DeleteFromStorage(const DeleteJob &job) {
|
|||||||
QString path = job.metadata_.url().toLocalFile();
|
QString path = job.metadata_.url().toLocalFile();
|
||||||
QFileInfo fileInfo(path);
|
QFileInfo fileInfo(path);
|
||||||
|
|
||||||
|
if (job.use_trash_) {
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
|
if (fileInfo.isDir())
|
||||||
|
return Utilities::MoveToTrashRecursive(path);
|
||||||
|
else
|
||||||
|
return QFile::moveToTrash(path);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (fileInfo.isDir())
|
if (fileInfo.isDir())
|
||||||
return Utilities::RemoveRecursive(path);
|
return Utilities::RemoveRecursive(path);
|
||||||
else
|
else
|
||||||
|
@ -91,6 +91,8 @@
|
|||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "appearance.h"
|
#include "appearance.h"
|
||||||
|
#include "filesystemmusicstorage.h"
|
||||||
|
#include "deletefiles.h"
|
||||||
#include "engine/enginetype.h"
|
#include "engine/enginetype.h"
|
||||||
#include "engine/enginebase.h"
|
#include "engine/enginebase.h"
|
||||||
#include "engine/engine_fwd.h"
|
#include "engine/engine_fwd.h"
|
||||||
@ -100,6 +102,7 @@
|
|||||||
#include "dialogs/trackselectiondialog.h"
|
#include "dialogs/trackselectiondialog.h"
|
||||||
#include "dialogs/edittagdialog.h"
|
#include "dialogs/edittagdialog.h"
|
||||||
#include "dialogs/addstreamdialog.h"
|
#include "dialogs/addstreamdialog.h"
|
||||||
|
#include "dialogs/deleteconfirmationdialog.h"
|
||||||
#include "organize/organizedialog.h"
|
#include "organize/organizedialog.h"
|
||||||
#include "widgets/fancytabwidget.h"
|
#include "widgets/fancytabwidget.h"
|
||||||
#include "widgets/playingwidget.h"
|
#include "widgets/playingwidget.h"
|
||||||
@ -261,15 +264,16 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
|||||||
playlist_play_pause_(nullptr),
|
playlist_play_pause_(nullptr),
|
||||||
playlist_stop_after_(nullptr),
|
playlist_stop_after_(nullptr),
|
||||||
playlist_undoredo_(nullptr),
|
playlist_undoredo_(nullptr),
|
||||||
playlist_organize_(nullptr),
|
playlist_copy_url_(nullptr),
|
||||||
playlist_show_in_collection_(nullptr),
|
playlist_show_in_collection_(nullptr),
|
||||||
playlist_copy_to_collection_(nullptr),
|
playlist_copy_to_collection_(nullptr),
|
||||||
playlist_move_to_collection_(nullptr),
|
playlist_move_to_collection_(nullptr),
|
||||||
|
playlist_open_in_browser_(nullptr),
|
||||||
|
playlist_organize_(nullptr),
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
playlist_copy_to_device_(nullptr),
|
playlist_copy_to_device_(nullptr),
|
||||||
#endif
|
#endif
|
||||||
playlist_open_in_browser_(nullptr),
|
playlist_delete_(nullptr),
|
||||||
playlist_copy_url_(nullptr),
|
|
||||||
playlist_queue_(nullptr),
|
playlist_queue_(nullptr),
|
||||||
playlist_queue_play_next_(nullptr),
|
playlist_queue_play_next_(nullptr),
|
||||||
playlist_skip_(nullptr),
|
playlist_skip_(nullptr),
|
||||||
@ -286,7 +290,8 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
|||||||
doubleclick_addmode_(BehaviourSettingsPage::AddBehaviour_Append),
|
doubleclick_addmode_(BehaviourSettingsPage::AddBehaviour_Append),
|
||||||
doubleclick_playmode_(BehaviourSettingsPage::PlayBehaviour_Never),
|
doubleclick_playmode_(BehaviourSettingsPage::PlayBehaviour_Never),
|
||||||
menu_playmode_(BehaviourSettingsPage::PlayBehaviour_Never),
|
menu_playmode_(BehaviourSettingsPage::PlayBehaviour_Never),
|
||||||
exit_count_(0)
|
exit_count_(0),
|
||||||
|
delete_files_(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
qLog(Debug) << "Starting";
|
qLog(Debug) << "Starting";
|
||||||
@ -659,16 +664,16 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
|||||||
playlist_menu_->addAction(ui_->action_add_files_to_transcoder);
|
playlist_menu_->addAction(ui_->action_add_files_to_transcoder);
|
||||||
#endif
|
#endif
|
||||||
playlist_menu_->addSeparator();
|
playlist_menu_->addSeparator();
|
||||||
|
playlist_copy_url_ = playlist_menu_->addAction(IconLoader::Load("edit-copy"), tr("Copy URL(s)..."), this, SLOT(PlaylistCopyUrl()));
|
||||||
|
playlist_show_in_collection_ = playlist_menu_->addAction(IconLoader::Load("edit-find"), tr("Show in collection..."), this, SLOT(ShowInCollection()));
|
||||||
|
playlist_open_in_browser_ = playlist_menu_->addAction(IconLoader::Load("document-open-folder"), tr("Show in file browser..."), this, SLOT(PlaylistOpenInBrowser()));
|
||||||
|
playlist_organize_ = playlist_menu_->addAction(IconLoader::Load("edit-copy"), tr("Organize files..."), this, SLOT(PlaylistMoveToCollection()));
|
||||||
|
playlist_copy_to_collection_ = playlist_menu_->addAction(IconLoader::Load("edit-copy"), tr("Copy to collection..."), this, SLOT(PlaylistCopyToCollection()));
|
||||||
|
playlist_move_to_collection_ = playlist_menu_->addAction(IconLoader::Load("go-jump"), tr("Move to collection..."), this, SLOT(PlaylistMoveToCollection()));
|
||||||
#if defined(HAVE_GSTREAMER) && !defined(Q_OS_WIN)
|
#if defined(HAVE_GSTREAMER) && !defined(Q_OS_WIN)
|
||||||
playlist_copy_to_device_ = playlist_menu_->addAction(IconLoader::Load("device"), tr("Copy to device..."), this, SLOT(PlaylistCopyToDevice()));
|
playlist_copy_to_device_ = playlist_menu_->addAction(IconLoader::Load("device"), tr("Copy to device..."), this, SLOT(PlaylistCopyToDevice()));
|
||||||
#endif
|
#endif
|
||||||
playlist_copy_to_collection_ = playlist_menu_->addAction(IconLoader::Load("edit-copy"), tr("Copy to collection..."), this, SLOT(PlaylistCopyToCollection()));
|
playlist_delete_ = playlist_menu_->addAction(IconLoader::Load("edit-delete"), tr("Delete from disk..."), this, SLOT(PlaylistDelete()));
|
||||||
playlist_move_to_collection_ = playlist_menu_->addAction(IconLoader::Load("go-jump"), tr("Move to collection..."), this, SLOT(PlaylistMoveToCollection()));
|
|
||||||
playlist_organize_ = playlist_menu_->addAction(IconLoader::Load("edit-copy"), tr("Organize files..."), this, SLOT(PlaylistMoveToCollection()));
|
|
||||||
playlist_open_in_browser_ = playlist_menu_->addAction(IconLoader::Load("document-open-folder"), tr("Show in file browser..."), this, SLOT(PlaylistOpenInBrowser()));
|
|
||||||
playlist_open_in_browser_->setVisible(false);
|
|
||||||
playlist_show_in_collection_ = playlist_menu_->addAction(IconLoader::Load("edit-find"), tr("Show in collection..."), this, SLOT(ShowInCollection()));
|
|
||||||
playlist_copy_url_ = playlist_menu_->addAction(IconLoader::Load("edit-copy"), tr("Copy URL(s)..."), this, SLOT(PlaylistCopyUrl()));
|
|
||||||
playlist_menu_->addSeparator();
|
playlist_menu_->addSeparator();
|
||||||
playlistitem_actions_separator_ = playlist_menu_->addSeparator();
|
playlistitem_actions_separator_ = playlist_menu_->addSeparator();
|
||||||
playlist_menu_->addAction(ui_->action_clear_playlist);
|
playlist_menu_->addAction(ui_->action_clear_playlist);
|
||||||
@ -990,6 +995,10 @@ void MainWindow::ReloadSettings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.beginGroup(PlaylistSettingsPage::kSettingsGroup);
|
||||||
|
delete_files_ = s.value("delete_files", false).toBool();
|
||||||
|
s.endGroup();
|
||||||
|
|
||||||
osd_->ReloadSettings();
|
osd_->ReloadSettings();
|
||||||
|
|
||||||
album_cover_choice_controller_->search_cover_auto_action()->setChecked(settings_.value("search_for_cover_auto", true).toBool());
|
album_cover_choice_controller_->search_cover_auto_action()->setChecked(settings_.value("search_for_cover_auto", true).toBool());
|
||||||
@ -1733,6 +1742,7 @@ void MainWindow::PlaylistRightClick(const QPoint &global_pos, const QModelIndex
|
|||||||
playlist_copy_to_device_->setVisible(false);
|
playlist_copy_to_device_->setVisible(false);
|
||||||
#endif
|
#endif
|
||||||
playlist_organize_->setVisible(false);
|
playlist_organize_->setVisible(false);
|
||||||
|
playlist_delete_->setVisible(false);
|
||||||
|
|
||||||
playlist_copy_url_->setVisible(selected > 0);
|
playlist_copy_url_->setVisible(selected > 0);
|
||||||
|
|
||||||
@ -1805,6 +1815,10 @@ void MainWindow::PlaylistRightClick(const QPoint &global_pos, const QModelIndex
|
|||||||
playlist_copy_to_device_->setVisible(editable > 0);
|
playlist_copy_to_device_->setVisible(editable > 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
|
playlist_delete_->setVisible(delete_files_ && editable > 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Remove old item actions, if any.
|
// Remove old item actions, if any.
|
||||||
for (QAction *action : playlistitem_actions_) {
|
for (QAction *action : playlistitem_actions_) {
|
||||||
playlist_menu_->removeAction(action);
|
playlist_menu_->removeAction(action);
|
||||||
@ -2850,3 +2864,39 @@ void MainWindow::Love() {
|
|||||||
if (tray_icon_) tray_icon_->LoveStateChanged(false);
|
if (tray_icon_) tray_icon_->LoveStateChanged(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::PlaylistDelete() {
|
||||||
|
|
||||||
|
if (!delete_files_) return;
|
||||||
|
|
||||||
|
SongList selected_songs;
|
||||||
|
QStringList files;
|
||||||
|
bool is_current_item = false;
|
||||||
|
for (const QModelIndex &proxy_idx : ui_->playlist->view()->selectionModel()->selectedRows()) {
|
||||||
|
QModelIndex source_idx = app_->playlist_manager()->current()->proxy()->mapToSource(proxy_idx);
|
||||||
|
PlaylistItemPtr item = app_->playlist_manager()->current()->item_at(source_idx.row());
|
||||||
|
if (!item || !item->Metadata().url().isLocalFile()) continue;
|
||||||
|
selected_songs << item->Metadata();
|
||||||
|
files << item->Metadata().url().toLocalFile();
|
||||||
|
if (item == app_->player()->GetCurrentItem()) is_current_item = true;
|
||||||
|
}
|
||||||
|
if (selected_songs.isEmpty()) return;
|
||||||
|
|
||||||
|
if (DeleteConfirmationDialog::warning(files) != QDialogButtonBox::Yes) return;
|
||||||
|
|
||||||
|
if (app_->player()->GetState() == Engine::Playing && app_->playlist_manager()->current()->rowCount() == selected_songs.count()) {
|
||||||
|
app_->player()->Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ui_->playlist->view()->RemoveSelected();
|
||||||
|
|
||||||
|
if (app_->player()->GetState() == Engine::Playing && is_current_item) {
|
||||||
|
app_->player()->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MusicStorage> storage(new FilesystemMusicStorage("/"));
|
||||||
|
DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, true);
|
||||||
|
connect(delete_files, SIGNAL(Finished(SongList)), SLOT(DeleteFinished(SongList)));
|
||||||
|
delete_files->Start(selected_songs);
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -264,6 +264,8 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
|||||||
|
|
||||||
void ExitFinished();
|
void ExitFinished();
|
||||||
|
|
||||||
|
void PlaylistDelete();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void SaveSettings();
|
void SaveSettings();
|
||||||
@ -331,15 +333,16 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
|||||||
QAction *playlist_play_pause_;
|
QAction *playlist_play_pause_;
|
||||||
QAction *playlist_stop_after_;
|
QAction *playlist_stop_after_;
|
||||||
QAction *playlist_undoredo_;
|
QAction *playlist_undoredo_;
|
||||||
QAction *playlist_organize_;
|
QAction *playlist_copy_url_;
|
||||||
QAction *playlist_show_in_collection_;
|
QAction *playlist_show_in_collection_;
|
||||||
QAction *playlist_copy_to_collection_;
|
QAction *playlist_copy_to_collection_;
|
||||||
QAction *playlist_move_to_collection_;
|
QAction *playlist_move_to_collection_;
|
||||||
|
QAction *playlist_open_in_browser_;
|
||||||
|
QAction *playlist_organize_;
|
||||||
#ifndef Q_OS_WIN
|
#ifndef Q_OS_WIN
|
||||||
QAction *playlist_copy_to_device_;
|
QAction *playlist_copy_to_device_;
|
||||||
#endif
|
#endif
|
||||||
QAction *playlist_open_in_browser_;
|
QAction *playlist_delete_;
|
||||||
QAction *playlist_copy_url_;
|
|
||||||
QAction *playlist_queue_;
|
QAction *playlist_queue_;
|
||||||
QAction* playlist_queue_play_next_;
|
QAction* playlist_queue_play_next_;
|
||||||
QAction *playlist_skip_;
|
QAction *playlist_skip_;
|
||||||
@ -369,6 +372,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
|||||||
Song song_playing_;
|
Song song_playing_;
|
||||||
QImage image_original_;
|
QImage image_original_;
|
||||||
int exit_count_;
|
int exit_count_;
|
||||||
|
bool delete_files_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ class MusicStorage {
|
|||||||
typedef std::function<void(float progress)> ProgressFunction;
|
typedef std::function<void(float progress)> ProgressFunction;
|
||||||
|
|
||||||
struct CopyJob {
|
struct CopyJob {
|
||||||
|
CopyJob() : overwrite_(false), mark_as_listened_(false), remove_original_(false), albumcover_(false) {}
|
||||||
QString source_;
|
QString source_;
|
||||||
QString destination_;
|
QString destination_;
|
||||||
Song metadata_;
|
Song metadata_;
|
||||||
@ -70,7 +71,9 @@ class MusicStorage {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct DeleteJob {
|
struct DeleteJob {
|
||||||
|
DeleteJob() : use_trash_(false) {}
|
||||||
Song metadata_;
|
Song metadata_;
|
||||||
|
bool use_trash_;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual QString LocalPath() const { return QString(); }
|
virtual QString LocalPath() const { return QString(); }
|
||||||
|
@ -253,6 +253,30 @@ QString MakeTempDir(const QString template_name) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MoveToTrashRecursive(const QString &path) {
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
|
QDir dir(path);
|
||||||
|
for (const QString &child : dir.entryList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Hidden)) {
|
||||||
|
if (!MoveToTrashRecursive(path + "/" + child))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const QString &child : dir.entryList(QDir::NoDotAndDotDot | QDir::Files | QDir::Hidden)) {
|
||||||
|
if (!QFile::moveToTrash(path + "/" + child))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir.rmdir(path);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool RemoveRecursive(const QString &path) {
|
bool RemoveRecursive(const QString &path) {
|
||||||
|
|
||||||
QDir dir(path);
|
QDir dir(path);
|
||||||
|
@ -64,6 +64,7 @@ quint64 FileSystemFreeSpace(const QString &path);
|
|||||||
|
|
||||||
QString MakeTempDir(const QString template_name = QString());
|
QString MakeTempDir(const QString template_name = QString());
|
||||||
|
|
||||||
|
bool MoveToTrashRecursive(const QString &path);
|
||||||
bool RemoveRecursive(const QString &path);
|
bool RemoveRecursive(const QString &path);
|
||||||
bool CopyRecursive(const QString &source, const QString &destination);
|
bool CopyRecursive(const QString &source, const QString &destination);
|
||||||
bool Copy(QIODevice *source, QIODevice *destination);
|
bool Copy(QIODevice *source, QIODevice *destination);
|
||||||
|
@ -421,7 +421,7 @@ void DeviceView::Delete() {
|
|||||||
|
|
||||||
std::shared_ptr<MusicStorage> storage = device_index.data(MusicStorage::Role_Storage).value<std::shared_ptr<MusicStorage>>();
|
std::shared_ptr<MusicStorage> storage = device_index.data(MusicStorage::Role_Storage).value<std::shared_ptr<MusicStorage>>();
|
||||||
|
|
||||||
DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage);
|
DeleteFiles *delete_files = new DeleteFiles(app_->task_manager(), storage, false);
|
||||||
connect(delete_files, SIGNAL(Finished(SongList)), SLOT(DeleteFinished(SongList)));
|
connect(delete_files, SIGNAL(Finished(SongList)), SLOT(DeleteFinished(SongList)));
|
||||||
delete_files->Start(GetSelectedSongs());
|
delete_files->Start(GetSelectedSongs());
|
||||||
|
|
||||||
|
114
src/dialogs/deleteconfirmationdialog.cpp
Normal file
114
src/dialogs/deleteconfirmationdialog.cpp
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* Copyright 2020, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QFont>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QAbstractButton>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QAbstractItemView>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
#include "deleteconfirmationdialog.h"
|
||||||
|
|
||||||
|
DeleteConfirmationDialog::DeleteConfirmationDialog(const QStringList &files, QWidget *parent) : QDialog(parent, Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint), button_box_(new QDialogButtonBox(this)) {
|
||||||
|
|
||||||
|
setModal(true);
|
||||||
|
setWindowTitle(tr("Delete files"));
|
||||||
|
setWindowIcon(style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, this));
|
||||||
|
|
||||||
|
QLabel *label_icon = new QLabel(this);
|
||||||
|
label_icon->setPixmap(style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, this).pixmap(style()->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this), style()->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this)));
|
||||||
|
label_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
QLabel *label_text_top = new QLabel(this);
|
||||||
|
QFont label_text_top_font = label_text_top->font();
|
||||||
|
label_text_top_font.setBold(true);
|
||||||
|
label_text_top_font.setPointSize(label_text_top_font.pointSize() + 4);
|
||||||
|
label_text_top->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this)));
|
||||||
|
label_text_top->setContentsMargins(0, 0, 0, 0);
|
||||||
|
label_text_top->setFont(label_text_top_font);
|
||||||
|
label_text_top->setText(tr("The following files will be deleted from disk:"));
|
||||||
|
|
||||||
|
QListWidget *list = new QListWidget(this);
|
||||||
|
list->setSelectionMode(QAbstractItemView::NoSelection);
|
||||||
|
list->addItems(files);
|
||||||
|
|
||||||
|
QLabel *label_text_bottom = new QLabel(this);
|
||||||
|
QFont label_text_bottom_font = label_text_bottom->font();
|
||||||
|
label_text_bottom_font.setBold(true);
|
||||||
|
label_text_bottom_font.setPointSize(label_text_bottom_font.pointSize() + 4);
|
||||||
|
label_text_bottom->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this)));
|
||||||
|
label_text_bottom->setContentsMargins(0, 0, 0, 0);
|
||||||
|
label_text_bottom->setFont(label_text_bottom_font);
|
||||||
|
label_text_bottom->setText(tr("Are you sure you want to continue?"));
|
||||||
|
|
||||||
|
button_box_->setStandardButtons(QDialogButtonBox::Yes|QDialogButtonBox::Cancel);
|
||||||
|
connect(button_box_, SIGNAL(clicked(QAbstractButton*)), this, SLOT(ButtonClicked(QAbstractButton*)));
|
||||||
|
|
||||||
|
// Add layout
|
||||||
|
QGridLayout *grid = new QGridLayout(this);
|
||||||
|
grid->addWidget(label_icon, 0, 0, 2, 1, Qt::AlignTop);
|
||||||
|
grid->addWidget(label_text_top, 0, 1, 1, 1);
|
||||||
|
grid->addWidget(list, 1, 1, 1, 2);
|
||||||
|
grid->addWidget(label_text_bottom, 2, 1, 1, 2);
|
||||||
|
grid->addWidget(button_box_, 3, 1, 1, 2, Qt::AlignRight);
|
||||||
|
grid->setSizeConstraint(QLayout::SetNoConstraint);
|
||||||
|
setLayout(grid);
|
||||||
|
|
||||||
|
// Set size of dialog
|
||||||
|
int max_width = 0;
|
||||||
|
int max_height = 0;
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||||
|
QScreen *screen = QWidget::screen();
|
||||||
|
#else
|
||||||
|
QScreen *screen = (window() && window()->windowHandle() ? window()->windowHandle()->screen() : QGuiApplication::primaryScreen());
|
||||||
|
#endif
|
||||||
|
if (screen) {
|
||||||
|
max_width = screen->geometry().size().width() / 0.5;
|
||||||
|
max_height = static_cast<int>(float(screen->geometry().size().height()) / float(1.5));
|
||||||
|
}
|
||||||
|
int min_width = std::min(list->sizeHintForColumn(0) + 100, max_width);
|
||||||
|
int min_height = std::min((list->sizeHintForRow(0) * list->count()) + 160, max_height);
|
||||||
|
setMinimumSize(min_width, min_height);
|
||||||
|
adjustSize();
|
||||||
|
setMinimumSize(0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteConfirmationDialog::ButtonClicked(QAbstractButton *button) {
|
||||||
|
|
||||||
|
done(button_box_->standardButton(button));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialogButtonBox::StandardButton DeleteConfirmationDialog::warning(const QStringList &files, QWidget *parent) {
|
||||||
|
|
||||||
|
DeleteConfirmationDialog box(files, parent);
|
||||||
|
return static_cast<QDialogButtonBox::StandardButton>(box.exec());
|
||||||
|
|
||||||
|
}
|
43
src/dialogs/deleteconfirmationdialog.h
Normal file
43
src/dialogs/deleteconfirmationdialog.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Strawberry Music Player
|
||||||
|
* Copyright 2020, Jonas Kvinge <jonas@jkvinge.net>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DELETECONFIRMATIONDIALOG_H
|
||||||
|
#define DELETECONFIRMATIONDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class DeleteConfirmationDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DeleteConfirmationDialog(const QStringList &files, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
static QDialogButtonBox::StandardButton warning(const QStringList &files, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void ButtonClicked(QAbstractButton *button);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QDialogButtonBox *button_box_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DELETECONFIRMATIONDIALOG_H
|
@ -178,6 +178,8 @@ void CollectionSettingsPage::Load() {
|
|||||||
ui_->spinbox_disk_cache_size->setValue(s.value(kSettingsDiskCacheSize, kSettingsDiskCacheSizeDefault).toInt());
|
ui_->spinbox_disk_cache_size->setValue(s.value(kSettingsDiskCacheSize, kSettingsDiskCacheSizeDefault).toInt());
|
||||||
ui_->combobox_disk_cache_size->setCurrentIndex(s.value(kSettingsDiskCacheSizeUnit, static_cast<int>(CacheSizeUnit_MB)).toInt());
|
ui_->combobox_disk_cache_size->setCurrentIndex(s.value(kSettingsDiskCacheSizeUnit, static_cast<int>(CacheSizeUnit_MB)).toInt());
|
||||||
|
|
||||||
|
ui_->checkbox_delete_files->setChecked(s.value("delete_files", false).toBool());
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
DiskCacheEnable(ui_->checkbox_disk_cache->checkState());
|
DiskCacheEnable(ui_->checkbox_disk_cache->checkState());
|
||||||
@ -227,6 +229,8 @@ void CollectionSettingsPage::Save() {
|
|||||||
s.setValue(kSettingsDiskCacheSize, ui_->spinbox_disk_cache_size->value());
|
s.setValue(kSettingsDiskCacheSize, ui_->spinbox_disk_cache_size->value());
|
||||||
s.setValue(kSettingsDiskCacheSizeUnit, ui_->combobox_disk_cache_size->currentIndex());
|
s.setValue(kSettingsDiskCacheSizeUnit, ui_->combobox_disk_cache_size->currentIndex());
|
||||||
|
|
||||||
|
s.setValue("delete_files", ui_->checkbox_delete_files->isChecked());
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -450,6 +450,13 @@ If there are no matches then it will use the largest image in the directory.</st
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkbox_delete_files">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable delete files in the right click context menu</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
|
@ -83,6 +83,8 @@ void PlaylistSettingsPage::Load() {
|
|||||||
ui_->checkbox_editmetadatainline->setChecked(s.value("editmetadatainline", false).toBool());
|
ui_->checkbox_editmetadatainline->setChecked(s.value("editmetadatainline", false).toBool());
|
||||||
ui_->checkbox_writemetadata->setChecked(s.value(Playlist::kWriteMetadata, false).toBool());
|
ui_->checkbox_writemetadata->setChecked(s.value(Playlist::kWriteMetadata, false).toBool());
|
||||||
|
|
||||||
|
ui_->checkbox_delete_files->setChecked(s.value("delete_files", false).toBool());
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
Init(ui_->layout_playlistsettingspage->parentWidget());
|
Init(ui_->layout_playlistsettingspage->parentWidget());
|
||||||
@ -118,6 +120,7 @@ void PlaylistSettingsPage::Save() {
|
|||||||
s.setValue(Playlist::kPathType, static_cast<int>(path));
|
s.setValue(Playlist::kPathType, static_cast<int>(path));
|
||||||
s.setValue("editmetadatainline", ui_->checkbox_editmetadatainline->isChecked());
|
s.setValue("editmetadatainline", ui_->checkbox_editmetadatainline->isChecked());
|
||||||
s.setValue(Playlist::kWriteMetadata, ui_->checkbox_writemetadata->isChecked());
|
s.setValue(Playlist::kWriteMetadata, ui_->checkbox_writemetadata->isChecked());
|
||||||
|
s.setValue("delete_files", ui_->checkbox_delete_files->isChecked());
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkbox_delete_files">
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable delete files in the right click context menu</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupbox_paths">
|
<widget class="QGroupBox" name="groupbox_paths">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "core/filesystemmusicstorage.h"
|
#include "core/filesystemmusicstorage.h"
|
||||||
#include "core/iconloader.h"
|
#include "core/iconloader.h"
|
||||||
#include "core/mimedata.h"
|
#include "core/mimedata.h"
|
||||||
|
#include "dialogs/deleteconfirmationdialog.h"
|
||||||
#include "fileview.h"
|
#include "fileview.h"
|
||||||
#include "fileviewlist.h"
|
#include "fileviewlist.h"
|
||||||
#include "ui_fileview.h"
|
#include "ui_fileview.h"
|
||||||
@ -85,9 +86,7 @@ FileView::FileView(QWidget *parent)
|
|||||||
connect(ui_->list, SIGNAL(CopyToCollection(QList<QUrl>)), SIGNAL(CopyToCollection(QList<QUrl>)));
|
connect(ui_->list, SIGNAL(CopyToCollection(QList<QUrl>)), SIGNAL(CopyToCollection(QList<QUrl>)));
|
||||||
connect(ui_->list, SIGNAL(MoveToCollection(QList<QUrl>)), SIGNAL(MoveToCollection(QList<QUrl>)));
|
connect(ui_->list, SIGNAL(MoveToCollection(QList<QUrl>)), SIGNAL(MoveToCollection(QList<QUrl>)));
|
||||||
connect(ui_->list, SIGNAL(CopyToDevice(QList<QUrl>)), SIGNAL(CopyToDevice(QList<QUrl>)));
|
connect(ui_->list, SIGNAL(CopyToDevice(QList<QUrl>)), SIGNAL(CopyToDevice(QList<QUrl>)));
|
||||||
#ifdef HAVE_GSTREAMER
|
|
||||||
connect(ui_->list, SIGNAL(Delete(QStringList)), SLOT(Delete(QStringList)));
|
connect(ui_->list, SIGNAL(Delete(QStringList)), SLOT(Delete(QStringList)));
|
||||||
#endif
|
|
||||||
connect(ui_->list, SIGNAL(EditTags(QList<QUrl>)), SIGNAL(EditTags(QList<QUrl>)));
|
connect(ui_->list, SIGNAL(EditTags(QList<QUrl>)), SIGNAL(EditTags(QList<QUrl>)));
|
||||||
|
|
||||||
QString filter(FileView::kFileFilter);
|
QString filter(FileView::kFileFilter);
|
||||||
@ -231,40 +230,24 @@ void FileView::UndoCommand::undo() {
|
|||||||
|
|
||||||
void FileView::Delete(const QStringList &filenames) {
|
void FileView::Delete(const QStringList &filenames) {
|
||||||
|
|
||||||
#ifdef HAVE_GSTREAMER
|
if (filenames.isEmpty()) return;
|
||||||
|
|
||||||
if (filenames.isEmpty())
|
if (DeleteConfirmationDialog::warning(filenames) != QDialogButtonBox::Yes) return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (QMessageBox::warning(this, tr("Delete files"),
|
DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage_, true);
|
||||||
tr("These files will be deleted from disk, are you sure you want to continue?"),
|
|
||||||
QMessageBox::Yes, QMessageBox::Cancel) != QMessageBox::Yes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DeleteFiles *delete_files = new DeleteFiles(task_manager_, storage_);
|
|
||||||
connect(delete_files, SIGNAL(Finished(SongList)), SLOT(DeleteFinished(SongList)));
|
connect(delete_files, SIGNAL(Finished(SongList)), SLOT(DeleteFinished(SongList)));
|
||||||
delete_files->Start(filenames);
|
delete_files->Start(filenames);
|
||||||
|
|
||||||
#else
|
|
||||||
Q_UNUSED(filenames)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileView::DeleteFinished(const SongList &songs_with_errors) {
|
void FileView::DeleteFinished(const SongList &songs_with_errors) {
|
||||||
|
|
||||||
#ifdef HAVE_GSTREAMER
|
|
||||||
|
|
||||||
if (songs_with_errors.isEmpty()) return;
|
if (songs_with_errors.isEmpty()) return;
|
||||||
|
|
||||||
OrganizeErrorDialog *dialog = new OrganizeErrorDialog(this);
|
OrganizeErrorDialog *dialog = new OrganizeErrorDialog(this);
|
||||||
dialog->Show(OrganizeErrorDialog::Type_Delete, songs_with_errors);
|
dialog->Show(OrganizeErrorDialog::Type_Delete, songs_with_errors);
|
||||||
// It deletes itself when the user closes it
|
// It deletes itself when the user closes it
|
||||||
|
|
||||||
#else
|
|
||||||
Q_UNUSED(songs_with_errors)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileView::showEvent(QShowEvent *e) {
|
void FileView::showEvent(QShowEvent *e) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user