Skip to content

Commit

Permalink
WTrackMenu: add action, slot and TrackPointerOperation for RemoveFrom…
Browse files Browse the repository at this point in the history
…Disk
  • Loading branch information
ronso0 committed Oct 30, 2020
1 parent 0e16a27 commit 947b40e
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 0 deletions.
157 changes: 157 additions & 0 deletions src/widget/wtrackmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,14 @@ void WTrackMenu::createActions() {
connect(m_pPurgeAct, &QAction::triggered, this, &WTrackMenu::slotPurge);
}

if (featureIsEnabled(Feature::RemoveFromDisk)) {
m_pRemoveFromDiskAct = new QAction(tr("Remove from disk"), this);
connect(m_pRemoveFromDiskAct,
&QAction::triggered,
this,
&WTrackMenu::slotRemoveFromDisk);
}

if (featureIsEnabled(Feature::Properties)) {
m_pPropertiesAct = new QAction(tr("Properties"), this);
connect(m_pPropertiesAct, &QAction::triggered, this, &WTrackMenu::slotShowDlgTrackInfo);
Expand Down Expand Up @@ -465,6 +473,11 @@ void WTrackMenu::setupActions() {
}
}

if (featureIsEnabled(Feature::RemoveFromDisk) &&
m_pTrackModel->hasCapabilities(TrackModel::Capability::RemoveFromDisk)) {
addAction(m_pRemoveFromDiskAct);
}

if (featureIsEnabled(Feature::FileBrowser)) {
addAction(m_pFileBrowserAct);
}
Expand Down Expand Up @@ -714,6 +727,13 @@ void WTrackMenu::updateMenus() {
}
}

if (featureIsEnabled(Feature::RemoveFromDisk)) {
bool locked = m_pTrackModel->hasCapabilities(TrackModel::Capability::Locked);
if (m_pTrackModel->hasCapabilities(TrackModel::Capability::RemoveFromDisk)) {
m_pRemoveFromDiskAct->setEnabled(!locked);
}
}

if (featureIsEnabled(Feature::Properties)) {
m_pPropertiesAct->setEnabled(singleTrackSelected);
}
Expand Down Expand Up @@ -1528,6 +1548,143 @@ void WTrackMenu::slotClearAllMetadata() {
&trackOperator);
}

namespace {

class RemoveTrackFilesFromDiskTrackPointerOperation : public mixxx::TrackPointerOperation {
public:
mutable QList<TrackRef> tr_tracksToPurge;
mutable QList<QString> tr_tracksToKeep;

private:
void doApply(
const TrackPointer& pTrack) const override {
QString location = pTrack->getLocation();
if (location.isNull()) {
return;
}
QFile file(location);
auto trackRef = TrackRef::fromFileInfo(
pTrack->getFileInfo(),
pTrack->getId());
VERIFY_OR_DEBUG_ASSERT(trackRef.isValid()) {
return;
}
if (file.exists() && !file.remove()) {
// deletion failed, log warning.
qWarning()
<< "Queued file"
<< location
<< "could not be deleted. Track is not purged";
tr_tracksToKeep.append(location);
return;
}
}
};

} // anonymous namespace

void WTrackMenu::slotRemoveFromDisk() {
// Remove duplicates to prevent delete errors later on.
// Collect file locations for the Delete warning.
QList<TrackRef> trackRefsToDelete;
QList<QString> trackLocations;
trackRefsToDelete.reserve(getTrackCount());
trackLocations.reserve(trackRefsToDelete.size());
for (const auto& trackRef : getTrackRefs()) {
DEBUG_ASSERT(trackRef.hasLocation());
if (!trackRefsToDelete.contains(trackRef)) {
trackRefsToDelete.append(trackRef);
trackLocations.append(trackRef.getLocation());
}
}

// TODO Use a dialog with a QListView that can be scrolled horizontally?
// Or improve linebreaks and formatting in the current plain textview.
// TODO Should each item may have a checkbox to allow removing it from the delete list
// or is it okay for the user to Cancel and adjust the selection in the tracks table?
// TODO Allow to keep all selected tracks' references

// Show Delete warning.
// Primitive hack to populate a pseudo list.
QMessageBox msgBoxDelete(QMessageBox::Critical,
QObject::tr("Delete Files"),
nullptr);
msgBoxDelete.setInformativeText(
QObject::tr("<b>Permanently delete these %1 files from disk?</b>"
" "
" <br>"
"%2<br>"
"<br>"
"<b>This can not be undone!</b><br>")
.arg(QString::number(trackLocations.length()),
QString(QStringLiteral("&#8226; ")) +
trackLocations.join(
QStringLiteral("<br>&#8226; "))));
// TODO use Qt::MarkdownText for Qt >= 5.14
msgBoxDelete.setTextFormat(Qt::RichText);
QAbstractButton* deleteBtn = msgBoxDelete.addButton(
tr("Delete Files!"), QMessageBox::AcceptRole);
msgBoxDelete.addButton(QMessageBox::Cancel);
msgBoxDelete.setDefaultButton(QMessageBox::Cancel);
msgBoxDelete.exec();
if (msgBoxDelete.clickedButton() != deleteBtn) {
return;
}

// Set up and initiate the track batch operation
const auto progressLabelText =
tr("Removing %n track file(s) from disk Removing %n track file(s) from disk ",
"ooooooooooooooooooooooooooooOooooooooooooooooooooooo",
getTrackCount());
const auto trackOperator =
RemoveTrackFilesFromDiskTrackPointerOperation();
applyTrackPointerOperation(
progressLabelText,
&trackOperator);

if (trackOperator.tr_tracksToPurge.length() > 0) {
// Purge only those tracks whose files were actually deleted.
m_pLibrary->trackCollections()->purgeTracks(trackOperator.tr_tracksToPurge);
// Optional message box:
QMessageBox msgBoxPurgeTracks(QMessageBox::Information,
QObject::tr("Yeaiij!"),
nullptr);
msgBoxPurgeTracks.setInformativeText(
QObject::tr(
"<br><br><b>"
"%1 annoying tracks were deleted from disk and"
"purged from the Mixxx database."
"</b><br><br><br>")
.arg(QString::number(trackOperator.tr_tracksToPurge.length())));
msgBoxPurgeTracks.setTextFormat(Qt::RichText);
msgBoxPurgeTracks.exec();
}

// Show list of tracks that are not going to be purged.
if (trackOperator.tr_tracksToKeep.length() >= 0) {
return;
}

QMessageBox msgBoxKeepTracks(QMessageBox::Warning,
QObject::tr("Some Files Were Not Deleted"),
nullptr);
msgBoxKeepTracks.setInformativeText(
QObject::tr("<br><br><b>"
"The following %1 files could not be deleted from disk."
"Make sure you have write access to those files and "
"try again later.</b>"
"<br>"
"%2"
"<br>")
.arg(QString::number(
trackOperator.tr_tracksToKeep.length()),
QString(QStringLiteral("&#8226; ")) +
trackOperator.tr_tracksToKeep.join(
QStringLiteral("<br>&#8226; "))));
msgBoxKeepTracks.setTextFormat(Qt::RichText);
msgBoxKeepTracks.exec();
}

void WTrackMenu::slotShowDlgTrackInfo() {
if (isEmpty()) {
return;
Expand Down
2 changes: 2 additions & 0 deletions src/widget/wtrackmenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class WTrackMenu : public QMenu {
void slotHide();
void slotUnhide();
void slotPurge();
void slotRemoveFromDisk();

private:
// This getter verifies that m_pTrackModel is set when
Expand Down Expand Up @@ -224,6 +225,7 @@ class WTrackMenu : public QMenu {
QAction* m_pHideAct{};
QAction* m_pUnhideAct{};
QAction* m_pPurgeAct{};
QAction* m_pRemoveFromDiskAct{};

// Show track-editor action
QAction* m_pPropertiesAct{};
Expand Down

0 comments on commit 947b40e

Please sign in to comment.