1 /* ExternTracksPlaylistGenerator.cpp */
2 
3 /* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras)
4  *
5  * This file is part of sayonara player
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "ExternTracksPlaylistGenerator.h"
22 #include "Components/Directories/MetaDataScanner.h"
23 #include "Interfaces/PlaylistInterface.h"
24 #include "Playlist.h"
25 
26 #include "Utils/Algorithm.h"
27 #include "Utils/MetaData/MetaDataList.h"
28 #include "Utils/Language/Language.h"
29 
30 #include <QStringList>
31 #include <QThread>
32 
33 namespace
34 {
addNewPlaylist(PlaylistCreator * playlistCreator)35 	PlaylistPtr addNewPlaylist(PlaylistCreator* playlistCreator)
36 	{
37 		const auto name = playlistCreator->requestNewPlaylistName();
38 		auto index = playlistCreator->createPlaylist(MetaDataList(), name, true);
39 
40 		return playlistCreator->playlist(index);
41 	}
42 }
43 
44 struct ExternTracksPlaylistGenerator::Private
45 {
46 	PlaylistCreator* playlistCreator;
47 	PlaylistPtr playlist;
48 	int targetRowIndex;
49 
PrivateExternTracksPlaylistGenerator::Private50 	Private(PlaylistCreator* playlistCreator, PlaylistPtr playlist) :
51 		playlistCreator {playlistCreator},
52 		playlist(playlist ? playlist : addNewPlaylist(playlistCreator)),
53 		targetRowIndex {-1} {}
54 };
55 
ExternTracksPlaylistGenerator(PlaylistCreator * playlistCreator,PlaylistPtr playlist)56 ExternTracksPlaylistGenerator::ExternTracksPlaylistGenerator(PlaylistCreator* playlistCreator, PlaylistPtr playlist)
57 {
58 	m = Pimpl::make<Private>(playlistCreator, playlist);
59 }
60 
61 ExternTracksPlaylistGenerator::~ExternTracksPlaylistGenerator() = default;
62 
insertPaths(const QStringList & paths,int targetRowIndex)63 void ExternTracksPlaylistGenerator::insertPaths(const QStringList& paths, int targetRowIndex)
64 {
65 	if(!paths.isEmpty())
66 	{
67 		m->targetRowIndex = targetRowIndex;
68 		scanFiles(paths);
69 	}
70 }
71 
addPaths(const QStringList & paths)72 void ExternTracksPlaylistGenerator::addPaths(const QStringList& paths)
73 {
74 	const auto mode = m->playlist->mode();
75 	if(!Playlist::Mode::isActiveAndEnabled(mode.append()))
76 	{
77 		m->playlist->clear();
78 	}
79 
80 	insertPaths(paths, m->playlist->count() - 1);
81 }
82 
scanFiles(const QStringList & paths)83 void ExternTracksPlaylistGenerator::scanFiles(const QStringList& paths)
84 {
85 	m->playlist->setBusy(true);
86 
87 	using Directory::MetaDataScanner;
88 
89 	auto* t = new QThread();
90 	auto* worker = new MetaDataScanner(paths, true, nullptr);
91 
92 	connect(t, &QThread::started, worker, &MetaDataScanner::start);
93 	connect(t, &QThread::finished, t, &QObject::deleteLater);
94 	connect(worker, &MetaDataScanner::sigFinished, this, &ExternTracksPlaylistGenerator::filesScanned);
95 	connect(worker, &MetaDataScanner::sigFinished, t, &QThread::quit);
96 
97 	worker->moveToThread(t);
98 	t->start();
99 }
100 
filesScanned()101 void ExternTracksPlaylistGenerator::filesScanned()
102 {
103 	auto* worker = static_cast<Directory::MetaDataScanner*>(sender());
104 
105 	auto playlist = m->playlistCreator->playlistById(m->playlist->id());
106 	if(!playlist)
107 	{
108 		emit sigFinished();
109 		return;
110 	}
111 
112 	playlist->setBusy(false);
113 
114 	if(worker->metadata().isEmpty())
115 	{
116 		emit sigFinished();
117 		return;
118 	}
119 
120 	if(m->targetRowIndex < 0)
121 	{
122 		playlist->clear();
123 		playlist->insertTracks(worker->metadata(), 0);
124 	}
125 
126 	else if(m->targetRowIndex >= playlist->count())
127 	{
128 		playlist->appendTracks(worker->metadata());
129 	}
130 
131 	else
132 	{
133 		playlist->insertTracks(worker->metadata(), m->targetRowIndex);
134 	}
135 
136 	worker->deleteLater();
137 	emit sigFinished();
138 }
139