Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better file export #3572

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8dbb96f
Add Grantlee lib to dependencies
poelzi Jan 18, 2021
5874dbe
Major track export overhaul
poelzi Jan 18, 2021
ad7ac51
Use the the last right click selected playlist, not the current
poelzi Jan 18, 2021
167550a
Add libgrantlee5-dev to debian build env
poelzi Jan 18, 2021
69f357d
Fix build problems
poelzi Jan 18, 2021
4672c8b
Make Key a Q_GADGET and add string properties for formatting
poelzi Jan 18, 2021
b97b6cc
Use index for position index and dup for duplication counter
poelzi Jan 19, 2021
0d9618e
Add support for exporting files from context menu
poelzi Jan 19, 2021
d129f2d
Export crate summary into file exporter context
poelzi Jan 19, 2021
e2d9ec9
Add render function which does not escape html characters
poelzi Jan 20, 2021
19f00f6
Add grantlee plugin with mixxx specific filters
poelzi Jan 21, 2021
715355c
Fix Exporter Test
poelzi Jan 21, 2021
fc287dc
Use CrateSummaryWrapper as QObject wrapper
poelzi Jan 22, 2021
993a5e7
Add zeropad filter for adding 0 prefixes
poelzi Jan 22, 2021
515d393
Move exportPlaylistItemsIntoFile to Parser
poelzi Jan 22, 2021
999edbf
Add support for creating a playlist on file export
poelzi Jan 23, 2021
7c86579
Add PlaylistSummary for repersenting playlists
poelzi Nov 22, 2020
f6fc540
Add PlaylistSummary wrapper and export to track exporter
poelzi Jan 23, 2021
cc9b5fa
Add round filter, move default patterns to code
poelzi Jan 23, 2021
998667f
Compile fixes
poelzi Jan 24, 2021
9324697
Merge branch 'main' of https://github.com/mixxxdj/mixxx into better-e…
poelzi Jan 25, 2021
7c1d480
Merge branch 'main' of https://github.com/mixxxdj/mixxx into better-e…
poelzi Jan 26, 2021
1d64ce4
Add function to ensure safe filename on all platforms
poelzi Feb 1, 2021
3057941
Use tabwidget for export dialog
poelzi Feb 1, 2021
dd3d9e6
cleanup group filter
poelzi Feb 1, 2021
3a79ffa
Fix missing assignment of crateWrapper
poelzi Feb 2, 2021
7fad172
Properly escape problematic filenames on all platforms
poelzi Feb 2, 2021
488671b
Use Dropdown Menu for pattern suggestions, not a ComboBox
poelzi Feb 3, 2021
4d0ce25
Implement default lookup function for keys (not working)
poelzi Feb 3, 2021
049c65d
fix clazy warnings
poelzi Feb 5, 2021
2118737
clazy fixes
poelzi Feb 7, 2021
87aa753
Use one button line in export
poelzi Feb 7, 2021
49aa05d
Escape playlist name in menu
poelzi Feb 7, 2021
1dd67eb
Prevent crashes on patterns like "{{ }}"
poelzi Feb 18, 2021
82652f0
Go back to a QComboBox but with custom item handling
poelzi Feb 19, 2021
28f0439
Merge branch 'main' of https://github.com/mixxxdj/mixxx into better-e…
poelzi Apr 12, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
libebur128-dev \
libfftw3-dev \
libflac-dev \
libgrantlee5-dev \
libid3tag0-dev \
liblilv-dev \
libmad0-dev \
Expand Down
30 changes: 29 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,6 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/library/dlgtrackmetadataexport.cpp
src/library/export/dlgtrackexport.ui
src/library/export/trackexportdlg.cpp
src/library/export/trackexportwizard.cpp
src/library/export/trackexportworker.cpp
src/library/externaltrackcollection.cpp
src/library/hiddentablemodel.cpp
Expand Down Expand Up @@ -708,7 +707,9 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/library/trackset/crate/cratefeaturehelper.cpp
src/library/trackset/crate/cratestorage.cpp
src/library/trackset/crate/cratetablemodel.cpp
src/library/trackset/crate/cratesummary.cpp
src/library/trackset/playlistfeature.cpp
src/library/trackset/playlistsummary.cpp
src/library/trackset/setlogfeature.cpp
src/library/trackset/tracksettablemodel.cpp
src/library/traktor/traktorfeature.cpp
Expand Down Expand Up @@ -868,6 +869,8 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL
src/util/dnd.cpp
src/util/duration.cpp
src/util/experiment.cpp
src/util/fileutils.cpp
src/util/formatter.cpp
src/util/fileaccess.cpp
src/util/fileinfo.cpp
src/util/imageutils.cpp
Expand Down Expand Up @@ -1499,6 +1502,8 @@ add_executable(mixxx-test
src/test/enginemastertest.cpp
src/test/enginemicrophonetest.cpp
src/test/enginesynctest.cpp
src/test/formatter_test.cpp
src/test/fileutils_test.cpp
src/test/fileinfo_test.cpp
src/test/globaltrackcache_test.cpp
src/test/hotcuecontrol_test.cpp
Expand Down Expand Up @@ -1890,6 +1895,29 @@ target_link_libraries(mixxx-lib PUBLIC FpClassify)
# in production code
target_include_directories(mixxx-lib SYSTEM PUBLIC "${gtest_SOURCE_DIR}/include")

# Grantlee5
find_package(Grantlee5 REQUIRED)

target_link_libraries(mixxx-lib PUBLIC
Grantlee5::Templates
Grantlee5::TextDocument
)

# grantlee plugin
add_library(mixxxformatter MODULE
src/util/formatterplugin/mixxxformatter.cpp
src/util/fileutils.cpp
)

set_target_properties(mixxxformatter PROPERTIES AUTOMOC ON)
target_include_directories(mixxxformatter PRIVATE src)

grantlee_adjust_plugin_name(mixxxformatter)

target_link_libraries(mixxxformatter
Grantlee5::Templates
)

# LAME
find_package(mp3lame REQUIRED)
target_link_libraries(mixxx-lib PUBLIC mp3lame::mp3lame)
Expand Down
1 change: 1 addition & 0 deletions packaging/debian/control.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Build-Depends: debhelper (>= 11),
# Only needed for running tests that use SQLite.
libqt5sql5-sqlite,
libqt5x11extras5-dev,
libgrantlee5-dev,
cmake (>= 3.13),
libjack-dev,
portaudio19-dev,
Expand Down
143 changes: 143 additions & 0 deletions src/library/dao/playlistdao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "library/trackcollection.h"
#include "track/track.h"
#include "util/compatibility.h"
#include "util/db/dbconnection.h"
#include "util/db/fwdsqlquery.h"
#include "util/math.h"

Expand All @@ -21,6 +22,32 @@ PlaylistDAO::PlaylistDAO()
void PlaylistDAO::initialize(const QSqlDatabase& database) {
DAO::initialize(database);
populatePlaylistMembershipCache();

// create temporary views
QString queryString = QLatin1String(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
QString queryString = QLatin1String(
QString queryString = QStringLiteral(

"CREATE TEMPORARY VIEW IF NOT EXISTS PlaylistsCountsDurations "
"AS SELECT "
" Playlists.id AS id, "
" Playlists.name AS name, "
" LOWER(Playlists.name) AS sort_name, "
" COUNT(case library.mixxx_deleted when 0 then 1 else null end) "
" AS count, "
" SUM(case library.mixxx_deleted "
" when 0 then library.duration else 0 end) AS durationSeconds "
"FROM Playlists "
"LEFT JOIN PlaylistTracks "
" ON PlaylistTracks.playlist_id = Playlists.id "
"LEFT JOIN library "
" ON PlaylistTracks.track_id = library.id "
" WHERE Playlists.hidden = 0 "
" GROUP BY Playlists.id");
queryString.append(
mixxx::DbConnection::collateLexicographically(
" ORDER BY sort_name"));
QSqlQuery query(m_database);
if (!query.exec(queryString)) {
LOG_FAILED_QUERY(query);
}
}

void PlaylistDAO::populatePlaylistMembershipCache() {
Expand Down Expand Up @@ -1160,6 +1187,122 @@ void PlaylistDAO::getPlaylistsTrackIsIn(TrackId trackId,
}
}

QList<PlaylistSummary> PlaylistDAO::createPlaylistSummaryForTracks(const QList<TrackId>& tracks) {
QSet<int> allPlaylistIds;
QSet<int> playlistIds;
QMap<int, int> trackCount;
for (TrackId trackId : tracks) {
PlaylistDAO::getPlaylistsTrackIsIn(trackId, &playlistIds);
allPlaylistIds += playlistIds;
for (int playlistId : qAsConst(playlistIds)) {
trackCount[playlistId] = trackCount.value(playlistId, 0) + 1;
}
}
QList<PlaylistSummary> summaries = PlaylistDAO::createPlaylistSummary(&allPlaylistIds);
for (PlaylistSummary summary : summaries) {
DEBUG_ASSERT(trackCount.contains(summary.id()));
summary.setMatches(trackCount.value(summary.id()));
}
return summaries;
}

QList<PlaylistSummary> PlaylistDAO::createPlaylistSummary(const QSet<int>* playlistIds) {
QList<PlaylistSummary> playlistLabels;

// Setup the sidebar playlist model
QSqlTableModel playlistTableModel(this, m_database);
playlistTableModel.setTable("PlaylistsCountsDurations");

if (playlistIds) {
QStringList idList;
for (const auto& playlistId : *playlistIds) {
idList.append(QString::number(playlistId));
}
playlistTableModel.setFilter(QString("id in [%1]").arg(idList.join(",")));
}

playlistTableModel.select();
while (playlistTableModel.canFetchMore()) {
playlistTableModel.fetchMore();
}
QSqlRecord record = playlistTableModel.record();
int nameColumn = record.indexOf("name");
int idColumn = record.indexOf("id");
int countColumn = record.indexOf("count");
int durationColumn = record.indexOf("durationSeconds");

for (int row = 0; row < playlistTableModel.rowCount(); ++row) {
int id =
playlistTableModel
.data(playlistTableModel.index(row, idColumn))
.toInt();
QString name =
playlistTableModel
.data(playlistTableModel.index(row, nameColumn))
.toString();
int count =
playlistTableModel
.data(playlistTableModel.index(row, countColumn))
.toInt();
int duration =
playlistTableModel
.data(playlistTableModel.index(row, durationColumn))
.toInt();
PlaylistSummary playlist(id, name);
playlist.setCount(count);
playlist.setDuration(duration);
playlistLabels.append(playlist);
}
return playlistLabels;
}
PlaylistSummary PlaylistDAO::getPlaylistSummary(int playlistId) {
if (playlistId == -1) {
return PlaylistSummary();
}
QSqlTableModel playlistTableModel(this, m_database);
playlistTableModel.setTable("PlaylistsCountsDurations");

playlistTableModel.setFilter(QString("id = %1").arg(playlistId));

playlistTableModel.select();
while (playlistTableModel.canFetchMore()) {
playlistTableModel.fetchMore();
}
QSqlRecord record = playlistTableModel.record();
int nameColumn = record.indexOf("name");
int idColumn = record.indexOf("id");
int countColumn = record.indexOf("count");
int durationColumn = record.indexOf("durationSeconds");

if (playlistTableModel.rowCount() == 0) {
return PlaylistSummary();
}
VERIFY_OR_DEBUG_ASSERT(playlistTableModel.rowCount() == 1) {
qWarning() << "playlist id matched to multiple results";
}

int id =
playlistTableModel
.data(playlistTableModel.index(0, idColumn))
.toInt();
QString name =
playlistTableModel
.data(playlistTableModel.index(0, nameColumn))
.toString();
int count =
playlistTableModel
.data(playlistTableModel.index(0, countColumn))
.toInt();
int duration =
playlistTableModel
.data(playlistTableModel.index(0, durationColumn))
.toInt();
PlaylistSummary summary(id, name);
summary.setCount(count);
summary.setDuration(duration);
return summary;
}

void PlaylistDAO::setAutoDJProcessor(AutoDJProcessor* pAutoDJProcessor) {
m_pAutoDJProcessor = pAutoDJProcessor;
}
Expand Down
6 changes: 5 additions & 1 deletion src/library/dao/playlistdao.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

#include <QHash>
#include <QObject>
#include <QSqlDatabase>
#include <QSet>
#include <QSqlDatabase>

#include "library/dao/dao.h"
#include "library/trackset/playlistsummary.h"
#include "track/trackid.h"
#include "util/class.h"

Expand Down Expand Up @@ -117,6 +118,9 @@ class PlaylistDAO : public QObject, public virtual DAO {
bool isTrackInPlaylist(TrackId trackId, const int playlistId) const;

void getPlaylistsTrackIsIn(TrackId trackId, QSet<int>* playlistSet) const;
QList<PlaylistSummary> createPlaylistSummary(const QSet<int>* playlistIds = nullptr);
QList<PlaylistSummary> createPlaylistSummaryForTracks(const QList<TrackId>& tracks);
PlaylistSummary getPlaylistSummary(int playlistId);

void setAutoDJProcessor(AutoDJProcessor* pAutoDJProcessor);

Expand Down
Loading