Skip to content

Commit 715e1b0

Browse files
committed
feat(QML): add library settings
1 parent 50c2790 commit 715e1b0

21 files changed

Lines changed: 1549 additions & 124 deletions

res/qml/Settings/AudioRouter.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ Rectangle {
476476
tooltips: !root.hiddenConnections ? [] : [null, `${root.hiddenConnections} connection${root.hiddenConnections > 1 ? 's' : ''} hidden\nUse the advanced mode to view them`, null]
477477

478478
onOptionsChanged: {
479-
if (modeChoice.selected.startsWith("advanced")) {
479+
if (modeChoice.selected?.startsWith("advanced")) {
480480
modeChoice.selected = options[1];
481481
}
482482
}

res/qml/Settings/Library.qml

Lines changed: 1007 additions & 6 deletions
Large diffs are not rendered by default.

res/qml/Settings/RatioChoice.qml

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,14 @@ Item {
1616
property color inactiveColor: Theme.darkGray2
1717
property real maxWidth: 0
1818
property alias metric: fontMetrics
19-
property bool normalizedWidth: false
19+
property bool normalizedWidth: true
2020
required property list<string> options
21-
property string selected: options.length ? options[0] : null
21+
property var selected: options.length ? options[0] : null
2222
property real spacing: 9
2323
property list<var> tooltips: []
2424

25-
implicitHeight: (contentList.visible ? contentList.height : contentSpin.height)
26-
implicitWidth: {
27-
let minimumSize = options.reduce((acc, option) => acc + fontMetrics.advanceWidth(option) + root.spacing * 2, 0);
28-
let normalizedSize = root.cellSize * root.options.length;
29-
let size = root.normalizedWidth ? normalizedSize : minimumSize;
30-
if (root.maxWidth > size) {
31-
return size + root.spacing;
32-
} else {
33-
return contentSpin.implicitWidth;
34-
}
35-
}
25+
implicitHeight: (contentList.visible ? contentList.height : contentSpin.height) + dropRatio.radius * 2
26+
implicitWidth: (contentList.visible ? contentList.width : contentSpin.width) + dropRatio.radius * 2
3627

3728
onTooltipsChanged: {
3829
popup.close();
@@ -169,7 +160,7 @@ Item {
169160
radius: parent.height / 2
170161
}
171162
contentItem: Item {
172-
width: contentSpin.textWidth + 2 * contentSpin.spacing
163+
width: contentSpin.textWidth + 2 * contentSpin.spacing + 20
173164

174165
Rectangle {
175166
id: content
@@ -224,6 +215,8 @@ Item {
224215
}
225216

226217
onValueChanged: {
218+
if (!contentSpin.visible)
219+
return;
227220
root.selected = contentSpin.textFromValue(value) ?? "";
228221
popup.tooltip = root.tooltips[contentSpin.value] ?? "";
229222
popup.x = contentSpin.width / 2 - popup.width / 2;
@@ -250,8 +243,8 @@ Item {
250243
DropShadow {
251244
id: dropRatio
252245

253-
anchors.fill: contentList.visible ? contentList : contentSpin
254-
anchors.margins: 0
246+
anchors.fill: root
247+
anchors.margins: dropRatio.radius
255248
color: "#80000000"
256249
horizontalOffset: 0
257250
radius: 4.0

res/qml/Theme/Theme.qml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ pragma Singleton
22
import QtQuick 2.12
33

44
QtObject {
5-
property color accent: "#2D4EA1"
65
property color accentColor: "#3a60be"
7-
property color backgroundColor: "#1e1e1e"
6+
property color backgroundColor: "#1e1e20"
87
property color blue: "#01dcfc"
98
property color bpmSliderBarColor: blue
109
property color buttonActiveColor: white
@@ -14,10 +13,10 @@ QtObject {
1413
property color crossfaderBarColor: blue
1514
property color crossfaderOrientationColor: lightGray
1615
property color darkGray: "#0f0f0f"
17-
property color darkGray2: "#242424"
16+
property color darkGray2: "#2e2e2e"
1817
property color darkGray3: "#3F3F3F"
1918
property color darkGray4: "#202020"
20-
property color deckActiveColor: green
19+
property color deckActiveColor: white
2120
property color deckBackgroundColor: darkGray
2221
property color deckBeatjumpBackgroundColor: midGray3
2322
property color deckBeatjumpLabelColor: darkGray3
@@ -26,7 +25,7 @@ QtObject {
2625
property color deckLineColor: darkGray2
2726
property color deckLoopBackgroundColor: midGray3
2827
property color deckLoopLabelColor: darkGray3
29-
property color deckTextColor: white
28+
property color deckTextColor: lightGray2
3029
property color effectColor: yellow
3130
property color effectUnitColor: red
3231
property color embeddedBackgroundColor: "#a0000000"
@@ -69,7 +68,7 @@ QtObject {
6968
property color red: "#ea2a4e"
7069
property color samplerColor: blue
7170
property color sunkenBackgroundColor: "#0C0C0C"
72-
property color textColor: white
71+
property color textColor: lightGray2
7372
property int textFontPixelSize: 14
7473
property color toolbarActiveColor: white
7574
property color toolbarBackgroundColor: darkGray2

src/library/dao/directorydao.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,36 @@ QList<mixxx::FileInfo> DirectoryDAO::loadAllDirectories(
4949
return allDirs;
5050
}
5151

52-
QStringList DirectoryDAO::getRootDirStrings() const {
52+
QList<DirectoryDAO::RootDirectory> DirectoryDAO::getRootDirectories() const {
5353
DEBUG_ASSERT(m_database.isOpen());
54-
const auto statement =
55-
QStringLiteral("SELECT %1 FROM %2")
56-
.arg(
57-
kLocationColumn,
58-
kTable);
54+
const auto statement = QStringLiteral(
55+
"SELECT d.%1, COUNT(t.directory) AS total_track, SUM(l.duration) "
56+
"AS total_runtime FROM %2 d LEFT JOIN track_locations t ON d.%3 = "
57+
"t.directory LEFT JOIN library l ON t.id = l.id GROUP BY d.%4;")
58+
.arg(kLocationColumn,
59+
kTable,
60+
kLocationColumn,
61+
kLocationColumn);
5962
FwdSqlQuery query(
6063
m_database,
6164
statement);
6265
VERIFY_OR_DEBUG_ASSERT(query.execPrepared()) {
6366
return {};
6467
}
6568

66-
QStringList allDirs;
69+
QList<DirectoryDAO::RootDirectory> allDirs;
6770
const auto locationIndex = query.fieldIndex(kLocationColumn);
71+
const auto totalTrackIndex = query.fieldIndex("total_track");
72+
const auto totalRuntimeIndex = query.fieldIndex("total_runtime");
6873
while (query.next()) {
6974
const auto locationValue =
7075
query.fieldValue(locationIndex).toString();
71-
allDirs.append(locationValue);
76+
const auto totalTrackValue =
77+
query.fieldValue(totalTrackIndex).toUInt();
78+
const auto totalRuntimeValue =
79+
query.fieldValue(totalRuntimeIndex).toUInt();
80+
allDirs.append(DirectoryDAO::RootDirectory{
81+
locationValue, totalTrackValue, totalRuntimeValue});
7282
}
7383
return allDirs;
7484
}

src/library/dao/directorydao.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,19 @@
88

99
class DirectoryDAO : public DAO {
1010
public:
11+
struct RootDirectory {
12+
QString path;
13+
uint trackCount;
14+
uint totalSecond;
15+
};
16+
1117
~DirectoryDAO() override = default;
1218

1319
QList<mixxx::FileInfo> loadAllDirectories(
1420
bool skipInvalidOrMissing = false) const;
1521
/// Same as loadAllDirectories() just with paths as QString.
1622
/// See DlgPrefLibrary::populateDirList() for info.
17-
QStringList getRootDirStrings() const;
23+
QList<RootDirectory> getRootDirectories() const;
1824

1925
enum class AddResult {
2026
Ok,

src/library/scanner/libraryscanner.cpp

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -118,36 +118,40 @@ LibraryScanner::LibraryScanner(
118118
// connect them to our slots to run the command on the scanner thread.
119119
connect(this, &LibraryScanner::startScan, this, &LibraryScanner::slotStartScan);
120120

121-
m_pProgressDlg.reset(new LibraryScannerDlg());
122-
connect(this,
123-
&LibraryScanner::progressLoading,
124-
m_pProgressDlg.data(),
125-
&LibraryScannerDlg::slotUpdate);
126-
connect(this,
127-
&LibraryScanner::progressHashing,
128-
m_pProgressDlg.data(),
129-
&LibraryScannerDlg::slotUpdate);
130-
connect(this,
131-
&LibraryScanner::scanStarted,
132-
m_pProgressDlg.data(),
133-
&LibraryScannerDlg::slotScanStarted);
134-
connect(this,
135-
&LibraryScanner::scanFinished,
136-
m_pProgressDlg.data(),
137-
&LibraryScannerDlg::slotScanFinished);
138-
connect(m_pProgressDlg.data(),
139-
&LibraryScannerDlg::scanCancelled,
140-
this,
141-
&LibraryScanner::slotCancel,
142-
Qt::DirectConnection);
143-
connect(&m_trackDao,
144-
&TrackDAO::progressVerifyTracksOutside,
145-
m_pProgressDlg.data(),
146-
&LibraryScannerDlg::slotUpdate);
147-
connect(&m_trackDao,
148-
&TrackDAO::progressCoverArt,
149-
m_pProgressDlg.data(),
150-
&LibraryScannerDlg::slotUpdateCover);
121+
#ifdef MIXXX_USE_QML
122+
if (!CmdlineArgs::Instance().isQml())
123+
#endif
124+
{
125+
m_pProgressDlg.reset(new LibraryScannerDlg());
126+
connect(this,
127+
&LibraryScanner::progressLoading,
128+
m_pProgressDlg.data(),
129+
&LibraryScannerDlg::slotUpdate);
130+
connect(this,
131+
&LibraryScanner::progressHashing,
132+
m_pProgressDlg.data(),
133+
&LibraryScannerDlg::slotUpdate);
134+
connect(this,
135+
&LibraryScanner::scanStarted,
136+
m_pProgressDlg.data(),
137+
&LibraryScannerDlg::slotScanStarted);
138+
connect(this,
139+
&LibraryScanner::scanFinished,
140+
m_pProgressDlg.data(),
141+
&LibraryScannerDlg::slotScanFinished);
142+
connect(m_pProgressDlg.data(),
143+
&LibraryScannerDlg::scanCancelled,
144+
this,
145+
&LibraryScanner::slotCancel);
146+
connect(&m_trackDao,
147+
&TrackDAO::progressVerifyTracksOutside,
148+
m_pProgressDlg.data(),
149+
&LibraryScannerDlg::slotUpdate);
150+
connect(&m_trackDao,
151+
&TrackDAO::progressCoverArt,
152+
m_pProgressDlg.data(),
153+
&LibraryScannerDlg::slotUpdateCover);
154+
}
151155
}
152156

153157
LibraryScanner::~LibraryScanner() {
@@ -195,6 +199,7 @@ void LibraryScanner::slotStartScan() {
195199
// finish the scan immediately.
196200
if (m_libraryRootDirs.isEmpty()) {
197201
changeScannerState(IDLE);
202+
emit scanFinished();
198203
return;
199204
}
200205
changeScannerState(SCANNING);

src/library/trackcollection.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,15 @@ QList<mixxx::FileInfo> TrackCollection::loadRootDirs(bool skipInvalidOrMissing)
141141
}
142142

143143
QStringList TrackCollection::getRootDirStrings() const {
144-
return m_directoryDao.getRootDirStrings();
144+
QStringList rootDirStrings;
145+
for (auto& rootDirectory : m_directoryDao.getRootDirectories()) {
146+
rootDirStrings.append(rootDirectory.path);
147+
}
148+
return rootDirStrings;
149+
}
150+
151+
QList<DirectoryDAO::RootDirectory> TrackCollection::getRootDirectories() const {
152+
return m_directoryDao.getRootDirectories();
145153
}
146154

147155
DirectoryDAO::AddResult TrackCollection::addDirectory(const mixxx::FileInfo& rootDir) {

src/library/trackcollection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class TrackCollection : public QObject,
4646
QList<mixxx::FileInfo> loadRootDirs(
4747
bool skipInvalidOrMissing = false) const;
4848
QStringList getRootDirStrings() const;
49+
QList<DirectoryDAO::RootDirectory> getRootDirectories() const;
4950

5051
const CrateStorage& crates() const {
5152
DEBUG_ASSERT_QOBJECT_THREAD_AFFINITY(this);

src/library/trackcollectionmanager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ class TrackCollectionManager: public QObject,
9898
// Same as startLibraryScan() but don't emit the scan summary.
9999
void startLibraryAutoScan();
100100

101+
LibraryScanner* scanner() const {
102+
return m_pScanner.get();
103+
}
104+
101105
signals:
102106
void libraryScanStarted();
103107
void libraryScanFinished();

0 commit comments

Comments
 (0)