1 #include "playlistscontextmenu.h"
2 
3 #include <QMenu>
4 #include <QAction>
5 #include <QDesktopServices>
6 #include <QClipboard>
7 #include <QApplication>
8 #include <QUrl>
9 #include <QInputDialog>
10 #include <QFileDialog>
11 #include <QStandardPaths>
12 
13 namespace PlaylistsUi {
PlaylistsContextMenu(Model * m,ProxyFilterModel * p,QListView * v,QLineEdit * s,QObject * parent)14   PlaylistsContextMenu::PlaylistsContextMenu(Model *m, ProxyFilterModel *p, QListView *v, QLineEdit *s, QObject *parent) : QObject(parent), model(m), proxy(p), view(v), search(s) {
15     Q_ASSERT(model);
16     Q_ASSERT(proxy);
17     Q_ASSERT(view);
18     Q_ASSERT(search);
19   }
20 
show(const QPoint & pos)21   void PlaylistsContextMenu::show(const QPoint &pos) {
22     auto index = view->indexAt(pos);
23     if (!index.isValid()) {
24       return;
25     }
26 
27     QMenu menu;
28     QAction remove(tr("Remove"));
29     QAction rename(tr("Rename"));
30     QAction savem3u(tr("Save as m3u"));
31     QAction reload(tr("Reload from filesystem"));
32     QAction play(tr("Play"));
33 
34     connect(&reload, &QAction::triggered, [&]() {
35       on_reload(index);
36     });
37     reload.setIcon(view->style()->standardIcon(QStyle::SP_BrowserReload));
38 
39     remove.setIcon(view->style()->standardIcon(QStyle::SP_TrashIcon));
40     savem3u.setIcon(view->style()->standardIcon(QStyle::SP_DialogSaveButton));
41     //rename.setIcon(view->style()->standardIcon(QStyle::SP_FileIcon));
42     play.setIcon(view->style()->standardIcon(QStyle::SP_MediaPlay));
43 
44     connect(&remove, &QAction::triggered, [&]() {
45       emit removed(index);
46     });
47 
48     connect(&rename, &QAction::triggered, [&]() {
49       on_rename(index);
50     });
51 
52     QAction clear_filter(tr("Clear filter"));
53     clear_filter.setIcon(view->style()->standardIcon(QStyle::SP_DialogCancelButton));
54     if (!search->text().isEmpty()) {
55        connect(&clear_filter, &QAction::triggered, [=]() {
56          search->clear();
57        });
58        menu.addAction(&clear_filter);
59        menu.addSeparator();
60     }
61 
62     connect(&savem3u, &QAction::triggered, [&]() {
63       on_savem3u(index);
64     });
65 
66     connect(&play, &QAction::triggered, [&]() {
67       emit view->doubleClicked(index);
68     });
69 
70     menu.addAction(&play);
71     menu.addSeparator();
72     menu.addAction(&rename);
73     menu.addAction(&savem3u);
74     menu.addAction(&reload);
75     menu.addSeparator();
76     menu.addAction(&remove);
77     menu.exec(view->viewport()->mapToGlobal(pos));
78   }
79 
on_rename(const QModelIndex & index)80   void PlaylistsContextMenu::on_rename(const QModelIndex &index)  {
81     auto i = model->itemAt(proxy->mapToSource(index));
82     bool ok;
83     QString new_name = QInputDialog::getText(view, QString("%1 '%2'").arg(tr("Rename playlist")).arg(i->name()), "", QLineEdit::Normal, i->name(), &ok, Qt::Widget);
84     if (ok && !new_name.isEmpty()) {
85       i->rename(new_name);
86     }
87     model->persist();
88   }
89 
on_savem3u(const QModelIndex & index)90   void PlaylistsContextMenu::on_savem3u(const QModelIndex &index) {
91     auto i = model->itemAt(proxy->mapToSource(index));
92     QByteArray m3u = i->toM3U();
93     QString fname = QFileDialog::getSaveFileName(view, tr("Save as m3u"), QStandardPaths::writableLocation(QStandardPaths::MusicLocation) + "/" + i->name(), "m3u (*.m3u)");
94     QFile f(fname);
95     if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
96       f.write(m3u);
97       f.close();
98     } else {
99       qWarning() << "error opening file " << fname << "for writing";
100     }
101   }
102 
on_reload(const QModelIndex & index)103   void PlaylistsContextMenu::on_reload(const QModelIndex &index) {
104     model->itemAt(index)->reload();
105     model->persist();
106     emit playlistChanged(model->itemAt(index));
107   }
108 }
109