1 #include "library/baseexternallibraryfeature.h"
2 
3 #include <QMenu>
4 
5 #include "library/basesqltablemodel.h"
6 #include "library/library.h"
7 #include "library/trackcollection.h"
8 #include "library/trackcollectionmanager.h"
9 #include "moc_baseexternallibraryfeature.cpp"
10 #include "util/logger.h"
11 #include "widget/wlibrarysidebar.h"
12 
13 namespace {
14 
15 const mixxx::Logger kLogger("BaseExternalLibraryFeature");
16 
17 } // namespace
18 
BaseExternalLibraryFeature(Library * pLibrary,UserSettingsPointer pConfig)19 BaseExternalLibraryFeature::BaseExternalLibraryFeature(
20         Library* pLibrary,
21         UserSettingsPointer pConfig)
22         : LibraryFeature(pLibrary, pConfig),
23           m_pTrackCollection(pLibrary->trackCollections()->internalCollection()) {
24     m_pAddToAutoDJAction = make_parented<QAction>(tr("Add to Auto DJ Queue (bottom)"), this);
25     connect(m_pAddToAutoDJAction,
26             &QAction::triggered,
27             this,
28             &BaseExternalLibraryFeature::slotAddToAutoDJ);
29 
30     m_pAddToAutoDJTopAction = make_parented<QAction>(tr("Add to Auto DJ Queue (top)"), this);
31     connect(m_pAddToAutoDJTopAction,
32             &QAction::triggered,
33             this,
34             &BaseExternalLibraryFeature::slotAddToAutoDJTop);
35 
36     m_pAddToAutoDJReplaceAction = make_parented<QAction>(tr("Add to Auto DJ Queue (replace)"), this);
37     connect(m_pAddToAutoDJReplaceAction,
38             &QAction::triggered,
39             this,
40             &BaseExternalLibraryFeature::slotAddToAutoDJReplace);
41 
42     m_pImportAsMixxxPlaylistAction = make_parented<QAction>(tr("Import Playlist"), this);
43     connect(m_pImportAsMixxxPlaylistAction,
44             &QAction::triggered,
45             this,
46             &BaseExternalLibraryFeature::slotImportAsMixxxPlaylist);
47 }
48 
bindSidebarWidget(WLibrarySidebar * pSidebarWidget)49 void BaseExternalLibraryFeature::bindSidebarWidget(WLibrarySidebar* pSidebarWidget) {
50     // store the sidebar widget pointer for later use in onRightClickChild
51     m_pSidebarWidget = pSidebarWidget;
52 }
53 
onRightClick(const QPoint & globalPos)54 void BaseExternalLibraryFeature::onRightClick(const QPoint& globalPos) {
55     Q_UNUSED(globalPos);
56     m_lastRightClickedIndex = QModelIndex();
57 }
58 
onRightClickChild(const QPoint & globalPos,const QModelIndex & index)59 void BaseExternalLibraryFeature::onRightClickChild(
60         const QPoint& globalPos, const QModelIndex& index) {
61     //Save the model index so we can get it in the action slots...
62     m_lastRightClickedIndex = index;
63     QMenu menu(m_pSidebarWidget);
64     menu.addAction(m_pAddToAutoDJAction);
65     menu.addAction(m_pAddToAutoDJTopAction);
66     menu.addAction(m_pAddToAutoDJReplaceAction);
67     menu.addSeparator();
68     menu.addAction(m_pImportAsMixxxPlaylistAction);
69     menu.exec(globalPos);
70 }
71 
slotAddToAutoDJ()72 void BaseExternalLibraryFeature::slotAddToAutoDJ() {
73     //qDebug() << "slotAddToAutoDJ() row:" << m_lastRightClickedIndex.data();
74     addToAutoDJ(PlaylistDAO::AutoDJSendLoc::BOTTOM);
75 }
76 
slotAddToAutoDJTop()77 void BaseExternalLibraryFeature::slotAddToAutoDJTop() {
78     //qDebug() << "slotAddToAutoDJTop() row:" << m_lastRightClickedIndex.data();
79     addToAutoDJ(PlaylistDAO::AutoDJSendLoc::TOP);
80 }
81 
slotAddToAutoDJReplace()82 void BaseExternalLibraryFeature::slotAddToAutoDJReplace() {
83     //qDebug() << "slotAddToAutoDJReplace() row:" << m_lastRightClickedIndex.data();
84     addToAutoDJ(PlaylistDAO::AutoDJSendLoc::REPLACE);
85 }
86 
addToAutoDJ(PlaylistDAO::AutoDJSendLoc loc)87 void BaseExternalLibraryFeature::addToAutoDJ(PlaylistDAO::AutoDJSendLoc loc) {
88     //qDebug() << "slotAddToAutoDJ() row:" << m_lastRightClickedIndex.data();
89 
90     QList<TrackId> trackIds;
91     QString playlist;
92     appendTrackIdsFromRightClickIndex(&trackIds, &playlist);
93     if (trackIds.isEmpty()) {
94         return;
95     }
96 
97     PlaylistDAO &playlistDao = m_pTrackCollection->getPlaylistDAO();
98     playlistDao.addTracksToAutoDJQueue(trackIds, loc);
99 }
100 
slotImportAsMixxxPlaylist()101 void BaseExternalLibraryFeature::slotImportAsMixxxPlaylist() {
102     // qDebug() << "slotAddToAutoDJ() row:" << m_lastRightClickedIndex.data();
103 
104     QList<TrackId> trackIds;
105     QString playlist;
106     appendTrackIdsFromRightClickIndex(&trackIds, &playlist);
107     if (trackIds.isEmpty()) {
108         return;
109     }
110 
111     PlaylistDAO& playlistDao = m_pTrackCollection->getPlaylistDAO();
112 
113     int playlistId = playlistDao.createUniquePlaylist(&playlist);
114 
115     if (playlistId != -1) {
116         playlistDao.appendTracksToPlaylist(trackIds, playlistId);
117     } else {
118         // Do not change strings here without also changing strings in
119         // src/library/baseplaylistfeature.cpp
120         QMessageBox::warning(nullptr,
121                 tr("Playlist Creation Failed"),
122                 tr("An unknown error occurred while creating playlist: ") + playlist);
123     }
124 }
125 
126 // This is a common function for all external Librarys copied to Mixxx DB
appendTrackIdsFromRightClickIndex(QList<TrackId> * trackIds,QString * pPlaylist)127 void BaseExternalLibraryFeature::appendTrackIdsFromRightClickIndex(
128         QList<TrackId>* trackIds, QString* pPlaylist) {
129     if (!m_lastRightClickedIndex.isValid()) {
130         return;
131     }
132 
133     DEBUG_ASSERT(pPlaylist);
134     *pPlaylist = m_lastRightClickedIndex.data().toString();
135     QScopedPointer<BaseSqlTableModel> pPlaylistModelToAdd(
136             getPlaylistModelForPlaylist(*pPlaylist));
137 
138     if (!pPlaylistModelToAdd || !pPlaylistModelToAdd->initialized()) {
139         qDebug() << "BaseExternalLibraryFeature::appendTrackIdsFromRightClickIndex "
140                 "could not initialize a playlist model for playlist:" << *pPlaylist;
141         return;
142     }
143 
144     pPlaylistModelToAdd->setSort(pPlaylistModelToAdd->fieldIndex(
145             ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_POSITION), Qt::AscendingOrder);
146     pPlaylistModelToAdd->select();
147 
148     // Copy Tracks
149     int rows = pPlaylistModelToAdd->rowCount();
150     for (int i = 0; i < rows; ++i) {
151         QModelIndex index = pPlaylistModelToAdd->index(i, 0);
152         VERIFY_OR_DEBUG_ASSERT(index.isValid()) {
153             continue;
154         }
155         const TrackId trackId = pPlaylistModelToAdd->getTrackId(index);
156         if (!trackId.isValid()) {
157             kLogger.warning()
158                     << "Failed to add track"
159                     << pPlaylistModelToAdd->getTrackLocation(index)
160                     << "to playlist"
161                     << *pPlaylist;
162             continue;
163         }
164         if (kLogger.traceEnabled()) {
165             kLogger.trace()
166                     << "Adding track"
167                     << pPlaylistModelToAdd->getTrackLocation(index)
168                     << "to playlist"
169                     << *pPlaylist;
170         }
171         trackIds->append(trackId);
172     }
173 }
174