diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f0a8a569b..0676e74c0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -391,6 +391,7 @@ set(SOURCES
widgets/progressitemdelegate.cpp
widgets/ratingwidget.cpp
widgets/renametablineedit.cpp
+ widgets/scrollmessagebox.cpp
widgets/sliderwidget.cpp
widgets/stickyslider.cpp
widgets/stretchheaderview.cpp
@@ -674,6 +675,7 @@ set(HEADERS
widgets/progressitemdelegate.h
widgets/ratingwidget.h
widgets/renametablineedit.h
+ widgets/scrollmessagebox.h
widgets/sliderwidget.h
widgets/stickyslider.h
widgets/stretchheaderview.h
diff --git a/src/library/libraryview.cpp b/src/library/libraryview.cpp
index 1fbe3c4b8..1589a579d 100644
--- a/src/library/libraryview.cpp
+++ b/src/library/libraryview.cpp
@@ -45,6 +45,7 @@
#include "ui/iconloader.h"
#include "ui/organisedialog.h"
#include "ui/organiseerrordialog.h"
+#include "widgets/scrollmessagebox.h"
using smart_playlists::Wizard;
@@ -663,11 +664,19 @@ void LibraryView::Organise() {
}
void LibraryView::Delete() {
- if (QMessageBox::warning(this, tr("Delete files"),
- tr("These files will be permanently deleted from "
- "disk, are you sure you want to continue?"),
- QMessageBox::Yes,
- QMessageBox::Cancel) != QMessageBox::Yes)
+
+ const SongList selected_songs = GetSelectedSongs();
+
+ QString message = tr("The following files will be permanently deleted from "
+ "disk:") +
+ "
";
+ for (const Song& song : selected_songs) {
+ message += ("- " + song.url().toString() + "
");
+ }
+ message += "
" + tr("Are you sure you want to continue?");
+
+ if (ScrollMessageBox::warning(this, tr("Delete files"),
+ message, {QDialogButtonBox::No | QDialogButtonBox::Yes}, QDialogButtonBox::No) != QDialogButtonBox::Yes)
return;
// We can cheat and always take the storage of the first directory, since
@@ -683,7 +692,7 @@ void LibraryView::Delete() {
DeleteFiles* delete_files = new DeleteFiles(app_->task_manager(), storage);
connect(delete_files, SIGNAL(Finished(SongList)),
SLOT(DeleteFinished(SongList)));
- delete_files->Start(GetSelectedSongs());
+ delete_files->Start(selected_songs);
}
void LibraryView::EditTracks() {
diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp
index f40340c42..dd45ff91f 100644
--- a/src/ui/mainwindow.cpp
+++ b/src/ui/mainwindow.cpp
@@ -125,6 +125,7 @@
#include "widgets/osd.h"
#include "widgets/stylehelper.h"
#include "widgets/trackslider.h"
+#include "widgets/scrollmessagebox.h"
#ifdef Q_OS_DARWIN
#include "ui/macsystemtrayicon.h"
@@ -2377,13 +2378,6 @@ void MainWindow::PlaylistOrganiseSelected(bool copy) {
void MainWindow::PlaylistDelete() {
// Note: copied from LibraryView::Delete
- if (QMessageBox::warning(this, tr("Delete files"),
- tr("These files will be permanently deleted from "
- "disk, are you sure you want to continue?"),
- QMessageBox::Yes,
- QMessageBox::Cancel) != QMessageBox::Yes)
- return;
-
std::shared_ptr storage(new FilesystemMusicStorage("/"));
// Get selected songs
@@ -2412,6 +2406,20 @@ void MainWindow::PlaylistDelete() {
}
}
+ qLog(Debug) << "deleting" << selected_songs.count() << "songs";
+
+ QString message = tr("The following files will be permanently deleted from "
+ "disk:") +
+ "";
+ for (const Song& song : selected_songs) {
+ message += ("- " + song.url().toString() + "
");
+ }
+ message += "
" + tr("Are you sure you want to continue?");
+
+ if (ScrollMessageBox::warning(this, tr("Delete files"),
+ message, {QDialogButtonBox::No | QDialogButtonBox::Yes}, QDialogButtonBox::No) != QDialogButtonBox::Yes)
+ return;
+
ui_->playlist->view()->RemoveSelected(true);
DeleteFiles* delete_files = new DeleteFiles(app_->task_manager(), storage);
@@ -2901,6 +2909,12 @@ void MainWindow::keyPressEvent(QKeyEvent* event) {
if (event->key() == Qt::Key_Space) {
app_->player()->PlayPause();
event->accept();
+ } else if (event->key() == Qt::Key_Left) {
+ app_->player()->SeekBackward();
+ event->accept();
+ } else if (event->key() == Qt::Key_Right) {
+ app_->player()->SeekForward();
+ event->accept();
} else {
QMainWindow::keyPressEvent(event);
}
diff --git a/src/widgets/scrollmessagebox.cpp b/src/widgets/scrollmessagebox.cpp
new file mode 100644
index 000000000..c46464a54
--- /dev/null
+++ b/src/widgets/scrollmessagebox.cpp
@@ -0,0 +1,143 @@
+/* This file is part of Clementine.
+ Copyright 2010, David Sansome
+
+ Clementine 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.
+
+ Clementine 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 Clementine. If not, see .
+*/
+
+#include "scrollmessagebox.h"
+#include
+#include
+#include
+#include
+#include
+
+ScrollMessageBox::ScrollMessageBox(QMessageBox::Icon icon, QString const& title,
+ QString const& text, QDialogButtonBox::StandardButtons buttons /*= QDialogButtonBox::Ok*/,
+ QWidget* parent /*= 0*/) :
+ QDialog(parent, Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint) {
+
+ QLabel *iconLabel;
+ QScrollArea *scroll;
+
+ label = new QLabel;
+ label->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this)));
+ label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
+ label->setOpenExternalLinks(true);
+ label->setContentsMargins(2, 0, 0, 0);
+ label->setIndent(9);
+
+ scroll = new QScrollArea(this);
+ scroll->setGeometry(QRect(10, 20, 560, 430));
+ scroll->setWidget(label);
+ scroll->setWidgetResizable(true);
+
+ iconLabel = new QLabel;
+ iconLabel->setPixmap(standardIcon((QMessageBox::Icon)icon));
+ iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+ buttonBox = new QDialogButtonBox(buttons);
+ buttonBox->setCenterButtons(style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, this));
+ QObject::connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),
+ this, SLOT(handle_buttonClicked(QAbstractButton*)));
+
+ QGridLayout *grid = new QGridLayout;
+
+ grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop);
+ grid->addWidget(scroll, 0, 1, 1, 1);
+ grid->addWidget(buttonBox, 1, 0, 1, 2);
+ grid->setSizeConstraint(QLayout::SetNoConstraint);
+ setLayout(grid);
+
+ if (!title.isEmpty() || !text.isEmpty()) {
+ setWindowTitle(title);
+ label->setText(text);
+ }
+
+ setModal(true);
+}
+
+QPixmap ScrollMessageBox::standardIcon(QMessageBox::Icon icon) {
+ QStyle *style = this->style();
+ int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this);
+ QIcon tmpIcon;
+
+ switch (icon) {
+ case QMessageBox::Information:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, 0, this);
+ break;
+ case QMessageBox::Warning:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, 0, this);
+ break;
+ case QMessageBox::Critical:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, 0, this);
+ break;
+ case QMessageBox::Question:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, 0, this);
+ default:
+ break;
+ }
+
+ if (!tmpIcon.isNull()) {
+ return tmpIcon.pixmap(iconSize, iconSize);
+ }
+ return QPixmap();
+}
+
+void ScrollMessageBox::handle_buttonClicked(QAbstractButton *button) {
+ int ret = buttonBox->standardButton(button);
+ done(ret);
+}
+
+void ScrollMessageBox::setDefaultButton(QPushButton *button) {
+ if (!buttonBox->buttons().contains(button))
+ return;
+ button->setDefault(true);
+ button->setFocus();
+}
+
+void ScrollMessageBox::setDefaultButton(QDialogButtonBox::StandardButton button) {
+ setDefaultButton(buttonBox->button(button));
+}
+
+void ScrollMessageBox::showEvent(QShowEvent *e) {
+ QDialog::showEvent(e);
+}
+
+QDialogButtonBox::StandardButton ScrollMessageBox::critical(QWidget* parent, QString const& title, QString const& text,
+ QDialogButtonBox::StandardButtons buttons, QDialogButtonBox::StandardButton defaultButton) {
+ ScrollMessageBox box(QMessageBox::Critical, title, text, buttons, parent);
+ box.setDefaultButton(defaultButton);
+ return static_cast(box.exec());
+}
+
+QDialogButtonBox::StandardButton ScrollMessageBox::information(QWidget* parent, QString const& title, QString const& text,
+ QDialogButtonBox::StandardButtons buttons, QDialogButtonBox::StandardButton defaultButton) {
+ ScrollMessageBox box(QMessageBox::Information, title, text, buttons, parent);
+ box.setDefaultButton(defaultButton);
+ return static_cast(box.exec());
+}
+
+QDialogButtonBox::StandardButton ScrollMessageBox::question(QWidget* parent, QString const& title, QString const& text,
+ QDialogButtonBox::StandardButtons buttons, QDialogButtonBox::StandardButton defaultButton) {
+ ScrollMessageBox box(QMessageBox::Question, title, text, buttons, parent);
+ box.setDefaultButton(defaultButton);
+ return static_cast(box.exec());
+}
+
+QDialogButtonBox::StandardButton ScrollMessageBox::warning(QWidget* parent, QString const& title, QString const& text,
+ QDialogButtonBox::StandardButtons buttons, QDialogButtonBox::StandardButton defaultButton) {
+ ScrollMessageBox box(QMessageBox::Warning, title, text, buttons, parent);
+ box.setDefaultButton(defaultButton);
+ return static_cast(box.exec());
+}
diff --git a/src/widgets/scrollmessagebox.h b/src/widgets/scrollmessagebox.h
new file mode 100644
index 000000000..17e471b8e
--- /dev/null
+++ b/src/widgets/scrollmessagebox.h
@@ -0,0 +1,54 @@
+/* This file is part of Clementine.
+ Copyright 2010, David Sansome
+
+ Clementine 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.
+
+ Clementine 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 Clementine. If not, see .
+*/
+
+#ifndef SCROLLMESSAGEBOX_H
+#define SCROLLMESSAGEBOX_H
+
+#include
+#include
+#include
+#include
+
+class ScrollMessageBox : public QDialog {
+ Q_OBJECT
+
+public:
+ ScrollMessageBox(QMessageBox::Icon icon, QString const& title, QString const& text,
+ QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Ok, QWidget* parent = 0);
+
+ void setDefaultButton(QDialogButtonBox::StandardButton button);
+
+ static QDialogButtonBox::StandardButton critical(QWidget* parent, QString const& title, QString const& text, QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Ok, QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::NoButton);
+ static QDialogButtonBox::StandardButton information(QWidget* parent, QString const& title, QString const& text, QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Ok, QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::NoButton);
+ static QDialogButtonBox::StandardButton question(QWidget* parent, QString const& title, QString const& text, QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Ok, QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::NoButton);
+ static QDialogButtonBox::StandardButton warning(QWidget* parent, QString const& title, QString const& text, QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Ok, QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::NoButton);
+
+ void showEvent ( QShowEvent * event ) override;
+
+private:
+ QPixmap standardIcon(QMessageBox::Icon icon);
+ void setDefaultButton(QPushButton *button);
+ void updateSize();
+
+ QLabel *label;
+ QDialogButtonBox *buttonBox;
+
+private Q_SLOTS:
+ void handle_buttonClicked(QAbstractButton *button);
+};
+
+#endif // SCROLLMESSAGEBOX_H