summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRJ Ryan <rryan@mixxx.org>2014-01-29 01:40:48 -0500
committerRJ Ryan <rryan@mixxx.org>2014-02-13 23:31:31 -0500
commit3fa83e6f2d91ee63f40994c2c4171db09f04d983 (patch)
treee0810bb27026ed45d6caaac8ab64c78be31a9176 /src
parent47970a144612700e9f1b31617f11c815c6b37cc7 (diff)
Handle creation of scoped bookmarks on drop of files in Mixxx.
* Clean up / unify processing of dropped URLs across all drop handlers. * Support dropping of playlists on the analysis, playlists, crate, autodj, and track table sections of the library (previously was only supported in playlists).
Diffstat (limited to 'src')
-rw-r--r--src/library/analysisfeature.cpp11
-rw-r--r--src/library/autodjfeature.cpp16
-rw-r--r--src/library/cratefeature.cpp9
-rw-r--r--src/library/mixxxlibraryfeature.cpp11
-rw-r--r--src/library/playlistfeature.cpp30
-rw-r--r--src/util/dnd.h95
-rw-r--r--src/widget/wlibrarysidebar.cpp2
-rw-r--r--src/widget/woverview.cpp21
-rw-r--r--src/widget/wspinny.cpp23
-rw-r--r--src/widget/wtracktableview.cpp32
-rw-r--r--src/widget/wwaveformviewer.cpp23
11 files changed, 150 insertions, 123 deletions
diff --git a/src/library/analysisfeature.cpp b/src/library/analysisfeature.cpp
index a6790ecd71..8e163b1854 100644
--- a/src/library/analysisfeature.cpp
+++ b/src/library/analysisfeature.cpp
@@ -12,6 +12,7 @@
#include "mixxxkeyboard.h"
#include "analyserqueue.h"
#include "soundsourceproxy.h"
+#include "util/dnd.h"
const QString AnalysisFeature::m_sAnalysisViewName = QString("Analysis");
@@ -134,15 +135,7 @@ void AnalysisFeature::cleanupAnalyser() {
bool AnalysisFeature::dropAccept(QList<QUrl> urls, QObject* pSource) {
Q_UNUSED(pSource);
- QList<QFileInfo> files;
- foreach (QUrl url, urls) {
- // XXX: Possible WTF alert - Previously we thought we needed toString() here
- // but what you actually want in any case when converting a QUrl to a file
- // system path is QUrl::toLocalFile(). This is the second time we have
- // flip-flopped on this, but I think toLocalFile() should work in any
- // case. toString() absolutely does not work when you pass the result to a
- files.append(url.toLocalFile());
- }
+ QList<QFileInfo> files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true);
// Adds track, does not insert duplicates, handles unremoving logic.
QList<int> trackIds = m_pTrackCollection->getTrackDAO().addTracks(files, true);
analyzeTracks(trackIds);
diff --git a/src/library/autodjfeature.cpp b/src/library/autodjfeature.cpp
index 9338842278..083fb8e0ab 100644
--- a/src/library/autodjfeature.cpp
+++ b/src/library/autodjfeature.cpp
@@ -15,6 +15,7 @@
#include "widget/wlibrary.h"
#include "mixxxkeyboard.h"
#include "soundsourceproxy.h"
+#include "util/dnd.h"
const QString AutoDJFeature::m_sAutoDJViewName = QString("Auto DJ");
@@ -119,17 +120,10 @@ bool AutoDJFeature::dropAccept(QList<QUrl> urls, QObject* pSource) {
//TODO: Filter by supported formats regex and reject anything that doesn't match.
TrackDAO &trackDao = m_pTrackCollection->getTrackDAO();
- //If a track is dropped onto a playlist's name, but the track isn't in the library,
- //then add the track to the library before adding it to the playlist.
- QList<QFileInfo> files;
- foreach (QUrl url, urls) {
- //XXX: See the note in PlaylistFeature::dropAccept() about using QUrl::toLocalFile()
- // instead of toString()
- QFileInfo file = url.toLocalFile();
- if (SoundSourceProxy::isFilenameSupported(file.fileName())) {
- files.append(file);
- }
- }
+ // If a track is dropped onto a playlist's name, but the track isn't in the
+ // library, then add the track to the library before adding it to the
+ // playlist.
+ QList<QFileInfo> files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true);
QList<int> trackIds;
if (pSource) {
trackIds = trackDao.getTrackIds(files);
diff --git a/src/library/cratefeature.cpp b/src/library/cratefeature.cpp
index 6630b8e1de..2671d3d4be 100644
--- a/src/library/cratefeature.cpp
+++ b/src/library/cratefeature.cpp
@@ -20,6 +20,7 @@
#include "mixxxkeyboard.h"
#include "treeitem.h"
#include "soundsourceproxy.h"
+#include "util/dnd.h"
CrateFeature::CrateFeature(QObject* parent,
TrackCollection* pTrackCollection,
@@ -114,13 +115,7 @@ bool CrateFeature::dropAcceptChild(const QModelIndex& index, QList<QUrl> urls,
QObject* pSource) {
QString crateName = index.data().toString();
int crateId = m_crateDao.getCrateIdByName(crateName);
- QList<QFileInfo> files;
- foreach (QUrl url, urls) {
- //XXX: See the comment in PlaylistFeature::dropAcceptChild() about
- // QUrl::toLocalFile() vs. QUrl::toString() usage.
- files.append(url.toLocalFile());
- }
-
+ QList<QFileInfo> files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true);
QList<int> trackIds;
if (pSource) {
trackIds = m_pTrackCollection->getTrackDAO().getTrackIds(files);
diff --git a/src/library/mixxxlibraryfeature.cpp b/src/library/mixxxlibraryfeature.cpp
index 3badd625d0..09b6bfb036 100644
--- a/src/library/mixxxlibraryfeature.cpp
+++ b/src/library/mixxxlibraryfeature.cpp
@@ -14,6 +14,7 @@
#include "treeitem.h"
#include "soundsourceproxy.h"
#include "widget/wlibrary.h"
+#include "util/dnd.h"
MixxxLibraryFeature::MixxxLibraryFeature(QObject* parent,
TrackCollection* pTrackCollection,
@@ -162,15 +163,7 @@ bool MixxxLibraryFeature::dropAccept(QList<QUrl> urls, QObject* pSource) {
if (pSource) {
return false;
} else {
- QList<QFileInfo> files;
- foreach (QUrl url, urls) {
- // XXX: Possible WTF alert - Previously we thought we needed toString() here
- // but what you actually want in any case when converting a QUrl to a file
- // system path is QUrl::toLocalFile(). This is the second time we have
- // flip-flopped on this, but I think toLocalFile() should work in any
- // case. toString() absolutely does not work when you pass the result to a
- files.append(url.toLocalFile());
- }
+ QList<QFileInfo> files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true);
// Adds track, does not insert duplicates, handles unremoving logic.
QList<int> trackIds = m_trackDao.addTracks(files, true);
diff --git a/src/library/playlistfeature.cpp b/src/library/playlistfeature.cpp
index 6d7bd687fc..07bc6e7533 100644
--- a/src/library/playlistfeature.cpp
+++ b/src/library/playlistfeature.cpp
@@ -4,10 +4,6 @@
#include <QFileInfo>
#include "library/playlistfeature.h"
-#include "library/parser.h"
-#include "library/parserm3u.h"
-#include "library/parserpls.h"
-#include "library/parsercsv.h"
#include "widget/wlibrary.h"
#include "widget/wlibrarysidebar.h"
@@ -17,6 +13,7 @@
#include "library/treeitem.h"
#include "mixxxkeyboard.h"
#include "soundsourceproxy.h"
+#include "util/dnd.h"
PlaylistFeature::PlaylistFeature(QObject* parent,
TrackCollection* pTrackCollection,
@@ -90,29 +87,8 @@ bool PlaylistFeature::dropAcceptChild(const QModelIndex& index, QList<QUrl> urls
QString playlistName = index.data().toString();
int playlistId = m_playlistDao.getPlaylistIdFromName(playlistName);
//m_playlistDao.appendTrackToPlaylist(url.toLocalFile(), playlistId);
- QList<QFileInfo> files;
- foreach (QUrl url, urls) {
- // XXX: Possible WTF alert - Previously we thought we needed toString() here
- // but what you actually want in any case when converting a QUrl to a file
- // system path is QUrl::toLocalFile(). This is the second time we have
- // flip-flopped on this, but I think toLocalFile() should work in any
- // case. toString() absolutely does not work when you pass the result to a
- if (url.toString().endsWith(".m3u") || url.toString().endsWith(".m3u8")) {
- QScopedPointer<ParserM3u> playlist_parser(new ParserM3u());
- QList<QString> track_list = playlist_parser->parse(url.toLocalFile());
- for (int i = 0; i < track_list.size(); i++) {
- files.append(track_list.at(i));
- }
- } else if (url.toString().endsWith(".pls")) {
- QScopedPointer<ParserPls> playlist_parser(new ParserPls());
- QList<QString> track_list = playlist_parser->parse(url.toLocalFile());
- for (int i = 0; i < track_list.size(); i++) {
- files.append(track_list.at(i));
- }
- } else {
- files.append(url.toLocalFile());
- }
- }
+
+ QList<QFileInfo> files = DragAndDropHelper::supportedTracksFromUrls(urls, false, true);
QList<int> trackIds;
if (pSource) {
diff --git a/src/util/dnd.h b/src/util/dnd.h
new file mode 100644
index 0000000000..415ceee762
--- /dev/null
+++ b/src/util/dnd.h
@@ -0,0 +1,95 @@
+#ifndef DND_H
+#define DND_H
+
+#include <QUrl>
+#include <QList>
+#include <QString>
+#include <QFileInfo>
+#include <QRegExp>
+#include <QScopedPointer>
+
+#include "soundsourceproxy.h"
+#include "library/parser.h"
+#include "library/parserm3u.h"
+#include "library/parserpls.h"
+#include "library/parsercsv.h"
+#include "util/sandbox.h"
+
+class DragAndDropHelper {
+ public:
+ static QList<QFileInfo> supportedTracksFromUrls(const QList<QUrl>& urls,
+ bool firstOnly,
+ bool acceptPlaylists) {
+ QList<QFileInfo> fileLocations;
+ foreach (const QUrl& url, urls) {
+
+ // XXX: Possible WTF alert - Previously we thought we needed
+ // toString() here but what you actually want in any case when
+ // converting a QUrl to a file system path is
+ // QUrl::toLocalFile(). This is the second time we have flip-flopped
+ // on this, but I think toLocalFile() should work in any
+ // case. toString() absolutely does not work when you pass the
+ // result to a (this comment was never finished by the original
+ // author).
+ QString file(url.toLocalFile());
+
+ // If the file is on a network share, try just converting the URL to
+ // a string...
+ if (file.isEmpty()) {
+ file = url.toString();
+ }
+
+ if (file.isEmpty()) {
+ continue;
+ }
+
+ if (acceptPlaylists && (file.endsWith(".m3u") || file.endsWith(".m3u8"))) {
+ QScopedPointer<ParserM3u> playlist_parser(new ParserM3u());
+ QList<QString> track_list = playlist_parser->parse(file);
+ foreach (const QString& playlistFile, track_list) {
+ addFileToList(playlistFile, &fileLocations);
+ }
+ } else if (acceptPlaylists && url.toString().endsWith(".pls")) {
+ QScopedPointer<ParserPls> playlist_parser(new ParserPls());
+ QList<QString> track_list = playlist_parser->parse(file);
+ foreach (const QString& playlistFile, track_list) {
+ addFileToList(playlistFile, &fileLocations);
+ }
+ } else {
+ addFileToList(file, &fileLocations);
+ }
+
+ if (firstOnly && !fileLocations.isEmpty()) {
+ break;
+ }
+ }
+
+ return fileLocations;
+ }
+
+ private:
+
+ static bool addFileToList(const QString& file, QList<QFileInfo>* files) {
+ QFileInfo fileInfo(file);
+
+ // Since the user just dropped these files into Mixxx we have permission
+ // to touch the file. Create a security token to keep this permission
+ // across reboots.
+ Sandbox::createSecurityToken(fileInfo);
+
+ if (!fileInfo.exists()) {
+ return false;
+ }
+
+ // Filter out invalid URLs (eg. files that aren't supported audio
+ // filetypes, etc.)
+ if (!SoundSourceProxy::isFilenameSupported(fileInfo.fileName())) {
+ return false;
+ }
+
+ files->append(fileInfo);
+ return true;
+ }
+};
+
+#endif /* DND_H */
diff --git a/src/widget/wlibrarysidebar.cpp b/src/widget/wlibrarysidebar.cpp
index f650eb3462..4d1a0625d6 100644
--- a/src/widget/wlibrarysidebar.cpp
+++ b/src/widget/wlibrarysidebar.cpp
@@ -111,7 +111,6 @@ void WLibrarySidebar::timerEvent(QTimerEvent *event) {
// Drag-and-drop "drop" event. Occurs when something is dropped onto the track sources view
void WLibrarySidebar::dropEvent(QDropEvent * event) {
if (event->mimeData()->hasUrls()) {
- QList<QUrl> urls(event->mimeData()->urls());
// Drag and drop within this widget
if ((event->source() == this)
&& (event->possibleActions() & Qt::MoveAction)) {
@@ -127,6 +126,7 @@ void WLibrarySidebar::dropEvent(QDropEvent * event) {
QModelIndex destIndex = indexAt(event->pos());
// event->source() will return NULL if something is droped from
// a different application
+ QList<QUrl> urls(event->mimeData()->urls());
if (sidebarModel->dropAccept(destIndex, urls, event->source())) {
event->acceptProposedAction();
} else {
diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp
index 134cf76d2c..b02cab4e5b 100644
--- a/src/widget/woverview.cpp
+++ b/src/widget/woverview.cpp
@@ -27,6 +27,7 @@
#include "trackinfoobject.h"
#include "mathstuff.h"
#include "util/timer.h"
+#include "util/dnd.h"
#include "waveform/waveform.h"
#include "waveform/waveformwidgetfactory.h"
@@ -499,18 +500,14 @@ void WOverview::dragEnterEvent(QDragEnterEvent* event) {
}
void WOverview::dropEvent(QDropEvent* event) {
- if (event->mimeData()->hasUrls() &&
- event->mimeData()->urls().size() > 0) {
- QList<QUrl> urls(event->mimeData()->urls());
- QUrl url = urls.first();
- QString name = url.toLocalFile();
- //If the file is on a network share, try just converting the URL to a string...
- if (name == "") {
- name = url.toString();
+ if (event->mimeData()->hasUrls()) {
+ QList<QFileInfo> files = DragAndDropHelper::supportedTracksFromUrls(
+ event->mimeData()->urls(), true, false);
+ if (!files.isEmpty()) {
+ event->accept();
+ emit(trackDropped(files.at(0).canonicalFilePath(), m_group));
+ return;
}
- event->accept();
- emit(trackDropped(name, m_group));
- } else {
- event->ignore();
}
+ event->ignore();
}
diff --git a/src/widget/wspinny.cpp b/src/widget/wspinny.cpp
index 212ab27561..8036acbd27 100644
--- a/src/widget/wspinny.cpp
+++ b/src/widget/wspinny.cpp
@@ -15,6 +15,7 @@
#include "widget/wspinny.h"
#include "vinylcontrol/vinylcontrolmanager.h"
#include "vinylcontrol/vinylcontrol.h"
+#include "util/dnd.h"
WSpinny::WSpinny(QWidget* parent, VinylControlManager* pVCMan)
: QGLWidget(parent, SharedGLContext::getWidget()),
@@ -498,19 +499,15 @@ void WSpinny::dragEnterEvent(QDragEnterEvent * event)
}
}
-void WSpinny::dropEvent(QDropEvent * event)
-{
+void WSpinny::dropEvent(QDropEvent * event) {
if (event->mimeData()->hasUrls()) {
- QList<QUrl> urls(event->mimeData()->urls());
- QUrl url = urls.first();
- QString name = url.toLocalFile();
- //If the file is on a network share, try just converting the URL to a string...
- if (name == "")
- name = url.toString();
-
- event->accept();
- emit(trackDropped(name, m_group));
- } else {
- event->ignore();
+ QList<QFileInfo> files = DragAndDropHelper::supportedTracksFromUrls(
+ event->mimeData()->urls(), true, false);
+ if (!files.isEmpty()) {
+ event->accept();
+ emit(trackDropped(files.at(0).canonicalFilePath(), m_group));
+ return;
+ }
}
+ event->ignore();
}
diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp
index 0d7d44be27..3091f30038 100644
--- a/src/widget/wtracktableview.cpp
+++ b/src/widget/wtracktableview.cpp
@@ -16,6 +16,7 @@
#include "dlgtrackinfo.h"
#include "soundsourceproxy.h"
#include "playermanager.h"
+#include "util/dnd.h"
WTrackTableView::WTrackTableView(QWidget * parent,
ConfigObject<ConfigValue> * pConfig,
@@ -902,20 +903,6 @@ void WTrackTableView::dropEvent(QDropEvent * event) {
event->ignore();
return;
}
- QList<QUrl> urls(event->mimeData()->urls());
- QUrl url;
- QModelIndex selectedIndex; //Index of a selected track (iterator)
-
- // Filter out invalid URLs (eg. files that aren't supported audio filetypes, etc.)
- QRegExp fileRx(SoundSourceProxy::supportedFileExtensionsRegex(),
- Qt::CaseInsensitive);
- for (int i = 0; i < urls.size(); ++i) {
- if (fileRx.indexIn(urls.at(i).path()) == -1) {
- // remove invalid urls and decrease i because the size of
- // urls has changed.
- urls.removeAt(--i);
- }
- }
// Save the vertical scrollbar position. Adding new tracks and moving tracks in
// the SQL data models causes a select() (ie. generation of a new result set),
@@ -1038,9 +1025,18 @@ void WTrackTableView::dropEvent(QDropEvent * event) {
// clears them)
this->selectionModel()->clear();
+ // Add all the dropped URLs/tracks to the track model (playlist/crate)
+ QList<QFileInfo> fileList = DragAndDropHelper::supportedTracksFromUrls(
+ event->mimeData()->urls(), false, true);
+
+ QList<QString> fileLocationList;
+ foreach (const QFileInfo& fileInfo, fileList) {
+ fileLocationList.append(fileInfo.canonicalFilePath());
+ }
+
// Drag-and-drop from an external application
// eg. dragging a track from Windows Explorer onto the track table.
- int numNewRows = urls.count();
+ int numNewRows = fileLocationList.count();
// Have to do this here because the index is invalid after
// addTrack
@@ -1061,12 +1057,6 @@ void WTrackTableView::dropEvent(QDropEvent * event) {
selectionStartRow = model()->rowCount();
}
- // Add all the dropped URLs/tracks to the track model (playlist/crate)
- QList<QString> fileLocationList;
- foreach(url, urls) {
- QString file(url.toLocalFile());
- fileLocationList.append(file);
- }
// calling the addTracks returns number of failed additions
int tracksAdded = trackModel->addTracks(destIndex, fileLocationList);
diff --git a/src/widget/wwaveformviewer.cpp b/src/widget/wwaveformviewer.cpp
index f61368ffe8..ff0ed311b7 100644
--- a/src/widget/wwaveformviewer.cpp
+++ b/src/widget/wwaveformviewer.cpp
@@ -13,6 +13,7 @@
#include "waveform/widgets/waveformwidgetabstract.h"
#include "widget/wwaveformviewer.h"
#include "waveform/waveformwidgetfactory.h"
+#include "util/dnd.h"
WWaveformViewer::WWaveformViewer(const char *group, ConfigObject<ConfigValue>* pConfig, QWidget * parent)
: WWidget(parent),
@@ -161,20 +162,16 @@ void WWaveformViewer::dragEnterEvent(QDragEnterEvent * event) {
}
void WWaveformViewer::dropEvent(QDropEvent * event) {
- if (event->mimeData()->hasUrls() &&
- event->mimeData()->urls().size() > 0) {
- QList<QUrl> urls(event->mimeData()->urls());
- QUrl url = urls.first();
- QString name = url.toLocalFile();
- //If the file is on a network share, try just converting the URL to a string...
- if (name == "")
- name = url.toString();
-
- event->accept();
- emit(trackDropped(name, m_pGroup));
- } else {
- event->ignore();
+ if (event->mimeData()->hasUrls()) {
+ QList<QFileInfo> files = DragAndDropHelper::supportedTracksFromUrls(
+ event->mimeData()->urls(), true, false);
+ if (!files.isEmpty()) {
+ event->accept();
+ emit(trackDropped(files.at(0).canonicalFilePath(), m_pGroup));
+ return;
+ }
}
+ event->ignore();
}
void WWaveformViewer::onTrackLoaded( TrackPointer track) {