Compare commits

...

417 Commits

Author SHA1 Message Date
Jonas Kvinge
4eb11c32b0 Release 0.6.11 2020-05-16 14:40:35 +02:00
Jonas Kvinge
25457bc09a Release 0.6.11 2020-05-16 14:39:53 +02:00
Jonas Kvinge
d5cfb5f733 Merge branch 'master' of github.com:strawberrymusicplayer/strawberry 2020-05-16 14:14:34 +02:00
Jonas Kvinge
79ba6e628e Use art id from the API as cover filename for Subsonic
Fixes #433
2020-05-16 14:13:22 +02:00
King_DuckZ
ef73add05a Warning fix on gcc 8.3.0 (#439)
Fixes warning:
assuming signed overflow does not occur when
simplifying conditional to constant [-Wstrict-overflow]

Signed-off-by: Michele Santullo <m.santullo@posteo.net>

Co-authored-by: Michele Santullo <m.santullo@posteo.net>
2020-05-16 13:34:42 +02:00
Strawbs Bot
ec3d11fb27 Update translations 2020-05-16 01:03:55 +02:00
Jonas Kvinge
3fbc7031b5 Update about dialog 2020-05-16 00:45:15 +02:00
Jonas Kvinge
40beb5e428 Update Changelog 2020-05-15 23:54:15 +02:00
Jonas Kvinge
0f608c8ef0 Update debian/copyright 2020-05-15 23:48:44 +02:00
Jonas Kvinge
8509cb4743 Spotify: Fix clearing access token 2020-05-15 23:36:01 +02:00
Jonas Kvinge
f4429e8c4a Make Musicbrainz cover provider respect rate limiting 2020-05-15 22:53:21 +02:00
Jonas Kvinge
e9e0829cdc Remove end dash from title 2020-05-15 22:15:52 +02:00
Strawbs Bot
93f0230423 Update translations 2020-05-15 01:03:01 +02:00
plonibarploni
f26a0df4a4 strip directory from OpenInFileManager command (#436) 2020-05-14 22:19:26 +02:00
Jonas Kvinge
c7d4624282 Update README.md 2020-05-14 22:12:55 +02:00
Jonas Kvinge
b03eee2a22 Update Changelog 2020-05-14 22:10:18 +02:00
Jonas Kvinge
7d4d72e706 Make Discogs provider respect rate limiting 2020-05-14 19:31:40 +02:00
Jonas Kvinge
e3c367984b Make it possible to receive SearchResults before SearchFinished 2020-05-14 19:30:29 +02:00
Jonas Kvinge
0ebfa10d32 Update details in playing widget 2020-05-14 19:29:34 +02:00
Jonas Kvinge
16d9a077f0 emit SearchCoverInProgress before SearchCoverAutomatically 2020-05-14 19:29:07 +02:00
Strawbs Bot
a9d8bbad42 Update translations 2020-05-14 01:03:53 +02:00
Jonas Kvinge
d78bb94af3 Fix Tidal OAuth login 2020-05-13 21:56:11 +02:00
Jonas Kvinge
b139c0a824 Dont use song count from backend for CDDA devices 2020-05-13 19:42:13 +02:00
Jonas Kvinge
5b0b924d34 Fix crash in CD songloader 2020-05-13 19:00:57 +02:00
Strawbs Bot
f75acf820c Update translations 2020-05-13 01:05:26 +02:00
Jonas Kvinge
43a47f33ac Dont link chromaprint unless its enabled
Fixes #432
2020-05-12 22:39:56 +02:00
Jonas Kvinge
fcea3a0877 Add option to scrobbler setting for showing login error
Fixes #430
2020-05-12 22:25:00 +02:00
Jonas Kvinge
a950ec3bd5 Adjust login state widget placement for covers and lyrics settings 2020-05-12 22:15:53 +02:00
Jonas Kvinge
e35501ff0a Delete remaining network replies and local redirct server in destructor 2020-05-12 21:28:42 +02:00
Jonas Kvinge
4bfad9dad8 Fix use of QString::right() 2020-05-12 21:12:08 +02:00
Jonas Kvinge
c5c7a07c12 Add QImageReader::imageFormatsForMimeType replacement function 2020-05-12 19:48:37 +02:00
Jonas Kvinge
7e22e0e552 Use original image format when saving images from Subsonic and Tidal
Fixes #435
2020-05-12 18:50:57 +02:00
Jonas Kvinge
84ec4bdc79 Check content type for image in album cover fetcher search 2020-05-12 18:47:32 +02:00
Jonas Kvinge
2bcad9b637 Do AddOrUpdateSongs in database thread 2020-05-12 18:45:24 +02:00
Jonas Kvinge
c8d5f03070 Dont use reference in AlbumSongsReplyReceived 2020-05-12 15:58:36 +02:00
Jonas Kvinge
168e101a5a Subsonic: Disconnect signal/slots 2020-05-12 15:55:13 +02:00
Jonas Kvinge
b4bc7333d9 Use album id as cover filename for Subsonic
Fixes #433
2020-05-12 15:53:15 +02:00
Strawbs Bot
e8b58c940e Update translations 2020-05-11 01:03:48 +02:00
Jonas Kvinge
ec7202e3f6 Use refresh token for ListenBrainz 2020-05-11 00:51:18 +02:00
Jonas Kvinge
9a740f7962 Change variable name 2020-05-11 00:49:54 +02:00
Jonas Kvinge
9210fdee0d Make spotify refresh login 2020-05-10 17:10:20 +02:00
Jonas Kvinge
d7661f0964 Fix possible crash in album cover fetcher 2020-05-10 16:54:14 +02:00
Jonas Kvinge
139e148912 Use shared_ptr for scrobbler cache items 2020-05-10 14:59:04 +02:00
Jonas Kvinge
1b8dedb4ed Clear access token when login is expired 2020-05-10 14:53:40 +02:00
Jonas Kvinge
5d6b0fa329 Reset last played song when playlist is finished 2020-05-10 13:08:29 +02:00
Jonas Kvinge
f35bbd89c9 Initialize QNetworkReply pointer 2020-05-10 12:56:12 +02:00
Jonas Kvinge
538a9e42f4 Remove these 2020-05-10 12:50:37 +02:00
Jonas Kvinge
623147dea7 Add Json cover provider class 2020-05-10 12:49:11 +02:00
Jonas Kvinge
dfecd0cd12 Show Json parse error 2020-05-10 12:48:48 +02:00
Jonas Kvinge
fe3af3a676 Clear albums on close in cover manager 2020-05-10 11:50:05 +02:00
Strawbs Bot
25f60331ed Update translations 2020-05-10 01:04:15 +02:00
Jonas Kvinge
d4860a3426 Use defaults from context UI 2020-05-09 18:37:43 +02:00
Jonas Kvinge
e7e77ed86b Add automatically search for album cover to context settings 2020-05-09 18:31:10 +02:00
Jonas Kvinge
dc80459c59 Remove debug print 2020-05-09 02:30:32 +02:00
Jonas Kvinge
2f2de59234 Fix AuthError function 2020-05-09 02:07:51 +02:00
Jonas Kvinge
7bccc21878 Add setting for cover providers 2020-05-09 01:48:08 +02:00
Strawbs Bot
40f9dafa44 Update translations 2020-05-09 01:04:23 +02:00
Jonas Kvinge
355d436d29 Sort settings pages 2020-05-08 20:25:02 +02:00
Jonas Kvinge
079b684388 Remove duplicate include 2020-05-08 20:17:33 +02:00
Jonas Kvinge
fd11f46d30 Add album cover provider from Musixmatch 2020-05-08 20:14:16 +02:00
Jonas Kvinge
cb7099199a Fix memory include 2020-05-08 18:47:55 +02:00
Jonas Kvinge
8566d91e89 Remove some unneeded includes, etc 2020-05-08 18:44:07 +02:00
Jonas Kvinge
f44ce49ea7 Add setting for lyric providers and add more providers
Fixes #335
2020-05-08 18:35:36 +02:00
Jonas Kvinge
6ef69f6b32 Format code 2020-05-08 18:34:33 +02:00
Strawbs Bot
f5983d5f10 Update translations 2020-05-07 01:03:30 +02:00
Jonas Kvinge
54cce5e089 Use album grouping function 2020-05-06 22:35:55 +02:00
Jonas Kvinge
4e4e596a1e Change some parameters to const 2020-05-06 22:26:29 +02:00
Jonas Kvinge
727a1f5ad1 Sort songs in collection by song title instead of track if previous
grouping is not the album.

Fixes #295
2020-05-06 22:14:59 +02:00
Jonas Kvinge
85fa86625b Fix infinite loop in stylesheetloader
Fixes #361
2020-05-06 21:43:44 +02:00
Jonas Kvinge
2c91877f83 Add option to show/hide sidebar
Fixes #393
2020-05-06 18:15:17 +02:00
Jonas Kvinge
7d1fac44e9 Update non collection songs with manually unset cover 2020-05-05 23:57:37 +02:00
Jonas Kvinge
2e34abfc0d Fix mpris:artUrl when using embedded cover
Fixes #426
2020-05-04 23:23:24 +02:00
Jonas Kvinge
81ba63e247 Turn on git revision 2020-05-02 15:18:39 +02:00
Strawbs Bot
8b11a65522 Update translations 2020-05-02 01:01:45 +02:00
Jonas Kvinge
7190ad1d15 Remove styles directory when uninstalling 2020-05-01 19:55:45 +02:00
Jonas Kvinge
1c9bae5df5 Update libnettle dll in nsi 2020-05-01 18:41:36 +02:00
Jonas Kvinge
cc7fd73916 Update libhogweed dll in nsi 2020-05-01 16:55:58 +02:00
Jonas Kvinge
6d8725f268 Release 0.6.10 2020-05-01 16:42:20 +02:00
Jonas Kvinge
373c7cdbc4 Update Changelog 2020-05-01 16:40:54 +02:00
Jonas Kvinge
a4855bb33b Decrease margin for top title in context a little 2020-05-01 16:40:29 +02:00
Jonas Kvinge
57c1358ded Ignore replies not containing images from Discogs 2020-05-01 12:02:15 +02:00
Jonas Kvinge
eb4ce1feab Use toUtf8() not toLocal8Bit() when converting string for UNC path
Fixes #418
2020-04-30 17:32:31 +02:00
Strawbs Bot
838c17e144 Update translations 2020-04-30 01:03:38 +02:00
Strawbs Bot
4499cbca3c Update translations 2020-04-29 01:08:07 +02:00
Jonas Kvinge
a835a4a2f7 Minor fixes to collection pixmap cache
- Add variables for cache size defaults
- Increase default disk cache size
- Change the pixmap cache settings UI to look better
- Add current pixmap disk cache used to settings
2020-04-29 00:33:38 +02:00
Jonas Kvinge
9cc6a94353 Replace some NewClosure's with lambda connects 2020-04-28 22:29:10 +02:00
Jonas Kvinge
5ed9d9c4a0 Update Changelog 2020-04-28 22:28:45 +02:00
Jonas Kvinge
9c5ac7080d Remove unused connect 2020-04-28 22:28:24 +02:00
Jonas Kvinge
6346370e86 Set some properties on font size spinboxes 2020-04-28 20:56:35 +02:00
Jonas Kvinge
80697f8f30 Add toolchain files to cmake dir 2020-04-28 16:24:40 +02:00
Jonas Kvinge
18b8b56367 Use leap 15.1 for source build 2020-04-28 16:23:27 +02:00
Jonas Kvinge
760aacca26 Make context fonts configurable
Fixes #362
2020-04-28 01:11:00 +02:00
Strawbs Bot
1a4f0dcf5a Update translations 2020-04-28 01:02:50 +02:00
Jonas Kvinge
947484a71c Set content margin for label top in context 2020-04-27 22:20:50 +02:00
Jonas Kvinge
a74439d038 Always load 32x32 icon for engine and device
Fixes #417
2020-04-27 21:36:49 +02:00
Jonas Kvinge
c338618593 Do size checking of icon sizes when loading system theme icons 2020-04-27 21:36:08 +02:00
Jonas Kvinge
011897da53 Remove gstreamer registry file on startup for Windows
Workaround for issue #266
2020-04-27 15:54:37 +02:00
Jonas Kvinge
3fcaa58947 Add back libtag.dll (required for GStreamer plugin) 2020-04-27 15:52:38 +02:00
Strawbs Bot
ef8bd4362a Update translations 2020-04-27 01:03:05 +02:00
Jonas Kvinge
627a2ef6dd Dont use system icon for clear search field icon
Fixes #413
2020-04-27 00:24:49 +02:00
Jonas Kvinge
2732536d6e Fix device state text color in devices
Fixes #414
2020-04-27 00:22:46 +02:00
Jonas Kvinge
5a1b4b3ff8 Remove logging include 2020-04-26 18:49:18 +02:00
Jonas Kvinge
d93ec82e4f Fix save album cover to file
Fixes #412
2020-04-26 18:48:07 +02:00
Jonas Kvinge
15080972f3 Turn off uniformItemSizes
Fixes #411
2020-04-26 18:32:42 +02:00
Strawbs Bot
171b58f737 Update translations 2020-04-26 01:09:51 +02:00
Jonas Kvinge
c008ab6141 Fix resume playback on startup for CUE 2020-04-25 15:57:02 +02:00
Jonas Kvinge
f14c3654dc Add search for lyrics as a seperate option
Double click album to show fullsize

Fixes #299
2020-04-25 14:48:43 +02:00
Jonas Kvinge
ae05a61551 Read date and genre from individual tracks in cue sheets
Fixes #347
2020-04-25 13:47:25 +02:00
Jonas Kvinge
8e1def225b Move some files 2020-04-25 01:59:21 +02:00
Jonas Kvinge
6e061764ee Remove phonon 2020-04-25 01:42:29 +02:00
Jonas Kvinge
ac55b22839 Fix scrobble duration 2020-04-25 01:15:23 +02:00
Jonas Kvinge
49f77d3b75 Change timeouts 2020-04-25 00:13:48 +02:00
Jonas Kvinge
4abc650edf Make scrobbler handle streams 2020-04-25 00:07:42 +02:00
Jonas Kvinge
5ba00b61be Remove unneeded includes 2020-04-25 00:07:18 +02:00
Jonas Kvinge
bc16a6c4cb Sort album cover search results by score and pick the first 3 2020-04-25 00:03:43 +02:00
Jonas Kvinge
ea4dc6f040 Add link directories 2020-04-24 19:48:57 +02:00
Strawbs Bot
749ae8d5eb Update translations 2020-04-24 01:10:40 +02:00
Jonas Kvinge
7a56ffb7c3 Use COMPILE_LANGUAGE when setting compile options 2020-04-24 00:01:59 +02:00
Jonas Kvinge
e62ab23de2 Add taglib includes 2020-04-24 00:01:23 +02:00
Jonas Kvinge
c6f6118506 Use system taglib on macOS 2020-04-24 00:00:07 +02:00
Jonas Kvinge
8a5d5ad952 Fix some compile warnings in taglib 2020-04-23 21:51:14 +02:00
Jonas Kvinge
49e2615d14 Fix missing declaration 2020-04-23 21:50:50 +02:00
Jonas Kvinge
9289394261 Remove some compile options 2020-04-23 21:50:25 +02:00
Jonas Kvinge
8da4c88fd3 Fix compile warnings 2020-04-23 21:08:28 +02:00
Jonas Kvinge
a303850341 Use initialization list in cueparser 2020-04-23 21:07:17 +02:00
Jonas Kvinge
fb33610672 Remove unneeded this 2020-04-23 21:06:54 +02:00
Jonas Kvinge
d024dd6563 Minor code fixes to Subsonic 2020-04-23 21:06:26 +02:00
Jonas Kvinge
0be48f9f59 Minor code fixes to Tidal 2020-04-23 21:05:57 +02:00
Jonas Kvinge
df9292bafe Remove unneeded this 2020-04-23 21:05:17 +02:00
Jonas Kvinge
c1dcef3477 Improve Musicbrainz cover provider 2020-04-23 21:04:37 +02:00
Jonas Kvinge
48bc1f8361 Improve Last.fm cover provider code 2020-04-23 21:03:36 +02:00
Jonas Kvinge
2b2b4dbcf4 Improve Discogs cover provider 2020-04-23 21:02:48 +02:00
Jonas Kvinge
a1eadecdef Fix compile warnings in tests 2020-04-23 21:01:34 +02:00
Jonas Kvinge
f0b529952d Fix some compile warnings in singleapplication 2020-04-23 21:00:43 +02:00
Jonas Kvinge
c1ac2debb8 Fix some compile warnings in taglib 2020-04-23 21:00:16 +02:00
Jonas Kvinge
ac40094d37 Update CMakeLists.txt files 2020-04-23 20:59:09 +02:00
Jonas Kvinge
cb2bb4cb67 Fix CI 2020-04-22 15:38:10 +02:00
Strawbs Bot
f2965940cc Update translations 2020-04-22 01:01:32 +02:00
Strawbs Bot
c9ca147898 Update translations 2020-04-21 01:08:13 +02:00
Jonas Kvinge
c379d7f846 Minor code improvements to Deezer cover provider 2020-04-20 23:52:06 +02:00
Jonas Kvinge
45ae1ed265 Make Tidal album cover provider search for tracks too 2020-04-20 23:26:36 +02:00
Jonas Kvinge
9bf00eff40 Minor changes to Qobuz cover provider (and fix compile) 2020-04-20 22:58:57 +02:00
Jonas Kvinge
1677b3d5b9 Add Qobuz album cover provider 2020-04-20 22:12:40 +02:00
Jonas Kvinge
2a6806004a Fix update song length in context 2020-04-20 18:52:59 +02:00
Jonas Kvinge
39347d69df Only show song length in context when available 2020-04-20 18:46:26 +02:00
Jonas Kvinge
a2c0e4d4b1 Improve album cover loader, lyrics search and streaming support
- Improve album cover loader
- Add album cover loader result struct
- Move album cover thumbnail scaling to album cover loader
- Make init art manual look for album cover images in song directory
- Make album cover search work for songs outside of collection and
  streams
- Make album cover search work based on artist + title if album is not
  present
- Update art manual in playlist for local files, devices and CDDA
- Make lyrics search work for streams
- Add stream dialog to menu
- Remove dead code in InternetSearchModel
- Simplify code in InternetSearchView
2020-04-20 18:03:18 +02:00
Jonas Kvinge
ab2ffd9ac1 Add configure internet service to menu 2020-04-20 18:01:45 +02:00
Jonas Kvinge
c69fff52cc Remove useless using std 2020-04-20 17:49:06 +02:00
Strawbs Bot
1cfe61dc72 Update translations 2020-04-20 01:01:39 +02:00
Strawbs Bot
a23f39d81e Update translations 2020-04-19 01:01:32 +02:00
Strawbs Bot
b7724ff583 Update translations 2020-04-18 01:01:40 +02:00
Jonas Kvinge
e5dba60fab Remove song_id and artist_id from initialization list 2020-04-17 22:17:57 +02:00
Jonas Kvinge
2ccf489a83 Remove debug line 2020-04-17 17:23:43 +02:00
Jonas Kvinge
068939ca0b Fallback to SHA1 hash for cover filename if artist / album is stripped 2020-04-17 17:22:50 +02:00
Strawbs Bot
94ba8614ec Update translations 2020-04-16 01:01:39 +02:00
Strawbs Bot
f12a0c2379 Update translations 2020-04-15 01:01:28 +02:00
Strawbs Bot
8ab257645b Update translations 2020-04-14 01:11:19 +02:00
Jonas Kvinge
6331a0615f Update device schema 2020-04-13 23:24:35 +02:00
Jonas Kvinge
a21855fa20 Merge pull request #406 from strawberrymusicplayer/tidal
Add back Tidal support
2020-04-13 22:37:41 +02:00
Jonas Kvinge
12150c2180 Change database file 2020-04-13 19:05:55 +02:00
Jonas Kvinge
d90aecb164 Add back Tidal support 2020-04-13 19:04:06 +02:00
Jonas Kvinge
e738f2bc9f Recreate indexes and views in upgrade schema 11 2020-04-13 16:32:31 +02:00
Jonas Kvinge
2f72c41cda Improve internet classes 2020-04-13 06:30:40 +02:00
Jonas Kvinge
aa43d42cdb Remove const from signal slot connects 2020-04-13 05:57:48 +02:00
Jonas Kvinge
be8228e33c Fix song_id check 2020-04-13 04:17:45 +02:00
Jonas Kvinge
5591472dbd Change artist and song ID to strings 2020-04-13 03:39:51 +02:00
Strawbs Bot
30e6ced4e9 Update translations 2020-04-13 01:01:36 +02:00
Strawbs Bot
5f4c2bae89 Update translations 2020-04-12 01:01:28 +02:00
Strawbs Bot
0f036d9a43 Update translations 2020-04-11 01:01:39 +02:00
Strawbs Bot
1695ac3a32 Update translations 2020-04-10 01:02:01 +02:00
Jonas Kvinge
07a19ba619 Use slash 2020-04-09 20:41:14 +02:00
Jonas Kvinge
4dd78d89a0 Add option to remove problematic filename characters 2020-04-09 19:59:31 +02:00
Jonas Kvinge
8f4056faa6 Allow all characters except slash and backslash when organising music
Fixes #404
2020-04-09 18:14:02 +02:00
Jonas Kvinge
7b40c33892 Add missing semicolon in desktop file 2020-04-09 16:02:06 +02:00
Jonas Kvinge
b06bb5142f Turn on git revision 2020-04-09 16:01:12 +02:00
Jonas Kvinge
d576156ee1 Update snap version 2020-04-09 03:41:08 +02:00
Jonas Kvinge
77079968a5 Release 0.6.9 2020-04-09 02:32:32 +02:00
Jonas Kvinge
e12aca6214 Update maketarball.sh.in 2020-04-09 02:32:17 +02:00
Strawbs Bot
2a72891f28 Update translations 2020-04-09 00:42:40 +02:00
Jonas Kvinge
6fe47e78f1 Remove APE file detection by content
Fixes #373
2020-04-09 00:26:25 +02:00
Jonas Kvinge
0094894b52 Update ccpp.yml 2020-04-08 23:57:59 +02:00
Jonas Kvinge
0951bfb7ac Update Changelog 2020-04-08 23:38:00 +02:00
Jonas Kvinge
60e8519b65 Fix track and title in playlist not being movable
Fixes #403
2020-04-08 22:44:39 +02:00
Jonas Kvinge
78df0ed707 Change variable name 2020-04-08 22:32:01 +02:00
Jonas Kvinge
e3da0d6c9f Update config.yml 2020-04-08 19:27:32 +02:00
Jonas Kvinge
5df30580a6 Switch GitHub actions to use openSUSE 2020-04-08 01:15:39 +02:00
Strawbs Bot
4816b7dcd8 Update translations 2020-04-08 01:09:21 +02:00
Jonas Kvinge
75bced198b Hide open Audio CD on Windows 2020-04-08 01:00:21 +02:00
Jonas Kvinge
b500813617 Disable open Audio CD on Windows 2020-04-08 00:56:19 +02:00
Jonas Kvinge
a80037f7fc Update .travis.yml 2020-04-08 00:42:00 +02:00
Jonas Kvinge
1a6345342f Add Travis-CI 2020-04-07 17:05:01 +02:00
Jonas Kvinge
21b2193cd0 Add explicit 2020-04-07 16:49:15 +02:00
Jonas Kvinge
3efc496c41 Add better error handling for CDDA loader 2020-04-07 16:48:12 +02:00
Strawbs Bot
16340fbb78 Add Hungarian 2020-04-07 02:02:31 +02:00
Jonas Kvinge
a858b28bc4 Remove unused QGuiApplication include 2020-04-07 01:44:03 +02:00
Jonas Kvinge
307961cc7e Center organise and transcoder dialog on same screen as mainwindow 2020-04-07 01:26:17 +02:00
Strawbs Bot
3074377b55 Update translations 2020-04-07 01:03:31 +02:00
Jonas Kvinge
5a3edc00ac Remove extra check for oversized window 2020-04-06 23:14:23 +02:00
Jonas Kvinge
5a5f50e1e4 Use current_screen() function in OSD Pretty 2020-04-06 23:01:50 +02:00
Jonas Kvinge
7f39a38d6c Center cover manager on same screen as mainwindow 2020-04-06 22:30:03 +02:00
Jonas Kvinge
8321a48af7 Add missing QGuiApplication include 2020-04-06 22:26:55 +02:00
Jonas Kvinge
7e613f032e Add upgrade step to GitHub Actions 2020-04-06 22:26:19 +02:00
Jonas Kvinge
1c38c39db2 Center settings on current screen 2020-04-06 22:02:32 +02:00
Jonas Kvinge
4a0235c2ed Check for null pointer in OSD Pretty 2020-04-06 22:01:44 +02:00
Jonas Kvinge
b92961fda0 Merge branch 'circleci' 2020-04-06 06:46:39 +02:00
Jonas Kvinge
a2a06be62f Merge pull request #399 from plonibarploni/patch-2
Fix 'Show in file browser' for Caja
2020-04-06 05:21:18 +02:00
plonibarploni
c0956ed3b0 Fix 'Show in file browser' for Caja 2020-04-05 22:33:06 -04:00
Jonas Kvinge
3705e4e4d4 Add Ubuntu Focal to CircleCI 2020-04-06 03:07:09 +02:00
Jonas Kvinge
3fdbe84573 Rewrite parts of context to be adjustable and adjust album to width 2020-04-06 02:47:57 +02:00
Strawbs Bot
fb8e7d803f Update translations 2020-04-06 01:01:36 +02:00
Strawbs Bot
b01821aa03 Add Polish
Fixes #397
2020-04-05 13:24:58 +02:00
Strawbs Bot
69f974c9d0 Update translations 2020-04-05 01:02:31 +02:00
Jonas Kvinge
5db8b743fe Subsonic: Fix setting size 2020-04-04 23:34:04 +02:00
Jonas Kvinge
c424b0c888 Subsonic: Check if int values are strings 2020-04-04 23:31:27 +02:00
Strawbs Bot
d035c7d3b8 Update translations 2020-04-01 01:01:37 +02:00
Jonas Kvinge
144ffbc428 Subsonic: Handle track as string 2020-04-01 00:33:00 +02:00
Jonas Kvinge
afa8486d40 Update bug_report.md 2020-03-22 20:33:46 +01:00
Jonas Kvinge
a4cd42c448 Update README.md 2020-03-22 19:39:24 +01:00
Jonas Kvinge
853f4b75fa Update README.md 2020-03-22 00:17:40 +01:00
Jonas Kvinge
b95612287f This is a combination of 2 commits. (#390)
Add CircleCI
2020-03-20 16:17:11 +01:00
Jonas Kvinge
64e779172c Remove Travis-CI from master branch 2020-03-20 00:33:05 +01:00
Jonas Kvinge
10a136b4a3 Update macdeploy.py 2020-03-19 21:54:02 +01:00
Jonas Kvinge
ddc3af28ab Add back Travis-CI for macOS builds 2020-03-19 19:21:24 +01:00
Strawbs Bot
f602948dcf Update translations 2020-03-19 01:03:27 +01:00
Jonas Kvinge
973229cf4e Dont allow copy music to optical drives
Fixes #387
2020-03-17 20:44:51 +01:00
Strawbs Bot
d1f5cbea4a Update translations 2020-03-17 01:01:55 +01:00
Jonas Kvinge
49fe670ddb Center text of track column in tag fetcher
Fixes #388
2020-03-16 23:30:53 +01:00
Strawbs Bot
d6d87675c9 Update translations 2020-03-16 01:02:00 +01:00
Jonas Kvinge
1ca1927904 Only search for cover automatically for collection songs 2020-03-15 02:56:22 +01:00
Jonas Kvinge
454c3d1a3c Fix macOS build 2020-03-15 02:00:13 +01:00
Jonas Kvinge
11f5004112 Use a shorter playlist name when songs are added from file view
Fixes #363
2020-03-15 01:56:48 +01:00
Jonas Kvinge
625343f698 Check xdg-mime on Unix to find default file manager on Unix
Fixes #382
2020-03-15 01:21:30 +01:00
Jonas Kvinge
89d96a3ec1 Update README.md 2020-03-12 19:36:07 +01:00
Jonas Kvinge
c4c47fa196 Update README.md 2020-03-12 19:28:42 +01:00
Jonas Kvinge
ca35894b82 Update README.md 2020-03-12 19:27:00 +01:00
Jonas Kvinge
0213b6556b Add missing memory include 2020-03-08 19:13:13 +01:00
Jonas Kvinge
4edfd9be30 Merge branch 'master' of github.com:strawberrymusicplayer/strawberry 2020-03-08 18:40:56 +01:00
Jonas Kvinge
e55d9cafb6 Update logger 2020-03-08 18:40:39 +01:00
Jonas Kvinge
8deb0ed556 Move setting highDPI options 2020-03-08 18:36:48 +01:00
Strawbs Bot
82f995f243 Add Korean 2020-03-07 15:26:13 +01:00
Jonas Kvinge
b41c2ca724 Update README.md 2020-03-07 15:19:11 +01:00
Strawbs Bot
06ddbaf2cc Update translations 2020-03-01 01:02:03 +01:00
Jonas Kvinge
2adbfe1fbd Update required Qt version in README 2020-02-29 21:50:59 +01:00
Jonas Kvinge
7ae049b559 Require Qt 5.6 or higher 2020-02-29 21:50:10 +01:00
Jonas Kvinge
72913ceb1a Check that Qt version is higher than 5.9 to use QDir::isEmpty() 2020-02-29 21:40:20 +01:00
Jonas Kvinge
6a2be22fa1 Remove empty directories when organizing music
Fixes #353
2020-02-28 22:23:12 +01:00
Strawbs Bot
eaf20ce8d2 Update translations 2020-02-26 01:07:17 +01:00
Jonas Kvinge
97f9e142b4 Set hiDPI options 2020-02-25 01:15:05 +01:00
Jonas Kvinge
2e0f7b367f Remove tidal and qobuz
Fixes #369
2020-02-25 01:08:03 +01:00
Jonas Kvinge
7312e3f452 Find backtrace quiet 2020-02-23 20:42:30 +01:00
Strawbs Bot
8faa9f075b Update translations 2020-02-23 01:02:20 +01:00
Jonas Kvinge
584dcae075 Change variables 2020-02-22 17:39:06 +01:00
Jonas Kvinge
910e869b8d Use selectedRows() where possible 2020-02-22 15:31:25 +01:00
Jonas Kvinge
469e00b396 Remove setBaseStyle() 2020-02-22 13:43:33 +01:00
Strawbs Bot
ec46c758ba Update translations 2020-02-22 01:01:59 +01:00
Jonas Kvinge
8970e46bce More code fixes to mainwindow 2020-02-22 00:09:45 +01:00
Jonas Kvinge
3a4107d903 Workaround crash when mapToSource() fails 2020-02-21 22:42:21 +01:00
Jonas Kvinge
52ee21d550 Remove C++11Compat.cmake 2020-02-18 01:22:04 +01:00
Strawbs Bot
cdda4826cb Update translations 2020-02-18 01:02:19 +01:00
Jonas Kvinge
6745df5041 Update libffi 2020-02-17 20:22:02 +01:00
Jonas Kvinge
3d3efe1117 Remove extra whitespace 2020-02-17 20:21:45 +01:00
Strawbs Bot
82e5ae05ce Update translations 2020-02-17 01:01:39 +01:00
Strawbs Bot
0dbdd55a6a Update translations 2020-02-12 01:09:03 +01:00
Jonas Kvinge
424b0e61cb Remove extra newlines 2020-02-12 00:07:05 +01:00
Jonas Kvinge
533da8f89c Use isLocalFile() 2020-02-12 00:06:19 +01:00
Strawbs Bot
31506662db Update translations 2020-02-10 01:08:12 +01:00
Jonas Kvinge
7ff1a88ca8 Add QCoreApplication to xineengine.cpp 2020-02-09 04:20:22 +01:00
Jonas Kvinge
1851f26e3f Reduce includes 2020-02-09 02:29:35 +01:00
Jonas Kvinge
84cd65dd6c Reduce includes 2020-02-08 15:03:11 +01:00
Jonas Kvinge
8e0d792bf0 Reduce includes 2020-02-08 03:40:30 +01:00
Strawbs Bot
e74548b991 Update translations 2020-02-08 01:04:53 +01:00
Jonas Kvinge
2356ff5ebb Fix tabs order
Fixes #366
2020-02-08 00:01:12 +01:00
Gavin D. Howard
691f5d99ca Implement disk caching of album art (#360)
* Implement disk caching of album art

This includes a button to clear the cache in the settings, as
requested.

Closes #358

* Make the cache size defaults match

* Implement the review by jonaski

* Fix more problems with the PR
2020-02-07 23:18:18 +01:00
Jonas Kvinge
ab7b65a30b Remove chartlyrics 2020-02-06 22:33:38 +01:00
Daniel Kolesa
814bb3006c libstrawberry-common: check for library/includes for backtrace() (#364)
This is a non-standard header, so it should be checked properly.
This fixes compilation with musl libc and possibly other C library
implementations.
2020-02-06 20:04:23 +01:00
Jonas Kvinge
4bd4d3ae03 Update ccpp.yml 2020-02-06 18:40:05 +01:00
Jonas Kvinge
af1b0ace19 Use bultin taglib on Windows too by default 2020-02-06 18:37:02 +01:00
Jonas Kvinge
fb54febe03 Update .gitignore 2020-02-06 18:36:34 +01:00
Strawbs Bot
28faae5a4a Update translations 2020-01-29 01:03:25 +01:00
Jonas Kvinge
624a920aec Dont update temporary metadata while editing song with inline editor 2020-01-28 19:41:46 +01:00
Jonas Kvinge
2bf8187bff Add missing signal 2020-01-28 18:19:15 +01:00
Jonas Kvinge
cf06bf91e3 Change git url 2020-01-24 17:27:29 +01:00
Jonas Kvinge
e96f0504c0 Move related stuff into Rpm/Deb Cmake files 2020-01-21 23:53:28 +01:00
Jonas Kvinge
5fd61725bd Fixes for debian packaging 2020-01-21 23:15:15 +01:00
Jonas Kvinge
3fddfa075b Update .gitignore 2020-01-21 23:14:40 +01:00
Strawbs Bot
d712e5c409 Update translations 2020-01-21 01:01:48 +01:00
Jonas Kvinge
6287afae6c Fix Subsonic compatibility with LMS
Fixes #354
2020-01-20 19:19:14 +01:00
Jonas Kvinge
925540055a Use QString::number 2020-01-20 18:15:37 +01:00
Jonas Kvinge
d4373aae93 Subsonic: Handle album id as string 2020-01-20 17:45:40 +01:00
Jonas Kvinge
c4be310081 Use static taglib on windows 2020-01-16 20:46:10 +01:00
Jonas Kvinge
d1aa276465 Move -DTAGLIB_STATIC 2020-01-16 01:56:47 +01:00
Jonas Kvinge
2af6fc7452 Add -DTAGLIB_STATIC 2020-01-16 01:40:30 +01:00
Jonas Kvinge
ed15394a96 Delete qwindowsvistastyle.dll on uninstall 2020-01-15 23:12:08 +01:00
Jonas Kvinge
3791d11162 Disable libgstwasapi.dll 2020-01-15 17:12:18 +01:00
Jonas Kvinge
032ddabc06 Add qwindowsvistastyle.dll to nsi 2020-01-15 01:27:14 +01:00
Jonas Kvinge
bfb93ac6ed Update alsa in snap 2020-01-12 18:42:50 +01:00
Jonas Kvinge
f6d889d752 Add qtwayland5 to snap
Fixes #344
2020-01-12 18:02:13 +01:00
Jonas Kvinge
a7053f4269 Update README.md 2020-01-12 17:02:46 +01:00
Jonas Kvinge
233a6d06be Update README.md 2020-01-12 17:02:19 +01:00
Jonas Kvinge
853224148f Remove macOS builds 2020-01-12 16:56:19 +01:00
Jonas Kvinge
c5c8c27b2e Update README.md 2020-01-12 16:34:04 +01:00
Jonas Kvinge
d352d5fcff Turn back git revision 2020-01-07 21:41:31 +01:00
Strawbs Bot
0003de9320 Update translations 2020-01-07 01:01:46 +01:00
Jonas Kvinge
04f43e77af Update Changelog 2020-01-05 23:49:34 +01:00
Jonas Kvinge
be7cc55488 Release 0.6.8 2020-01-05 23:27:31 +01:00
Jonas Kvinge
c8f3379a48 Fix crash when deleting playlist folder. 2020-01-05 23:26:07 +01:00
Jonas Kvinge
b5a7945e49 Use QModelIndex::model() 2020-01-05 23:25:23 +01:00
Strawbs Bot
0bdac2e97d Update translations 2020-01-05 22:52:27 +01:00
Jonas Kvinge
1468a821fb Fix restoring to correct screen when maximized 2020-01-05 22:21:55 +01:00
Jonas Kvinge
3cdc8dc4b6 Use QWidget::screen() with Qt 5.14 2020-01-05 19:15:28 +01:00
Jonas Kvinge
aa255aa7e6 Use current screen, not primary screen 2020-01-05 19:14:25 +01:00
Strawbs Bot
66e5ccb9cc Update translations 2020-01-05 01:02:24 +01:00
Jonas Kvinge
2215f300bf Added option to disable playlist clear button
Fixes #339
2020-01-04 06:38:25 +01:00
Jonas Kvinge
eec767406b Add confirmation before clearing playlists with more than 500 songs 2020-01-04 06:11:21 +01:00
Jonas Kvinge
31aa42c2fa Fix compile with translations on Windows 2020-01-03 02:07:37 +01:00
Strawbs Bot
e912c59402 Add Italian 2020-01-03 01:46:38 +01:00
Strawbs Bot
c9988976f3 Update translations 2020-01-03 01:02:34 +01:00
Jonas Kvinge
443be1c2c8 Increase lyrics score if lyrics text > 60 2020-01-02 19:21:27 +01:00
Jonas Kvinge
7f442cff3b Fix QProxyStyle 2020-01-02 18:57:53 +01:00
Strawbs Bot
3696ae44ad Update translations 2019-12-31 01:09:52 +01:00
Jonas Kvinge
fc2d601424 Remove useless stdbool.h include 2019-12-30 23:14:40 +01:00
Jonas Kvinge
8818f24114 Fix compile with Qt 5.14 and above 2019-12-30 02:28:54 +01:00
Jonas Kvinge
0e12c8249e Fix actions builds 2019-12-30 00:49:39 +01:00
Strawbs Bot
06d62a70a9 Update translations 2019-12-30 00:35:45 +01:00
Jonas Kvinge
76d8018ca2 Remove HTML from translations 2019-12-29 23:53:54 +01:00
Jonas Kvinge
4123b41a5e Merge branch 'master' of github.com:jonaski/strawberry 2019-12-29 23:47:07 +01:00
Jonas Kvinge
5930257fed Remove HTML from translations 2019-12-29 23:46:49 +01:00
Jonas Kvinge
d3d60327ab Remove the answer to life the universe and everything 2019-12-29 23:46:35 +01:00
Strawbs Bot
5080ffb9fc Update translations 2019-12-29 23:41:39 +01:00
Jonas Kvinge
9b688a5179 Remove HTML from translations
Fixes #260
2019-12-29 23:37:48 +01:00
Strawbs Bot
a603dc5227 Update translations 2019-12-29 01:02:01 +01:00
Jonas Kvinge
c25f682caf Emit ExitFinished if no internet services are enabled 2019-12-28 03:35:07 +01:00
Jonas Kvinge
27a2fd298d Add the device view container widget to the tabbar
Fixes bugs related to the tabbar and the widgets being unresponsive

Fixes #279
Fixes #321
2019-12-28 03:13:41 +01:00
Strawbs Bot
bb38053cb3 Update translations 2019-12-24 01:01:42 +01:00
Strawbs Bot
5e82ee8695 Add German 2019-12-22 14:56:55 +01:00
Strawbs Bot
6c691ff9a8 Update translations 2019-12-22 14:55:33 +01:00
Jonas Kvinge
ac5a14fe4a Add StartupWMClass to desktop file
Fixes #305
2019-12-22 14:16:24 +01:00
Jonas Kvinge
00402d13ef Fix collection watcher on macOS
Fixes #324
2019-12-22 14:15:25 +01:00
Gavin D. Howard
079a559247 Make context title and summary changeable (#329)
* Make context title and summary changeable

Closes #30

* Fix checkboxes on context settings page

So...I am new to Qt, and I forgot that checkboxes can have a label.
Duh. Fixed.

* Put context settings in a different place

* Put ReplaceMessage and ReplaceVariable in Utilities
2019-12-22 12:09:05 +01:00
Strawbs Bot
a19ea8fdba Update translations 2019-12-22 01:04:20 +01:00
Jonas Kvinge
c6e172f942 Remove unused afc_port_ variable 2019-12-22 00:54:56 +01:00
Jonas Kvinge
bdc9f3e8bf Use AFC_E_SUCCESS 2019-12-22 00:45:01 +01:00
Jonas Kvinge
8ec5a587fc Fix compile 2019-12-21 22:34:42 +01:00
Jonas Kvinge
9caf46f2fb Use QString::asprintf 2019-12-21 22:07:04 +01:00
Jonas Kvinge
13fdbfc5e8 Use QString::asprintf 2019-12-21 21:56:48 +01:00
Jonas Kvinge
882c94110e Update temporary metadata when tags are changed 2019-12-21 21:55:24 +01:00
Jonas Kvinge
97bc980611 Upgrade packages 2019-12-21 18:26:51 +01:00
Jonas Kvinge
be9bf5c173 Replace use of QSet::fromList with Qt 5.14 and above 2019-12-21 18:22:18 +01:00
Jonas Kvinge
6df38c389c Replace use of QSet::toList() with QSet::values() 2019-12-21 18:19:09 +01:00
Jonas Kvinge
6c6bceb8cc Replace use of QString::sprintf 2019-12-21 18:17:58 +01:00
Jonas Kvinge
b5a897bb4d Replace use of QString::sprintf 2019-12-21 18:15:45 +01:00
Jonas Kvinge
ab85b716bb Replace use of QTime::start() with QElapsedTimer 2019-12-21 18:11:54 +01:00
Jonas Kvinge
8e256e6d5c Fix indent 2019-12-21 17:55:24 +01:00
Jonas Kvinge
288036a63b Fix spelling 2019-12-21 17:54:43 +01:00
Jonas Kvinge
f2005c3343 Update README.md 2019-12-11 20:46:15 +01:00
Jonas Kvinge
79d516b899 Update README.md 2019-12-11 20:45:27 +01:00
Jonas Kvinge
28b2f6eae3 Update README.md 2019-12-11 20:21:03 +01:00
Strawbs Bot
09ed2b945c Update translations 2019-12-07 12:45:08 +01:00
Jonas Kvinge
74aec89ef0 Add French 2019-12-05 19:58:07 +01:00
Jonas Kvinge
4faa23d099 Add Indonesian 2019-12-05 19:57:14 +01:00
Jonas Kvinge
5c4997ab20 Turn back git revision 2019-12-05 19:53:41 +01:00
Jonas Kvinge
cd490ca946 Release 0.6.7 2019-11-27 23:09:49 +01:00
Jonas Kvinge
793f6b00e6 Allow 4 tagreader workers 2019-11-27 22:57:51 +01:00
Strawbs Bot
c1ec568fda Update translations 2019-11-27 01:03:22 +01:00
Jonas Kvinge
4e2b52975e Remove require for sqlite on centos since we use customized sqlite 2019-11-26 23:43:34 +01:00
Jonas Kvinge
c141df6b86 Remove low-latency setting for wasapisink 2019-11-26 22:30:56 +01:00
Jonas Kvinge
63b781765a Update copyrights 2019-11-26 22:30:14 +01:00
Jonas Kvinge
c121e141e7 Remove duplicate entries in Changelog 2019-11-26 22:29:13 +01:00
Jonas Kvinge
7544c9a9f5 Update nsi with libprotobuf-22.dll 2019-11-26 19:42:38 +01:00
Jonas Kvinge
722a088515 Only remove pixmap cache when removing parents in collection model 2019-11-26 19:42:05 +01:00
Jonas Kvinge
0ce75bff58 Remove unused code in context albums 2019-11-26 19:41:32 +01:00
Strawbs Bot
3744b6d3de Update translations 2019-11-26 01:02:03 +01:00
Jonas Kvinge
a4ebd91e8d Make sure QSqlQuery::exec() was successful 2019-11-25 22:43:09 +01:00
Jonas Kvinge
3bb0ee916d Update Changelog 2019-11-25 22:31:42 +01:00
Jonas Kvinge
fd6afdf5f3 Extend url test 2019-11-25 22:30:33 +01:00
Jonas Kvinge
47c13a840e Handle different urls in collection backend for backward compatibility 2019-11-25 22:29:12 +01:00
Jonas Kvinge
5b61992b3c Save cover urls encoded 2019-11-25 22:28:48 +01:00
Jonas Kvinge
36331dc253 Fix removing nodes from pending art 2019-11-25 22:25:29 +01:00
Strawbs Bot
4265cf31b2 Update translations 2019-11-25 01:05:00 +01:00
Jonas Kvinge
337e47269f Remove portable, we dont use it 2019-11-25 00:35:48 +01:00
Jonas Kvinge
7039234471 Fix compile collection model test 2019-11-25 00:35:16 +01:00
Jonas Kvinge
f7f9333d91 Add collection backend url tests 2019-11-25 00:34:59 +01:00
Jonas Kvinge
bf35665932 Update all songs for the same directory+album when updating compilations
- Fixes a bug where the songs are stuck in various artists, because the
album has child songs, it will be stuck with various artists as the
parent node.
2019-11-25 00:28:49 +01:00
Jonas Kvinge
089a2271c2 Add GitHub Actions 2019-11-24 20:04:05 +01:00
Jonas Kvinge
f8e83e3631 Fix loading replay gain setting
Fixes #311
2019-11-24 19:34:05 +01:00
Strawbs Bot
46fd329913 Update translations 2019-11-23 01:07:52 +01:00
Jonas Kvinge
6b9ba96e77 Revert "Tidal: Add explicit to album titles"
This reverts commit b7d360d850.
2019-11-21 22:55:39 +01:00
Jonas Kvinge
b7d360d850 Tidal: Add explicit to album titles 2019-11-20 22:13:28 +01:00
Jonas Kvinge
8e226302ab Allow scrobbling songs without album
Fixes #309
2019-11-20 21:30:41 +01:00
Jonas Kvinge
7795b9edaf Dont replace metadata when loading playlists 2019-11-20 19:34:57 +01:00
Jonas Kvinge
9375d9699a No 2019-11-19 21:51:15 +01:00
Jonas Kvinge
cf0442d5b8 Fix setting pixmap cache limit 2019-11-19 21:49:46 +01:00
Jonas Kvinge
b386ca14df Show fullsize cover on doubleclick 2019-11-19 21:20:36 +01:00
Jonas Kvinge
ea47fae31e Add seperator between "unset cover" and "show fullsize" 2019-11-19 21:19:44 +01:00
Jonas Kvinge
e0fed07b10 Change pixmap cache limit 2019-11-19 21:03:06 +01:00
Jonas Kvinge
779d5ff7b6 Dont reset pixmap cache on model reset 2019-11-19 20:56:03 +01:00
Jonas Kvinge
eb6fbd03ec Update Changelog 2019-11-19 20:49:54 +01:00
Jonas Kvinge
95409d1b0e Remove unused variables 2019-11-19 20:47:06 +01:00
Jonas Kvinge
49599c8731 Add back ChartLyrics
This reverts commit c992768efe.
2019-11-19 20:45:22 +01:00
Jonas Kvinge
572f94e000 Update Changelog 2019-11-18 17:25:57 +01:00
Jonas Kvinge
c0a2ad5f50 Change comment 2019-11-18 17:16:58 +01:00
Jonas Kvinge
71fa5acc74 Fix previous player and doubleclick playlist song behaviour settings 2019-11-17 23:46:10 +01:00
Jonas Kvinge
bac5b7679d Use killproc.exe instead in nsi 2019-11-17 16:34:30 +01:00
Strawbs Bot
93ade821a5 Update translations 2019-11-17 01:10:32 +01:00
Jonas Kvinge
a718e19979 Use KillProc in nsi 2019-11-15 23:25:12 +01:00
Jonas Kvinge
8ac83a46f5 Remove clang compiler flag 2019-11-15 23:24:37 +01:00
Jonas Kvinge
1b65dcd7df Fix comparison between signed/unsigned 2019-11-15 00:23:06 +01:00
Jonas Kvinge
bbad45f1e7 Minor cmake fixes 2019-11-15 00:22:41 +01:00
Jonas Kvinge
331b9cca18 Remove sudo 2019-11-14 21:23:50 +01:00
Jonas Kvinge
a9accb7d85 Refactor scrobbler authentication code
Fix a crash when authentication is cancelled
2019-11-14 21:07:30 +01:00
Jonas Kvinge
1862e70628 Declare song using source 2019-11-14 00:09:35 +01:00
Jonas Kvinge
c4f7054ca6 Use QUrl::FullyEncoded in update compilations 2019-11-13 23:51:04 +01:00
Jonas Kvinge
175e568a28 Minor improvements to update compilations 2019-11-13 21:27:04 +01:00
Jonas Kvinge
c8d580e7de No need to delete pixmap cache when deleting empty parents 2019-11-13 21:16:48 +01:00
Jonas Kvinge
bc0c50ee65 Remove commented code 2019-11-13 21:12:50 +01:00
Jonas Kvinge
45e9dd96d1 Remove left click on analyzer to popup menu
Fixes #294
2019-11-11 00:01:39 +01:00
Jonas Kvinge
1cc73562a3 Turn back git revision 2019-11-10 15:35:36 +01:00
700 changed files with 53552 additions and 16688 deletions

544
.circleci/config.yml Normal file
View File

@@ -0,0 +1,544 @@
version: 2.1
commands:
cmake:
description: Configure build
steps:
- run:
name: Configure build
command: cmake ..
working_directory: build
build_source:
description: Create source tarball
steps:
- run:
name: Create source tarball
command: ../dist/scripts/maketarball.sh
working_directory: build
build_rpm:
description: Build RPM
steps:
- run:
name: Create RPM build sources directories
command: mkdir -p ~/rpmbuild/SOURCES /usr/src/packages/SOURCES
- run:
name: Copy source tarball 1
command: cp strawberry-*.tar.xz ~/rpmbuild/SOURCES/
working_directory: build
- run:
name: Copy source tarball 2
command: cp strawberry-*.tar.xz /usr/src/packages/SOURCES/
working_directory: build
- run:
name: Build RPM
command: rpmbuild -ba ../dist/unix/strawberry.spec
working_directory: build
build_deb:
description: Build Deb
steps:
- run:
name: make deb
command: dpkg-buildpackage -b -d -uc -us -nc -j2
install_opensuse_dependencies:
description: Install openSUSE dependencies
steps:
- run:
name: Update packages
command: zypper --non-interactive --gpg-auto-import-keys ref
- run:
name: Install openSUSE dependencies
command: >
zypper --non-interactive --gpg-auto-import-keys install
lsb-release
rpm-build
git
tar
make
cmake
gcc
gcc-c++
gettext-tools
glibc-devel
libboost_headers-devel
boost-devel
glib2-devel
glib2-tools
dbus-1-devel
alsa-devel
libnotify-devel
libgnutls-devel
protobuf-devel
sqlite3-devel
libpulse-devel
gstreamer-devel
gstreamer-plugins-base-devel
libxine-devel
vlc-devel
libQt5Core-devel
libQt5Gui-devel
libQt5Widgets-devel
libQt5Concurrent-devel
libQt5Network-devel
libQt5Sql-devel
libQt5DBus-devel
libQt5Test-devel
libqt5-qtx11extras-devel
libqt5-qtbase-common-devel
libQt5Sql5-sqlite
libqt5-linguist-devel
libcdio-devel
libgpod-devel
libplist-devel
libmtp-devel
libusbmuxd-devel
libchromaprint-devel
desktop-file-utils
update-desktop-files
appstream-glib
hicolor-icon-theme
install_fedora_dependencies:
description: Install Fedora dependencies
steps:
- run:
name: Update packages
command: yum update --assumeyes
- run:
name: Upgrade packages
command: yum upgrade --assumeyes
- run:
name: Install Fedora dependencies
command: >
dnf install --assumeyes
@development-tools
redhat-lsb-core
git
glibc
gcc-c++
rpmdevtools
make
cmake
pkgconfig
glib
man
tar
gettext
openssh
boost-devel
dbus-devel
protobuf-devel
protobuf-compiler
sqlite-devel
alsa-lib-devel
pulseaudio-libs-devel
libnotify-devel
gnutls-devel
qt5-devel
qt5-qtbase-devel
qt5-qtx11extras-devel
qt5-qttools-devel
gstreamer1-devel
gstreamer1-plugins-base-devel
taglib-devel
libcdio-devel
libgpod-devel
libplist-devel
libusbmuxd-devel
libmtp-devel
libchromaprint-devel
fftw-devel
desktop-file-utils
libappstream-glib
hicolor-icon-theme
install_mageia_dependencies:
description: Install Mageia dependencies
steps:
- run:
name: Add extra media
command: urpmi.addmedia --distrib http://www.mirrorservice.org/sites/mageia.org/pub/mageia/distrib/7/x86_64
- run:
name: Update packages
command: urpmi.update -a
- run:
name: Configure auto update
command: urpmi --auto-update
- run:
name: Install dependencies
command: >
urpmi --force
urpmi-debuginfo-install
git
tar
rpmdevtools
make
cmake
glibc
binutils
gcc-c++
man
gettext
notification-daemon
dbus-devel
libgnutls-devel
lib64boost-devel
lib64protobuf-devel
protobuf-compiler
lib64sqlite3-devel
lib64alsa2-devel
lib64pulseaudio-devel
lib64notify-devel
lib64qt5core-devel
lib64qt5gui-devel
lib64qt5widgets-devel
lib64qt5network-devel
lib64qt5concurrent-devel
lib64qt5sql-devel
lib64qt5dbus-devel
lib64qt5x11extras-devel
lib64qt5help-devel
libqt5test-devel
lib64gstreamer1.0-devel
lib64gstreamer-plugins-base1.0-devel
lib64cdio-devel
lib64gpod-devel
lib64plist-devel
lib64usbmuxd-devel
lib64mtp-devel
lib64raw1394-devel
lib64chromaprint-devel
libfftw-devel
desktop-file-utils
appstream-util
libappstream-glib8
hicolor-icon-theme
qt5ct
lib64mesaegl1
install_debian_dependencies:
description: Install Debian dependencies
steps:
- run:
name: Install Debian dependencies
command: >
apt-get update && apt-get install -y
build-essential
ssh
git
make
cmake
gcc
pkg-config
fakeroot
gettext
lsb-release
libglib2.0-dev
dpkg-dev
libdbus-1-dev
libboost-dev
libprotobuf-dev
protobuf-compiler
libsqlite3-dev
libgnutls28-dev
libasound2-dev
libpulse-dev
qtbase5-dev
qtbase5-dev-tools
qtbase5-private-dev
libqt5x11extras5-dev
qttools5-dev
libgstreamer1.0-dev
libgstreamer-plugins-base1.0-dev
gstreamer1.0-alsa
gstreamer1.0-pulseaudio
libchromaprint-dev
libfftw3-dev
libcdio-dev
libmtp-dev
libgpod-dev
libimobiledevice-dev
libplist-dev
libusbmuxd-dev
install_ubuntu_dependencies:
description: Install Ubuntu dependencies
steps:
- run:
name: Setup environment
command: |
echo 'export DEBIAN_FRONTEND=noninteractive' >> $BASH_ENV
source $BASH_ENV
- run:
name: Install Ubuntu dependencies
command: >
apt-get update && apt-get install -y
build-essential
ssh
git
make
cmake
pkg-config
gcc
fakeroot
wget
curl
gettext
lsb-release
dpkg-dev
libglib2.0-dev
libboost-dev
libdbus-1-dev
libprotobuf-dev
protobuf-compiler
libsqlite3-dev
libgnutls28-dev
libasound2-dev
libpulse-dev
qtbase5-dev
qtbase5-dev-tools
qtbase5-private-dev
libqt5x11extras5-dev
qttools5-dev
libgstreamer1.0-dev
libgstreamer-plugins-base1.0-dev
libgstreamer-plugins-good1.0-dev
gstreamer1.0-alsa
gstreamer1.0-pulseaudio
libchromaprint-dev
libfftw3-dev
libcdio-dev
libmtp-dev
libgpod-dev
libimobiledevice-dev
libplist-dev
libusbmuxd-dev
jobs:
build_source:
docker:
- image: opensuse/leap:15.1
steps:
- install_opensuse_dependencies
- checkout
- cmake
- build_source
build_opensuse_tumbleweed:
docker:
- image: opensuse/tumbleweed
environment:
RPM_BUILD_NCPUS: "2"
steps:
- run:
name: Update packages
command: zypper --non-interactive --gpg-auto-import-keys ref
- run:
name: Upgrade packages
command: zypper --non-interactive --gpg-auto-import-keys dup
- install_opensuse_dependencies
- checkout
- cmake
- build_source
- build_rpm
build_opensuse_lp151:
docker:
- image: opensuse/leap:15.1
environment:
RPM_BUILD_NCPUS: "2"
steps:
- install_opensuse_dependencies
- checkout
- cmake
- build_source
- build_rpm
build_opensuse_lp152:
docker:
- image: opensuse/leap:15.2
environment:
RPM_BUILD_NCPUS: "2"
steps:
- install_opensuse_dependencies
- checkout
- cmake
- build_source
- build_rpm
build_fedora_30:
docker:
- image: fedora:30
environment:
RPM_BUILD_NCPUS: "2"
steps:
- install_fedora_dependencies
- checkout
- cmake
- build_source
- build_rpm
build_fedora_31:
docker:
- image: fedora:31
environment:
RPM_BUILD_NCPUS: "2"
steps:
- install_fedora_dependencies
- checkout
- cmake
- build_source
- build_rpm
build_mageia_7:
docker:
- image: mageia:7
environment:
RPM_BUILD_NCPUS: "2"
steps:
- install_mageia_dependencies
- checkout
- cmake
- build_source
- build_rpm
build_debian_stretch:
docker:
- image: debian:stretch
steps:
- install_debian_dependencies
- checkout
- cmake
- build_deb
build_debian_buster:
docker:
- image: debian:buster
steps:
- install_debian_dependencies
- checkout
- cmake
- build_deb
build_debian_bullseye:
docker:
- image: debian:bullseye
steps:
- install_debian_dependencies
- checkout
- cmake
- build_deb
build_ubuntu_bionic:
docker:
- image: ubuntu:bionic
steps:
- install_ubuntu_dependencies
- checkout
- cmake
- build_deb
build_ubuntu_eoan:
docker:
- image: ubuntu:eoan
steps:
- install_ubuntu_dependencies
- checkout
- cmake
- build_deb
build_ubuntu_focal:
docker:
- image: ubuntu:focal
steps:
- install_ubuntu_dependencies
- checkout
- cmake
- build_deb
workflows:
version: 2
build_all:
jobs:
- build_source:
filters:
tags:
only: /.*/
- build_opensuse_tumbleweed:
filters:
tags:
only: /.*/
- build_opensuse_lp151:
filters:
tags:
only: /.*/
- build_opensuse_lp152:
filters:
tags:
only: /.*/
- build_fedora_30:
filters:
tags:
only: /.*/
- build_fedora_31:
filters:
tags:
only: /.*/
- build_mageia_7:
filters:
tags:
only: /.*/
- build_debian_stretch:
filters:
tags:
only: /.*/
- build_debian_buster:
filters:
tags:
only: /.*/
- build_debian_bullseye:
filters:
tags:
only: /.*/
- build_ubuntu_eoan:
filters:
tags:
only: /.*/
- build_ubuntu_bionic:
filters:
tags:
only: /.*/
- build_ubuntu_focal:
filters:
tags:
only: /.*/

View File

@@ -7,6 +7,8 @@ assignees: ''
---
For general technical questions and help with technical issues please use the forum on https://forum.strawberrymusicplayer.org/
**Describe the bug**
A clear and concise description of what the bug is.

51
.github/workflows/ccpp.yml vendored Normal file
View File

@@ -0,0 +1,51 @@
name: C/C++ CI
on: [push, pull_request]
jobs:
build-linux:
runs-on: ubuntu-latest
container:
image: opensuse/leap:15.1
steps:
- uses: actions/checkout@v1
- name: Update Packages
run: zypper ref
- name: Install Packages
run: zypper --non-interactive --gpg-auto-import-keys install lsb-release rpm-build git tar make cmake gcc gcc-c++ gettext-tools glibc-devel libboost_headers-devel boost-devel glib2-devel glib2-tools dbus-1-devel alsa-devel libnotify-devel libgnutls-devel protobuf-devel sqlite3-devel libpulse-devel gstreamer-devel gstreamer-plugins-base-devel libxine-devel vlc-devel taglib-devel libQt5Core-devel libQt5Gui-devel libQt5Widgets-devel libQt5Concurrent-devel libQt5Network-devel libQt5Sql-devel libQt5DBus-devel libQt5Test-devel libqt5-qtx11extras-devel libqt5-qtbase-common-devel libQt5Sql5-sqlite libqt5-linguist-devel libcdio-devel libgpod-devel libplist-devel libmtp-devel libusbmuxd-devel libchromaprint-devel desktop-file-utils update-desktop-files appstream-glib hicolor-icon-theme
- name: Create Build Environment
run: mkdir -p build
- name: Configure CMake
working-directory: build
shell: bash
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
- name: Build
working-directory: build
shell: bash
run: cmake --build . --config $BUILD_TYPE
build-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: Unlink python
run: brew unlink python@2
- name: Install Packages
run: brew install glib pkgconfig boost libffi protobuf protobuf-c qt gettext gnutls fftw sqlite chromaprint gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav libcdio libmtp libimobiledevice libplist create-dmg taglib
- name: Create Build Environment
run: cmake -E make_directory ${{runner.workspace}}/build
- name: Configure CMake
env:
Qt5_DIR: /usr/local/opt/qt5/lib/cmake
Qt5LinguistTools_DIR: /usr/local/opt/qt5/lib/cmake/Qt5LinguistTools
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DUSE_BUNDLE=ON -DUSE_SYSTEM_TAGLIB=ON
- name: Build
working-directory: ${{runner.workspace}}/build
shell: bash
run: cmake --build . --config $BUILD_TYPE
- name: Install
working-directory: ${{runner.workspace}}/build
shell: bash
run: make install

5
.gitignore vendored
View File

@@ -73,6 +73,11 @@ CMakeLists.txt.user*
target_wrapper.*
compile_commands.json
*.kdev4
*.vscode
*.code-workspace
*.sublime-workspace
# Temporary files
*~
*.autosave

View File

@@ -1,7 +1,6 @@
sudo: required
language: C++
os:
- linux
- osx
services:
- docker
@@ -16,32 +15,31 @@ before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
docker build -f Dockerfile -t strawberry-build . || travis_terminate 1;
docker run --name build -itd strawberry-build /bin/bash || travis_terminate 1;
docker exec build git clone https://github.com/jonaski/strawberry;
docker exec build git clone https://github.com/strawberrymusicplayer/strawberry;
fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
git fetch --unshallow || travis_terminate 1;
git pull || travis_terminate 1;
brew update || travis_terminate 1;
brew unlink python || travis_terminate 1;
brew install glib pkgconfig libffi protobuf protobuf-c qt gettext gnutls fftw sqlite chromaprint;
brew unlink python@2 || travis_terminate 1;
brew install glib pkgconfig libffi protobuf protobuf-c qt gettext gnutls fftw sqlite chromaprint zlib taglib;
brew install gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav;
brew install libcdio libmtp libimobiledevice libplist;
brew install create-dmg;
export Qt5_DIR=/usr/local/opt/qt5/lib/cmake;
export Qt5LinguistTools_DIR=/usr/local/opt/qt5/lib/cmake/Qt5LinguistTools;
export PATH="/usr/local/opt/gettext/bin:$PATH";
export PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig/:$PKG_CONFIG_PATH;
export PKG_CONFIG_PATH="/usr/local/opt/libffi/lib/pkgconfig/:/usr/local/opt/zlib/lib/pkgconfig:$PKG_CONFIG_PATH";
ls /usr/local/lib/gstreamer-1.0;
fi
before_script:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker exec build cmake -Hstrawberry -Bbuild ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir build; cd build; cmake .. -DUSE_BUNDLE=ON ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir build; cd build; cmake .. -DUSE_BUNDLE=ON -DUSE_SYSTEM_TAGLIB=ON ; fi
script:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker exec build make -C build -j8 ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
make -j8 || travis_terminate 1;
make install || travis_terminate 1;
sudo make dmg;
make dmg;
fi
after_success:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ls -lh strawberry*.dmg; fi
@@ -49,7 +47,7 @@ after_success:
if [[ "$TRAVIS_BRANCH" == "master" ]]; then
rsync -e "ssh -o StrictHostKeyChecking=no" -va strawberry*.dmg travis@echoes.jkvinge.net:/home/travis/builds/macos;
elif [[ "$TRAVIS_BRANCH" == "macos" ]]; then
rsync -e "ssh -o StrictHostKeyChecking=no" -va strawberry*.dmg travis@echoes.jkvinge.net:/home/travis/builds/macos-test;
rsync -e "ssh -o StrictHostKeyChecking=no" -va strawberry*.dmg travis@echoes.jkvinge.net:/home/travis/builds/macos;
fi
fi

View File

@@ -1,16 +1,8 @@
cmake_minimum_required(VERSION 2.8.11)
cmake_minimum_required(VERSION 3.0)
include(CheckIncludeFiles)
include(CheckFunctionExists)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Woverloaded-virtual -Wno-sign-compare -fpermissive")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wpedantic")
endif()
if(CMAKE_VERSION VERSION_GREATER 3.0)
check_function_exists(geteuid HAVE_GETEUID)
check_function_exists(getpwuid HAVE_GETPWUID)
@@ -19,14 +11,15 @@ endif()
set(SINGLEAPP-SOURCES singleapplication.cpp singleapplication_p.cpp)
set(SINGLEAPP-MOC-HEADERS singleapplication.h singleapplication_p.h)
QT5_WRAP_CPP(SINGLEAPP-SOURCES-MOC ${SINGLEAPP-MOC-HEADERS})
ADD_LIBRARY(singleapplication STATIC ${SINGLEAPP-SOURCES} ${SINGLEAPP-SOURCES-MOC})
add_library(singleapplication STATIC ${SINGLEAPP-SOURCES} ${SINGLEAPP-SOURCES-MOC})
target_link_libraries(singleapplication Qt5::Core Qt5::Widgets Qt5::Network)
set(SINGLECOREAPP-SOURCES singlecoreapplication.cpp singlecoreapplication_p.cpp)
set(SINGLECOREAPP-MOC-HEADERS singlecoreapplication.h singlecoreapplication_p.h)
QT5_WRAP_CPP(SINGLECOREAPP-SOURCES-MOC ${SINGLECOREAPP-MOC-HEADERS})
ADD_LIBRARY(singlecoreapplication STATIC ${SINGLECOREAPP-SOURCES} ${SINGLECOREAPP-SOURCES-MOC})
add_library(singlecoreapplication STATIC ${SINGLECOREAPP-SOURCES} ${SINGLECOREAPP-SOURCES-MOC})
target_link_libraries(singlecoreapplication Qt5::Core Qt5::Widgets Qt5::Network)
configure_file(config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h")
include_directories(${CMAKE_CURRENT_BINARY_DIR})

View File

@@ -31,13 +31,18 @@
//
//
#include <stdlib.h>
#include <limits>
#include <QtGlobal>
#include <QCoreApplication>
#include <QThread>
#include <QSharedMemory>
#include <QLocalSocket>
#include <QByteArray>
#include <QDateTime>
#include <QTime>
#include <QElapsedTimer>
#include <QtDebug>
#include "singleapplication.h"
#include "singleapplication_p.h"
@@ -88,7 +93,7 @@ SingleApplication::SingleApplication(int &argc, char *argv[], bool allowSecondar
}
InstancesInfo* inst = static_cast<InstancesInfo*>(d->memory->data());
QTime time;
QElapsedTimer time;
time.start();
// Make sure the shared memory block is initialised and in consistent state
@@ -174,7 +179,7 @@ bool SingleApplication::sendMessage(QByteArray message, int timeout) {
if (isPrimary()) return false;
// Make sure the socket is connected
d->connectToPrimary(timeout, SingleApplicationPrivate::Reconnect);
d->connectToPrimary(timeout, SingleApplicationPrivate::Reconnect);
d->socket->write(message);
bool dataWritten = d->socket->waitForBytesWritten(timeout);

View File

@@ -36,7 +36,8 @@
#include <QtGlobal>
#include <QApplication>
#include <QLocalSocket>
#include <QFlags>
#include <QByteArray>
class SingleApplicationPrivate;

View File

@@ -44,12 +44,14 @@
# include <pwd.h>
#endif
#include <QDir>
#include <QIODevice>
#include <QSharedMemory>
#include <QByteArray>
#include <QDataStream>
#include <QCryptographicHash>
#include <QLocalServer>
#include <QLocalSocket>
#include <QDir>
#include "singleapplication.h"
#include "singleapplication_p.h"
@@ -59,8 +61,8 @@
# include <lmcons.h>
#endif
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication *q_ptr)
: q_ptr(q_ptr),
SingleApplicationPrivate::SingleApplicationPrivate(SingleApplication *_q_ptr)
: q_ptr(_q_ptr),
memory(nullptr),
socket(nullptr),
server(nullptr),
@@ -114,12 +116,9 @@ void SingleApplicationPrivate::genBlockServerName() {
#ifdef Q_OS_UNIX
QByteArray username;
#if defined(HAVE_GETEUID) && defined(HAVE_GETPWUID)
uid_t uid = geteuid();
if (uid != -1) {
struct passwd *pw = getpwuid(uid);
if (pw) {
username = pw->pw_name;
}
struct passwd *pw = getpwuid(geteuid());
if (pw) {
username = pw->pw_name;
}
#endif
if (username.isEmpty()) username = qgetenv("USER");
@@ -187,7 +186,7 @@ void SingleApplicationPrivate::startPrimary() {
void SingleApplicationPrivate::startSecondary() {}
void SingleApplicationPrivate::connectToPrimary(int msecs, ConnectionType connectionType) {
void SingleApplicationPrivate::connectToPrimary(const int msecs, const ConnectionType connectionType) {
// Connect to the Local Server of the Primary Instance if not already connected.
if (socket == nullptr) {
@@ -215,9 +214,7 @@ void SingleApplicationPrivate::connectToPrimary(int msecs, ConnectionType connec
QByteArray initMsg;
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
writeStream.setVersion(QDataStream::Qt_5_6);
#endif
writeStream << blockServerName.toLatin1();
writeStream << static_cast<quint8>(connectionType);
@@ -229,9 +226,8 @@ void SingleApplicationPrivate::connectToPrimary(int msecs, ConnectionType connec
QByteArray header;
QDataStream headerStream(&header, QIODevice::WriteOnly);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
headerStream.setVersion(QDataStream::Qt_5_6);
#endif
headerStream << static_cast <quint64>(initMsg.length());
socket->write(header);
@@ -316,9 +312,7 @@ void SingleApplicationPrivate::readInitMessageHeader(QLocalSocket *sock) {
QDataStream headerStream(sock);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
headerStream.setVersion(QDataStream::Qt_5_6);
#endif
// Read the header to know the message length
quint64 msgLen = 0;
@@ -350,9 +344,7 @@ void SingleApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
QByteArray msgBytes = sock->read(info.msgLen);
QDataStream readStream(msgBytes);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
readStream.setVersion(QDataStream::Qt_5_6);
#endif
// server name
QByteArray latin1Name;
@@ -394,14 +386,14 @@ void SingleApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
}
void SingleApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, quint32 instanceId) {
void SingleApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, const quint32 instanceId) {
Q_Q(SingleApplication);
Q_EMIT q->receivedMessage(instanceId, dataSocket->readAll());
}
void SingleApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, quint32 instanceId) {
void SingleApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, const quint32 instanceId) {
if (closedSocket->bytesAvailable() > 0)
Q_EMIT slotDataAvailable(closedSocket, instanceId);

View File

@@ -35,13 +35,15 @@
#define SINGLEAPPLICATION_P_H
#include <QtGlobal>
#include <QLocalSocket>
#include <QLocalServer>
#include <QSharedMemory>
#include <QObject>
#include <QMap>
#include "singleapplication.h"
class QLocalServer;
class QLocalSocket;
class QSharedMemory;
struct InstancesInfo {
bool primary;
quint32 secondary;
@@ -72,14 +74,14 @@ class SingleApplicationPrivate : public QObject {
};
Q_DECLARE_PUBLIC(SingleApplication)
SingleApplicationPrivate( SingleApplication *q_ptr );
SingleApplicationPrivate(SingleApplication *_q_ptr);
~SingleApplicationPrivate();
void genBlockServerName();
void initializeMemoryBlock();
void startPrimary();
void startSecondary();
void connectToPrimary(int msecs, ConnectionType connectionType );
void connectToPrimary(const int msecs, const ConnectionType connectionType);
quint16 blockChecksum();
qint64 primaryPid();
void readInitMessageHeader(QLocalSocket *socket);
@@ -96,8 +98,8 @@ class SingleApplicationPrivate : public QObject {
public slots:
void slotConnectionEstablished();
void slotDataAvailable(QLocalSocket*, quint32);
void slotClientConnectionClosed(QLocalSocket*, quint32);
void slotDataAvailable(QLocalSocket*, const quint32);
void slotClientConnectionClosed(QLocalSocket*, const quint32);
};
#endif // SINGLEAPPLICATION_P_H

View File

@@ -31,13 +31,18 @@
//
//
#include <stdlib.h>
#include <limits>
#include <QtGlobal>
#include <QCoreApplication>
#include <QThread>
#include <QSharedMemory>
#include <QLocalSocket>
#include <QByteArray>
#include <QDateTime>
#include <QTime>
#include <QElapsedTimer>
#include <QtDebug>
#include "singlecoreapplication.h"
#include "singlecoreapplication_p.h"
@@ -89,7 +94,7 @@ SingleCoreApplication::SingleCoreApplication(int &argc, char *argv[], bool allow
}
InstancesInfo* inst = static_cast<InstancesInfo*>(d->memory->data());
QTime time;
QElapsedTimer time;
time.start();
// Make sure the shared memory block is initialised and in consistent state
@@ -175,7 +180,7 @@ bool SingleCoreApplication::sendMessage(QByteArray message, int timeout) {
if(isPrimary()) return false;
// Make sure the socket is connected
d->connectToPrimary(timeout, SingleCoreApplicationPrivate::Reconnect);
d->connectToPrimary(timeout, SingleCoreApplicationPrivate::Reconnect);
d->socket->write(message);
bool dataWritten = d->socket->waitForBytesWritten(timeout);

View File

@@ -36,7 +36,8 @@
#include <QtGlobal>
#include <QCoreApplication>
#include <QLocalSocket>
#include <QFlags>
#include <QByteArray>
class SingleCoreApplicationPrivate;

View File

@@ -44,12 +44,14 @@
# include <pwd.h>
#endif
#include <QDir>
#include <QIODevice>
#include <QSharedMemory>
#include <QByteArray>
#include <QDataStream>
#include <QCryptographicHash>
#include <QLocalServer>
#include <QLocalSocket>
#include <QDir>
#include "singlecoreapplication.h"
#include "singlecoreapplication_p.h"
@@ -59,8 +61,8 @@
# include <lmcons.h>
#endif
SingleCoreApplicationPrivate::SingleCoreApplicationPrivate(SingleCoreApplication *q_ptr)
: q_ptr(q_ptr),
SingleCoreApplicationPrivate::SingleCoreApplicationPrivate(SingleCoreApplication *_q_ptr)
: q_ptr(_q_ptr),
memory(nullptr),
socket(nullptr),
server(nullptr),
@@ -114,12 +116,9 @@ void SingleCoreApplicationPrivate::genBlockServerName() {
#ifdef Q_OS_UNIX
QByteArray username;
#if defined(HAVE_GETEUID) && defined(HAVE_GETPWUID)
uid_t uid = geteuid();
if (uid != -1) {
struct passwd *pw = getpwuid(uid);
if (pw) {
username = pw->pw_name;
}
struct passwd *pw = getpwuid(geteuid());
if (pw) {
username = pw->pw_name;
}
#endif
if (username.isEmpty()) username = qgetenv("USER");
@@ -187,7 +186,7 @@ void SingleCoreApplicationPrivate::startPrimary() {
void SingleCoreApplicationPrivate::startSecondary() {}
void SingleCoreApplicationPrivate::connectToPrimary(int msecs, ConnectionType connectionType) {
void SingleCoreApplicationPrivate::connectToPrimary(const int msecs, const ConnectionType connectionType) {
// Connect to the Local Server of the Primary Instance if not already connected.
if (socket == nullptr) {
@@ -215,9 +214,7 @@ void SingleCoreApplicationPrivate::connectToPrimary(int msecs, ConnectionType co
QByteArray initMsg;
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
writeStream.setVersion(QDataStream::Qt_5_6);
#endif
writeStream << blockServerName.toLatin1();
writeStream << static_cast<quint8>(connectionType);
@@ -229,9 +226,8 @@ void SingleCoreApplicationPrivate::connectToPrimary(int msecs, ConnectionType co
QByteArray header;
QDataStream headerStream(&header, QIODevice::WriteOnly);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
headerStream.setVersion(QDataStream::Qt_5_6);
#endif
headerStream << static_cast <quint64>(initMsg.length());
socket->write(header);
@@ -316,9 +312,7 @@ void SingleCoreApplicationPrivate::readInitMessageHeader(QLocalSocket *sock) {
QDataStream headerStream(sock);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
headerStream.setVersion(QDataStream::Qt_5_6);
#endif
// Read the header to know the message length
quint64 msgLen = 0;
@@ -350,9 +344,7 @@ void SingleCoreApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
QByteArray msgBytes = sock->read(info.msgLen);
QDataStream readStream(msgBytes);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
readStream.setVersion(QDataStream::Qt_5_6);
#endif
// server name
QByteArray latin1Name;
@@ -394,14 +386,14 @@ void SingleCoreApplicationPrivate::readInitMessageBody(QLocalSocket *sock) {
}
void SingleCoreApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, quint32 instanceId) {
void SingleCoreApplicationPrivate::slotDataAvailable(QLocalSocket *dataSocket, const quint32 instanceId) {
Q_Q(SingleCoreApplication);
Q_EMIT q->receivedMessage(instanceId, dataSocket->readAll());
}
void SingleCoreApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, quint32 instanceId) {
void SingleCoreApplicationPrivate::slotClientConnectionClosed(QLocalSocket *closedSocket, const quint32 instanceId) {
if (closedSocket->bytesAvailable() > 0)
Q_EMIT slotDataAvailable(closedSocket, instanceId);

View File

@@ -35,13 +35,15 @@
#define SINGLECOREAPPLICATION_P_H
#include <QtGlobal>
#include <QLocalSocket>
#include <QLocalServer>
#include <QSharedMemory>
#include <QObject>
#include <QMap>
#include "singlecoreapplication.h"
class QLocalServer;
class QLocalSocket;
class QSharedMemory;
struct InstancesInfo {
bool primary;
quint32 secondary;
@@ -72,14 +74,14 @@ class SingleCoreApplicationPrivate : public QObject {
};
Q_DECLARE_PUBLIC(SingleCoreApplication)
SingleCoreApplicationPrivate( SingleCoreApplication *q_ptr );
SingleCoreApplicationPrivate(SingleCoreApplication *_q_ptr);
~SingleCoreApplicationPrivate();
void genBlockServerName();
void initializeMemoryBlock();
void startPrimary();
void startSecondary();
void connectToPrimary(int msecs, ConnectionType connectionType );
void connectToPrimary(const int msecs, const ConnectionType connectionType);
quint16 blockChecksum();
qint64 primaryPid();
void readInitMessageHeader(QLocalSocket *socket);
@@ -96,8 +98,8 @@ class SingleCoreApplicationPrivate : public QObject {
public slots:
void slotConnectionEstablished();
void slotDataAvailable(QLocalSocket*, quint32);
void slotClientConnectionClosed(QLocalSocket*, quint32);
void slotDataAvailable(QLocalSocket*, const quint32);
void slotClientConnectionClosed(QLocalSocket*, const quint32);
};
#endif // SINGLECOREAPPLICATION_P_H

View File

@@ -1,8 +1,4 @@
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -fpermissive -Wall -Woverloaded-virtual -Wno-sign-compare -Wno-delete-non-virtual-dtor")
cmake_minimum_required(VERSION 3.0)
set(TAGLIB_SOVERSION_CURRENT 17)
set(TAGLIB_SOVERSION_REVISION 0)

View File

@@ -87,12 +87,15 @@ public:
// static members
////////////////////////////////////////////////////////////////////////////////
bool APE::File::isSupported(IOStream *stream)
bool APE::File::isSupported(IOStream*)
{
// An APE file has an ID "MAC " somewhere. An ID3v2 tag may precede.
const ByteVector buffer = Utils::readHeader(stream, bufferSize(), true);
return (buffer.find("MAC ") >= 0);
// FIXME:
//const ByteVector buffer = Utils::readHeader(stream, bufferSize(), true);
//return (buffer.find("MAC ") >= 0);
return false;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -264,6 +264,7 @@ int ASF::Attribute::dataSize() const
case BytesType:
if(d->pictureValue.isValid())
return d->pictureValue.dataSize();
break;
case GuidType:
return d->byteVectorValue.size();
}
@@ -305,6 +306,7 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const
data.append(d->pictureValue.render());
break;
}
break;
case GuidType:
data.append(d->byteVectorValue);
break;

View File

@@ -51,7 +51,7 @@ namespace
int chunkIndex(const ChunkList &chunks, const ByteVector &id)
{
for(int i = 0; i < chunks.size(); i++) {
for (unsigned long int i = 0 ; i < chunks.size() ; i++) {
if(chunks[i].name == id)
return i;
}
@@ -64,8 +64,8 @@ namespace
if(name.size() != 4)
return false;
for(int i = 0; i < 4; i++) {
if(name[i] < 32 || name[i] > 127)
for (int i = 0 ; i < 4 ; i++) {
if (name[i] < 32)
return false;
}
@@ -227,7 +227,7 @@ bool DSDIFF::File::save()
return save(AllTags);
}
bool DSDIFF::File::save(TagTypes tags, StripTags strip, ID3v2::Version version)
bool DSDIFF::File::save(TagTypes tags, StripTags, ID3v2::Version version)
{
if(readOnly()) {
debug("DSDIFF::File::save() -- File is read only.");

View File

@@ -180,7 +180,7 @@ bool DSF::File::save()
////////////////////////////////////////////////////////////////////////////////
void DSF::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
void DSF::File::read(bool, Properties::ReadStyle propertiesStyle)
{
// A DSF file consists of four chunks: DSD chunk, format chunk, data chunk, and metadata chunk
// The file format is not chunked in the sense of a RIFF File, though

View File

@@ -228,10 +228,10 @@ namespace
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "OGA") {
/* .oga can be any audio in the Ogg container. First try FLAC, then Vorbis. */
File *file = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(file->isValid())
return file;
delete file;
File *file_flac = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if (file_flac->isValid())
return file_flac;
delete file_flac;
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
}
if(ext == "FLAC")

View File

@@ -92,8 +92,8 @@ namespace TagLib {
class TAGLIB_EXPORT FileTypeResolver
{
TAGLIB_IGNORE_MISSING_DESTRUCTOR
public:
virtual ~FileTypeResolver();
/*!
* This method must be overridden to provide an additional file type
* resolver. If the resolver is able to determine the file type it should
@@ -286,4 +286,4 @@ namespace TagLib {
}
} // namespace Strawberry_TagLib::TagLib
#endif
#endif // TAGLIB_FILEREF_H

View File

@@ -60,9 +60,9 @@ bool Mod::FileBase::readString(String &s, unsigned long size)
return true;
}
void Mod::FileBase::writeByte(unsigned char byte)
void Mod::FileBase::writeByte(unsigned char _byte)
{
ByteVector data(1, byte);
ByteVector data(1, _byte);
writeBlock(data);
}
@@ -86,11 +86,11 @@ void Mod::FileBase::writeU32B(unsigned long number)
writeBlock(ByteVector::fromUInt(number, true));
}
bool Mod::FileBase::readByte(unsigned char &byte)
bool Mod::FileBase::readByte(unsigned char &_byte)
{
ByteVector data(readBlock(1));
if(data.size() < 1) return false;
byte = data[0];
_byte = data[0];
return true;
}

View File

@@ -122,15 +122,15 @@ MP4::Atom::find(const char *name1, const char *name2, const char *name3, const c
}
MP4::AtomList
MP4::Atom::findall(const char *name, bool recursive)
MP4::Atom::findall(const char *_name, bool recursive)
{
MP4::AtomList result;
for(AtomList::ConstIterator it = children.begin(); it != children.end(); ++it) {
if((*it)->name == name) {
if((*it)->name == _name) {
result.append(*it);
}
if(recursive) {
result.append((*it)->findall(name, recursive));
result.append((*it)->findall(_name, recursive));
}
}
return result;

View File

@@ -67,7 +67,7 @@ namespace TagLib {
};
struct AtomData {
AtomData(AtomDataType type, ByteVector data) : type(type), locale(0), data(data) {}
AtomData(AtomDataType _type, ByteVector _data) : type(_type), locale(0), data(_data) {}
AtomDataType type;
int locale;
ByteVector data;

View File

@@ -334,14 +334,14 @@ ByteVector TableOfContentsFrame::renderFields() const
data.append(flags);
data.append((char)(entryCount()));
ByteVectorList::ConstIterator it = d->childElements.begin();
while(it != d->childElements.end()) {
while (it != d->childElements.end()) {
data.append(*it);
data.append('\0');
it++;
}
FrameList l = d->embeddedFrameList;
for(FrameList::ConstIterator it = l.begin(); it != l.end(); ++it)
data.append((*it)->render());
for (FrameList::ConstIterator it2 = l.begin(); it2 != l.end(); ++it2)
data.append((*it2)->render());
return data;
}

View File

@@ -417,7 +417,7 @@ namespace
{"TYER", "TDRC"}, // 2.3 -> 2.4
{"TIME", "TDRC"}, // 2.3 -> 2.4
};
const size_t deprecatedFramesSize = sizeof(deprecatedFrames) / sizeof(deprecatedFrames[0]);;
const size_t deprecatedFramesSize = sizeof(deprecatedFrames) / sizeof(deprecatedFrames[0]);
}
String Frame::frameIDToKey(const ByteVector &id)

View File

@@ -69,7 +69,7 @@ public:
// public members
////////////////////////////////////////////////////////////////////////////////
MPEG::Header::Header(const ByteVector &data) :
MPEG::Header::Header(const ByteVector&) :
d(new HeaderPrivate())
{
debug("MPEG::Header::Header() - This constructor is no longer used.");

View File

@@ -296,10 +296,10 @@ void Ogg::File::writePacket(unsigned int i, const ByteVector &packet)
break;
page.setPageSequenceNumber(page.pageSequenceNumber() + numberOfNewPages);
const ByteVector data = page.render();
const ByteVector data2 = page.render();
seek(pageOffset + 18);
writeBlock(data.mid(18, 8));
writeBlock(data2.mid(18, 8));
if(page.header()->lastPageOfStream())
break;

View File

@@ -379,8 +379,7 @@ ByteVector Ogg::XiphComment::render(bool addFramingBit) const
// std::pair<String, StringList> where the first String is the field name and
// the StringList is the values associated with that field.
FieldListMap::ConstIterator it = d->fieldListMap.begin();
for(; it != d->fieldListMap.end(); ++it) {
for(FieldListMap::ConstIterator it = d->fieldListMap.begin() ; it != d->fieldListMap.end() ; ++it) {
// And now iterate over the values of the current list.
@@ -398,7 +397,7 @@ ByteVector Ogg::XiphComment::render(bool addFramingBit) const
}
}
for(PictureConstIterator it = d->pictureList.begin(); it != d->pictureList.end(); ++it) {
for (PictureConstIterator it = d->pictureList.begin(); it != d->pictureList.end(); ++it) {
ByteVector picture = (*it)->render().toBase64();
data.append(ByteVector::fromUInt(picture.size() + 23, false));
data.append("METADATA_BLOCK_PICTURE=");

View File

@@ -46,8 +46,8 @@ struct Chunk
class RIFF::File::FilePrivate
{
public:
explicit FilePrivate(Endianness endianness) :
endianness(endianness),
explicit FilePrivate(Endianness _endianness) :
endianness(_endianness),
size(0),
sizeOffset(0) {}

View File

@@ -77,11 +77,6 @@ ByteVectorList::ByteVectorList() :
}
ByteVectorList::ByteVectorList(const ByteVectorList &l) : List<ByteVector>(l)
{
}
ByteVectorList::~ByteVectorList()
{

View File

@@ -53,13 +53,6 @@ namespace TagLib {
*/
virtual ~ByteVectorList();
/*!
* Make a shallow, implicitly shared, copy of \a l. Because this is
* implicitly shared, this method is lightweight and suitable for
* pass-by-value usage.
*/
ByteVectorList(const ByteVectorList &l);
/*!
* Convert the ByteVectorList to a ByteVector separated by \a separator. By
* default a space is used.

View File

@@ -43,8 +43,8 @@ public:
long position;
};
ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &data) :
data(data),
ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &_data) :
data(_data),
position(0)
{
}

View File

@@ -71,9 +71,9 @@ using namespace Strawberry_TagLib::TagLib;
class File::FilePrivate
{
public:
FilePrivate(IOStream *stream, bool owner) :
stream(stream),
streamOwner(owner),
FilePrivate(IOStream *_stream, bool _owner) :
stream(_stream),
streamOwner(_owner),
valid(true) {}
~FilePrivate()

View File

@@ -58,7 +58,7 @@ namespace
#endif
}
FileHandle openFile(const int fileDescriptor, bool readOnly)
FileHandle openFile(const int, bool)
{
return InvalidFileHandle;
}

View File

@@ -28,16 +28,10 @@
using namespace Strawberry_TagLib::TagLib;
PropertyMap::PropertyMap() : SimplePropertyMap()
{
}
PropertyMap::PropertyMap() : SimplePropertyMap() {}
PropertyMap::PropertyMap(const PropertyMap &m) : SimplePropertyMap(m), unsupported(m.unsupported)
{
}
PropertyMap::PropertyMap(const SimplePropertyMap &m) {
PropertyMap::PropertyMap(const SimplePropertyMap &m)
{
for(SimplePropertyMap::ConstIterator it = m.begin(); it != m.end(); ++it){
String key = it->first.upper();
if(!key.isEmpty())
@@ -45,14 +39,13 @@ PropertyMap::PropertyMap(const SimplePropertyMap &m)
else
unsupported.append(it->first);
}
}
PropertyMap::~PropertyMap()
{
}
PropertyMap::~PropertyMap() {}
bool PropertyMap::insert(const String &key, const StringList &values) {
bool PropertyMap::insert(const String &key, const StringList &values)
{
String realKey = key.upper();
Iterator result = SimplePropertyMap::find(realKey);
if(result == end())
@@ -60,6 +53,7 @@ bool PropertyMap::insert(const String &key, const StringList &values)
else
SimplePropertyMap::operator[](realKey).append(values);
return true;
}
bool PropertyMap::replace(const String &key, const StringList &values)

View File

@@ -115,8 +115,6 @@ namespace TagLib {
PropertyMap();
PropertyMap(const PropertyMap &m);
/*!
* Creates a PropertyMap initialized from a SimplePropertyMap. Copies all
* entries from \a m that have valid keys.

View File

@@ -62,13 +62,6 @@ StringList::StringList() :
}
StringList::StringList(const StringList &l) :
List<String>(l),
d(nullptr)
{
}
StringList::StringList(const String &s) :
List<String>(),
d(nullptr)

View File

@@ -57,7 +57,7 @@ namespace TagLib {
* implicitly shared, this method is lightweight and suitable for
* pass-by-value usage.
*/
StringList(const StringList &l);
StringList(const StringList &l) = default;
/*!
* Constructs a StringList with \a s as a member.

View File

@@ -193,7 +193,7 @@ namespace TagLib
// The last resort. May cause a buffer overflow.
length = vsprintf(buf, format, args);
if(length >= BufferSize) {
if(length >= (int)BufferSize) {
debug("Utils::formatString() - Buffer overflow! Returning an empty string.");
length = -1;
}

View File

@@ -110,7 +110,7 @@ template<typename T>
class ValueReader : public Reader
{
public:
explicit ValueReader(T &value) : value(value)
explicit ValueReader(T &_value) : value(_value)
{
}
@@ -151,7 +151,7 @@ private:
class ByteReader : public ValueReader<unsigned char>
{
public:
explicit ByteReader(unsigned char &byte) : ValueReader<unsigned char>(byte) {}
explicit ByteReader(unsigned char &_byte) : ValueReader<unsigned char>(_byte) {}
unsigned int read(Strawberry_TagLib::TagLib::File &file, unsigned int limit)
{
@@ -172,8 +172,8 @@ template<typename T>
class NumberReader : public ValueReader<T>
{
public:
NumberReader(T &value, bool bigEndian) :
ValueReader<T>(value), bigEndian(bigEndian)
NumberReader(T &_value, bool _bigEndian) :
ValueReader<T>(_value), bigEndian(_bigEndian)
{
}
@@ -184,8 +184,8 @@ protected:
class U16Reader : public NumberReader<unsigned short>
{
public:
U16Reader(unsigned short &value, bool bigEndian)
: NumberReader<unsigned short>(value, bigEndian) {}
U16Reader(unsigned short &_value, bool _bigEndian)
: NumberReader<unsigned short>(_value, _bigEndian) {}
unsigned int read(Strawberry_TagLib::TagLib::File &file, unsigned int limit)
{
@@ -203,8 +203,8 @@ public:
class U32Reader : public NumberReader<unsigned long>
{
public:
U32Reader(unsigned long &value, bool bigEndian = true) :
NumberReader<unsigned long>(value, bigEndian)
U32Reader(unsigned long &_value, bool _bigEndian = true) :
NumberReader<unsigned long>(_value, _bigEndian)
{
}
@@ -479,11 +479,11 @@ bool XM::File::save()
if(sampleHeaderSize > 18U) {
seek(pos + 18);
const unsigned int len = std::min(sampleHeaderSize - 18U, 22UL);
const unsigned int len2 = std::min(sampleHeaderSize - 18U, 22UL);
if(sampleNameIndex >= lines.size())
writeString(String(), len);
writeString(String(), len2);
else
writeString(lines[sampleNameIndex ++], len);
writeString(lines[sampleNameIndex ++], len2);
}
}
pos += sampleHeaderSize;
@@ -560,10 +560,10 @@ void XM::File::read(bool)
StructReader pattern;
pattern.byte(packingType).u16L(rowCount).u16L(dataSize);
unsigned int count = pattern.read(*this, patternHeaderLength - 4U);
READ_ASSERT(count == std::min(patternHeaderLength - 4U, (unsigned long)pattern.size()));
unsigned int count2 = pattern.read(*this, patternHeaderLength - 4U);
READ_ASSERT(count2 == std::min(patternHeaderLength - 4U, (unsigned long)pattern.size()));
seek(patternHeaderLength - (4 + count) + dataSize, Current);
seek(patternHeaderLength - (4 + count2) + dataSize, Current);
}
StringList intrumentNames;
@@ -583,17 +583,17 @@ void XM::File::read(bool)
instrument.string(instrumentName, 22).byte(instrumentType).u16L(sampleCount);
// 4 for instrumentHeaderSize
unsigned int count = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
READ_ASSERT(count == std::min(instrumentHeaderSize, (unsigned long)instrument.size() + 4));
unsigned int count2 = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
READ_ASSERT(count2 == std::min(instrumentHeaderSize, (unsigned long)instrument.size() + 4));
long offset = 0;
if(sampleCount > 0) {
unsigned long sampleHeaderSize = 0;
sumSampleCount += sampleCount;
// wouldn't know which header size to assume otherwise:
READ_ASSERT(instrumentHeaderSize >= count + 4 && readU32L(sampleHeaderSize));
READ_ASSERT(instrumentHeaderSize >= count2 + 4 && readU32L(sampleHeaderSize));
// skip unhandled header proportion:
seek(instrumentHeaderSize - count - 4, Current);
seek(instrumentHeaderSize - count2 - 4, Current);
for(unsigned short j = 0; j < sampleCount; ++ j) {
unsigned long sampleLength = 0;
@@ -618,17 +618,17 @@ void XM::File::read(bool)
.byte(compression)
.string(sampleName, 22);
unsigned int count = sample.read(*this, sampleHeaderSize);
READ_ASSERT(count == std::min(sampleHeaderSize, (unsigned long)sample.size()));
unsigned int count3 = sample.read(*this, sampleHeaderSize);
READ_ASSERT(count3 == std::min(sampleHeaderSize, (unsigned long)sample.size()));
// skip unhandled header proportion:
seek(sampleHeaderSize - count, Current);
seek(sampleHeaderSize - count3, Current);
offset += sampleLength;
sampleNames.append(sampleName);
}
}
else {
offset = instrumentHeaderSize - count;
offset = instrumentHeaderSize - count2;
}
intrumentNames.append(instrumentName);
seek(offset, Current);

View File

@@ -1,30 +1,12 @@
# Strawberry Music Player
# Copyright 2013, Jonas Kvinge <jonas@strawbs.net>
#
# Strawberry is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Strawberry is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
project(strawberry)
cmake_minimum_required(VERSION 2.8.11)
if(CMAKE_VERSION VERSION_GREATER 3.0)
cmake_policy(SET CMP0054 NEW)
endif()
cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0054 NEW)
include(CheckCXXCompilerFlag)
include(CheckCXXSourceRuns)
include(CheckIncludeFiles)
include(FindPkgConfig)
include(cmake/C++11Compat.cmake)
include(cmake/Version.cmake)
include(cmake/Summary.cmake)
include(cmake/OptionalSource.cmake)
@@ -33,6 +15,8 @@ include(cmake/Rpm.cmake)
include(cmake/Deb.cmake)
include(cmake/Dmg.cmake)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(LINUX ON)
endif()
@@ -43,8 +27,46 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
set(OPENBSD ON)
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
list(APPEND COMPILE_OPTIONS
$<$<COMPILE_LANGUAGE:C>:--std=c99>
$<$<COMPILE_LANGUAGE:CXX>:--std=c++11>
-U__STRICT_ANSI__
-Wall
-Wextra
-Wpedantic
-Wunused
-Wshadow
-Wundef
-Wuninitialized
-Wredundant-decls
-Wcast-align
-Winit-self
-Wmissing-include-dirs
-Wmissing-declarations
-Wstrict-overflow=2
-Wunused-parameter
-Wformat=2
-Wdisabled-optimization
-Wno-sign-conversion
$<$<COMPILE_LANGUAGE:CXX>:-Woverloaded-virtual>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-old-style-cast>
$<$<COMPILE_LANGUAGE:CXX>:-fpermissive>
)
if(APPLE)
list(APPEND COMPILE_OPTIONS -Wno-unused-parameter)
endif()
option(BUILD_WERROR "Build with -Werror" OFF)
if(BUILD_WERROR)
list(APPEND COMPILE_OPTIONS -Werror)
endif(BUILD_WERROR)
add_compile_options(${COMPILE_OPTIONS})
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
add_definitions(-DNDEBUG)
@@ -56,32 +78,21 @@ if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
set(DEBUG ON)
endif()
if (CMAKE_CXX_COMPILER MATCHES ".*clang")
set(CMAKE_COMPILER_IS_CLANGXX 1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-uninitialized")
endif()
if (APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --stdlib=libc++")
endif(APPLE)
find_program(CCACHE_EXECUTABLE NAMES ccache)
if (CCACHE_EXECUTABLE)
message(STATUS "ccache found: will be used for compilation and linkage")
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_EXECUTABLE})
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_EXECUTABLE})
endif ()
find_program(QT_LCONVERT_EXECUTABLE NAMES lconvert lconvert-qt5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH)
find_program(QT_LCONVERT_EXECUTABLE NAMES lconvert lconvert-qt5)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED glib-2.0)
pkg_check_modules(GIO REQUIRED gio-2.0)
pkg_check_modules(GOBJECT REQUIRED gobject-2.0)
pkg_check_modules(CDIO libcdio)
find_package(Threads)
find_package(GnuTLS)
find_package(Boost REQUIRED)
find_package(Threads)
find_package(Backtrace QUIET)
if(Backtrace_FOUND)
set(HAVE_BACKTRACE ON)
endif()
find_package(GnuTLS)
find_package(Protobuf REQUIRED)
find_library(PROTOBUF_STATIC_LIBRARY libprotobuf.a libprotobuf)
if(LINUX)
@@ -98,6 +109,10 @@ endif()
if(X11_FOUND)
set(HAVE_X11 ON)
endif()
pkg_check_modules(GLIB REQUIRED glib-2.0)
pkg_check_modules(GIO REQUIRED gio-2.0)
pkg_check_modules(GOBJECT REQUIRED gobject-2.0)
pkg_check_modules(LIBCDIO libcdio)
pkg_check_modules(GSTREAMER gstreamer-1.0)
pkg_check_modules(GSTREAMER_BASE gstreamer-base-1.0)
pkg_check_modules(GSTREAMER_AUDIO gstreamer-audio-1.0)
@@ -106,7 +121,6 @@ pkg_check_modules(GSTREAMER_TAG gstreamer-tag-1.0)
pkg_check_modules(GSTREAMER_PBUTILS gstreamer-pbutils-1.0)
pkg_check_modules(LIBXINE libxine)
pkg_check_modules(LIBVLC libvlc)
pkg_check_modules(PHONON phonon4qt5)
pkg_check_modules(SQLITE REQUIRED sqlite3>=3.9)
pkg_check_modules(LIBPULSE libpulse)
pkg_check_modules(CHROMAPRINT libchromaprint)
@@ -118,12 +132,8 @@ pkg_check_modules(LIBPLIST libplist)
find_package(Gettext)
find_package(FFTW3)
if(WIN32)
find_package(ZLIB REQUIRED)
endif(WIN32)
# QT
set(QT_MIN_VERSION 5.5)
set(QT_MIN_VERSION 5.6)
set(QT_COMPONENTS Core Concurrent Widgets Network Sql)
if(X11_FOUND)
@@ -139,7 +149,7 @@ if(WIN32)
list(APPEND QT_COMPONENTS WinExtras)
endif()
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED ${QT_COMPONENTS})
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS ${QT_COMPONENTS})
set(QT_LIBRARIES ${Qt5Core_LIBRARIES} ${Qt5Concurrent_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES} ${Qt5Sql_LIBRARIES})
@@ -157,7 +167,7 @@ if(Qt5WinExtras_FOUND)
list(APPEND QT_LIBRARIES ${Qt5WinExtras_LIBRARIES})
endif()
find_package(Qt5LinguistTools CONFIG)
find_package(Qt5 ${QT_MIN_VERSION} QUIET COMPONENTS LinguistTools CONFIG)
if (Qt5LinguistTools_FOUND)
set(QT_LCONVERT_EXECUTABLE Qt5::lconvert)
endif()
@@ -187,13 +197,12 @@ pkg_check_modules(TAGLIB taglib)
# - Audio file detection by content.
# - DSF and DSDIFF support
#
if (TAGLIB_VERSION VERSION_GREATER 1.11.1 OR WIN32)
option(USE_SYSTEM_TAGLIB "Use system taglib" ON)
else()
option(USE_SYSTEM_TAGLIB "Use system taglib" OFF)
endif()
# Some distros create their own version numbers for taglib so versions are not reliable anymore.
# Force to use our own copy of taglib unless USE_SYSTEM_TAGLIB is set.
option(USE_SYSTEM_TAGLIB "Use system taglib" OFF)
if (TAGLIB_FOUND AND USE_SYSTEM_TAGLIB)
if (TAGLIB_VERSION VERSION_GREATER 1.11.1 OR WIN32)
if (TAGLIB_VERSION VERSION_GREATER 1.11.1)
message(STATUS "Using system taglib library")
else()
message(WARNING "Using system taglib library. Version 1.11.1 or less has a bug corrupting Ogg files, make sure your systems version has been patched!")
@@ -210,6 +219,7 @@ else()
add_subdirectory(3rdparty/utf8-cpp)
add_subdirectory(3rdparty/taglib)
set(HAVE_TAGLIB_DSFFILE ON)
add_definitions(-DTAGLIB_STATIC)
endif()
# SingleApplication
@@ -286,10 +296,6 @@ optional_component(VLC ON "Engine: VLC backend"
DEPENDS "libvlc" LIBVLC_FOUND
)
optional_component(PHONON OFF "Engine: Phonon backend (UNSTABLE)"
DEPENDS "phonon4qt5" PHONON_FOUND
)
optional_component(CHROMAPRINT ON "Chromaprint (Tag fetching from Musicbrainz)"
DEPENDS "chromaprint" CHROMAPRINT_FOUND
)
@@ -303,7 +309,7 @@ optional_component(GLOBALSHORTCUTS ON "Global shortcuts"
)
optional_component(AUDIOCD ON "Devices: Audio CD support"
DEPENDS "libcdio" CDIO_FOUND
DEPENDS "libcdio" LIBCDIO_FOUND
)
optional_component(UDISKS2 ON "Devices: UDisks2 backend"
@@ -340,9 +346,8 @@ optional_component(TRANSLATIONS ON "Translations"
DEPENDS "Qt5LinguistTools" Qt5LinguistTools_FOUND
)
optional_component(TIDAL ON "Tidal support")
optional_component(QOBUZ ON "Qobuz support")
optional_component(SUBSONIC ON "Subsonic support")
optional_component(TIDAL ON "Tidal support")
optional_component(MOODBAR ON "Moodbar"
DEPENDS "fftw3" FFTW3_FOUND
@@ -400,17 +405,14 @@ if(HAVE_XINE)
XINE_ANALYZER)
endif()
# Set up definitions and paths
# Set up definitions
add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS)
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_STRICT_ITERATORS)
add_definitions(-DQT_USE_QSTRINGBUILDER)
add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
add_definitions(-DQT_NO_CAST_TO_ASCII -DQT_STRICT_ITERATORS)
include_directories(${GLIB_INCLUDE_DIRS})
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
include_directories(${TAGLIB_INCLUDE_DIRS})
add_definitions(-DQT_NO_CAST_TO_ASCII)
# Subdirectories
add_subdirectory(src)
@@ -434,8 +436,8 @@ add_custom_target(uninstall
# Show a summary of what we have enabled
summary_show()
if(NOT HAVE_GSTREAMER AND NOT HAVE_XINE AND NOT HAVE_VLC AND NOT HAVE_PHONON)
message(FATAL_ERROR "You need to have either GStreamer, Xine, VLC or Phonon to compile!")
if(NOT HAVE_GSTREAMER AND NOT HAVE_XINE AND NOT HAVE_VLC)
message(FATAL_ERROR "You need to have either GStreamer, Xine or VLC to compile!")
elseif(NOT HAVE_GSTREAMER)
message(WARNING "GStreamer is the only engine that is fully implemented. Using other engines is possible but not recommended.")
endif()

132
Changelog
View File

@@ -2,6 +2,138 @@ Strawberry Music Player
=======================
ChangeLog
0.6.11:
Bugfixes:
* Fixed MPRIS missing art url when playing albums with embedded cover.
* Fixed updating local non collection songs when manually unsetting cover.
* Fixed infinite loop and preceding crash when CSS background-color was set in qt5ct.
* Fixed UI freeze when updating the database from a large Subsonic or Tidal collection.
* Fixed crash when CD loading fails in devices.
* Fixed CD devices showing up with having 0 songs after loading.
* Fixed the album cover loading indicator being stuck if no cover providers were available.
* Fixed the playing widget not updating artist, album or title after metadata has changed for a song when no album cover was loaded.
Enhancements:
* Sort songs in collection by song title instead of track if previous grouping is not the album.
* Added option to switch on/off automatically searching for album covers to context settings.
* Reset last played song when playlist is finished.
* Checking content type of received HTTP request for image when receiving album covers.
* Added option to scrobbler setting for turning off login error popup.
* Made MusicBrainz and Discogs cover providers respect rate limiting.
New features:
* Added option to show/hide sidebar.
* Added settings for selecting album cover and lyrics providers.
* Added album covers from Musixmatch and Spotify.
* Added lyrics from Genius, Musixmatch and ChartLyrics.
0.6.10:
Bugfixes:
* Fixed Subsonic album covers not working for albums with non ASCII charcters.
* Fixed reading date and genre from individual tracks in CUE sheets.
* Fixed resume playback on startup for CUE songs.
* Fixed album cover manager not showing complete album titles in the list of album covers.
* Fixed save album cover to file saving "no cover" image instead of actual album cover.
* Fixed device state text color in devices not being visible when using a dark theme.
* Fixed engine and device in context using too large icons when icons were loaded from the system theme.
* Fixed "Secure connection setup failed" problem on Windows when playing streams.
* Fixed margin for song title text in context.
* Fixed UNC paths with non ASCII charcters not working.
Enhancements:
* Allowing all characters except slash and backslash when organising music unless options to strip characters is checked.
* New option in organising music to remove problematic filename characters that removes less characters than the FAT option.
* General improvements to the album cover loader and album cover providers code.
* Fixed loading album cover images from album directory for songs added to the playlist from outside of the collection.
* Made automatic album cover search work for songs outside of the collection and for streams.
* Made album cover search work based on artist + title if album title is not present for providers supporting song/track search.
* Update art manual in playlist for local files, devices and CDDA to avoid loading covers multiple times.
* Made lyrics search work for streams.
* Added "add stream" to menu.
* Only showing song length in context when available.
* Sort album cover search results by score and pick the best 3 first before trying others to improve album cover search speed.
* Make scrobbler work for streams.
* Added search for lyrics as a seperate option in context.
* Made font and font sizes in context configurable.
* Splitting artist and song title to the relevant metadata when artist and song title is sent as title seperated by a dash in streams.
* Added label to show collection pixmap disk cache used in settings.
* Icreased default collection pixmap disk cache to 360.
New features:
* Added back Tidal streaming support.
* Added Qobuz album cover provider.
Removed features:
* Removed Phonon engine support.
Version 0.6.9:
BugFixes:
* Fixed playlist metadata updating interfering with manual tag editing.
* Fixed order of tabs in all windows.
* Fixed playlist right click using wrong songs for determining menu options when playlist was filtered.
* Fixed possible crashes on playlist right click.
* Fixed possible null pointer crash in OSD pretty.
* Fixed track and title in playlist not being movable.
* Fixed Subsonic support to handle numeric Json values like track and disc both as strings and integers.
* Fixed Subsonic compatibility with LMS (Lightweight Music Server).
* Disabled "open Audio CD" from menu on Windows where CD support is currently not supported.
* Fixed files containing "MAC" being detected as Monkey's Audio.
Enhancements:
* Improved support for High DPI displays.
* Added CMake check for backtrace() to fix compilation with musl libc.
* Made album cover in context adjust to width.
* Made settings, cover manager, organise dialog and transcode music dialog center on the same display where the mainwindow is located.
* Removing empty directories when organizing music.
* Made file selection work in "Show file in browser" for Dolphin and Nautilus.
* Implemented disk caching of album thumbnails in collection tree.
* Use a shorter playlist name when songs are added from file view.
* Disabled optical drives in copy to device menu.
* Added better error handling for CDDA loading.
* Added Polish, Hungarian and Korean translations.
Removed features:
* Chartlyrics support (Unstable API).
* Tidal support (No agreement).
* QObuz support (No agreement).
Version 0.6.8:
* Fixed stuck tabbar and collection GUI with some themes.
* Fixed possible crashes related to QProxyStyle.
* Fixed a bug where metadata in the playlist was not updated when editing metadata for the current playing track.
* Fixed crash when deleting a folder with playlists.
* Fixed restoring to correct screen when maximized.
* Increased lyrics score if lyrics text is larger than 60 characters to avoid using "no lyrics available" text.
* Made context title and summary changeable.
* Added option to disable playlist clear button.
* Added confirmation dialog before clearing playlists with more than 500 songs.
* Added German, French, Italian and Indonesian translations.
* Added StartupWMClass to desktop file.
* Replaced use of Qt deprecated functionality as of 5.14.
* (macOS) Fixed filesystem watcher to correctly pick up changed collection directories.
* (Windows) Fixed translations not being included.
Version 0.6.7:
* Fixed crash when cancelling scrobbler authentication
* Fixed "Double clicking a song in the playlist" behaviour setting
* Fixed "Pressing Previous in player" behaviour setting
* Fixed updating compilations where there are spaces or special characters in filenames
* Fixed cases where songs were stuck in "Various Artists" because not all songs in
the same compilation was removed from the model before readded with actual artist.
* Fixed a bug when importing playlists where metadata was reset
* Fixed scrobbler to also scrobble songs without album title
* Fixed text for replay gain setting not loading in backend setting
* Added back lyrics from Chartlyrics
* Added ability to show fullsize cover on double-click in playing widget
* Added separator between "unset cover" and "show fullsize" in popup menu
* Removed left click on analyzer to popup menu
* (Windows) Added killproc executable to terminate running process before uninstalling
Version 0.6.6:
* Fixed lowercased album artist in playlist column

View File

@@ -1,13 +1,26 @@
:strawberry: Strawberry Music Player [![Build Status](https://travis-ci.org/jonaski/strawberry.svg?branch=master)](https://travis-ci.org/jonaski/strawberry)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FRJUYV5QP6HW8)
:strawberry: Strawberry Music Player [![Build Status](https://github.com/strawberrymusicplayer/strawberry/workflows/C/C++%20CI/badge.svg)](https://github.com/strawberrymusicplayer/strawberry/actions)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/jonaskvinge)
=======================
Strawberry is a music player and music collection organizer. It is a fork of Clementine released in 2018 aimed at music collectors, audio enthusiasts and audiophiles. The name is inspired by the band Strawbs. It's based on a heavily modified version of Clementine created in 2012-2013. It's written in C++ and Qt 5.
Strawberry is a music player and music collection organizer. It is a fork of Clementine released in 2018 aimed at music collectors and audiophiles. It's written in C++ using the Qt 5 framework.
![Browse](https://www.strawberrymusicplayer.org/pictures/screenshot-002-large.png)
Resources:
* Website: https://www.strawberrymusicplayer.org/
* Github: https://github.com/jonaski/strawberry
* Buildbot: http://buildbot.strawberrymusicplayer.org/
* Forum: https://forum.strawberrymusicplayer.org/
* Github: https://github.com/strawberrymusicplayer/strawberry
* Buildbot: https://buildbot.strawberrymusicplayer.org/
* Latest builds: https://builds.strawberrymusicplayer.org/
* openSUSE buildservice: https://build.opensuse.org/package/show/home:jonaski:audio/strawberry
* PPA: https://launchpad.net/~jonaski/+archive/ubuntu/strawberry
* Translations: https://translate.zanata.org/iteration/view/strawberry/master
The program is free software, released under GPL. If you like this program and can make use of it, consider sponsoring or donating to help fund the project.
To sponsor, visit [my GitHub sponsors profile](https://github.com/sponsors/jonaski).
Funding developers through GitHub Sponsors is one more way to contribute to open source projects you appreciate, it helps developers get the resources they need, and recognize contributors working behind the scenes to make open source better for everyone.
You can also make a one-time payment through [paypal.me/jonaskvinge](https://paypal.me/jonaskvinge)
### :heavy_check_mark: Features:
@@ -19,21 +32,19 @@ Strawberry is a music player and music collection organizer. It is a fork of Cle
* Advanced audio output and device configuration for bit-perfect playback on Linux
* Edit tags on music files
* Fetch tags from MusicBrainz
* Album cover art from Last.fm, Musicbrainz, Discogs, Deezer and Tidal
* Song lyrics from AudD, lyrics.ovh and lololyrics.com
* Album cover art from [Last.fm](https://www.last.fm/), [Musicbrainz](https://musicbrainz.org/), [Discogs](https://www.discogs.com/), [Musixmatch](https://www.musixmatch.com/), [Deezer](https://www.deezer.com/), [Tidal](https://www.tidal.com/), [Qobuz](https://www.qobuz.com/) and [Spotify](https://www.spotify.com/)
* Song lyrics from [AudD](https://audd.io/), [Genius](https://genius.com/), [Musixmatch](https://www.musixmatch.com/), [ChartLyrics](http://www.chartlyrics.com/), [lyrics.ovh](https://lyrics.ovh/) and [lololyrics.com](https://www.lololyrics.com/)
* Support for multiple backends
* Audio analyzer
* Audio equalizer
* Transfer music to iPod, iPhone, MTP or mass-storage USB player
* Subsonic streaming support
* Unofficial streaming support for Tidal and Qobuz
* Scrobbler with support for Last.fm, Libre.fm and ListenBrainz
**Tidal and Qobuz streaming in Strawberry is unofficial. You need an official API token (or App ID/Secret) to use it, we can not provide API tokens, or help getting them. Tidal will not work with Tidal Masters (MQA), because MQA is a proprietary format in lossy quality without an open source decoder, we can't support it.**
* Scrobbler with support for [Last.fm](https://www.last.fm/), [Libre.fm](https://libre.fm/) and [ListenBrainz](https://listenbrainz.org/)
* Subsonic and Tidal streaming support
It has so far been tested to work on Linux, OpenBSD, macOS and Windows.
**We do not provide releases for macOS, only experimental builds, they may have issues. There currently isn't any macOS developers actively working on this project.**
It has so far been tested to work on Linux, OpenBSD and Windows.
**We currently do not provide releases for macOS because there aren't any macOS developers actively working on this project. Development builds are available**
### :heavy_exclamation_mark: Requirements
@@ -45,14 +56,14 @@ To build Strawberry from source you need the following installed on your system
* [POSIX thread (pthread)](http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html)
* [GLib](https://developer.gnome.org/glib/)
* [Protobuf library and compiler](https://developers.google.com/protocol-buffers/)
* [Qt 5.5 or higher with components Core, Gui, Widgets, Concurrent, Network and Sql](https://www.qt.io/)
* [Qt 5.6 or higher with components Core, Gui, Widgets, Concurrent, Network and Sql](https://www.qt.io/)
* [Qt 5 components X11Extras and DBus for Linux/BSD, MacExtras for macOS and WinExtras for Windows](https://www.qt.io/)
* [SQLite 3.9 or newer with FTS5](https://www.sqlite.org)
* [Chromaprint library](https://acoustid.org/chromaprint)
* [ALSA library (linux)](https://www.alsa-project.org/)
* [DBus (linux)](https://www.freedesktop.org/wiki/Software/dbus/)
* [PulseAudio (linux optional)](https://www.freedesktop.org/wiki/Software/PulseAudio/?)
* [GStreamer](https://gstreamer.freedesktop.org/), [Xine](https://www.xine-project.org), [VLC](https://www.videolan.org) or [Phonon](https://techbase.kde.org/Phonon)
* [GStreamer](https://gstreamer.freedesktop.org/), [Xine](https://www.xine-project.org) or [VLC](https://www.videolan.org)
* [GnuTLS](https://www.gnutls.org/)
Optional dependencies:
@@ -63,14 +74,14 @@ Optional dependencies:
* iPhone, iPod Touch, iPad and Apple TV devices: [libimobiledevice, libplist and libusbmuxd](https://www.libimobiledevice.org/)
* Moodbar: [fftw3](http://www.fftw.org/)
Either GStreamer, Xine, VLC or Phonon engine is required, but only GStreamer is fully implemented so far.
Either GStreamer, Xine or VLC engine is required, but only GStreamer is fully implemented so far.
You should also install the gstreamer plugins base and good, and optionally bad and ugly.
### :wrench: Compiling from source
### Get the code:
git clone https://github.com/jonaski/strawberry
git clone https://github.com/strawberrymusicplayer/strawberry
### Compile and install:
@@ -84,11 +95,3 @@ You should also install the gstreamer plugins base and good, and optionally bad
[![Packaging status](https://repology.org/badge/vertical-allrepos/strawberry.svg)](https://repology.org/metapackage/strawberry/versions)
### :computer: Screenshot
![Browse](https://www.strawberrymusicplayer.org/pictures/screenshot-002-large.png)
### :moneybag: Donate
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FRJUYV5QP6HW8)

View File

@@ -1,9 +0,0 @@
# Hacky stuff to make C++11 features work with old compilers.
if (CMAKE_COMPILER_IS_GNUCC)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
if (GCC_VERSION VERSION_LESS 4.7)
add_definitions(-Doverride=)
endif()
endif()

View File

@@ -1,5 +1,20 @@
add_custom_target(deb
COMMAND cp -r -p ${CMAKE_SOURCE_DIR}/debian ${CMAKE_BINARY_DIR}/
COMMAND dpkg-buildpackage -b -d -uc -us
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
find_program(LSB_RELEASE_EXEC lsb_release)
find_program(DPKG_BUILDPACKAGE dpkg-buildpackage)
if (LSB_RELEASE_EXEC AND DPKG_BUILDPACKAGE)
execute_process(COMMAND env LC_ALL=C date "+%a, %-d %b %Y %H:%M:%S %z" OUTPUT_VARIABLE DEB_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND /bin/sh "-c" "${LSB_RELEASE_EXEC} -cs"
OUTPUT_VARIABLE DEB_CODENAME
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (DEB_CODENAME)
configure_file(${CMAKE_SOURCE_DIR}/debian/changelog.in ${CMAKE_SOURCE_DIR}/debian/changelog)
add_custom_target(deb
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${DPKG_BUILDPACKAGE} -b -d -uc -us
)
endif()
endif()

View File

@@ -1,6 +1,6 @@
add_custom_target(dmg
COMMAND sudo /usr/local/opt/qt5/bin/macdeployqt strawberry.app
COMMAND sudo ${CMAKE_SOURCE_DIR}/dist/macos/macdeploy.py strawberry.app
COMMAND sudo ${CMAKE_SOURCE_DIR}/dist/macos/create-dmg.sh strawberry.app
COMMAND /usr/local/opt/qt5/bin/macdeployqt strawberry.app
COMMAND ${CMAKE_SOURCE_DIR}/dist/macos/macdeploy.py strawberry.app
COMMAND ${CMAKE_SOURCE_DIR}/dist/macos/create-dmg.sh strawberry.app
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

View File

@@ -2,6 +2,8 @@ find_program(LSB_RELEASE_EXEC lsb_release)
find_program(RPMBUILD_EXEC rpmbuild)
if (LSB_RELEASE_EXEC AND RPMBUILD_EXEC)
execute_process(COMMAND env LC_ALL="en_US.utf8" date "+%a %b %d %Y" OUTPUT_VARIABLE RPM_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND /bin/sh "-c" "${LSB_RELEASE_EXEC} -is | tr '[:upper:]' '[:lower:]' | cut -d' ' -f1"
OUTPUT_VARIABLE DIST_NAME
OUTPUT_STRIP_TRAILING_WHITESPACE
@@ -22,7 +24,6 @@ if (LSB_RELEASE_EXEC AND RPMBUILD_EXEC)
if (DIST_VERSION)
message(STATUS "Distro Version: ${DIST_VERSION}")
endif()
set(RPM_ARCH x86_64 CACHE STRING "Architecture of the rpm file")
set(RPMBUILD_DIR ~/rpmbuild CACHE STRING "Rpmbuild directory, for the rpm target")
if (${DIST_NAME} STREQUAL "opensuse")
if (DIST_RELEASE)
@@ -56,11 +57,12 @@ if (LSB_RELEASE_EXEC AND RPMBUILD_EXEC)
set(RPM_DISTRO ${DIST_NAME} CACHE STRING "Suffix of the rpm file")
endif()
message(STATUS "RPM Suffix: ${RPM_DISTRO}")
configure_file(${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec.in ${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec @ONLY)
add_custom_target(rpm
COMMAND ${CMAKE_SOURCE_DIR}/dist/scripts/maketarball.sh
COMMAND ${CMAKE_COMMAND} -E copy strawberry-${STRAWBERRY_VERSION_PACKAGE}.tar.xz ${RPMBUILD_DIR}/SOURCES/
COMMAND ${RPMBUILD_EXEC} -bs ${CMAKE_SOURCE_DIR}/dist/rpm/strawberry.spec
COMMAND ${RPMBUILD_EXEC} -bb ${CMAKE_SOURCE_DIR}/dist/rpm/strawberry.spec
COMMAND ${RPMBUILD_EXEC} -bs ${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec
COMMAND ${RPMBUILD_EXEC} -bb ${CMAKE_SOURCE_DIR}/dist/unix/strawberry.spec
)
endif()
endif()

View File

@@ -0,0 +1,9 @@
SET(CMAKE_SYSTEM_NAME Windows)
SET(HOME "$ENV{HOME}")
SET(CMAKE_C_COMPILER "${HOME}/mxe-shared/usr/bin/i686-w64-mingw32.shared-gcc")
SET(CMAKE_CXX_COMPILER "${HOME}/mxe-shared/usr/bin/i686-w64-mingw32.shared-g++")
SET(CMAKE_RC_COMPILER "${HOME}/mxe-shared/usr/bin/i686-w64-mingw32.shared-windres")
SET(CMAKE_FIND_ROOT_PATH "${HOME}/mxe-shared/usr/i686-w64-mingw32.shared/")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@@ -0,0 +1,9 @@
SET(CMAKE_SYSTEM_NAME Windows)
SET(HOME "$ENV{HOME}")
SET(CMAKE_C_COMPILER "${HOME}/mxe-shared/usr/bin/x86_64-w64-mingw32.shared-gcc")
SET(CMAKE_CXX_COMPILER "${HOME}/mxe-shared/usr/bin/x86_64-w64-mingw32.shared-g++")
SET(CMAKE_RC_COMPILER "${HOME}/mxe-shared/usr/bin/x86_64-w64-mingw32.shared-windres")
SET(CMAKE_FIND_ROOT_PATH "${HOME}/mxe-shared/usr/x86_64-w64-mingw32.shared/")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@@ -1,6 +1,6 @@
set(STRAWBERRY_VERSION_MAJOR 0)
set(STRAWBERRY_VERSION_MINOR 6)
set(STRAWBERRY_VERSION_PATCH 6)
set(STRAWBERRY_VERSION_PATCH 11)
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
set(INCLUDE_GIT_REVISION OFF)

View File

@@ -10,6 +10,9 @@
<file>schema/schema-7.sql</file>
<file>schema/schema-8.sql</file>
<file>schema/schema-9.sql</file>
<file>schema/schema-10.sql</file>
<file>schema/schema-11.sql</file>
<file>schema/schema-12.sql</file>
<file>schema/device-schema.sql</file>
<file>style/strawberry.css</file>
<file>html/playing-tooltip-plain.html</file>
@@ -39,5 +42,6 @@
<file>pictures/rainbowdash.png</file>
<file>fonts/HumongousofEternitySt.ttf</file>
<file>mood/sample.mood</file>
<file>text/ghosts.txt</file>
</qresource>
</RCC>

View File

@@ -90,7 +90,6 @@
<file>icons/128x128/love.png</file>
<file>icons/128x128/subsonic.png</file>
<file>icons/128x128/tidal.png</file>
<file>icons/128x128/qobuz.png</file>
<file>icons/64x64/albums.png</file>
<file>icons/64x64/alsa.png</file>
<file>icons/64x64/application-exit.png</file>
@@ -182,7 +181,6 @@
<file>icons/64x64/love.png</file>
<file>icons/64x64/subsonic.png</file>
<file>icons/64x64/tidal.png</file>
<file>icons/64x64/qobuz.png</file>
<file>icons/48x48/albums.png</file>
<file>icons/48x48/alsa.png</file>
<file>icons/48x48/application-exit.png</file>
@@ -205,6 +203,7 @@
<file>icons/48x48/document-download.png</file>
<file>icons/48x48/document-new.png</file>
<file>icons/48x48/document-open-folder.png</file>
<file>icons/48x48/document-open-remote.png</file>
<file>icons/48x48/document-open.png</file>
<file>icons/48x48/document-save.png</file>
<file>icons/48x48/document-search.png</file>
@@ -277,7 +276,6 @@
<file>icons/48x48/love.png</file>
<file>icons/48x48/subsonic.png</file>
<file>icons/48x48/tidal.png</file>
<file>icons/48x48/qobuz.png</file>
<file>icons/32x32/albums.png</file>
<file>icons/32x32/alsa.png</file>
<file>icons/32x32/application-exit.png</file>
@@ -300,6 +298,7 @@
<file>icons/32x32/document-download.png</file>
<file>icons/32x32/document-new.png</file>
<file>icons/32x32/document-open-folder.png</file>
<file>icons/32x32/document-open-remote.png</file>
<file>icons/32x32/document-open.png</file>
<file>icons/32x32/document-save.png</file>
<file>icons/32x32/document-search.png</file>
@@ -372,7 +371,6 @@
<file>icons/32x32/love.png</file>
<file>icons/32x32/subsonic.png</file>
<file>icons/32x32/tidal.png</file>
<file>icons/32x32/qobuz.png</file>
<file>icons/22x22/albums.png</file>
<file>icons/22x22/alsa.png</file>
<file>icons/22x22/application-exit.png</file>
@@ -395,6 +393,7 @@
<file>icons/22x22/document-download.png</file>
<file>icons/22x22/document-new.png</file>
<file>icons/22x22/document-open-folder.png</file>
<file>icons/22x22/document-open-remote.png</file>
<file>icons/22x22/document-open.png</file>
<file>icons/22x22/document-save.png</file>
<file>icons/22x22/document-search.png</file>
@@ -467,6 +466,5 @@
<file>icons/22x22/love.png</file>
<file>icons/22x22/subsonic.png</file>
<file>icons/22x22/tidal.png</file>
<file>icons/22x22/qobuz.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -11,25 +11,25 @@ CREATE TABLE device_%deviceid_subdirectories (
CREATE TABLE device_%deviceid_songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,

25
data/schema/schema-10.sql Normal file
View File

@@ -0,0 +1,25 @@
DROP TABLE IF EXISTS tidal_artists_songs;
DROP TABLE IF EXISTS tidal_albums_songs;
DROP TABLE IF EXISTS tidal_songs;
DROP TABLE IF EXISTS qobuz_artists_songs;
DROP TABLE IF EXISTS qobuz_albums_songs;
DROP TABLE IF EXISTS qobuz_songs;
DROP TABLE IF EXISTS tidal_artists_songs_fts;
DROP TABLE IF EXISTS tidal_albums_songs_fts;
DROP TABLE IF EXISTS tidal_songs_fts;
DROP TABLE IF EXISTS qobuz_artists_songs_fts;
DROP TABLE IF EXISTS qobuz_albums_songs_fts;
DROP TABLE IF EXISTS qobuz_songs_fts;
UPDATE schema_version SET version=10;

247
data/schema/schema-11.sql Normal file
View File

@@ -0,0 +1,247 @@
DROP VIEW IF EXISTS duplicated_songs;
DROP INDEX IF EXISTS idx_url;
DROP INDEX IF EXISTS idx_comp_artist;
DROP INDEX IF EXISTS idx_albumartist;
DROP INDEX IF EXISTS idx_artist;
DROP INDEX IF EXISTS idx_album;
DROP INDEX IF EXISTS idx_title;
ALTER TABLE songs RENAME TO songs_old;
ALTER TABLE subsonic_songs RENAME TO subsonic_songs_old;
ALTER TABLE playlist_items RENAME TO playlist_items_old;
CREATE TABLE songs (
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL DEFAULT -1,
url TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL DEFAULT -1,
mtime INTEGER NOT NULL DEFAULT -1,
ctime INTEGER NOT NULL DEFAULT -1,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
cue_path TEXT
);
CREATE INDEX IF NOT EXISTS idx_url ON songs (url);
CREATE INDEX IF NOT EXISTS idx_comp_artist ON songs (compilation_effective, artist);
CREATE INDEX IF NOT EXISTS idx_albumartist ON songs (albumartist);
CREATE INDEX IF NOT EXISTS idx_artist ON songs (artist);
CREATE INDEX IF NOT EXISTS idx_album ON songs (album);
CREATE INDEX IF NOT EXISTS idx_title ON songs (title);
CREATE VIEW duplicated_songs as select artist dup_artist, album dup_album, title dup_title from songs as inner_songs where artist != '' and album != '' and title != '' and unavailable = 0 group by artist, album , title having count(*) > 1;
CREATE TABLE subsonic_songs (
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL DEFAULT -1,
url TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL DEFAULT -1,
mtime INTEGER NOT NULL DEFAULT -1,
ctime INTEGER NOT NULL DEFAULT -1,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
cue_path TEXT
);
INSERT INTO songs (ROWID, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path)
SELECT ROWID, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path
FROM songs_old;
DROP TABLE songs_old;
DELETE FROM songs_fts;
INSERT INTO songs_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment
FROM songs;
INSERT INTO subsonic_songs (ROWID, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path)
SELECT ROWID, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path
FROM subsonic_songs_old;
DROP TABLE subsonic_songs_old;
DELETE FROM subsonic_songs_fts;
INSERT INTO subsonic_songs_fts (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment
FROM subsonic_songs;
CREATE TABLE playlist_items (
playlist INTEGER NOT NULL,
type INTEGER NOT NULL DEFAULT 0,
collection_id INTEGER,
playlist_url TEXT,
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER,
disc INTEGER,
year INTEGER,
originalyear INTEGER,
genre TEXT,
compilation INTEGER DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER,
length INTEGER,
bitrate INTEGER,
samplerate INTEGER,
bitdepth INTEGER,
source INTEGER,
directory_id INTEGER,
url TEXT,
filetype INTEGER,
filesize INTEGER,
mtime INTEGER,
ctime INTEGER,
unavailable INTEGER DEFAULT 0,
playcount INTEGER DEFAULT 0,
skipcount INTEGER DEFAULT 0,
lastplayed INTEGER DEFAULT 0,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER DEFAULT 0,
compilation_off INTEGER DEFAULT 0,
compilation_effective INTEGER DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER,
cue_path TEXT
);
INSERT INTO playlist_items (ROWID, playlist, type, collection_id, playlist_url, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path)
SELECT ROWID, playlist, type, collection_id, playlist_url, title, album, artist, albumartist, track, disc, year, originalyear, genre, compilation, composer, performer, grouping, comment, lyrics, artist_id, album_id, song_id, beginning, length, bitrate, samplerate, bitdepth, source, directory_id, url, filetype, filesize, mtime, ctime, unavailable, playcount, skipcount, lastplayed, compilation_detected, compilation_on, compilation_off, compilation_effective, art_automatic, art_manual, effective_albumartist, effective_originalyear, cue_path
FROM playlist_items_old;
DROP TABLE playlist_items_old;
DELETE FROM playlist_items_fts_;
INSERT INTO playlist_items_fts_ (ROWID, ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsperformer, ftsgrouping, ftsgenre, ftscomment)
SELECT ROWID, title, album, artist, albumartist, composer, performer, grouping, genre, comment
FROM playlist_items;
UPDATE schema_version SET version=11;

217
data/schema/schema-12.sql Normal file
View File

@@ -0,0 +1,217 @@
CREATE TABLE IF NOT EXISTS tidal_artists_songs (
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL DEFAULT -1,
url TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL DEFAULT -1,
mtime INTEGER NOT NULL DEFAULT -1,
ctime INTEGER NOT NULL DEFAULT -1,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
cue_path TEXT
);
CREATE TABLE IF NOT EXISTS tidal_albums_songs (
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL DEFAULT -1,
url TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL DEFAULT -1,
mtime INTEGER NOT NULL DEFAULT -1,
ctime INTEGER NOT NULL DEFAULT -1,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
cue_path TEXT
);
CREATE TABLE IF NOT EXISTS tidal_songs (
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL DEFAULT -1,
url TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL DEFAULT -1,
mtime INTEGER NOT NULL DEFAULT -1,
ctime INTEGER NOT NULL DEFAULT -1,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
cue_path TEXT
);
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_artists_songs_fts USING fts5(
ftstitle,
ftsalbum,
ftsartist,
ftsalbumartist,
ftscomposer,
ftsperformer,
ftsgrouping,
ftsgenre,
ftscomment,
tokenize = "unicode61 remove_diacritics 0"
);
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_albums_songs_fts USING fts5(
ftstitle,
ftsalbum,
ftsartist,
ftsalbumartist,
ftscomposer,
ftsperformer,
ftsgrouping,
ftsgenre,
ftscomment,
tokenize = "unicode61 remove_diacritics 0"
);
CREATE VIRTUAL TABLE IF NOT EXISTS tidal_songs_fts USING fts5(
ftstitle,
ftsalbum,
ftsartist,
ftsalbumartist,
ftscomposer,
ftsperformer,
ftsgrouping,
ftsgenre,
ftscomment,
tokenize = "unicode61 remove_diacritics 0"
);
UPDATE schema_version SET version=12;

View File

@@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS schema_version (
DELETE FROM schema_version;
INSERT INTO schema_version (version) VALUES (9);
INSERT INTO schema_version (version) VALUES (12);
CREATE TABLE IF NOT EXISTS directories (
path TEXT NOT NULL,
@@ -19,25 +19,25 @@ CREATE TABLE IF NOT EXISTS subdirectories (
CREATE TABLE IF NOT EXISTS songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@@ -76,25 +76,25 @@ CREATE TABLE IF NOT EXISTS songs (
CREATE TABLE IF NOT EXISTS tidal_artists_songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@@ -133,25 +133,25 @@ CREATE TABLE IF NOT EXISTS tidal_artists_songs (
CREATE TABLE IF NOT EXISTS tidal_albums_songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@@ -190,25 +190,25 @@ CREATE TABLE IF NOT EXISTS tidal_albums_songs (
CREATE TABLE IF NOT EXISTS tidal_songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@@ -247,196 +247,25 @@ CREATE TABLE IF NOT EXISTS tidal_songs (
CREATE TABLE IF NOT EXISTS subsonic_songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
genre TEXT,
compilation INTEGER NOT NULL DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL DEFAULT -1,
url TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL DEFAULT -1,
mtime INTEGER NOT NULL DEFAULT -1,
ctime INTEGER NOT NULL DEFAULT -1,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
cue_path TEXT
);
CREATE TABLE IF NOT EXISTS qobuz_artists_songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL DEFAULT -1,
url TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL DEFAULT -1,
mtime INTEGER NOT NULL DEFAULT -1,
ctime INTEGER NOT NULL DEFAULT -1,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
cue_path TEXT
);
CREATE TABLE IF NOT EXISTS qobuz_albums_songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
source INTEGER NOT NULL DEFAULT 0,
directory_id INTEGER NOT NULL DEFAULT -1,
url TEXT NOT NULL,
filetype INTEGER NOT NULL DEFAULT 0,
filesize INTEGER NOT NULL DEFAULT -1,
mtime INTEGER NOT NULL DEFAULT -1,
ctime INTEGER NOT NULL DEFAULT -1,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
cue_path TEXT
);
CREATE TABLE IF NOT EXISTS qobuz_songs (
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
@@ -491,56 +320,56 @@ CREATE TABLE IF NOT EXISTS playlist_items (
collection_id INTEGER,
playlist_url TEXT,
title TEXT NOT NULL,
album TEXT NOT NULL,
artist TEXT NOT NULL,
albumartist TEXT NOT NULL,
track INTEGER NOT NULL DEFAULT -1,
disc INTEGER NOT NULL DEFAULT -1,
year INTEGER NOT NULL DEFAULT -1,
originalyear INTEGER NOT NULL DEFAULT 0,
genre TEXT NOT NULL,
compilation INTEGER NOT NULL DEFAULT -1,
composer TEXT NOT NULL,
performer TEXT NOT NULL,
grouping TEXT NOT NULL,
comment TEXT NOT NULL,
lyrics TEXT NOT NULL,
title TEXT,
album TEXT,
artist TEXT,
albumartist TEXT,
track INTEGER,
disc INTEGER,
year INTEGER,
originalyear INTEGER,
genre TEXT,
compilation INTEGER DEFAULT 0,
composer TEXT,
performer TEXT,
grouping TEXT,
comment TEXT,
lyrics TEXT,
artist_id INTEGER NOT NULL DEFAULT -1,
album_id TEXT NOT NULL,
song_id INTEGER NOT NULL DEFAULT -1,
artist_id TEXT,
album_id TEXT,
song_id TEXT,
beginning INTEGER NOT NULL DEFAULT 0,
length INTEGER NOT NULL DEFAULT 0,
beginning INTEGER,
length INTEGER,
bitrate INTEGER NOT NULL DEFAULT -1,
samplerate INTEGER NOT NULL DEFAULT -1,
bitdepth INTEGER NOT NULL DEFAULT -1,
bitrate INTEGER,
samplerate INTEGER,
bitdepth INTEGER,
source INTEGER NOT NULL DEFAULT 0,
source INTEGER,
directory_id INTEGER,
url TEXT,
filetype INTEGER NOT NULL DEFAULT 0,
filetype INTEGER,
filesize INTEGER,
mtime INTEGER,
ctime INTEGER,
unavailable INTEGER DEFAULT 0,
playcount INTEGER NOT NULL DEFAULT 0,
skipcount INTEGER NOT NULL DEFAULT 0,
lastplayed INTEGER NOT NULL DEFAULT -1,
playcount INTEGER DEFAULT 0,
skipcount INTEGER DEFAULT 0,
lastplayed INTEGER DEFAULT 0,
compilation_detected INTEGER DEFAULT 0,
compilation_on INTEGER NOT NULL DEFAULT 0,
compilation_off INTEGER NOT NULL DEFAULT 0,
compilation_effective INTEGER NOT NULL DEFAULT 0,
compilation_on INTEGER DEFAULT 0,
compilation_off INTEGER DEFAULT 0,
compilation_effective INTEGER DEFAULT 0,
art_automatic TEXT,
art_manual TEXT,
effective_albumartist TEXT,
effective_originalyear INTEGER NOT NULL DEFAULT 0,
effective_originalyear INTEGER,
cue_path TEXT
@@ -645,51 +474,6 @@ CREATE VIRTUAL TABLE IF NOT EXISTS subsonic_songs_fts USING fts5(
);
CREATE VIRTUAL TABLE IF NOT EXISTS qobuz_artists_songs_fts USING fts5(
ftstitle,
ftsalbum,
ftsartist,
ftsalbumartist,
ftscomposer,
ftsperformer,
ftsgrouping,
ftsgenre,
ftscomment,
tokenize = "unicode61 remove_diacritics 0"
);
CREATE VIRTUAL TABLE IF NOT EXISTS qobuz_albums_songs_fts USING fts5(
ftstitle,
ftsalbum,
ftsartist,
ftsalbumartist,
ftscomposer,
ftsperformer,
ftsgrouping,
ftsgenre,
ftscomment,
tokenize = "unicode61 remove_diacritics 0"
);
CREATE VIRTUAL TABLE IF NOT EXISTS qobuz_songs_fts USING fts5(
ftstitle,
ftsalbum,
ftsartist,
ftsalbumartist,
ftscomposer,
ftsperformer,
ftsgrouping,
ftsgenre,
ftscomment,
tokenize = "unicode61 remove_diacritics 0"
);
CREATE VIRTUAL TABLE IF NOT EXISTS playlist_items_fts_ USING fts5(
ftstitle,

View File

@@ -52,19 +52,14 @@ macos QMenu {
font-size: 13pt;
}
#scrollarea_play {
#context-layout-container {
background-color: %palette-base;
font: 11pt;
}
#scrollarea_stop {
#context-widget-scrollarea {
background-color: %palette-base;
font: 11pt;
}
#scrollAreaWidgetContents_stop {
background-color: %palette-base;
}
#scrollAreaWidgetContents_play {
#context-layout-scrollarea {
background-color: %palette-base;
}

42
data/text/ghosts.txt Normal file
View File

@@ -0,0 +1,42 @@
Go to sleep my babies
Don't you wake up
The stars will keep you company
So close your eyes
Old Uncle Moon will shine his dearest sweetest dreams
And hold you in your arms
Until the morning comes.
Night Light
Dark the night, not a sound
Damp and cold, frosty ground
Above your head the lion screams
To tear you from your moonlit dreams.
Damp with sweat, mouth is dry
Twisted branches catch the eye
Beside your bed the angel stands
You cannot touch his withered hands.
Guardian Angel
As the lion's eyes dance before me
They are kindly yet bloody red
I can see that he is smiling
But I cannot live inside his head.
There the needle stands before me
I climb inside it towards the light
Where the angel stands in glory
His sword of peace defends the night.
So the world is spread before
As I fly high on angel wings
But the angel is deceiving
For he is weeping as he sings.
Night Light (continued)
Early birds, morning breeze
Spinning leaves, sleepy trees
Gently tap the window pane
It's good to see the sun again.
(Dave Cousins)

2
debian/changelog.in vendored
View File

@@ -1,4 +1,4 @@
strawberry (${STRAWBERRY_VERSION_DISPLAY}) unstable; urgency=low
strawberry (${STRAWBERRY_VERSION_DISPLAY}-${DEB_CODENAME}) ${DEB_CODENAME}; urgency=low
* Version ${STRAWBERRY_VERSION_DISPLAY}

2
debian/compat vendored
View File

@@ -1 +1 @@
9
11

12
debian/control vendored
View File

@@ -2,7 +2,7 @@ Source: strawberry
Section: sound
Priority: optional
Maintainer: Jonas Kvinge <jonas@jkvinge.net>
Build-Depends: debhelper (>= 7),
Build-Depends: debhelper (>= 11),
make,
cmake,
gcc,
@@ -16,10 +16,8 @@ Build-Depends: debhelper (>= 7),
libasound2-dev,
libpulse-dev,
libtag1-dev,
libqt5-dev,
qtbase5-dev,
qtbase5-dev-tools,
qtbase5-private-dev,
qttools5-dev,
libqt5x11extras5-dev,
libgstreamer1.0-dev,
@@ -32,7 +30,7 @@ Build-Depends: debhelper (>= 7),
libusbmuxd-dev,
libchromaprint-dev,
libfftw3-dev
Standards-Version: 3.9.8
Standards-Version: 4.2.1
Package: strawberry
Architecture: any
@@ -57,13 +55,13 @@ Description: Audio player and music collection organizer
- Advanced audio output and device configuration for bit-perfect playback on Linux
- Edit tags on music files
- Fetch tags from MusicBrainz
- Album cover art from Lastfm, Musicbrainz, Discogs, Deezer and Tidal
- Song lyrics from AudD, lyrics.ovh and lololyrics.com
- Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify
- Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com
- Support for multiple backends
- Audio analyzer
- Audio equalizer
- Transfer music to iPod, iPhone, MTP or mass-storage USB player
- Streaming support for Tidal, Qobuz and Subsonic
- Scrobbler with support for Last.fm, Libre.fm and ListenBrainz
- Streaming support for Subsonic
.
It is a fork of Clementine. The name is inspired by the band Strawbs.

89
debian/copyright vendored
View File

@@ -17,36 +17,59 @@ Copyright: 2011, 2012, David Sansome <me@davidsansome.com>
License: Apache-2.0
Files: src/core/main.h
src/core/iconloader.cpp
src/core/iconloader.h
src/core/iconmapper.h
src/config.h.in
src/version.h.in
src/context/contextview.cpp
src/context/contextview.h
src/context/contextalbum.cpp
src/context/contextalbum.h
src/engine/enginetype.cpp
src/engine/enginetype.h
src/engine/alsadevicefinder.cpp
src/engine/alsadevicefinder.h
src/engine/mmdevicefinder.cpp
src/engine/mmdevicefinder.h
src/engine/devicefinder.cpp
src/engine/devicefinder.h
src/engine/enginedevice.cpp
src/engine/enginedevice.h
src/engine/phononengine.cpp
src/engine/phononengine.h
src/internet/internetservice.cpp
src/internet/internetservice.h
src/internet/internettabsview.cpp
src/internet/internettabsview.h
src/internet/internetsongsview.cpp
src/internet/internetsongsview.h
src/settings/backendsettingspage.cpp
src/settings/backendsettingspage.h
src/settings/coverssettingspage.cpp
src/settings/coverssettingspage.h
src/settings/lyricssettingspage.cpp
src/settings/lyricssettingspage.h
src/settings/scrobblersettingspage.cpp
src/settings/scrobblersettingspage.h
src/settings/subsonicsettingspage.cpp
src/settings/subsonicsettingspage.h
src/settings/tidalsettingspage.cpp
src/settings/tidalsettingspage.h
src/covermanager/jsoncoverprovider.cpp
src/covermanager/jsoncoverprovider.h
src/covermanager/lastfmcoverprovider.cpp
src/covermanager/lastfmcoverprovider.h
src/covermanager/musicbrainzcoverprovider.cpp
src/covermanager/musicbrainzcoverprovider.h
src/covermanager/tidalcoverprovider.cpp
src/covermanager/tidalcoverprovider.h
src/covermanager/deezercoverprovider.cpp
src/covermanager/deezercoverprovider.h
src/covermanager/tidalcoverprovider.cpp
src/covermanager/tidalcoverprovider.h
src/covermanager/qobuzcoverprovider.cpp
src/covermanager/qobuzcoverprovider.h
src/covermanager/spotifycoverprovider.cpp
src/covermanager/spotifycoverprovider.h
src/covermanager/musixmatchcoverprovider.cpp
src/covermanager/musixmatchcoverprovider.h
src/globalshortcuts/globalshortcutbackend-system.cpp
src/globalshortcuts/globalshortcutbackend-system.h
src/globalshortcuts/globalshortcut.cpp
@@ -57,12 +80,11 @@ Files: src/core/main.h
src/globalshortcuts/keymapper_win.h
src/lyrics/*
src/scrobbler/*
src/tidal/*
src/qobuz/*
src/subsonic/*
src/tidal/*
src/transcoder/transcoderoptionswavpack.cpp
src/transcoder/transcoderoptionswavpack.h
Copyright: 2012-2014, 2017-2019, Jonas Kvinge <jonas@jkvinge.net>
Copyright: 2012-2014, 2017-2020, Jonas Kvinge <jonas@jkvinge.net>
License: GPL-3+
Files: src/core/main.cpp
@@ -72,28 +94,50 @@ Files: src/core/main.cpp
src/core/player.h
src/core/song.cpp
src/core/song.h
src/core/songloader.cpp
src/core/songloader.h
src/core/urlhandler.cpp
src/core/urlhandler.h
src/core/utilities.cpp
src/core/utilities.h
src/core/iconloader.cpp
src/core/iconloader.h
src/core/network.cpp
src/core/network.h
src/core/filesystemmusicstorage.cpp
src/core/filesystemmusicstorage.h
src/core/stylesheetloader.cpp
src/core/stylesheetloader.h
src/engine/gstenginepipeline.cpp
src/engine/gstenginepipeline.h
src/engine/vlcengine.cpp
src/engine/vlcengine.h
src/collection/collectionwatcher.cpp
src/collection/collectionwatcher.h
src/collection/collectionbackend.cpp
src/collection/collectionbackend.h
src/collection/collectionmodel.cpp
src/collection/collectionmodel.h
src/context/contextalbumsmodel.cpp
src/context/contextalbumsview.cpp
src/context/contextalbumsmodel.h
src/context/contextalbumsview.h
src/widgets/playingwidget.cpp
src/widgets/playingwidget.h
src/widgets/osdpretty.cpp
src/widgets/osdpretty.h
src/dialogs/about.cpp
src/dialogs/about.h
src/playlist/playlist.cpp
src/playlist/playlist.h
src/playlist/playlistitem.cpp
src/playlist/playlistitem.h
src/playlist/playlistdelegates.cpp
src/playlist/playlistdelegates.h
src/playlist/playlistbackend.cpp
src/playlist/playlistbackend.h
src/playlist/playlistview.cpp
src/playlist/playlistview.h
src/playlist/songplaylistitem.cpp
src/playlist/songplaylistitem.h
src/internet/internetplaylistitem.cpp
src/internet/internetsearch.cpp
src/internet/internetsearch.h
@@ -101,6 +145,10 @@ Files: src/core/main.cpp
src/internet/internetsearchview.h
src/internet/internetservices.cpp
src/internet/internetservices.h
src/internet/internetsongsview.cpp
src/internet/internetsongsview.h
src/internet/internetcollectionview.cpp
src/internet/internetcollectionview.h
ext/libstrawberry-tagreader/tagreader.cpp
ext/libstrawberry-tagreader/tagreader.h
src/device/devicemanager.cpp
@@ -113,10 +161,16 @@ Files: src/core/main.cpp
src/device/deviceview.h
src/device/connecteddevice.cpp
src/device/connecteddevice.h
src/device/mtpconnection.cpp
src/device/mtpconnection.h
src/device/mtpdevice.cpp
src/device/mtpdevice.h
src/globalshortcuts/globalshortcuts.cpp
src/globalshortcuts/globalshortcuts.h
src/settings/shortcutssettingspage.cpp
src/settings/shortcutssettingspage.h
src/settings/appearancesettingspage.cpp
src/settings/appearancesettingspage.h
src/organise/organise.cpp
src/organise/organise.h
src/organise/organisedialog.cpp
@@ -125,8 +179,22 @@ Files: src/core/main.cpp
src/organise/organiseerrordialog.h
src/transcoder/transcoder.cpp
src/transcoder/transcoder.h
src/musicbrainz/musicbrainzclient.cpp
src/musicbrainz/musicbrainzclient.h
src/covermanager/albumcoverloader.cpp
src/covermanager/albumcoverloader.h
src/covermanager/currentalbumcoverloader.cpp
src/covermanager/currentalbumcoverloader.h
src/covermanager/albumcoverchoicecontroller.cpp
src/covermanager/albumcoverchoicecontroller.h
src/covermanager/albumcoverfetchersearch.cpp
src/covermanager/albumcoverfetchersearch.h
src/covermanager/coverproviders.cpp
src/covermanager/coverproviders.h
src/covermanager/coverprovider.cpp
src/covermanager/coverprovider.h
Copyright: 2010, 2012-2014 David Sansome <me@davidsansome.com>
2012-2014, 2017-2018 Jonas Kvinge <jonas@jkvinge.net>
2012-2014, 2017-2020 Jonas Kvinge <jonas@jkvinge.net>
License: GPL-3+
Files: src/engine/enginebase.cpp
@@ -262,6 +330,7 @@ Files: src/internet/localredirectserver.cpp
src/internet/localredirectserver.h
Copyright: 2012, 2014, John Maguire <john.maguire@gmail.com>
2014, Krzysztof Sobiecki <sobkas@gmail.com>
2018-2019, Jonas Kvinge <jonas@jkvinge.net>
License: GPL-3+
Files: src/transcoder/transcoderoptionsopus.cpp

View File

@@ -11,7 +11,9 @@ ignore:
- /cmake/
- /data/
- /dist/
- /snap/
suffixes:
- jpg
- png
- gif

70
debian/rules vendored
View File

@@ -1,61 +1,19 @@
#!/usr/bin/make -f
# -*- makefile -*-
MY_MAKEFLAGS=
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
NUMJOBS=$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
MY_MAKEFLAGS=-j$(NUMJOBS)
endif
%:
dh $@ --buildsystem=cmake -builddirectory=build
configure: configure-stamp
configure-stamp:
dh_testdir
cmake .. \
-DCMAKE_INSTALL_PREFIX=$(CURDIR)/debian/strawberry/usr
touch configure-stamp
override_dh_auto_clean:
rm -f dist/macos/Info.plist
rm -f dist/macos/create-dmg.sh
rm -f dist/unix/PKGBUILD
rm -f dist/unix/strawberry.spec
rm -f dist/scripts/maketarball.sh
rm -f dist/windows/strawberry.nsi
rm -f src/translations/translations.pot
dh_auto_clean
build: build-stamp
build-stamp: configure-stamp
dh_testdir
make $(MY_MAKEFLAGS)
touch $@
override_dh_installchangelogs:
dh_installchangelogs Changelog
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
-make clean
-rm Makefile src/Makefile
dh_clean
install: build
dh_testdir
dh_testroot
dh_prep
dh_installdirs
make install
binary-indep: install
binary-arch: install
dh_testdir
dh_testroot
dh_installchangelogs
dh_installmenu
dh_installdocs
dh_gconf
dh_link
dh_strip
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure
override_dh_auto_test:

25
dist/CMakeLists.txt vendored
View File

@@ -1,15 +1,14 @@
execute_process(COMMAND env LC_ALL="en_US.utf8" date "+%a %b %d %Y" OUTPUT_VARIABLE RPM_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND env LC_ALL=C date "+%a, %-d %b %Y %H:%M:%S %z" OUTPUT_VARIABLE DEB_DATE OUTPUT_STRIP_TRAILING_WHITESPACE)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/maketarball.sh.in ${CMAKE_CURRENT_SOURCE_DIR}/scripts/maketarball.sh @ONLY)
if (RPM_DISTRO)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/rpm/strawberry.spec.in ${CMAKE_CURRENT_SOURCE_DIR}/rpm/strawberry.spec @ONLY)
endif()
configure_file(${CMAKE_SOURCE_DIR}/debian/changelog.in ${CMAKE_SOURCE_DIR}/debian/changelog)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pacman/PKGBUILD.in ${CMAKE_CURRENT_SOURCE_DIR}/pacman/PKGBUILD @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/macos/create-dmg.sh.in ${CMAKE_CURRENT_SOURCE_DIR}/macos/create-dmg.sh)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/windows/strawberry.nsi.in ${CMAKE_CURRENT_SOURCE_DIR}/windows/strawberry.nsi @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unix/PKGBUILD.in ${CMAKE_CURRENT_SOURCE_DIR}/unix/PKGBUILD @ONLY)
if (APPLE)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist.in ${CMAKE_CURRENT_SOURCE_DIR}/macos/Info.plist)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/macos/create-dmg.sh.in ${CMAKE_CURRENT_SOURCE_DIR}/macos/create-dmg.sh)
endif (APPLE)
if (WIN32)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/windows/strawberry.nsi.in ${CMAKE_CURRENT_SOURCE_DIR}/windows/strawberry.nsi @ONLY)
endif (WIN32)
if (UNIX AND NOT APPLE)
install(FILES ../data/icons/48x48/strawberry.png DESTINATION share/icons/hicolor/48x48/apps/)
@@ -17,8 +16,8 @@ if (UNIX AND NOT APPLE)
install(FILES ../data/icons/128x128/strawberry.png DESTINATION share/icons/hicolor/128x128/apps/)
install(FILES unix/org.strawberrymusicplayer.strawberry.desktop DESTINATION share/applications)
install(FILES unix/org.strawberrymusicplayer.strawberry.appdata.xml DESTINATION share/metainfo)
install(FILES man/strawberry.1 man/strawberry-tagreader.1 DESTINATION share/man/man1)
endif()
install(FILES unix/strawberry.1 unix/strawberry-tagreader.1 DESTINATION share/man/man1)
endif (UNIX AND NOT APPLE)
if (APPLE)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../dist/macos/Info.plist" DESTINATION "${CMAKE_BINARY_DIR}/strawberry.app/Contents")

View File

@@ -304,10 +304,9 @@ def CopyLibrary(path):
new_path = os.path.join(frameworks_dir, os.path.basename(path))
#args = ['cp', path, new_path]
args = ['ditto', '--arch=i386', '--arch=x86_64', path, new_path]
commands.append(args)
commands.append(['chmod', '+w', new_path])
LOGGER.info("Copying library '%s'", path)
commands.append(args)
args = ['chmod', 'u+w', new_path]
commands.append(args)
return new_path
@@ -318,9 +317,8 @@ def CopyPlugin(path, subdir):
#args = ['cp', path, new_path]
args = ['ditto', '--arch=i386', '--arch=x86_64', path, new_path]
commands.append(args)
commands.append(['chmod', '+w', new_path])
LOGGER.info("Copying plugin '%s'", path)
args = ['chmod', 'u+w', new_path]
commands.append(args)
return new_path
def CopyFramework(path):
@@ -351,6 +349,7 @@ def CopyFramework(src_binary):
commands.append(['mkdir', '-p', dest_dir])
commands.append(['cp', src_binary, dest_binary])
commands.append(['chmod', '+w', dest_binary])
# Copy special files from various places:
# QtCore has Resources/qt_menu.nib (copy to app's Resources)
@@ -472,7 +471,7 @@ def FindGioModule(name):
def main():
logging.basicConfig(filename='macdeploy.log', level=logging.DEBUG, format='%(asctime)s %(levelname)-8s %(message)s')
#FixBinary(binary)
FixBinary(binary)
try:
FixPlugin('strawberry-tagreader', '.')

View File

@@ -16,24 +16,27 @@ echo "Creating $name-$version.tar.xz..."
rm -f "$name-$version.tar.xz"
tar -cJf $name-$version.tar.xz \
--transform "s,^$rootnoslash,$name-$version," $exclude_vcs \
--exclude=".directory" \
--exclude="*.tar" \
--exclude="*.tar.*" \
--exclude="*.bz" \
--exclude="*.bz2" \
--exclude="*.xz" \
--exclude=".directory" \
--exclude="*.spec" \
--exclude="*.nsi" \
--exclude="*.kdev4" \
--exclude=".vscode" \
--exclude="$root/.github" \
--exclude="$root/Dockerfile" \
--exclude="$root/.travis.yml" \
--exclude="$root/.circleci" \
--exclude="$root/Dockerfile" \
--exclude="$root/CMakeLists.txt.user" \
--exclude="$root/build" \
--exclude="$root/zanata.xml" \
--exclude="$root/.zanata-cache" \
--exclude="$root/debian/changelog" \
--exclude="$root/dist/scripts/maketarball.sh" \
--exclude="$root/dist/pacman/PKGBUILD" \
--exclude="$root/dist/unix/PKGBUILD" \
--exclude="$root/dist/macos/create-dmg.sh" \
--exclude="$root/dist/macos/Info.plist" \
--exclude="$root/dist/windows/windres.rc" \

View File

@@ -32,7 +32,6 @@ depends=(
libusbmuxd
libplist
libimobiledevice
phonon-qt5
fftw
)
optdepends=(
@@ -54,7 +53,6 @@ build() {
cmake ../${pkgname}-@STRAWBERRY_VERSION_PACKAGE@ \
-DCMAKE_INSTALL_PREFIX=/usr \
-DUSE_SYSTEM_TAGLIB=ON \
-DENABLE_PHONON=ON \
-DENABLE_TRANSLATIONS=ON
make -j$(nproc)
}

View File

@@ -11,7 +11,7 @@
<name>Strawberry Music Player</name>
<summary>A music player and collection organizer</summary>
<url type="homepage">https://www.strawberrymusicplayer.org/</url>
<url type="bugtracker">https://github.com/jonaski/strawberry/</url>
<url type="bugtracker">https://github.com/strawberrymusicplayer/strawberry/</url>
<translation type="qt">strawberry</translation>
<description>
<p>
@@ -26,13 +26,13 @@
<li>Advanced audio output and device configuration for bit-perfect playback on Linux</li>
<li>Edit tags on music files</li>
<li>Fetch tags from MusicBrainz</li>
<li>Album cover art from Last.fm, Musicbrainz and Discogs</li>
<li>Song lyrics from AudD, lyrics.ovh and lololyrics.com</li>
<li>Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify</li>
<li>Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com</li>
<li>Support for multiple backends</li>
<li>Audio analyzer and equalizer</li>
<li>Transfer music to iPod, iPhone, MTP or mass-storage USB player</li>
<li>Streaming support for Tidal, Qobuz and Subsonic</li>
<li>Scrobbler with support for Last.fm, Libre.fm and ListenBrainz</li>
<li>Streaming support for Subsonic</li>
</ul>
</description>
<screenshots>

View File

@@ -11,3 +11,4 @@ Terminal=false
Categories=AudioVideo;Player;Qt;Audio;
StartupNotify=false
MimeType=x-content/audio-player;application/ogg;application/x-ogg;application/x-ogm-audio;audio/flac;audio/ogg;audio/vorbis;audio/aac;audio/mp4;audio/mpeg;audio/mpegurl;audio/vnd.rn-realaudio;audio/x-flac;audio/x-oggflac;audio/x-vorbis;audio/x-vorbis+ogg;audio/x-speex;audio/x-wav;audio/x-wavpack;audio/x-ape;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-musepack;audio/x-pn-realaudio;audio/x-scpls;video/x-ms-asf;x-scheme-handler/tidal;
StartupWMClass=strawberry

View File

@@ -25,9 +25,9 @@ Features:
.br
- Fetch tags from MusicBrainz
.br
- Album cover art from Lastfm, Musicbrainz, Discogs, Deezer and Tidal
- Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify
.br
- Song lyrics from AudD, lyrics.ovh and lololyrics.com
- Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com
.br
- Support for multiple backends
.br
@@ -37,7 +37,7 @@ Features:
.br
- Transfer music to iPod, iPhone, MTP or mass-storage USB player
.br
- Streaming from Tidal, Qobuz and Subsonic
- Streaming from Subsonic
.TP
It is a fork of Clementine. The name is inspired by the band Strawbs.
.SH OPTIONS

View File

@@ -44,7 +44,9 @@ BuildRequires: pkgconfig(dbus-1)
BuildRequires: pkgconfig(gnutls)
BuildRequires: pkgconfig(alsa)
BuildRequires: pkgconfig(protobuf)
%if ! 0%{?centos}
BuildRequires: pkgconfig(sqlite3) >= 3.9
%endif
%if ! 0%{?centos} && ! 0%{?mageia}
BuildRequires: pkgconfig(taglib)
%endif
@@ -102,14 +104,14 @@ Features:
- Advanced audio output and device configuration for bit-perfect playback on Linux
- Edit tags on music files
- Fetch tags from MusicBrainz
- Album cover art from Last.fm, Musicbrainz, Discogs, Deezer and Tidal
- Song lyrics from AudD, lyrics.ovh and lololyrics.com
- Album cover art from Last.fm, Musicbrainz, Discogs, Musixmatch, Deezer, Tidal, Qobuz and Spotify
- Song lyrics from AudD, Genius, Musixmatch, ChartLyrics, lyrics.ovh and lololyrics.com
- Support for multiple backends
- Audio analyzer
- Audio equalizer
- Transfer music to iPod, iPhone, MTP or mass-storage USB player
- Streaming support for Tidal, Qobuz and Subsonic
- Scrobbler with support for Last.fm, Libre.fm and ListenBrainz
- Streaming support for Subsonic
%prep
%setup -qn %{name}-@STRAWBERRY_VERSION_PACKAGE@
@@ -192,5 +194,5 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/org.strawberrymusicpl
%{_mandir}/man1/%{name}-tagreader.1.*
%changelog
* @RPM_DATE@ Jonas Kvinge <jonas@strawbs.net> - @STRAWBERRY_VERSION_RPM_V@
* @RPM_DATE@ Jonas Kvinge <jonas@jkvinge.net> - @STRAWBERRY_VERSION_RPM_V@
- Version @STRAWBERRY_VERSION_PACKAGE@

View File

@@ -68,13 +68,12 @@ SetCompressor /SOLID lzma
!include "MUI2.nsh"
!include "FileAssociation.nsh"
!include "Capabilities.nsh"
!include LogicLib.nsh
!include x64.nsh
!define MUI_ICON "strawberry.ico"
!define MUI_COMPONENTSPAGE_SMALLDESC
;!define MUI_FINISHPAGE_RUN
;!define MUI_FINISHPAGE_RUN_TEXT "Run Strawberry"
;!define MUI_FINISHPAGE_RUN_FUNCTION "RunStrawberry"
; Installer pages
!insertmacro MUI_PAGE_WELCOME
@@ -144,16 +143,14 @@ Function .onInit
FunctionEnd
;Function RunStrawberry
;ShellExecAsUser::ShellExecAsUser "" "$INSTDIR/strawberry.exe" ""
;FunctionEnd
Section "Delete old files" oldfiles
SectionEnd
Section "Strawberry" Strawberry
SetOutPath "$INSTDIR"
nsExec::Exec '"$INSTDIR\killproc.exe" strawberry.exe'
File "strawberry.exe"
File "strawberry-tagreader.exe"
File "strawberry.ico"
@@ -162,7 +159,7 @@ Section "Strawberry" Strawberry
File "libcdio-19.dll"
File "libchromaprint.dll"
File "libfaad-2.dll"
File "libffi-6.dll"
File "libffi-7.dll"
File "libfftw3-3.dll"
File "libFLAC-8.dll"
File "libfreetype-6.dll"
@@ -186,20 +183,20 @@ Section "Strawberry" Strawberry
File "libgsttag-1.0-0.dll"
File "libgstvideo-1.0-0.dll"
File "libharfbuzz-0.dll"
File "libhogweed-5.dll"
File "libhogweed-6.dll"
File "libiconv-2.dll"
File "libidn2-0.dll"
File "libintl-8.dll"
File "libjpeg-9.dll"
File "liblzma-5.dll"
File "libmp3lame-0.dll"
File "libnettle-7.dll"
File "libnettle-8.dll"
File "libogg-0.dll"
File "libopus-0.dll"
File "libpcre-1.dll"
File "libpcre2-16-0.dll"
File "libpng16-16.dll"
File "libprotobuf-21.dll"
File "libprotobuf-22.dll"
File "libsoup-2.4-1.dll"
File "libspeex-1.dll"
File "libsqlite3-0.dll"
@@ -243,6 +240,8 @@ Section "Strawberry" Strawberry
File "libxine-2.dll"
!endif
File "killproc.exe"
; Register Strawberry with Default Programs
Var /GLOBAL AppIcon
Var /GLOBAL AppExe
@@ -297,6 +296,11 @@ Section "Qt image format plugins" imageformats
File "/oname=qjpeg.dll" "imageformats\qjpeg.dll"
SectionEnd
Section "Qt style plugins" styles
SetOutPath "$INSTDIR\styles"
File "/oname=qwindowsvistastyle.dll" "styles\qwindowsvistastyle.dll"
SectionEnd
Section "Gstreamer plugins" gstreamer-plugins
SetOutPath "$INSTDIR\gstreamer-plugins"
@@ -318,7 +322,7 @@ Section "Gstreamer plugins" gstreamer-plugins
File "/oname=libgsttypefindfunctions.dll" "gstreamer-plugins\libgsttypefindfunctions.dll"
File "/oname=libgstgio.dll" "gstreamer-plugins\libgstgio.dll"
File "/oname=libgstdirectsound.dll" "gstreamer-plugins\libgstdirectsound.dll"
File "/oname=libgstwasapi.dll" "gstreamer-plugins\libgstwasapi.dll"
;File "/oname=libgstwasapi.dll" "gstreamer-plugins\libgstwasapi.dll"
File "/oname=libgstapetag.dll" "gstreamer-plugins\libgstapetag.dll"
File "/oname=libgsticydemux.dll" "gstreamer-plugins\libgsticydemux.dll"
File "/oname=libgstid3demux.dll" "gstreamer-plugins\libgstid3demux.dll"
@@ -406,28 +410,8 @@ Section "Uninstaller"
SectionEnd
Section "Uninstall"
; Kill strawberry.exe if it's running
; This calling convention is retarded...
;StrCpy $0 "strawberry.exe"
;KillProc::FindProcesses
;StrCmp $1 "-1" wooops
;StrCmp $0 "0" completed
;DetailPrint "Killing running strawberry.exe..."
;StrCpy $0 "strawberry.exe"
;KillProc::KillProcesses
;StrCmp $1 "-1" wooops
;Sleep 2000
;Goto completed
;wooops:
;DetailPrint "-> Error: Something went wrong while killing running strawberry.exe"
;Abort
;completed:
nsExec::Exec '"$INSTDIR\killproc.exe" strawberry.exe'
; Delete all the files
@@ -439,7 +423,7 @@ Section "Uninstall"
Delete "$INSTDIR\libcdio-19.dll"
Delete "$INSTDIR\libchromaprint.dll"
Delete "$INSTDIR\libfaad-2.dll"
Delete "$INSTDIR\libffi-6.dll"
Delete "$INSTDIR\libffi-7.dll"
Delete "$INSTDIR\libfftw3-3.dll"
Delete "$INSTDIR\libFLAC-8.dll"
Delete "$INSTDIR\libfreetype-6.dll"
@@ -463,20 +447,20 @@ Section "Uninstall"
Delete "$INSTDIR\libgsttag-1.0-0.dll"
Delete "$INSTDIR\libgstvideo-1.0-0.dll"
Delete "$INSTDIR\libharfbuzz-0.dll"
Delete "$INSTDIR\libhogweed-5.dll"
Delete "$INSTDIR\libhogweed-6.dll"
Delete "$INSTDIR\libiconv-2.dll"
Delete "$INSTDIR\libidn2-0.dll"
Delete "$INSTDIR\libintl-8.dll"
Delete "$INSTDIR\libjpeg-9.dll"
Delete "$INSTDIR\liblzma-5.dll"
Delete "$INSTDIR\libmp3lame-0.dll"
Delete "$INSTDIR\libnettle-7.dll"
Delete "$INSTDIR\libnettle-8.dll"
Delete "$INSTDIR\libogg-0.dll"
Delete "$INSTDIR\libopus-0.dll"
Delete "$INSTDIR\libpcre-1.dll"
Delete "$INSTDIR\libpcre2-16-0.dll"
Delete "$INSTDIR\libpng16-16.dll"
Delete "$INSTDIR\libprotobuf-21.dll"
Delete "$INSTDIR\libprotobuf-22.dll"
Delete "$INSTDIR\libsoup-2.4-1.dll"
Delete "$INSTDIR\libspeex-1.dll"
Delete "$INSTDIR\libsqlite3-0.dll"
@@ -523,6 +507,7 @@ Section "Uninstall"
Delete "$INSTDIR\gio-modules\libgiognutls.dll"
Delete "$INSTDIR\platforms\qwindows.dll"
Delete "$INSTDIR\sqldrivers\qsqlite.dll"
Delete "$INSTDIR\styles\qwindowsvistastyle.dll"
Delete "$INSTDIR\imageformats\qgif.dll"
Delete "$INSTDIR\imageformats\qico.dll"
@@ -602,12 +587,15 @@ Section "Uninstall"
Delete "$INSTDIR\xine-plugins\xineplug_post_visualizations.dll"
!endif
Delete "$INSTDIR\killproc.exe"
Delete "$INSTDIR\Uninstall.exe"
; Remove the installation folders.
RMDir "$INSTDIR\platforms"
RMDir "$INSTDIR\styles"
RMDir "$INSTDIR\sqldrivers"
RMDir "$INSTDIR\imageformats"
RMDir "$INSTDIR\gio-modules"
RMDir "$INSTDIR\gstreamer-plugins"
RMDir "$INSTDIR\xine-plugins"
RMDir "$INSTDIR"

View File

@@ -1,15 +1,6 @@
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Woverloaded-virtual -Wno-sign-compare -fpermissive")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wpedantic")
endif()
cmake_minimum_required(VERSION 3.0)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${GLIB_INCLUDE_DIRS})
include_directories(${GOBJECT_INCLUDE_DIRS})
include_directories(${GSTREAMER_INCLUDE_DIRS})

View File

@@ -19,14 +19,16 @@
* Boston, MA 02110-1301, USA.
*/
#include <QtGlobal>
#include <cstring>
#include <cmath>
#include <glib.h>
#include <gst/gst.h>
#include <gst/audio/gstaudiofilter.h>
#include <QMutex>
#include <QMutexLocker>
#include "gstfastspectrum.h"

View File

@@ -15,6 +15,7 @@
along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
#include <gst/gst.h>
#include "gstfastspectrum.h"

View File

@@ -1,15 +1,19 @@
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
cmake_minimum_required(VERSION 3.0)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_BINARY_DIR}/src)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Woverloaded-virtual -Wno-sign-compare -fpermissive")
if (Backtrace_FOUND)
include_directories(${Backtrace_INCLUDE_DIRS})
endif(Backtrace_FOUND)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wpedantic")
endif()
include_directories(${GLIB_INCLUDE_DIRS})
include_directories(${GLIBCONFIG_INCLUDE_DIRS})
include_directories(${PROTOBUF_INCLUDE_DIRS})
set(SOURCES
core/closure.cpp
@@ -33,15 +37,11 @@ endif(APPLE)
qt5_wrap_cpp(MOC ${HEADERS})
add_library(libstrawberry-common STATIC
${SOURCES}
${MOC}
)
add_library(libstrawberry-common STATIC ${SOURCES} ${MOC})
target_link_libraries(libstrawberry-common
#${PROTOBUF_LIBRARY}
${TAGLIB_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
if(Backtrace_FOUND)
target_link_libraries(libstrawberry-common ${Backtrace_LIBRARIES})
endif(Backtrace_FOUND)
target_link_libraries(libstrawberry-common ${TAGLIB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(libstrawberry-common Qt5::Core Qt5::Network)

View File

@@ -22,7 +22,6 @@
#include "closure.h"
#include "core/logging.h"
#include "core/timeconstants.h"
namespace _detail {

View File

@@ -15,6 +15,21 @@
*/
#include <QtGlobal>
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <memory>
#include <cxxabi.h>
#include <glib.h>
#ifdef HAVE_BACKTRACE
# include <execinfo.h>
#endif
#include <QByteArray>
#include <QList>
#include <QMap>
@@ -23,18 +38,10 @@
#include <QRegExp>
#include <QDateTime>
#include <QIODevice>
#include <QBuffer>
#include <QtMessageHandler>
#include <QMessageLogContext>
#include <cxxabi.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#ifdef Q_OS_UNIX
#include <execinfo.h>
#endif
#include <QDebug>
#include "logging.h"
@@ -51,28 +58,69 @@ static const char *kMessageHandlerMagic = "__logging_message__";
static const int kMessageHandlerMagicLength = strlen(kMessageHandlerMagic);
static QtMessageHandler sOriginalMessageHandler = nullptr;
void GLog(const char *domain, int level, const char *message, void *user_data) {
template <class T>
static T CreateLogger(Level level, const QString& class_name, int line, const char* category);
Q_UNUSED(domain);
Q_UNUSED(user_data);
void GLog(const char *domain, int level, const char *message, void*) {
switch (level) {
case G_LOG_FLAG_RECURSION:
case G_LOG_FLAG_FATAL:
case G_LOG_LEVEL_ERROR:
case G_LOG_LEVEL_CRITICAL: qLog(Error) << message; break;
case G_LOG_LEVEL_WARNING: qLog(Warning) << message; break;
case G_LOG_LEVEL_CRITICAL:
qLogCat(Error, domain) << message;
break;
case G_LOG_LEVEL_WARNING:
qLogCat(Warning, domain) << message;
break;
case G_LOG_LEVEL_MESSAGE:
case G_LOG_LEVEL_INFO: qLog(Info) << message; break;
case G_LOG_LEVEL_INFO:
qLogCat(Info, domain) << message;
break;
case G_LOG_LEVEL_DEBUG:
default: qLog(Debug) << message; break;
default:
qLogCat(Debug, domain) << message;
break;
}
}
static void MessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message) {
template <class T>
class DebugBase : public QDebug {
public:
DebugBase() : QDebug(sNullDevice) {}
DebugBase(QtMsgType t) : QDebug(t) {}
T& space() { return static_cast<T&>(QDebug::space()); }
T& noSpace() { return static_cast<T&>(QDebug::nospace()); }
};
Q_UNUSED(context);
// Debug message will be stored in a buffer.
class BufferedDebug : public DebugBase<BufferedDebug> {
public:
BufferedDebug() : DebugBase() {}
BufferedDebug(QtMsgType) : DebugBase(), buf_(new QBuffer, later_deleter) {
buf_->open(QIODevice::WriteOnly);
// QDebug doesn't have a method to set a new io device, but swap() allows the devices to be swapped between two instances.
QDebug other(buf_.get());
swap(other);
}
// Delete function for the buffer. Since a base class is holding a reference to the raw pointer,
// it shouldn't be deleted until after the deletion of this object is complete.
static void later_deleter(QBuffer* b) { b->deleteLater(); }
std::shared_ptr<QBuffer> buf_;
};
// Debug message will be logged immediately.
class LoggedDebug : public DebugBase<LoggedDebug> {
public:
LoggedDebug() : DebugBase() {}
LoggedDebug(QtMsgType t) : DebugBase(t) { nospace() << kMessageHandlerMagic; }
};
static void MessageHandler(QtMsgType type, const QMessageLogContext&, const QString &message) {
if (strncmp(kMessageHandlerMagic, message.toLocal8Bit().data(), kMessageHandlerMagicLength) == 0) {
fprintf(stderr, "%s\n", message.toLocal8Bit().data() + kMessageHandlerMagicLength);
@@ -82,14 +130,25 @@ static void MessageHandler(QtMsgType type, const QMessageLogContext &context, co
Level level = Level_Debug;
switch (type) {
case QtFatalMsg:
case QtCriticalMsg: level = Level_Error; break;
case QtWarningMsg: level = Level_Warning; break;
case QtCriticalMsg:
level = Level_Error;
break;
case QtWarningMsg:
level = Level_Warning;
break;
case QtDebugMsg:
default: level = Level_Debug; break;
default:
level = Level_Debug;
break;
}
for (const QString &line : message.split('\n')) {
CreateLogger(level, "unknown", -1) << line.toLocal8Bit().constData();
for (const QString& line : message.split('\n')) {
BufferedDebug d = CreateLogger<BufferedDebug>(level, "unknown", -1, nullptr);
d << line.toLocal8Bit().constData();
if (d.buf_) {
d.buf_->close();
fprintf(stderr, "%s\n", d.buf_->buffer().data());
}
}
if (type == QtFatalMsg) {
@@ -146,7 +205,7 @@ void SetLevels(const QString &levels) {
}
QString ParsePrettyFunction(const char *pretty_function) {
static QString ParsePrettyFunction(const char *pretty_function) {
// Get the class name out of the function name.
QString class_name = pretty_function;
@@ -169,7 +228,8 @@ QString ParsePrettyFunction(const char *pretty_function) {
return class_name;
}
QDebug CreateLogger(Level level, const QString &class_name, int line) {
template <class T>
static T CreateLogger(Level level, const QString &class_name, int line, const char* category) {
// Map the level to a string
const char *level_name = nullptr;
@@ -181,37 +241,40 @@ QDebug CreateLogger(Level level, const QString &class_name, int line) {
case Level_Fatal: level_name = " FATAL "; break;
}
QString filter_category = (category != nullptr) ? category : class_name;
// Check the settings to see if we're meant to show or hide this message.
Level threshold_level = sDefaultLevel;
if (sClassLevels && sClassLevels->contains(class_name)) {
threshold_level = sClassLevels->value(class_name);
if (sClassLevels && sClassLevels->contains(filter_category)) {
threshold_level = sClassLevels->value(filter_category);
}
if (level > threshold_level) {
return QDebug(sNullDevice);
return T();
}
QString function_line = class_name;
if (line != -1) {
function_line += ":" + QString::number(line);
}
if (category) {
function_line += "(" + QString(category) + ")";
}
QtMsgType type = QtDebugMsg;
if (level == Level_Fatal) {
type = QtFatalMsg;
}
QDebug ret(type);
ret.nospace() << kMessageHandlerMagic
<< QDateTime::currentDateTime()
.toString("hh:mm:ss.zzz")
.toLatin1()
.constData() << level_name
T ret(type);
ret.nospace() << QDateTime::currentDateTime().toString("hh:mm:ss.zzz").toLatin1().constData()
<< level_name
<< function_line.leftJustified(32).toLatin1().constData();
return ret.space();
}
QString CXXDemangle(const QString &mangled_function);
QString CXXDemangle(const QString &mangled_function) {
int status;
@@ -225,6 +288,8 @@ QString CXXDemangle(const QString &mangled_function) {
}
QString DarwinDemangle(const QString &symbol);
QString DarwinDemangle(const QString &symbol) {
QStringList split = symbol.split(' ', QString::SkipEmptyParts);
@@ -233,6 +298,8 @@ QString DarwinDemangle(const QString &symbol) {
}
QString LinuxDemangle(const QString &symbol);
QString LinuxDemangle(const QString &symbol) {
QRegExp regex("\\(([^+]+)");
@@ -244,6 +311,8 @@ QString LinuxDemangle(const QString &symbol) {
}
QString DemangleSymbol(const QString &symbol);
QString DemangleSymbol(const QString &symbol) {
#ifdef Q_OS_MACOS
return DarwinDemangle(symbol);
@@ -255,7 +324,7 @@ QString DemangleSymbol(const QString &symbol) {
}
void DumpStackTrace() {
#ifdef Q_OS_UNIX
#ifdef HAVE_BACKTRACE
void* callstack[128];
int callstack_size = backtrace(reinterpret_cast<void**>(&callstack), sizeof(callstack));
char** symbols = backtrace_symbols(reinterpret_cast<void**>(&callstack), callstack_size);
@@ -269,21 +338,26 @@ void DumpStackTrace() {
#endif
}
QDebug CreateLoggerFatal(int line, const char *class_name) { return qCreateLogger(line, class_name, Fatal); }
QDebug CreateLoggerError(int line, const char *class_name) { return qCreateLogger(line, class_name, Error); }
// These are the functions that create loggers for the rest of Clementine.
// It's okay that the LoggedDebug instance is copied to a QDebug in these. It
// doesn't override any behavior that should be needed after return.
#define qCreateLogger(line, pretty_function, category, level) logging::CreateLogger<LoggedDebug>(logging::Level_##level, logging::ParsePrettyFunction(pretty_function), line, category)
QDebug CreateLoggerFatal(int line, const char *pretty_function, const char* category) { return qCreateLogger(line, pretty_function, category, Fatal); }
QDebug CreateLoggerError(int line, const char *pretty_function, const char* category) { return qCreateLogger(line, pretty_function, category, Error); }
#ifdef QT_NO_WARNING_OUTPUT
QNoDebug CreateLoggerWarning(int, const char*) { return QNoDebug(); }
QNoDebug CreateLoggerWarning(int, const char*, const char*) { return QNoDebug(); }
#else
QDebug CreateLoggerWarning(int line, const char *class_name) { return qCreateLogger(line, class_name, Warning); }
QDebug CreateLoggerWarning(int line, const char *pretty_function, const char* category) { return qCreateLogger(line, pretty_function, category, Warning); }
#endif // QT_NO_WARNING_OUTPUT
#ifdef QT_NO_DEBUG_OUTPUT
QNoDebug CreateLoggerInfo(int, const char*) { return QNoDebug(); }
QNoDebug CreateLoggerDebug(int, const char*) { return QNoDebug(); }
QNoDebug CreateLoggerInfo(int, const char*, const char*) { return QNoDebug(); }
QNoDebug CreateLoggerDebug(int, const char*, const char*) { return QNoDebug(); }
#else
QDebug CreateLoggerInfo(int line, const char *class_name) { return qCreateLogger(line, class_name, Info); }
QDebug CreateLoggerDebug(int line, const char *class_name) { return qCreateLogger(line, class_name, Debug); }
QDebug CreateLoggerInfo(int line, const char *pretty_function, const char* category) { return qCreateLogger(line, pretty_function, category, Info); }
QDebug CreateLoggerDebug(int line, const char *pretty_function, const char* category) { return qCreateLogger(line, pretty_function, category, Debug); }
#endif // QT_NO_DEBUG_OUTPUT
} // namespace logging

View File

@@ -26,14 +26,20 @@
#ifdef QT_NO_DEBUG_STREAM
# define qLog(level) while (false) QNoDebug()
# define qLogCat(level, category) while (false) QNoDebug()
#else
#define qLog(level) logging::CreateLogger##level(__LINE__, __PRETTY_FUNCTION__)
# define qLog(level) logging::CreateLogger##level(__LINE__, __PRETTY_FUNCTION__, nullptr)
#define qCreateLogger(line, class_name, level) logging::CreateLogger(logging::Level_##level, logging::ParsePrettyFunction(class_name), line)
#endif // QT_NO_DEBUG_STREAM
// This macro specifies a separate category for message filtering.
// The default qLog will use the class name extracted from the function name for this purpose.
// The category is also printed in the message along with the class name.
# define qLogCat(level, category) logging::CreateLogger##level(__LINE__, __PRETTY_FUNCTION__, category)
#endif // QT_NO_DEBUG_STREAM
namespace logging {
class NullDevice : public QIODevice {
class NullDevice : public QIODevice {
protected:
qint64 readData(char*, qint64) { return -1; }
qint64 writeData(const char*, qint64 len) { return len; }
@@ -52,33 +58,30 @@ enum Level {
void DumpStackTrace();
QString ParsePrettyFunction(const char *pretty_function);
QDebug CreateLogger(Level level, const QString &class_name, int line);
QDebug CreateLoggerFatal(int line, const char *class_name);
QDebug CreateLoggerError(int line, const char *class_name);
QDebug CreateLoggerFatal(int line, const char *pretty_function, const char* category);
QDebug CreateLoggerError(int line, const char *pretty_function, const char* category);
#ifdef QT_NO_WARNING_OUTPUT
QNoDebug CreateLoggerWarning(int, const char*);
QNoDebug CreateLoggerWarning(int, const char*, const char*);
#else
QDebug CreateLoggerWarning(int line, const char *class_name);
QDebug CreateLoggerWarning(int line, const char *pretty_function, const char* category);
#endif // QT_NO_WARNING_OUTPUT
#ifdef QT_NO_DEBUG_OUTPUT
QNoDebug CreateLoggerInfo(int, const char*);
QNoDebug CreateLoggerDebug(int, const char*);
QNoDebug CreateLoggerInfo(int, const char*, const char*);
QNoDebug CreateLoggerDebug(int, const char*, const char*);
#else
QDebug CreateLoggerInfo(int line, const char *class_name);
QDebug CreateLoggerDebug(int line, const char *class_name);
#endif // QT_NO_DEBUG_OUTPUT
QDebug CreateLoggerInfo(int line, const char *pretty_function, const char* category);
QDebug CreateLoggerDebug(int line, const char *pretty_function, const char* category);
#endif // QT_NO_DEBUG_OUTPUT
void GLog(const char *domain, int level, const char *message, void *user_data);
void GLog(const char* domain, int level, const char* message, void* user_data);
extern const char *kDefaultLogLevels;
}
} // namespace logging
QDebug operator<<(QDebug debug, std::chrono::seconds secs);
#endif // LOGGING_H

View File

@@ -47,13 +47,13 @@ void _MessageHandlerBase::SetDevice(QIODevice *device) {
connect(device, SIGNAL(readyRead()), SLOT(DeviceReadyRead()));
// Yeah I know.
if (QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(device)) {
if (QAbstractSocket *abstractsocket = qobject_cast<QAbstractSocket*>(device)) {
flush_abstract_socket_ = &QAbstractSocket::flush;
connect(socket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
connect(abstractsocket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
}
else if (QLocalSocket* socket = qobject_cast<QLocalSocket*>(device)) {
else if (QLocalSocket *localsocket = qobject_cast<QLocalSocket*>(device)) {
flush_local_socket_ = &QLocalSocket::flush;
connect(socket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
connect(localsocket, SIGNAL(disconnected()), SLOT(DeviceClosed()));
}
else {
qFatal("Unsupported device type passed to _MessageHandlerBase");

View File

@@ -23,7 +23,6 @@
#include <QtGlobal>
#include <QObject>
#include <QThread>
#include <QIODevice>
#include <QBuffer>
#include <QByteArray>
#include <QMap>
@@ -33,6 +32,8 @@
#include "core/messagereply.h"
class QIODevice;
#define QStringFromStdString(x) QString::fromUtf8(x.data(), x.size())
#define DataCommaSizeFromQString(x) x.toUtf8().constData(), x.toUtf8().length()

View File

@@ -26,13 +26,16 @@ _MessageReplyBase::_MessageReplyBase(QObject *parent)
: QObject(parent), finished_(false), success_(false) {}
bool _MessageReplyBase::WaitForFinished() {
qLog(Debug) << "Waiting on ID" << id();
semaphore_.acquire();
qLog(Debug) << "Acquired ID" << id();
return success_;
}
void _MessageReplyBase::Abort() {
Q_ASSERT(!finished_);
finished_ = true;
success_ = false;
@@ -40,4 +43,5 @@ void _MessageReplyBase::Abort() {
emit Finished(success_);
qLog(Debug) << "Releasing ID" << id() << "(aborted)";
semaphore_.release();
}

View File

@@ -25,12 +25,11 @@
#include <QCoreApplication>
#include <QThread>
#include <QMutex>
#include <QLocalServer>
#include <QProcess>
#include <QQueue>
#include <QFile>
#include <QList>
#include <QLocalServer>
#include <QLocalSocket>
#include <QQueue>
#include <QString>
#include <QStringList>
#include <QAtomicInt>
@@ -39,7 +38,6 @@
class QLocalSocket;
// Base class containing signals and slots - required because moc doesn't do templated objects.
class _WorkerPoolBase : public QObject {
Q_OBJECT
@@ -159,7 +157,7 @@ WorkerPool<HandlerType>::WorkerPool(QObject *parent)
next_worker_(0),
next_id_(0) {
worker_count_ = qBound(1, QThread::idealThreadCount() / 2, 2);
worker_count_ = qBound(1, QThread::idealThreadCount() / 2, 4);
local_server_name_ = qApp->applicationName().toLower();
if (local_server_name_.isEmpty())

View File

@@ -1,41 +1,21 @@
include_directories(${PROTOBUF_INCLUDE_DIRS})
cmake_minimum_required(VERSION 3.0)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_SOURCE_DIR}/ext/libstrawberry-common)
include_directories(${CMAKE_SOURCE_DIR}/src)
include_directories(${CMAKE_BINARY_DIR}/src)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11 -U__STRICT_ANSI__ -Wall -Woverloaded-virtual -Wno-sign-compare -fpermissive")
link_directories(${PROTOBUF_LIBRARY_DIRS})
include_directories(${PROTOBUF_INCLUDE_DIRS})
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wpedantic")
endif()
link_directories(${TAGLIB_LIBRARY_DIRS})
include_directories(${TAGLIB_INCLUDE_DIRS})
set(MESSAGES
tagreadermessages.proto
)
set(SOURCES
fmpsparser.cpp
tagreader.cpp
)
set(HEADERS
)
qt5_wrap_cpp(MOC ${HEADERS})
set(MESSAGES tagreadermessages.proto)
set(SOURCES fmpsparser.cpp tagreader.cpp)
protobuf_generate_cpp(PROTO_SOURCES PROTO_HEADERS ${MESSAGES})
add_library(libstrawberry-tagreader STATIC
${PROTO_SOURCES}
${SOURCES}
${MOC}
)
target_link_libraries(libstrawberry-tagreader
${PROTOBUF_LIBRARY}
libstrawberry-common
)
add_library(libstrawberry-tagreader STATIC ${PROTO_SOURCES} ${SOURCES})
target_link_libraries(libstrawberry-tagreader ${PROTOBUF_LIBRARY} libstrawberry-common)

View File

@@ -22,6 +22,7 @@
#include <QList>
#include <QVariant>
#include <QString>
#include <QChar>
#include "fmpsparser.h"

View File

@@ -22,10 +22,11 @@
#include <QList>
#include <QMetaType>
#include <QVariant>
#include <QString>
#include <QRegExp>
class QVariant;
class FMPSParser {
public:
FMPSParser();

View File

@@ -23,7 +23,6 @@
#include <memory>
#include <list>
#include <map>
#include <utility>
#include <sys/stat.h>
#include <taglib/taglib.h>
@@ -42,6 +41,8 @@
#include <taglib/commentsframe.h>
#include <taglib/tag.h>
#include <taglib/apetag.h>
#include <taglib/apeitem.h>
#include <taglib/apeproperties.h>
#include <taglib/id3v2tag.h>
#include <taglib/id3v2frame.h>
#include <taglib/flacfile.h>
@@ -52,6 +53,7 @@
#include <taglib/speexfile.h>
#include <taglib/wavfile.h>
#include <taglib/wavpackfile.h>
#include <taglib/wavpackproperties.h>
#include <taglib/aifffile.h>
#include <taglib/asffile.h>
#include <taglib/asftag.h>
@@ -91,10 +93,6 @@
#include "fmpsparser.h"
#include "core/timeconstants.h"
#ifndef USE_SYSTEM_TAGLIB
using namespace Strawberry_TagLib;
#endif
class FileRefFactory {
public:
virtual ~FileRefFactory() {}
@@ -214,46 +212,46 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
// Handle all the files which have VorbisComments (Ogg, OPUS, ...) in the same way;
// apart, so we keep specific behavior for some formats by adding another "else if" block below.
if (TagLib::Ogg::XiphComment *tag = dynamic_cast<TagLib::Ogg::XiphComment*>(fileref->file()->tag())) {
ParseOggTag(tag->fieldListMap(), nullptr, &disc, &compilation, song);
if (!tag->pictureList().isEmpty()) {
if (TagLib::Ogg::XiphComment *tag_ogg = dynamic_cast<TagLib::Ogg::XiphComment*>(fileref->file()->tag())) {
ParseOggTag(tag_ogg->fieldListMap(), nullptr, &disc, &compilation, song);
if (!tag_ogg->pictureList().isEmpty()) {
song->set_art_automatic(kEmbeddedCover);
}
}
if (TagLib::FLAC::File *file = dynamic_cast<TagLib::FLAC::File *>(fileref->file())) {
if (TagLib::FLAC::File *file_flac = dynamic_cast<TagLib::FLAC::File *>(fileref->file())) {
song->set_bitdepth(file->audioProperties()->bitsPerSample());
song->set_bitdepth(file_flac->audioProperties()->bitsPerSample());
if (file->xiphComment()) {
ParseOggTag(file->xiphComment()->fieldListMap(), nullptr, &disc, &compilation, song);
if (!file->pictureList().isEmpty()) {
if (file_flac->xiphComment()) {
ParseOggTag(file_flac->xiphComment()->fieldListMap(), nullptr, &disc, &compilation, song);
if (!file_flac->pictureList().isEmpty()) {
song->set_art_automatic(kEmbeddedCover);
}
}
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
}
else if (TagLib::WavPack::File *file = dynamic_cast<TagLib::WavPack::File *>(fileref->file())) {
song->set_bitdepth(file->audioProperties()->bitsPerSample());
if (file->tag()) {
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
else if (TagLib::WavPack::File *file_wavpack = dynamic_cast<TagLib::WavPack::File *>(fileref->file())) {
song->set_bitdepth(file_wavpack->audioProperties()->bitsPerSample());
if (file_wavpack->tag()) {
ParseAPETag(file_wavpack->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
}
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
}
else if (TagLib::APE::File *file = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
if (file->tag()) {
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
else if (TagLib::APE::File *file_ape = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
if (file_ape->tag()) {
ParseAPETag(file_ape->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
}
song->set_bitdepth(file->audioProperties()->bitsPerSample());
song->set_bitdepth(file_ape->audioProperties()->bitsPerSample());
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
}
else if (TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
else if (TagLib::MPEG::File *file_mpeg = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
if (file->ID3v2Tag()) {
const TagLib::ID3v2::FrameListMap &map = file->ID3v2Tag()->frameListMap();
if (file_mpeg->ID3v2Tag()) {
const TagLib::ID3v2::FrameListMap &map = file_mpeg->ID3v2Tag()->frameListMap();
if (!map["TPOS"].isEmpty()) disc = TStringToQString(map["TPOS"].front()->toString()).trimmed();
if (!map["TCOM"].isEmpty()) Decode(map["TCOM"].front()->toString(), nullptr, song->mutable_composer());
@@ -290,7 +288,7 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
if (!map["APIC"].isEmpty()) song->set_art_automatic(kEmbeddedCover);
// Find a suitable comment tag. For now we ignore iTunNORM comments.
for (int i = 0; i < map["COMM"].size(); ++i) {
for (uint i = 0; i < map["COMM"].size(); ++i) {
const TagLib::ID3v2::CommentsFrame *frame = dynamic_cast<const TagLib::ID3v2::CommentsFrame*>(map["COMM"][i]);
if (frame && TStringToQString(frame->description()) != "iTunNORM") {
@@ -300,7 +298,7 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
}
// Parse FMPS frames
for (int i = 0; i < map["TXXX"].size(); ++i) {
for (uint i = 0; i < map["TXXX"].size(); ++i) {
const TagLib::ID3v2::UserTextIdentificationFrame *frame = dynamic_cast<const TagLib::ID3v2::UserTextIdentificationFrame*>(map["TXXX"][i]);
if (frame && frame->description().startsWith("FMPS_")) {
@@ -311,12 +309,12 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
}
}
else if (TagLib::MP4::File *file = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
else if (TagLib::MP4::File *file_mp4 = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
song->set_bitdepth(file->audioProperties()->bitsPerSample());
song->set_bitdepth(file_mp4->audioProperties()->bitsPerSample());
if (file->tag()) {
TagLib::MP4::Tag *mp4_tag = file->tag();
if (file_mp4->tag()) {
TagLib::MP4::Tag *mp4_tag = file_mp4->tag();
// Find album artists
if (mp4_tag->item("aART").isValid()) {
@@ -350,11 +348,11 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
}
}
else if (TagLib::ASF::File *file = dynamic_cast<TagLib::ASF::File*>(fileref->file())) {
else if (TagLib::ASF::File *file_asf = dynamic_cast<TagLib::ASF::File*>(fileref->file())) {
song->set_bitdepth(file->audioProperties()->bitsPerSample());
song->set_bitdepth(file_asf->audioProperties()->bitsPerSample());
const TagLib::ASF::AttributeListMap &attributes_map = file->tag()->attributeListMap();
const TagLib::ASF::AttributeListMap &attributes_map = file_asf->tag()->attributeListMap();
if (attributes_map.contains(kASF_OriginalDate_ID)) {
const TagLib::ASF::AttributeList &attributes = attributes_map[kASF_OriginalDate_ID];
@@ -370,9 +368,9 @@ void TagReader::ReadFile(const QString &filename, pb::tagreader::SongMetadata *s
}
}
else if (TagLib::MPC::File* file = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
if (file->tag()) {
ParseAPETag(file->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
else if (TagLib::MPC::File* file_mpc = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
if (file_mpc->tag()) {
ParseAPETag(file_mpc->APETag()->itemListMap(), nullptr, &disc, &compilation, song);
}
if (tag) Decode(tag->comment(), nullptr, song->mutable_comment());
}
@@ -580,26 +578,26 @@ bool TagReader::SaveFile(const QString &filename, const pb::tagreader::SongMetad
SetVorbisComments(tag, song);
}
else if (TagLib::WavPack::File *file = dynamic_cast<TagLib::WavPack::File*>(fileref->file())) {
TagLib::APE::Tag *tag = file->APETag(true);
else if (TagLib::WavPack::File *file_wavpack = dynamic_cast<TagLib::WavPack::File*>(fileref->file())) {
TagLib::APE::Tag *tag = file_wavpack->APETag(true);
if (!tag) return false;
SaveAPETag(tag, song);
}
else if (TagLib::APE::File *file = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
TagLib::APE::Tag *tag = file->APETag(true);
else if (TagLib::APE::File *file_ape = dynamic_cast<TagLib::APE::File*>(fileref->file())) {
TagLib::APE::Tag *tag = file_ape->APETag(true);
if (!tag) return false;
SaveAPETag(tag, song);
}
else if (TagLib::MPC::File *file = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
TagLib::APE::Tag *tag = file->APETag(true);
else if (TagLib::MPC::File *file_mpc = dynamic_cast<TagLib::MPC::File*>(fileref->file())) {
TagLib::APE::Tag *tag = file_mpc->APETag(true);
if (!tag) return false;
SaveAPETag(tag, song);
}
else if (TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
TagLib::ID3v2::Tag *tag = file->ID3v2Tag(true);
else if (TagLib::MPEG::File *file_mpeg = dynamic_cast<TagLib::MPEG::File*>(fileref->file())) {
TagLib::ID3v2::Tag *tag = file_mpeg->ID3v2Tag(true);
if (!tag) return false;
SetTextFrame("TPOS", song.disc() <= 0 -1 ? QString() : QString::number(song.disc()), tag);
SetTextFrame("TCOM", song.composer(), tag);
@@ -611,8 +609,8 @@ bool TagReader::SaveFile(const QString &filename, const pb::tagreader::SongMetad
SetUnsyncLyricsFrame(song.lyrics(), tag);
}
else if (TagLib::MP4::File *file = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
TagLib::MP4::Tag *tag = file->tag();
else if (TagLib::MP4::File *file_mp4 = dynamic_cast<TagLib::MP4::File*>(fileref->file())) {
TagLib::MP4::Tag *tag = file_mp4->tag();
tag->setItem("disk", TagLib::MP4::Item(song.disc() <= 0 -1 ? 0 : song.disc(), 0));
tag->setItem("\251wrt", TagLib::StringList(song.composer().c_str()));
tag->setItem("\251grp", TagLib::StringList(song.grouping().c_str()));
@@ -836,7 +834,7 @@ QByteArray TagReader::LoadEmbeddedAPEArt(const TagLib::APE::ItemListMap &map) co
TagLib::ByteVector data = it->second.binaryData();
int pos = data.find('\0') + 1;
if ((pos > 0) && (pos < data.size())) {
if ((pos > 0) && ((uint)pos < data.size())) {
ret = QByteArray(data.data() + pos, data.size() - pos);
}
}

Some files were not shown because too many files have changed in this diff Show More