├── gui ├── images │ ├── +material │ │ └── .gitignore │ ├── div.png │ ├── tv.png │ ├── none.png │ ├── noson.png │ ├── radio.png │ ├── lastfm.png │ ├── linein.png │ ├── no_cover.png │ ├── tunein.png │ ├── folder_album.png │ ├── folder_artist.png │ ├── folder_genre.png │ ├── folder_share.png │ ├── folder_track.png │ ├── folder_composer.png │ ├── wifi_phone_icon.png │ ├── music_download_icon.png │ ├── font-scalling.svg │ ├── graphic-scalling.svg │ ├── close.svg │ ├── media-playback-pause.svg │ ├── delete.svg │ ├── media-playlist-repeat.svg │ ├── audio-volume.svg │ ├── reload.svg │ ├── bell.svg │ ├── nightmode-enabled.svg │ ├── select-none.svg │ ├── sync.svg │ └── select.svg ├── i18n │ ├── noson_da.qm │ ├── noson_de.qm │ ├── noson_en.qm │ ├── noson_fr.qm │ ├── noson_nl.qm │ └── README.md ├── icons │ ├── noson-8x8.png │ ├── noson-16x16.png │ ├── noson-22x22.png │ ├── noson-24x24.png │ ├── noson-32x32.png │ ├── noson-36x36.png │ ├── noson-42x42.png │ ├── noson-48x48.png │ ├── noson-64x64.png │ ├── noson-72x72.png │ ├── noson-80x80.png │ ├── noson-96x96.png │ ├── noson-128x128.png │ ├── noson-192x192.png │ ├── noson-256x256.png │ └── noson-512x512.png ├── controls2_515 │ ├── qtquickcontrols2.conf │ ├── CMakeLists.txt │ ├── components │ │ ├── ActivitySpinner.qml │ │ ├── ListItemActions │ │ │ ├── Remove.qml │ │ │ ├── AddToQueue.qml │ │ │ ├── AddToPlaylist.qml │ │ │ └── AddToFavorites.qml │ │ ├── Flickables │ │ │ ├── MusicListView.qml │ │ │ └── MusicGridView.qml │ │ ├── SimpleRow.qml │ │ ├── IndexEmptyState.qml │ │ ├── IndexUpdateState.qml │ │ ├── ServiceEmptyState.qml │ │ ├── DataFailureState.qml │ │ ├── BlurredBackground.qml │ │ ├── AlarmsEmptyState.qml │ │ ├── RadiosEmptyState.qml │ │ ├── Dialog │ │ │ ├── DialogSettings.qml │ │ │ ├── DialogRemovePlaylist.qml │ │ │ └── DialogServiceLabel.qml │ │ ├── PopInfo.qml │ │ ├── PlaylistsEmptyState.qml │ │ ├── ZoneControls.qml │ │ ├── Units.qml │ │ ├── MusicFilter.qml │ │ ├── Delegates │ │ │ └── SimpleListItem.qml │ │ ├── MusicHeader.qml │ │ └── MusicCheckBox.qml │ ├── Welcome.qml │ └── ThisDevice │ │ ├── AddToQueue.qml │ │ ├── QueueAllButton.qml │ │ ├── PlayAllButton.qml │ │ └── ShuffleButton.qml ├── diskcache │ ├── diskcachefactory.h │ ├── cachingnetworkaccessmanager.h │ ├── cachereply.h │ ├── diskcachefactory.cpp │ ├── cachingnetworkaccessmanager.cpp │ └── cachereply.cpp ├── toolbox.js ├── signalhandler.h └── signalhandler.cpp ├── debian ├── source │ └── format ├── noson-app.lintian-overrides ├── rules ├── copyright └── control ├── win64 ├── .gitignore ├── qt.conf ├── noson.ico └── mui_welcome.bmp ├── android ├── .gitignore ├── package-sources │ ├── ic_launcher-web.png │ └── res │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png ├── README.txt ├── qtdeploy.json.in ├── linux-build-x86-qt515.sh ├── linux-build-x64-qt515.sh ├── linux-build-arm64-qt515.sh ├── linux-build-armv7-qt515.sh └── license.txt ├── .gitignore ├── backend ├── NosonApp │ ├── qmldir │ ├── cppdef.h │ ├── dbus │ │ ├── org.mpris.MediaPlayer2.xml │ │ └── org.mpris.MediaPlayer2.Player.xml │ ├── plugin.h │ ├── qmlsortbehavior.cpp │ ├── qmlfilterbehavior.cpp │ ├── qmlsortbehavior.h │ ├── future.cpp │ ├── future.h │ ├── tools.h │ ├── qmlfilterbehavior.h │ └── qmlsortfiltermodel.h ├── lib │ ├── zlib-1.3.1.tar.gz │ ├── noson-2.12.11.tar.gz │ └── cmake │ │ ├── FindFLAC.cmake │ │ ├── FindFLACXX.cmake │ │ └── DownloadProject.CMakeLists.cmake.in ├── NosonThumbnailer │ ├── qmldir │ ├── thumbnailer │ │ ├── netmanager.h │ │ ├── diskcachemanager.h │ │ ├── thumbnailerjob.cpp │ │ ├── diskcachemanager.cpp │ │ ├── abstractapi.cpp │ │ ├── thumbnailerjob.h │ │ ├── jsonparser.h │ │ ├── artistinfo.h │ │ └── albuminfo.h │ ├── artistartgenerator.h │ ├── albumartgenerator.h │ ├── thumbnailerimageresponse.h │ ├── artistartgenerator.cpp │ ├── albumartgenerator.cpp │ └── plugin.h ├── NosonMediaScanner │ ├── qmldir │ ├── cmake │ │ └── CheckFunctionKeywords.cmake │ ├── byteorder.cpp │ ├── packed.h │ ├── id3parser.h │ ├── flacparser.h │ ├── tools.h │ ├── mediarunnable.h │ ├── mediaparser.h │ ├── plugin.h │ ├── mediarunnable.cpp │ ├── mediaextractor.h │ ├── listmodel.cpp │ ├── mediainfo.h │ ├── mediafile.h │ ├── oggparser.h │ ├── listmodel.h │ ├── m4aparser.h │ └── plugin.cpp ├── CMakeLists.txt └── cli │ ├── CMakeLists.txt │ ├── tokenizer.h │ └── builtin.h ├── macosx ├── resources │ ├── noson.png │ └── Contents │ │ └── Info.plist ├── README.md └── env-path.sh ├── .gitmodules ├── noson-app.in ├── cmake_uninstall.cmake.in ├── .travis.yml ├── .github └── workflows │ ├── build-ubuntu-latest.yml │ └── appimage_ubuntu_jammy.yml └── cmake └── MSVCRuntime.cmake /gui/images/+material/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /win64/.gitignore: -------------------------------------------------------------------------------- 1 | Files/ 2 | *.exe 3 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | AndroidManifest.xml 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | *.user* 3 | *.qmlc 4 | *.list 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /win64/qt.conf: -------------------------------------------------------------------------------- 1 | [Paths] 2 | Plugins=. 3 | Translations=translations 4 | -------------------------------------------------------------------------------- /win64/noson.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/win64/noson.ico -------------------------------------------------------------------------------- /debian/noson-app.lintian-overrides: -------------------------------------------------------------------------------- 1 | noson-app: possible-gpl-code-linked-with-openssl 2 | -------------------------------------------------------------------------------- /gui/images/div.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/div.png -------------------------------------------------------------------------------- /gui/images/tv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/tv.png -------------------------------------------------------------------------------- /backend/NosonApp/qmldir: -------------------------------------------------------------------------------- 1 | module NosonApp 2 | plugin NosonApp 3 | classname NosonAppPlugin 4 | -------------------------------------------------------------------------------- /gui/i18n/noson_da.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/i18n/noson_da.qm -------------------------------------------------------------------------------- /gui/i18n/noson_de.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/i18n/noson_de.qm -------------------------------------------------------------------------------- /gui/i18n/noson_en.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/i18n/noson_en.qm -------------------------------------------------------------------------------- /gui/i18n/noson_fr.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/i18n/noson_fr.qm -------------------------------------------------------------------------------- /gui/i18n/noson_nl.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/i18n/noson_nl.qm -------------------------------------------------------------------------------- /gui/images/none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/none.png -------------------------------------------------------------------------------- /gui/images/noson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/noson.png -------------------------------------------------------------------------------- /gui/images/radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/radio.png -------------------------------------------------------------------------------- /gui/icons/noson-8x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-8x8.png -------------------------------------------------------------------------------- /gui/images/lastfm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/lastfm.png -------------------------------------------------------------------------------- /gui/images/linein.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/linein.png -------------------------------------------------------------------------------- /gui/images/no_cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/no_cover.png -------------------------------------------------------------------------------- /gui/images/tunein.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/tunein.png -------------------------------------------------------------------------------- /win64/mui_welcome.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/win64/mui_welcome.bmp -------------------------------------------------------------------------------- /gui/icons/noson-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-16x16.png -------------------------------------------------------------------------------- /gui/icons/noson-22x22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-22x22.png -------------------------------------------------------------------------------- /gui/icons/noson-24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-24x24.png -------------------------------------------------------------------------------- /gui/icons/noson-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-32x32.png -------------------------------------------------------------------------------- /gui/icons/noson-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-36x36.png -------------------------------------------------------------------------------- /gui/icons/noson-42x42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-42x42.png -------------------------------------------------------------------------------- /gui/icons/noson-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-48x48.png -------------------------------------------------------------------------------- /gui/icons/noson-64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-64x64.png -------------------------------------------------------------------------------- /gui/icons/noson-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-72x72.png -------------------------------------------------------------------------------- /gui/icons/noson-80x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-80x80.png -------------------------------------------------------------------------------- /gui/icons/noson-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-96x96.png -------------------------------------------------------------------------------- /gui/icons/noson-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-128x128.png -------------------------------------------------------------------------------- /gui/icons/noson-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-192x192.png -------------------------------------------------------------------------------- /gui/icons/noson-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-256x256.png -------------------------------------------------------------------------------- /gui/icons/noson-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/icons/noson-512x512.png -------------------------------------------------------------------------------- /gui/images/folder_album.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/folder_album.png -------------------------------------------------------------------------------- /gui/images/folder_artist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/folder_artist.png -------------------------------------------------------------------------------- /gui/images/folder_genre.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/folder_genre.png -------------------------------------------------------------------------------- /gui/images/folder_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/folder_share.png -------------------------------------------------------------------------------- /gui/images/folder_track.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/folder_track.png -------------------------------------------------------------------------------- /macosx/resources/noson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/macosx/resources/noson.png -------------------------------------------------------------------------------- /backend/lib/zlib-1.3.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/backend/lib/zlib-1.3.1.tar.gz -------------------------------------------------------------------------------- /gui/images/folder_composer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/folder_composer.png -------------------------------------------------------------------------------- /gui/images/wifi_phone_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/wifi_phone_icon.png -------------------------------------------------------------------------------- /backend/NosonThumbnailer/qmldir: -------------------------------------------------------------------------------- 1 | module NosonThumbnailer 2 | plugin NosonThumbnailer 3 | classname ThumbnailerPlugin -------------------------------------------------------------------------------- /backend/lib/noson-2.12.11.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/backend/lib/noson-2.12.11.tar.gz -------------------------------------------------------------------------------- /backend/NosonMediaScanner/qmldir: -------------------------------------------------------------------------------- 1 | module NosonMediaScanner 2 | plugin NosonMediaScanner 3 | classname MediaScannerPlugin 4 | -------------------------------------------------------------------------------- /gui/images/music_download_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/gui/images/music_download_icon.png -------------------------------------------------------------------------------- /android/package-sources/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/ic_launcher-web.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "backend/lib/noson"] 2 | path = backend/lib/noson 3 | url = https://github.com/janbar/noson.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /gui/controls2_515/qtquickcontrols2.conf: -------------------------------------------------------------------------------- 1 | [Material] 2 | Primary=#41cd52 3 | Accent=#41cd52 4 | Theme=System 5 | 6 | [Universal] 7 | Accent=#41cd52 8 | Theme=System 9 | -------------------------------------------------------------------------------- /android/package-sources/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janbar/noson-app/HEAD/android/package-sources/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /backend/NosonApp/cppdef.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define SAFE_DELETE(p) if ((p) != NULL) { delete (p); (p) = NULL; } 6 | #define SAFE_DELETE_ARRAY(p) if ((p) != NULL) { delete[] (p); (p) = NULL; } 7 | -------------------------------------------------------------------------------- /gui/images/font-scalling.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /gui/controls2_515/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # make the qml files visible on qtcreator 2 | file(GLOB_RECURSE CONTROLS2_QML_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.qml) 3 | 4 | add_custom_target(nosonapp_CONTROLS2_QMLFiles ALL SOURCES ${CONTROLS2_QML_FILES}) 5 | -------------------------------------------------------------------------------- /gui/i18n/README.md: -------------------------------------------------------------------------------- 1 | ### Update resource file 2 | 3 | lupdate ../ -ts noson_en.ts 4 | 5 | ### Release reviewed translations 6 | 7 | lrelease noson_en.ts 8 | lrelease noson_fr.ts 9 | lrelease noson_nl.ts 10 | lrelease noson_de.ts 11 | lrelease noson_da.ts 12 | 13 | -------------------------------------------------------------------------------- /gui/diskcache/diskcachefactory.h: -------------------------------------------------------------------------------- 1 | #ifndef DISKCACHEFACTORY_H 2 | #define DISKCACHEFACTORY_H 3 | 4 | #include 5 | 6 | class DiskCacheFactory : public QQmlNetworkAccessManagerFactory 7 | { 8 | public: 9 | DiskCacheFactory(int cacheSize); 10 | QNetworkAccessManager* create(QObject *parent); 11 | 12 | private: 13 | int mCacheSize; 14 | }; 15 | 16 | #endif // DISKCACHEFACTORY_H 17 | -------------------------------------------------------------------------------- /gui/images/graphic-scalling.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | %: 13 | dh $@ 14 | 15 | override_dh_auto_configure: 16 | dh_auto_configure -- 17 | -------------------------------------------------------------------------------- /android/README.txt: -------------------------------------------------------------------------------- 1 | 2 | ### Requirements: 3 | 4 | - Android SDK 31 5 | - Java jdk 17.0.12 6 | - Qt Creator 4.12 7 | 8 | - Qt >= 5.15 : Android NDK r21e 9 | 10 | ### Configure the build: 11 | 12 | source ./linux-build.sh -DKEYSTORE_FILE=~/.android/janbar.keystore -DKEYSTORE_ALIAS=key0 -DKEYSTORE_PASSWORD=${PASSWORD} 13 | 14 | ### Extras 15 | 16 | - Setup for lollipop (sdk21): 17 | ANDROID_NATIVE_API_LEVEL=21, ANDROID_SDK_MINVER=21, ANDROID_SDK_TARGET=21 18 | - Setup for marshmallow (sdk23): 19 | ANDROID_NATIVE_API_LEVEL=23, ANDROID_SDK_MINVER=23, ANDROID_SDK_TARGET=23 20 | 21 | -------------------------------------------------------------------------------- /gui/toolbox.js: -------------------------------------------------------------------------------- 1 | .pragma library 2 | 3 | // signal helpers 4 | 5 | function connectOnce(sig, slot) { 6 | var f = function() { slot.apply(this, arguments); sig.disconnect(f); }; 7 | sig.connect(f); 8 | } 9 | 10 | function connectWhileFalse(sig, slot) { 11 | var f = function() { slot.apply(this, arguments); if (arguments[0] === true) sig.disconnect(f); }; 12 | sig.connect(f); 13 | } 14 | 15 | function connectWhileTrue(sig, slot) { 16 | var f = function() { slot.apply(this, arguments); if (arguments[0] !== true) sig.disconnect(f); }; 17 | sig.connect(f); 18 | } 19 | -------------------------------------------------------------------------------- /gui/diskcache/cachingnetworkaccessmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef CACHINGNETWORKACCESSMANAGER_H 2 | #define CACHINGNETWORKACCESSMANAGER_H 3 | 4 | #include 5 | 6 | class CachingNetworkAccessManager : public QNetworkAccessManager 7 | { 8 | public: 9 | CachingNetworkAccessManager(QObject *parent = 0); 10 | 11 | QNetworkReply *createRequest(Operation op, const QNetworkRequest & req, QIODevice * outgoingData) Q_DECL_OVERRIDE; 12 | 13 | private: 14 | QStringList mUrlIgnoreList; 15 | bool shouldIgnoreUrl(const QString& url); 16 | }; 17 | 18 | #endif // CACHINGNETWORKACCESSMANAGER_H 19 | -------------------------------------------------------------------------------- /gui/controls2_515/components/ActivitySpinner.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.9 2 | import QtQuick.Controls 2.2 3 | 4 | Item { 5 | id: loading 6 | height: 96 7 | width: parent.width 8 | visible: false 9 | 10 | anchors { 11 | horizontalCenter: parent.horizontalCenter 12 | verticalCenter: parent.verticalCenter 13 | } 14 | 15 | BusyIndicator { 16 | anchors.verticalCenter: parent.verticalCenter 17 | anchors.horizontalCenter: parent.horizontalCenter 18 | running: loading.visible 19 | height: parent.height 20 | width: height 21 | opacity: 0.9 22 | z: 1 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/cmake/CheckFunctionKeywords.cmake: -------------------------------------------------------------------------------- 1 | include(CheckCSourceCompiles) 2 | 3 | macro(check_function_keywords _wordlist) 4 | set(${_result} "") 5 | foreach(flag ${_wordlist}) 6 | string(REGEX REPLACE "[-+/ ()]" "_" flagname "${flag}") 7 | string(TOUPPER "${flagname}" flagname) 8 | set(have_flag "HAVE_${flagname}") 9 | check_c_source_compiles("${flag} void func(); void func() { } int main() { func(); return 0; }" ${have_flag}) 10 | if(${have_flag} AND NOT ${_result}) 11 | set(${_result} "${flag}") 12 | # break() 13 | endif(${have_flag} AND NOT ${_result}) 14 | endforeach(flag) 15 | endmacro(check_function_keywords) 16 | -------------------------------------------------------------------------------- /backend/lib/cmake/FindFLAC.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Find and configure FLAC package 3 | # 4 | if(FLAC_INCLUDE_DIR AND FLAC_LIBRARIES) 5 | set(FLAC_FIND_QUIETLY true) 6 | endif() 7 | 8 | find_path(FLAC_INCLUDE_DIR FLAC/metadata.h) 9 | find_library(FLAC_LIBRARIES FLAC) 10 | 11 | if(FLAC_INCLUDE_DIR AND FLAC_LIBRARIES) 12 | set(FLAC_FOUND true) 13 | if(NOT FLAC_FIND_QUIETLY) 14 | message(STATUS "Found Flac: ${FLAC_LIBRARIES}") 15 | endif() 16 | else() 17 | if(FLAC_FIND_REQUIRED) 18 | message(FATAL_ERROR "Could not find FLAC") 19 | endif() 20 | if(NOT FLAC_FIND_QUIETLY) 21 | message(STATUS "Could not find FLAC") 22 | endif() 23 | endif() 24 | 25 | mark_as_advanced(FLAC_INCLUDE_DIR FLAC_LIBRARIES) 26 | 27 | -------------------------------------------------------------------------------- /backend/lib/cmake/FindFLACXX.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Find and configure FLACXX package 3 | # 4 | if(FLACXX_INCLUDE_DIR AND FLACXX_LIBRARIES) 5 | set(FLACXX_FIND_QUIETLY true) 6 | endif() 7 | 8 | find_path(FLACXX_INCLUDE_DIR FLAC++/metadata.h) 9 | find_library(FLACXX_LIBRARIES FLAC++) 10 | 11 | if(FLACXX_INCLUDE_DIR AND FLACXX_LIBRARIES) 12 | set(FLACXX_FOUND true) 13 | if(NOT FLACXX_FIND_QUIETLY) 14 | message(STATUS "Found Flac++: ${FLACXX_LIBRARIES}") 15 | endif() 16 | else() 17 | if(FLACXX_FIND_REQUIRED) 18 | message(FATAL_ERROR "Could not find FLAC++") 19 | endif() 20 | if(NOT FLACXX_FIND_QUIETLY) 21 | message(STATUS "Could not find FLAC++") 22 | endif() 23 | endif() 24 | 25 | mark_as_advanced(FLACXX_INCLUDE_DIR FLACXX_LIBRARIES) 26 | -------------------------------------------------------------------------------- /gui/signalhandler.h: -------------------------------------------------------------------------------- 1 | #ifndef SIGNALHANDLER_H 2 | #define SIGNALHANDLER_H 3 | 4 | #include 5 | #include 6 | 7 | class SignalHandler : public QObject 8 | { 9 | Q_OBJECT 10 | public: 11 | SignalHandler(QObject *parent = 0); 12 | virtual ~SignalHandler(); 13 | 14 | bool catchSignal(int signal); 15 | void omitSignal(int signal); 16 | 17 | signals: 18 | void catched(int signal); 19 | 20 | private slots: 21 | void forward(); 22 | 23 | private: 24 | SignalHandler(const SignalHandler&); 25 | SignalHandler& operator=(const SignalHandler&); 26 | 27 | QSocketNotifier *m_notifier; 28 | 29 | static int m_pipe[2]; 30 | static void handler(int signal, siginfo_t * info, void * data); 31 | }; 32 | 33 | #endif // SIGNALHANDLER_H 34 | -------------------------------------------------------------------------------- /backend/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2...3.20) 2 | 3 | OPTION (BUILD_LIBNOSON "Build libnoson from sources." ON) 4 | 5 | find_package(Qt5Core REQUIRED) 6 | message(STATUS "Found Qt5 version ${Qt5Core_VERSION}") 7 | 8 | if(NOT BUILD_DEPENDENCIES) 9 | if(NOT BUILD_LIBNOSON) 10 | find_package(noson 2.12 REQUIRED) 11 | endif() 12 | endif() 13 | if(NOT noson_FOUND) 14 | add_subdirectory (${CMAKE_CURRENT_SOURCE_DIR}/lib) 15 | endif() 16 | 17 | set(QML_IMPORT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/qml) 18 | set(QML_IMPORT_PATH ${QML_IMPORT_DIRECTORY} CACHE STRING "QML Import path" FORCE) 19 | 20 | add_subdirectory(NosonApp) 21 | add_subdirectory(NosonThumbnailer) 22 | add_subdirectory(NosonMediaScanner) 23 | 24 | # build the cli tool for desktop only 25 | if(NOT ANDROID) 26 | add_subdirectory(cli) 27 | endif() 28 | -------------------------------------------------------------------------------- /macosx/README.md: -------------------------------------------------------------------------------- 1 | ## Build instructions for MacOSX 2 | 3 | Install Xcode and CMake tool. 4 | 5 | Install required dependencies as follows. 6 | - Install a copy of Qt frameworks >= 5.15.2 in `/Users/Shared/Qt` 7 | 8 | Setup environment to build as follows. 9 | - `export PATH=/Applications/CMake.app/Contents/bin:$PATH` 10 | - `export QT_DIR=/Users/Shared/Qt/5.15.2/clang_64` 11 | - `export SOURCE_DIR=$(pwd)/noson-app` 12 | - `export BUILD_DIR=$(pwd)/noson-app/build` 13 | 14 | Download the sources and build. 15 | - `git clone https://github.com/janbar/noson-app.git $SOURCE_DIR` 16 | - `mkdir $BUILD_DIR && cd $BUILD_DIR` 17 | - `cmake -DCMAKE_PREFIX_PATH=$QT_DIR -DCMAKE_BUILD_TYPE=Release $SOURCE_DIR` 18 | - `make -j5` 19 | 20 | Generate the application bundle `Noson.app` 21 | - `$SOURCE_DIR/macosx/bundle.sh icon` 22 | - `$SOURCE_DIR/macosx/bundle.sh bundle` 23 | -------------------------------------------------------------------------------- /android/qtdeploy.json.in: -------------------------------------------------------------------------------- 1 | { 2 | "description": "This file is to be read by androiddeployqt", 3 | "qt": "@QT_ANDROID_QT_DIR@", 4 | "sdk": "@QT_ANDROID_SDK_ROOT@", 5 | "sdkBuildToolsRevision": "@QT_ANDROID_SDK_BUILDTOOLS_REVISION@", 6 | "ndk": "@QT_ANDROID_NDK_ROOT@", 7 | "toolchain-prefix": "llvm", 8 | "tool-prefix": "llvm", 9 | "useLLVM": true, 10 | "ndk-host": "@ANDROID_NDK_HOST_SYSTEM_NAME@", 11 | "architectures": { "@ANDROID_ABI@": "@QT_ANDROID_ARCHITECTURE@" }, 12 | "application-binary": "@QT_ANDROID_APP_TARGET@", 13 | "android-package": "@QT_ANDROID_APP_PACKAGE_NAME@", 14 | "android-app-name": "@QT_ANDROID_APP_NAME@", 15 | "qml-root-path": "@CMAKE_SOURCE_DIR@", 16 | "stdcpp-path": "@QT_ANDROID_STL_PATH@", 17 | @QT_ANDROID_APP_EXTRA_LIBS@ 18 | @QT_ANDROID_APP_EXTRA_PLUGINS@ 19 | "android-package-source-directory": "@QT_ANDROID_APP_PACKAGE_SOURCE_ROOT@" 20 | } 21 | -------------------------------------------------------------------------------- /backend/NosonApp/dbus/org.mpris.MediaPlayer2.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /gui/diskcache/cachereply.h: -------------------------------------------------------------------------------- 1 | #ifndef CACHEREPLY_H 2 | #define CACHEREPLY_H 3 | 4 | #include 5 | #include 6 | 7 | //QNetworkReply implementation which reads from the QNetworkDiskCache 8 | //partly copied from QNetworkReplyDataImpl, which is private 9 | class CacheReply : public QNetworkReply 10 | { 11 | public: 12 | CacheReply(QIODevice *cacheDev, const QNetworkRequest & req, 13 | QNetworkAccessManager::Operation op, 14 | QNetworkCacheMetaData meta, QObject *parent = 0); 15 | virtual ~CacheReply(); 16 | 17 | void abort() Q_DECL_OVERRIDE; 18 | qint64 bytesAvailable() const Q_DECL_OVERRIDE; 19 | bool isSequential() const Q_DECL_OVERRIDE; 20 | qint64 size() const Q_DECL_OVERRIDE; 21 | qint64 readData(char *data, qint64 maxlen) Q_DECL_OVERRIDE; 22 | 23 | private: 24 | QIODevice *mCacheDev; 25 | }; 26 | 27 | #endif // CACHEREPLY_H 28 | -------------------------------------------------------------------------------- /backend/lib/cmake/DownloadProject.CMakeLists.cmake.in: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved MIT License. See accompanying 2 | # file LICENSE or https://github.com/Crascit/DownloadProject for details. 3 | 4 | cmake_minimum_required(VERSION 3.8.2...3.20) 5 | 6 | # Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24 7 | if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") 8 | cmake_policy(SET CMP0135 NEW) 9 | endif() 10 | 11 | project(${DL_ARGS_PROJ}-download NONE) 12 | 13 | include(ExternalProject) 14 | ExternalProject_Add(${DL_ARGS_PROJ}-download 15 | ${DL_ARGS_UNPARSED_ARGUMENTS} 16 | SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" 17 | BINARY_DIR "${DL_ARGS_BINARY_DIR}" 18 | CONFIGURE_COMMAND "" 19 | BUILD_COMMAND "" 20 | INSTALL_COMMAND "" 21 | TEST_COMMAND "" 22 | ) 23 | -------------------------------------------------------------------------------- /gui/diskcache/diskcachefactory.cpp: -------------------------------------------------------------------------------- 1 | #include "diskcachefactory.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "cachingnetworkaccessmanager.h" 9 | #include "cachereply.h" 10 | 11 | DiskCacheFactory::DiskCacheFactory(int cacheSize) 12 | : mCacheSize(cacheSize) { } 13 | 14 | QNetworkAccessManager *DiskCacheFactory::create(QObject *parent) 15 | { 16 | QNetworkAccessManager *nam = new CachingNetworkAccessManager(parent); 17 | 18 | QNetworkDiskCache *diskCache = new QNetworkDiskCache(nam); 19 | QString cacheFolder = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); 20 | diskCache->setCacheDirectory(cacheFolder); 21 | diskCache->setMaximumCacheSize(mCacheSize); 22 | 23 | nam->setCache(diskCache); 24 | 25 | qDebug() << "installing network cache of" << (mCacheSize / 1024) << "KB in folder" << cacheFolder; 26 | 27 | return nam; 28 | } 29 | -------------------------------------------------------------------------------- /noson-app.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | NOSON_CLI=@NOSON_CLI@ 4 | NOSON_GUI=@NOSON_GUI@ 5 | PLUGINS_DIR=@PLUGINS_DIR@ 6 | 7 | # Check for an instance of AppImage 8 | if [ -n "$APPDIR" ] && [ -d "$APPDIR$PLUGINS_DIR" ]; then 9 | NOSON_CLI="$APPDIR$NOSON_CLI" 10 | NOSON_GUI="$APPDIR$NOSON_GUI" 11 | PLUGINS_DIR="$APPDIR$PLUGINS_DIR" 12 | fi 13 | 14 | # Launch the CLI else the GUI 15 | [ "--cli" = "$1" ] && shift && exec "$NOSON_CLI" $@ 16 | 17 | # Migrate the GUI settings 18 | if [ -f "$HOME/.config/janbar/noson.conf" ]; then 19 | mv "$HOME/.config/janbar/noson.conf" "$HOME/.config/janbar/io.github.janbar.noson.conf" 20 | [ -d "$HOME/.local/share/janbar/noson" ] && mv "$HOME/.local/share/janbar/noson" "$HOME/.local/share/janbar/io.github.janbar.noson" 21 | [ -d "$HOME/.cache/janbar/noson" ] && mv "$HOME/.cache/janbar/noson" "$HOME/.cache/janbar/io.github.janbar.noson" 22 | fi 23 | 24 | # Launch the GUI 25 | export QML2_IMPORT_PATH="$PLUGINS_DIR" 26 | exec "$NOSON_GUI" $@ 27 | -------------------------------------------------------------------------------- /macosx/env-path.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$QT_DIR" == "" ]]; then 4 | echo "QT_DIR not set" 5 | fi 6 | if [[ "$BUILD_DIR" == "" ]]; then 7 | echo "BUILD_DIR not set" 8 | fi 9 | if [[ "$SOURCE_DIR" == "" ]]; then 10 | echo "SOURCE_DIR not set" 11 | fi 12 | 13 | set -a 14 | APP_NAME=noson 15 | APP_BUNDLE=Noson.app 16 | 17 | SRC_OSX_DIR=$SOURCE_DIR/macosx 18 | SRC_RESOURCES_DIR=$SRC_OSX_DIR/resources 19 | 20 | BUILD_BIN_DIR=$BUILD_DIR 21 | BUILD_BUNDLE_DIR=$BUILD_DIR/$APP_BUNDLE 22 | BUILD_BUNDLE_CONTENTS_DIR=$BUILD_BUNDLE_DIR/Contents 23 | BUILD_BUNDLE_APP_DIR=$BUILD_BUNDLE_DIR/Contents/MacOS 24 | BUILD_BUNDLE_RES_DIR=$BUILD_BUNDLE_DIR/Contents/Resources 25 | BUILD_BUNDLE_FRW_DIR=$BUILD_BUNDLE_DIR/Contents/Frameworks 26 | BUILD_BUNDLE_PLUGIN_DIR=$BUILD_BUNDLE_DIR/Contents/PlugIns 27 | BUILD_BUNDLE_APP_FILE=$BUILD_BUNDLE_APP_DIR/noson-gui 28 | 29 | BUILD_BUNDLE_RES_QM_DIR=$BUILD_BUNDLE_RES_DIR/translations 30 | BUILD_BUNDLE_RES_BIN_DIR=$BUILD_BUNDLE_CONTENTS_DIR/Tools 31 | 32 | set +a 33 | -------------------------------------------------------------------------------- /android/linux-build-x86-qt515.sh: -------------------------------------------------------------------------------- 1 | BUILD_DIR=build-x86 2 | rm -rf $BUILD_DIR/* 3 | mkdir -p $BUILD_DIR 4 | 5 | export JAVA_HOME=$HOME/bin/java/jdk-17.0.12 6 | export ANDROID_SDK_ROOT=$HOME/bin/android/sdk 7 | export ANDROID_NDK=$HOME/bin/android/sdk/ndk/26.3.11579264 8 | export QT_DIR=$HOME/bin/Qt/5.15.16/android 9 | 10 | cmake .. -B $BUILD_DIR -DCMAKE_SYSTEM_NAME=Android \ 11 | -DCMAKE_PREFIX_PATH=$QT_DIR \ 12 | -DCMAKE_FIND_ROOT_PATH=${QT_DIR} \ 13 | -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ 14 | -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK/prebuilt/linux-x86_64/bin/make \ 15 | -DCMAKE_BUILD_TYPE=Debug \ 16 | -DANDROID_STL=c++_static \ 17 | -DANDROID_ABI="x86" \ 18 | -DANDROID_SDK_MINVER=24 \ 19 | -DANDROID_SDK_TARGET=26 \ 20 | -DANDROID_NATIVE_API_LEVEL=24 \ 21 | -DANDROID_SDK_BUILD_TOOLS_REVISION="31.0.0" \ 22 | -DANDROID_SDK_ROOT=$ANDROID_SDK_ROOT \ 23 | -DANDROID_NDK=$ANDROID_NDK \ 24 | -DQT_ANDROID_PLATFORM_LEVEL=31 \ 25 | $@ 26 | 27 | [ $? -eq 0 ] && cmake --build $BUILD_DIR --parallel 8 28 | -------------------------------------------------------------------------------- /android/linux-build-x64-qt515.sh: -------------------------------------------------------------------------------- 1 | BUILD_DIR=build-x64 2 | rm -rf $BUILD_DIR/* 3 | mkdir -p $BUILD_DIR 4 | 5 | export JAVA_HOME=$HOME/bin/java/jdk-17.0.12 6 | export ANDROID_SDK_ROOT=$HOME/bin/android/sdk 7 | export ANDROID_NDK=$HOME/bin/android/sdk/ndk/26.3.11579264 8 | export QT_DIR=$HOME/bin/Qt/5.15.16/android 9 | 10 | cmake .. -B $BUILD_DIR -DCMAKE_SYSTEM_NAME=Android \ 11 | -DCMAKE_PREFIX_PATH=$QT_DIR \ 12 | -DCMAKE_FIND_ROOT_PATH=${QT_DIR} \ 13 | -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ 14 | -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK/prebuilt/linux-x86_64/bin/make \ 15 | -DCMAKE_BUILD_TYPE=Debug \ 16 | -DANDROID_STL=c++_static \ 17 | -DANDROID_ABI="x86_64" \ 18 | -DANDROID_SDK_MINVER=24 \ 19 | -DANDROID_SDK_TARGET=26 \ 20 | -DANDROID_NATIVE_API_LEVEL=24 \ 21 | -DANDROID_SDK_BUILD_TOOLS_REVISION="31.0.0" \ 22 | -DANDROID_SDK_ROOT=$ANDROID_SDK_ROOT \ 23 | -DANDROID_NDK=$ANDROID_NDK \ 24 | -DQT_ANDROID_PLATFORM_LEVEL=31 \ 25 | $@ 26 | 27 | [ $? -eq 0 ] && cmake --build $BUILD_DIR --parallel 8 28 | -------------------------------------------------------------------------------- /android/linux-build-arm64-qt515.sh: -------------------------------------------------------------------------------- 1 | BUILD_DIR=build-arm64 2 | rm -rf $BUILD_DIR/* 3 | mkdir -p $BUILD_DIR 4 | 5 | export JAVA_HOME=$HOME/bin/java/jdk-17.0.12 6 | export ANDROID_SDK_ROOT=$HOME/bin/android/sdk 7 | export ANDROID_NDK=$HOME/bin/android/sdk/ndk/26.3.11579264 8 | export QT_DIR=$HOME/bin/Qt/5.15.16/android 9 | 10 | cmake .. -B $BUILD_DIR -DCMAKE_SYSTEM_NAME=Android \ 11 | -DCMAKE_PREFIX_PATH=$QT_DIR \ 12 | -DCMAKE_FIND_ROOT_PATH=${QT_DIR} \ 13 | -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ 14 | -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK/prebuilt/linux-x86_64/bin/make \ 15 | -DCMAKE_BUILD_TYPE=Release \ 16 | -DANDROID_STL=c++_static \ 17 | -DANDROID_ABI="arm64-v8a" \ 18 | -DANDROID_SDK_MINVER=24 \ 19 | -DANDROID_SDK_TARGET=26 \ 20 | -DANDROID_NATIVE_API_LEVEL=24 \ 21 | -DANDROID_SDK_BUILD_TOOLS_REVISION="31.0.0" \ 22 | -DANDROID_SDK_ROOT=$ANDROID_SDK_ROOT \ 23 | -DANDROID_NDK=$ANDROID_NDK \ 24 | -DQT_ANDROID_PLATFORM_LEVEL=31 \ 25 | $@ 26 | 27 | [ $? -eq 0 ] && cmake --build $BUILD_DIR --parallel 8 28 | -------------------------------------------------------------------------------- /android/linux-build-armv7-qt515.sh: -------------------------------------------------------------------------------- 1 | BUILD_DIR=build-armv7 2 | rm -rf $BUILD_DIR/* 3 | mkdir -p $BUILD_DIR 4 | 5 | export JAVA_HOME=$HOME/bin/java/jdk-17.0.12 6 | export ANDROID_SDK_ROOT=$HOME/bin/android/sdk 7 | export ANDROID_NDK=$HOME/bin/android/sdk/ndk/26.3.11579264 8 | export QT_DIR=$HOME/bin/Qt/5.15.16/android 9 | 10 | cmake .. -B $BUILD_DIR -DCMAKE_SYSTEM_NAME=Android \ 11 | -DCMAKE_PREFIX_PATH=$QT_DIR \ 12 | -DCMAKE_FIND_ROOT_PATH=${QT_DIR} \ 13 | -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \ 14 | -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK/prebuilt/linux-x86_64/bin/make \ 15 | -DCMAKE_BUILD_TYPE=Release \ 16 | -DANDROID_STL=c++_static \ 17 | -DANDROID_ABI="armeabi-v7a" \ 18 | -DANDROID_SDK_MINVER=24 \ 19 | -DANDROID_SDK_TARGET=26 \ 20 | -DANDROID_NATIVE_API_LEVEL=24 \ 21 | -DANDROID_SDK_BUILD_TOOLS_REVISION="31.0.0" \ 22 | -DANDROID_SDK_ROOT=$ANDROID_SDK_ROOT \ 23 | -DANDROID_NDK=$ANDROID_NDK \ 24 | -DQT_ANDROID_PLATFORM_LEVEL=31 \ 25 | $@ 26 | 27 | [ $? -eq 0 ] && cmake --build $BUILD_DIR --parallel 8 28 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/byteorder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #include "byteorder.h" 19 | 20 | static int test_endianess() { 21 | unsigned int test = 1; 22 | return (*((char*)(&test))) ? LITTLE_ENDIAN : BIG_ENDIAN; 23 | } 24 | 25 | int machine_bom = test_endianess(); 26 | -------------------------------------------------------------------------------- /macosx/resources/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildHashKey 6 | 7 | BuildTime 8 | 9 | CFBundleExecutable 10 | noson-gui 11 | CFBundleIconFile 12 | noson 13 | CFBundleIdentifier 14 | noson.janbar 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | Noson 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 23 | CFBundleVersion 24 | 25 | CSResourcesFileMapped 26 | 27 | LSRequiresCarbon 28 | 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 2 | MESSAGE(FATAL_ERROR "Cannot find install manifest: 3 | \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 4 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 5 | 6 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 7 | STRING(REGEX REPLACE "\n" ";" files "${files}") 8 | FOREACH(file ${files}) 9 | MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 10 | IF(EXISTS "$ENV{DESTDIR}${file}") 11 | EXEC_PROGRAM( 12 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 13 | OUTPUT_VARIABLE rm_out 14 | RETURN_VALUE rm_retval 15 | ) 16 | IF(NOT "${rm_retval}" STREQUAL 0) 17 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 18 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 19 | ELSE(EXISTS "$ENV{DESTDIR}${file}") 20 | MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 21 | ENDIF(EXISTS "$ENV{DESTDIR}${file}") 22 | ENDFOREACH(file) 23 | -------------------------------------------------------------------------------- /gui/diskcache/cachingnetworkaccessmanager.cpp: -------------------------------------------------------------------------------- 1 | #include "cachingnetworkaccessmanager.h" 2 | #include "cachereply.h" 3 | #include 4 | 5 | CachingNetworkAccessManager::CachingNetworkAccessManager(QObject *parent) 6 | : QNetworkAccessManager(parent) 7 | { 8 | //mUrlIgnoreList.append("[nocached_url]"); 9 | } 10 | 11 | QNetworkReply *CachingNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *outgoingData) 12 | { 13 | QNetworkCacheMetaData meta = cache()->metaData(req.url()); 14 | if(meta.isValid() && !shouldIgnoreUrl(req.url().url())) 15 | { 16 | //cache contains URL -> return cache reply 17 | //TODO need to check for expiration date? 18 | return new CacheReply(cache()->data(req.url()), req, op, meta); 19 | } 20 | else 21 | { 22 | return QNetworkAccessManager::createRequest(op, req, outgoingData); 23 | } 24 | } 25 | 26 | bool CachingNetworkAccessManager::shouldIgnoreUrl(const QString &url) 27 | { 28 | return mUrlIgnoreList.contains(url); 29 | } 30 | -------------------------------------------------------------------------------- /gui/controls2_515/components/ListItemActions/Remove.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014, 2015 3 | * Andrew Hayzen 4 | * Daniel Holm 5 | * Victor Thompson 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | import QtQuick 2.9 21 | import QtQuick.Controls 2.2 22 | 23 | MenuItem { 24 | text: qsTr("Remove") 25 | font.pointSize: units.fs("medium") 26 | height: visible ? implicitHeight : 0 27 | } 28 | -------------------------------------------------------------------------------- /gui/images/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /gui/controls2_515/Welcome.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | import "components" 24 | 25 | MusicPage { 26 | id: welcomePage 27 | objectName: "welcomePage" 28 | pageTitle: "" 29 | } 30 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/packed.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef PACKED_H 19 | #define PACKED_H 20 | 21 | #ifdef _MSC_VER 22 | #define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) ) 23 | #else 24 | #define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) 25 | #endif 26 | 27 | #endif /* PACKED_H */ 28 | -------------------------------------------------------------------------------- /gui/controls2_515/ThisDevice/AddToQueue.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | 21 | MenuItem { 22 | text: qsTr("Add to queue") 23 | font.pointSize: units.fs("medium") 24 | height: visible ? implicitHeight : 0 25 | 26 | property var modelItem 27 | 28 | onTriggered: { 29 | addQueue({id: modelItem.Id, payload: makeItemPayload(modelItem)}); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gui/controls2_515/components/ListItemActions/AddToQueue.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014, 2015, 2016 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | 24 | MenuItem { 25 | text: qsTr("Add to queue") 26 | font.pointSize: units.fs("medium") 27 | height: visible ? implicitHeight : 0 28 | 29 | onTriggered: addQueue({id: model.Id, payload: model.payload}) 30 | } 31 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/id3parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef ID3PARSER_H 19 | #define ID3PARSER_H 20 | 21 | #include "mediaparser.h" 22 | 23 | namespace mediascanner 24 | { 25 | 26 | class ID3Parser : public MediaParser 27 | { 28 | public: 29 | const char * commonName() override { return "ID3"; } 30 | bool match(const QFileInfo& fileInfo) override; 31 | bool parse(MediaFile * file, MediaInfo * info, bool debug) override; 32 | }; 33 | 34 | } 35 | 36 | #endif /* ID3PARSER_H */ 37 | 38 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/flacparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef FLACPARSER_H 19 | #define FLACPARSER_H 20 | 21 | #include "mediaparser.h" 22 | 23 | namespace mediascanner 24 | { 25 | 26 | class FLACParser : public MediaParser 27 | { 28 | public: 29 | const char * commonName() override { return "FLAC"; } 30 | bool match(const QFileInfo& fileInfo) override; 31 | bool parse(MediaFile * file, MediaInfo * info, bool debug) override; 32 | }; 33 | 34 | } 35 | 36 | #endif /* FLACPARSER_H */ 37 | 38 | -------------------------------------------------------------------------------- /gui/images/media-playback-pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef TOOLS_H 19 | #define TOOLS_H 20 | 21 | #include 22 | 23 | static inline QString normalizedString(const QString& str) 24 | { 25 | QString ret; 26 | QString tmp = str.normalized(QString::NormalizationForm_D); 27 | ret.reserve(tmp.size()); 28 | for (QString::const_iterator it = tmp.begin(); it != tmp.end(); ++it) 29 | { 30 | int cat = it->category(); 31 | if (cat != QChar::Mark_NonSpacing && cat != QChar::Mark_SpacingCombining) 32 | ret.append(*it); 33 | } 34 | return ret; 35 | } 36 | 37 | #endif /* TOOLS_H */ 38 | 39 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/mediarunnable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef MEDIADELAYEDRUNNABLE_H 19 | #define MEDIADELAYEDRUNNABLE_H 20 | 21 | #include 22 | #include 23 | 24 | namespace mediascanner 25 | { 26 | 27 | class MediaRunnable : public QRunnable 28 | { 29 | public: 30 | MediaRunnable(bool debug); 31 | virtual ~MediaRunnable() override; 32 | void setTimeout(qint64 timeout); 33 | qint64 timeLeft(); 34 | 35 | protected: 36 | bool m_debug; 37 | 38 | private: 39 | QElapsedTimer * m_timer; 40 | qint64 m_timeout; 41 | }; 42 | 43 | } 44 | 45 | 46 | #endif /* MEDIADELAYEDRUNNABLE_H */ 47 | 48 | -------------------------------------------------------------------------------- /gui/controls2_515/components/Flickables/MusicListView.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014, 2015 3 | * Andrew Hayzen 4 | * Daniel Holm 5 | * Victor Thompson 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | import QtQuick 2.9 21 | import QtQuick.Controls 2.2 22 | 23 | ListView { 24 | Component.onCompleted: { 25 | // Return values depending on the grid unit definition 26 | // for Flickable.maximumFlickVelocity and Flickable.flickDeceleration 27 | var scaleFactor = units.scaleFactor; 28 | maximumFlickVelocity = maximumFlickVelocity * scaleFactor; 29 | flickDeceleration = flickDeceleration * scaleFactor; 30 | } 31 | 32 | ScrollBar.vertical: ScrollBar {} 33 | } 34 | -------------------------------------------------------------------------------- /backend/NosonApp/plugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015-2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef NOSONAPPPLUGIN_H 22 | #define NOSONAPPPLUGIN_H 23 | 24 | #include 25 | #include 26 | 27 | class NosonAppPlugin : public QQmlExtensionPlugin 28 | { 29 | Q_OBJECT 30 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") 31 | 32 | public: 33 | NosonAppPlugin(QObject* parent = 0) 34 | : QQmlExtensionPlugin(parent) { } 35 | 36 | void registerTypes(const char *uri); 37 | void initializeEngine(QQmlEngine *engine, const char *uri); 38 | }; 39 | 40 | #endif // NOSONAPPPLUGIN_H 41 | 42 | 43 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/mediaparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef MEDIAPARSER_H 19 | #define MEDIAPARSER_H 20 | 21 | #include 22 | #include 23 | 24 | namespace mediascanner 25 | { 26 | 27 | struct MediaFile; 28 | struct MediaInfo; 29 | 30 | class MediaParser 31 | { 32 | public: 33 | virtual ~MediaParser() {} 34 | virtual const char * commonName() = 0; 35 | virtual bool match(const QFileInfo& fileInfo) = 0; 36 | virtual bool parse(MediaFile * file, MediaInfo * info, bool debug) = 0; 37 | }; 38 | 39 | typedef QSharedPointer MediaParserPtr; 40 | 41 | } 42 | 43 | #endif /* MEDIAPARSER_H */ 44 | 45 | -------------------------------------------------------------------------------- /gui/controls2_515/components/ListItemActions/AddToPlaylist.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014, 2015, 2016 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | 24 | MenuItem { 25 | text: qsTr("Add to playlist") 26 | font.pointSize: units.fs("medium") 27 | height: visible ? implicitHeight : 0 28 | 29 | onTriggered: { 30 | // WARNING: Get the payload of model now to increment the reference count 31 | stackView.push("qrc:/controls2/AddToPlaylist.qml", 32 | {"chosenElements": [{id: model.Id, payload: model.payload}]}) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gui/controls2_515/components/SimpleRow.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | 21 | Row { 22 | property alias column: columnComponent.sourceComponent 23 | 24 | spacing: units.gu(2) 25 | 26 | Loader { 27 | id: columnComponent 28 | anchors { 29 | verticalCenter: parent.verticalCenter 30 | } 31 | width: parent.width - parent.spacing 32 | 33 | onSourceComponentChanged: { 34 | for (var i=0; i < item.children.length; i++) { 35 | // binds to width so it is updated when screen size changes 36 | item.children[i].width = Qt.binding(function () { return width; }) 37 | } 38 | } 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/plugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef MEDIASCANNERPLUGIN_H 19 | #define MEDIASCANNERPLUGIN_H 20 | 21 | #include 22 | #include 23 | 24 | class MediaScannerPlugin : public QQmlExtensionPlugin 25 | { 26 | 27 | Q_OBJECT 28 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") 29 | 30 | public: 31 | MediaScannerPlugin(QObject* parent = nullptr) 32 | : QQmlExtensionPlugin(parent) { } 33 | 34 | virtual void registerTypes(const char* uri) override; 35 | virtual void initializeEngine(QQmlEngine* engine, const char* uri) override; 36 | static QObject* createMediaScanner(QQmlEngine *engine, QJSEngine *scriptEngine); 37 | }; 38 | 39 | #endif /* MEDIASCANNERPLUGIN_H */ 40 | 41 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/mediarunnable.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #include "mediarunnable.h" 19 | 20 | using namespace mediascanner; 21 | 22 | MediaRunnable::MediaRunnable(bool debug) 23 | : QRunnable() 24 | , m_debug(debug) 25 | , m_timer(nullptr) 26 | , m_timeout(0) 27 | { 28 | } 29 | 30 | MediaRunnable::~MediaRunnable() 31 | { 32 | if (m_timer) 33 | delete m_timer; 34 | } 35 | 36 | void MediaRunnable::setTimeout(qint64 timeout) 37 | { 38 | if (timeout < 0) 39 | m_timeout = 0; 40 | else if (!m_timer) 41 | { 42 | m_timer = new QElapsedTimer(); 43 | m_timer->start(); 44 | } 45 | m_timeout = timeout; 46 | } 47 | 48 | qint64 MediaRunnable::timeLeft() 49 | { 50 | if (!m_timer) 51 | return 0; 52 | return m_timeout - m_timer->elapsed(); 53 | } 54 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/netmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef NETMANAGER_H 22 | #define NETMANAGER_H 23 | 24 | #include "netrequest.h" 25 | 26 | #include 27 | 28 | namespace thumbnailer 29 | { 30 | 31 | class NetManager : public QObject 32 | { 33 | Q_OBJECT 34 | public: 35 | NetManager(QObject* parent = 0); 36 | ~NetManager(); 37 | 38 | QNetworkAccessManager* networkAccessManager(); 39 | 40 | static bool initSSLDefaultConfiguration(); 41 | 42 | signals: 43 | void request(NetRequest*); 44 | 45 | private slots: 46 | void onRequest(NetRequest* wr); 47 | 48 | private: 49 | QNetworkAccessManager* m_nam; 50 | }; 51 | 52 | } 53 | #endif /* NETMANAGER_H */ 54 | 55 | -------------------------------------------------------------------------------- /backend/NosonApp/qmlsortbehavior.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Canonical, Ltd. 3 | * 4 | * Authors: 5 | * Christian Dywan 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation; version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "qmlsortbehavior.h" 21 | 22 | using namespace nosonapp; 23 | 24 | SortBehavior::SortBehavior(QObject *parent) 25 | : QObject(parent) 26 | , m_property(QString()) 27 | , m_order(Qt::AscendingOrder) 28 | { 29 | 30 | } 31 | 32 | QString 33 | SortBehavior::property() const 34 | { 35 | return m_property; 36 | } 37 | 38 | Qt::SortOrder 39 | SortBehavior::order() const 40 | { 41 | return m_order; 42 | } 43 | 44 | void 45 | SortBehavior::setProperty(const QString& property) 46 | { 47 | m_property = property; 48 | Q_EMIT propertyChanged(); 49 | } 50 | 51 | void 52 | SortBehavior::setOrder(Qt::SortOrder order) 53 | { 54 | m_order = order; 55 | Q_EMIT orderChanged(); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /backend/NosonApp/qmlfilterbehavior.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Canonical, Ltd. 3 | * 4 | * Authors: 5 | * Christian Dywan 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation; version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include "qmlfilterbehavior.h" 21 | 22 | using namespace nosonapp; 23 | 24 | FilterBehavior::FilterBehavior(QObject *parent) 25 | : QObject(parent) 26 | , m_property(QString()) 27 | , m_pattern(REGEXP_TYPE()) 28 | { 29 | 30 | } 31 | 32 | QString 33 | FilterBehavior::property() const 34 | { 35 | return m_property; 36 | } 37 | 38 | void 39 | FilterBehavior::setProperty(const QString& property) 40 | { 41 | m_property = property; 42 | Q_EMIT propertyChanged(); 43 | } 44 | 45 | REGEXP_TYPE 46 | FilterBehavior::pattern() const 47 | { 48 | return m_pattern; 49 | } 50 | 51 | void 52 | FilterBehavior::setPattern(REGEXP_TYPE pattern) 53 | { 54 | m_pattern = pattern; 55 | Q_EMIT patternChanged(); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/mediaextractor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef MEDIAEXTRACTOR_H 19 | #define MEDIAEXTRACTOR_H 20 | 21 | #include "mediafile.h" 22 | #include "mediainfo.h" 23 | #include "mediarunnable.h" 24 | 25 | #define TAG_UNDEFINED "" 26 | 27 | namespace mediascanner 28 | { 29 | 30 | typedef void (*MediaExtractorCallback)(void * handle, MediaFilePtr& filePtr); 31 | 32 | class MediaExtractor : public MediaRunnable 33 | { 34 | public: 35 | MediaExtractor(void * handle, MediaExtractorCallback callback, MediaFilePtr& filePtr, bool debug); 36 | virtual ~MediaExtractor() override {} 37 | 38 | void run() override; 39 | 40 | private: 41 | void * m_handle; 42 | MediaExtractorCallback m_callback; 43 | MediaFilePtr m_filePtr; 44 | }; 45 | 46 | } 47 | 48 | #endif /* MEDIAEXTRACTOR_H */ 49 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/artistartgenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Canonical Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation; version 3. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU Lesser General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this program. If not, see . 15 | * 16 | * Authors: Pawel Stolowski 17 | */ 18 | 19 | #ifndef ARTISTARTGENERATOR_H 20 | #define ARTISTARTGENERATOR_H 21 | 22 | #include "thumbnailer/thumbnailer.h" 23 | 24 | #include 25 | 26 | #include 27 | 28 | namespace thumbnailer 29 | { 30 | 31 | namespace qml 32 | { 33 | 34 | class ArtistArtGenerator : public QQuickAsyncImageProvider 35 | { 36 | private: 37 | std::shared_ptr thumbnailer; 38 | 39 | public: 40 | ArtistArtGenerator(std::shared_ptr const& thumbnailer); 41 | QQuickImageResponse* requestImageResponse(const QString& id, const QSize& requestedSize) override; 42 | }; 43 | 44 | } // namespace qml 45 | 46 | } // namespace thumbnailer 47 | #endif /* ARTISTARTGENERATOR_H */ 48 | 49 | -------------------------------------------------------------------------------- /gui/controls2_515/ThisDevice/QueueAllButton.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | import "../components" 21 | 22 | Icon { 23 | height: units.gu(5) 24 | width: units.gu(16) 25 | source: "qrc:/images/add.svg" 26 | label { 27 | //: this appears in a button with limited space (around 14 characters) 28 | text: qsTr("Queue all") 29 | font.pointSize: units.fs("small") 30 | width: width - units.gu(6) 31 | elide: Text.ElideRight 32 | } 33 | 34 | property var model 35 | 36 | onClicked: { 37 | delayAddQueue.start() 38 | } 39 | 40 | Timer { 41 | id: delayAddQueue 42 | interval: 100 43 | onTriggered: { 44 | var items = makeContainerPayloads(model); 45 | addMultipleItemsToQueue(items); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /backend/cli/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2...3.20) 2 | 3 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 4 | set(CMAKE_CXX_STANDARD 11) 5 | 6 | ############################################################################### 7 | # configure 8 | include_directories(${noson_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} 9 | ${CMAKE_CURRENT_SOURCE_DIR} 10 | ) 11 | 12 | if (MSVC) 13 | set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /W3 /Od /RTC1") 14 | set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /EHsc /nologo") 15 | set (CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /O2 /EHsc /nologo") 16 | set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /O2 /EHsc /nologo") 17 | set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /Od /RTC1 /EHsc /nologo") 18 | endif () 19 | 20 | set( 21 | noson-cli_SOURCES 22 | noson.cpp 23 | ) 24 | 25 | set( 26 | noson-cli_HEADERS 27 | tokenizer.h 28 | builtin.h 29 | ) 30 | 31 | add_executable (noson-cli ${noson-cli_SOURCES} ${noson-cli_HEADERS}) 32 | 33 | if(NOT noson_FOUND) 34 | add_dependencies(noson-cli noson) 35 | endif() 36 | 37 | set(noson-cli_LIBRARIES ${noson_LIBRARIES}) 38 | 39 | if(MSVC) 40 | list(APPEND noson-cli_LIBRARIES ws2_32) 41 | endif() 42 | 43 | target_link_libraries(noson-cli ${noson-cli_LIBRARIES}) 44 | 45 | if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") 46 | find_library(SOCKET socket REQUIRED) 47 | find_library(NSL nsl REQUIRED) 48 | target_link_libraries(noson-cli socket nsl) 49 | endif() 50 | 51 | install(TARGETS noson-cli DESTINATION ${PLUGINS_DIR}/) 52 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/diskcachemanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef DISKCACHEMANAGER_H 22 | #define DISKCACHEMANAGER_H 23 | 24 | #include 25 | 26 | namespace thumbnailer 27 | { 28 | 29 | class DiskCacheManager : public QObject 30 | { 31 | Q_OBJECT 32 | public: 33 | DiskCacheManager(const QString& offlineStoragePath, 34 | qint64 maxCacheSize, QObject* parent = 0); 35 | ~DiskCacheManager(); 36 | 37 | QIODevice* queryData(const QUrl& url, bool noExpire = false); 38 | QIODevice* createData(const QUrl& url, const QDateTime& expirationDate); 39 | void insertData(QIODevice* cacheDev); 40 | 41 | void clear(); 42 | 43 | private: 44 | QNetworkDiskCache* m_cache; 45 | }; 46 | 47 | } 48 | #endif /* DISKCACHEMANAGER_H */ 49 | 50 | -------------------------------------------------------------------------------- /gui/images/delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: noson-app 3 | Source: https://github.com/janbar/noson-app 4 | 5 | Files: * 6 | Copyright: 2015 Jean-Luc Barriere 7 | License: GPL-3.0+ 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | . 13 | This package is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | . 18 | You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | . 21 | On Debian systems, the complete text of the GNU General 22 | Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". 23 | . 24 | If you modify this Program, or any covered work, by linking or 25 | combining it with the OpenSSL project's "OpenSSL" library (or a 26 | modified version of that library), containing parts covered by 27 | the terms of OpenSSL/SSLeay license, the licensors of this 28 | Program grant you additional permission to convey the resulting 29 | work. Corresponding Source for a non-source form of such a 30 | combination shall include the source code for the parts of the 31 | OpenSSL library used as well as that of the covered work. 32 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: required 3 | dist: xenial 4 | 5 | os: 6 | - linux 7 | 8 | env: 9 | - QTENV="qt511" 10 | - QTENV="qt512" 11 | 12 | compiler: 13 | - clang 14 | # - gcc 15 | 16 | addons: 17 | apt: 18 | sources: 19 | - ubuntu-toolchain-r-test 20 | packages: 21 | - cmake 22 | - freeglut3-dev 23 | - libpulse-dev 24 | - libflac-dev 25 | - libflac++-dev 26 | - zlib1g-dev 27 | - libssl-dev 28 | - libdbus-1-dev 29 | 30 | before_install: 31 | - if [ "$CC" = "clang" ]; then 32 | export CXX="clang++" CC="clang"; 33 | fi; 34 | - if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$CXX" = "g++" ]; then 35 | export CXX="g++" CC="gcc"; 36 | export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'; 37 | fi; 38 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then 39 | if [ "$QTENV" = "qt511" ]; then 40 | sudo add-apt-repository ppa:beineri/opt-qt-5.11.3-xenial -y; 41 | else 42 | sudo add-apt-repository ppa:beineri/opt-qt-5.12.6-xenial -y; 43 | fi; 44 | sudo apt-get update; 45 | sudo apt-get install ${QTENV}base ${QTENV}tools ${QTENV}declarative ${QTENV}quickcontrols2 ${QTENV}svg -y --allow-unauthenticated; 46 | fi; 47 | 48 | before_script: 49 | - source /opt/${QTENV}/bin/${QTENV}-env.sh 50 | - cmake --version 51 | - mkdir build && cd build 52 | - cmake .. -Wdev -DCMAKE_CXX_COMPILER=$(which $CXX) -DCMAKE_C_COMPILER=$(which $CC) -DCMAKE_INSTALL_PREFIX=$HOME 53 | 54 | script: 55 | - cmake --build . --target install 56 | - cmake --build . --target uninstall 57 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/albumartgenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Canonical Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation; version 3. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU Lesser General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this program. If not, see . 15 | * 16 | * Authors: Jussi Pakkanen 17 | * James Henstridge 18 | */ 19 | 20 | #ifndef ALBUMARTGENERATOR_H 21 | #define ALBUMARTGENERATOR_H 22 | 23 | #include "thumbnailer/thumbnailer.h" 24 | 25 | #include 26 | 27 | #include 28 | 29 | namespace thumbnailer 30 | { 31 | 32 | namespace qml 33 | { 34 | 35 | class AlbumArtGenerator : public QQuickAsyncImageProvider 36 | { 37 | private: 38 | std::shared_ptr thumbnailer; 39 | 40 | public: 41 | AlbumArtGenerator(std::shared_ptr const& thumbnailer); 42 | QQuickImageResponse* requestImageResponse(const QString& id, const QSize& requestedSize) override; 43 | }; 44 | 45 | } // namespace qml 46 | 47 | } // namespace thumbnailer 48 | #endif /* ALBUMARTGENERATOR_H */ 49 | 50 | -------------------------------------------------------------------------------- /gui/images/media-playlist-repeat.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/listmodel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #include "listmodel.h" 19 | #include "locked.h" 20 | 21 | using namespace mediascanner; 22 | 23 | ListModel::ListModel(QObject * parent) 24 | : QAbstractListModel(parent) 25 | , m_lock(0) 26 | , m_provider(MediaScanner::instance()) 27 | , m_dataState(ListModel::New) 28 | , m_updateSignaled(false) 29 | { 30 | m_lock = new QRecursiveMutex(); 31 | } 32 | 33 | ListModel::~ListModel() 34 | { 35 | { 36 | LockGuard g(m_lock); 37 | m_provider->unregisterModel(this); 38 | } 39 | delete m_lock; 40 | } 41 | 42 | bool ListModel::init(bool fill /*= true*/) 43 | { 44 | LockGuard g(m_lock); // is recursive 45 | m_provider->unregisterModel(this); 46 | m_provider->registerModel(this); 47 | m_dataState = ListModel::NoData; 48 | if (fill) 49 | return this->load(); 50 | return false; // not filled 51 | } 52 | -------------------------------------------------------------------------------- /.github/workflows/build-ubuntu-latest.yml: -------------------------------------------------------------------------------- 1 | name: build ubuntu 24.04 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | push: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-24.04 14 | environment: build 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | - name: Update package list 19 | run: sudo apt-get update 20 | - name: Install software-properties-common 21 | run: sudo apt-get install software-properties-common 22 | - name: Install clang compiler and tools 23 | run: | 24 | sudo apt-get -y install clang ccache cmake pkg-config curl wget 25 | - name: Install dependencies 26 | run: | 27 | sudo apt-get install -y \ 28 | libflac-dev libflac++-dev libpulse-dev zlib1g-dev \ 29 | libssl-dev libdbus-1-dev \ 30 | libqt5quickwidgets5 libqt5quickcontrols2-5 libqt5qmlmodels5 libqt5qml5 \ 31 | libqt5dbus5 libqt5svg5-dev qttools5-dev qttools5-dev-tools \ 32 | qtdeclarative5-dev qtquickcontrols2-5-dev qtmultimedia5-dev \ 33 | qml-module-qtquick2 qml-module-qtgraphicaleffects \ 34 | qml-module-qtquick-layouts qml-module-qtquick-controls2 \ 35 | qml-module-qt-labs-settings 36 | 37 | - name: Fetch submodules 38 | run: git submodule init && git submodule update 39 | - name: Configure build 40 | run: | 41 | cmake -B build -Wno-dev 42 | - name: Build 43 | run: cmake --build build 44 | - name: Install 45 | run: sudo cmake --install build 46 | -------------------------------------------------------------------------------- /gui/controls2_515/components/ListItemActions/AddToFavorites.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | import NosonApp 1.0 21 | 22 | MenuItem { 23 | property bool isFavorite: false 24 | property string description: "" 25 | property string art: "" 26 | property string iconSource: isFavorite ? "qrc:/images/starred.svg" : "qrc/images/non-starred.svg" 27 | 28 | text: isFavorite ? qsTr("Remove from favorites") : qsTr("Add to favorites") 29 | font.pointSize: units.fs("medium") 30 | height: visible ? implicitHeight : 0 31 | 32 | Component.onCompleted: { 33 | isFavorite = enabled && (AllFavoritesModel.findFavorite(model.payload) !== "") 34 | } 35 | 36 | onTriggered: { 37 | if (isFavorite && removeFromFavorites(model.payload)) 38 | isFavorite = false 39 | else if (!isFavorite && addItemToFavorites(model, description, art)) 40 | isFavorite = true 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /backend/NosonApp/qmlsortbehavior.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Canonical, Ltd. 3 | * 4 | * Authors: 5 | * Christian Dywan 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation; version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef NOSONAPPSORTBEHAVIOR_H 21 | #define NOSONAPPSORTBEHAVIOR_H 22 | 23 | #include 24 | 25 | namespace nosonapp 26 | { 27 | 28 | class SortBehavior : public QObject { 29 | Q_OBJECT 30 | 31 | Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged) 32 | Q_PROPERTY(Qt::SortOrder order READ order WRITE setOrder NOTIFY orderChanged) 33 | 34 | public: 35 | explicit SortBehavior(QObject *parent = 0); 36 | 37 | QString property() const; 38 | void setProperty(const QString& property); 39 | Qt::SortOrder order() const; 40 | void setOrder(Qt::SortOrder order); 41 | 42 | Q_SIGNALS: 43 | void propertyChanged(); 44 | void orderChanged(); 45 | 46 | private: 47 | QString m_property; 48 | Qt::SortOrder m_order; 49 | }; 50 | 51 | } 52 | 53 | #endif // NOSONAPPSORTBEHAVIOR_H 54 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/mediainfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef MEDIAINFO_H 19 | #define MEDIAINFO_H 20 | 21 | #include 22 | #include 23 | 24 | namespace mediascanner 25 | { 26 | 27 | struct MediaInfo 28 | { 29 | QString title; 30 | QString artist; 31 | QString album; 32 | QString albumArtist; 33 | QString genre; 34 | QString composer; 35 | int trackNo; 36 | int discNo; 37 | int year; 38 | bool hasArt; 39 | bool isDeleted; 40 | QString container; 41 | QString codec; 42 | int channels; 43 | int sampleRate; 44 | int bitRate; 45 | int duration; 46 | 47 | MediaInfo() 48 | : trackNo(0) 49 | , discNo(0) 50 | , year(0) 51 | , hasArt(false) 52 | , isDeleted(false) 53 | , channels(0) 54 | , sampleRate(0) 55 | , bitRate(0) 56 | , duration(0) 57 | {} 58 | }; 59 | 60 | typedef QSharedPointer MediaInfoPtr; 61 | 62 | } 63 | 64 | #endif /* MEDIAINFO_H */ 65 | 66 | -------------------------------------------------------------------------------- /gui/controls2_515/ThisDevice/PlayAllButton.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | import "../components" 21 | 22 | Icon { 23 | height: units.gu(5) 24 | width: units.gu(16) 25 | source: "qrc:/images/media-playback-start.svg" 26 | label { 27 | //: this appears in a button with limited space (around 14 characters) 28 | text: qsTr("Play all") 29 | font.pointSize: units.fs("small") 30 | width: width - units.gu(6) 31 | elide: Text.ElideRight 32 | } 33 | 34 | property var model 35 | 36 | onClicked: { 37 | delayPlayAll.start() 38 | } 39 | 40 | Timer { 41 | id: delayPlayAll 42 | interval: 100 43 | onTriggered: { 44 | var items = makeContainerPayloads(model); 45 | if (items.length > 0 && playAll(items[0])) { 46 | addMultipleItemsToQueue(items.slice(1, items.length)); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/mediafile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef MEDIAFILE_H 19 | #define MEDIAFILE_H 20 | 21 | #include "mediaparser.h" 22 | #include "mediainfo.h" 23 | 24 | #include 25 | #include 26 | 27 | namespace mediascanner 28 | { 29 | 30 | struct MediaFile 31 | { 32 | unsigned fileId; 33 | bool isPinned; 34 | bool isDirectory; 35 | QString filePath; 36 | QString baseName; 37 | QString suffix; 38 | QString path; 39 | qint64 size; 40 | QDateTime lastModified; 41 | MediaParserPtr parser; 42 | int retry; 43 | bool isValid; 44 | bool signaled; 45 | MediaInfoPtr mediaInfo; 46 | 47 | MediaFile(unsigned id) 48 | : fileId(id) 49 | , isPinned(false) 50 | , isDirectory(false) 51 | , retry(0) 52 | , isValid(false) 53 | , signaled(false) 54 | , mediaInfo(nullptr) 55 | { } 56 | }; 57 | 58 | typedef QSharedPointer MediaFilePtr; 59 | 60 | } 61 | 62 | #endif /* MEDIAFILE_H */ 63 | 64 | -------------------------------------------------------------------------------- /gui/controls2_515/components/IndexEmptyState.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | 24 | 25 | Rectangle { 26 | id: indexEmptyState 27 | anchors.fill: parent 28 | color: styleMusic.view.backgroundColor 29 | 30 | Column { 31 | anchors.centerIn: parent 32 | spacing: units.gu(4) 33 | width: parent.width > units.gu(44) ? parent.width - units.gu(8) : units.gu(40) 34 | 35 | Label { 36 | color: styleMusic.view.labelColor 37 | elide: Text.ElideRight 38 | font.pointSize: units.fs("x-large") 39 | horizontalAlignment: Text.AlignHCenter 40 | maximumLineCount: 2 41 | text: qsTr("No index found") 42 | width: parent.width 43 | wrapMode: Text.WordWrap 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /gui/controls2_515/components/IndexUpdateState.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | 24 | 25 | Rectangle { 26 | id: indexUpdateState 27 | anchors.fill: parent 28 | color: styleMusic.view.backgroundColor 29 | 30 | Column { 31 | anchors.centerIn: parent 32 | spacing: units.gu(4) 33 | width: parent.width > units.gu(44) ? parent.width - units.gu(8) : units.gu(40) 34 | 35 | Label { 36 | color: styleMusic.view.labelColor 37 | elide: Text.ElideRight 38 | font.pointSize: units.fs("x-large") 39 | horizontalAlignment: Text.AlignHCenter 40 | maximumLineCount: 2 41 | text: qsTr("Update in progress") 42 | width: parent.width 43 | wrapMode: Text.WordWrap 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /android/license.txt: -------------------------------------------------------------------------------- 1 | Qt Android CMake utility script 2 | ------------------------------- 3 | 4 | Copyright (c) 2018, Laurent Gomila (laurent.gom@gmail.com) 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | 3. Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from this 19 | software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/oggparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef OGGPARSER_H 19 | #define OGGPARSER_H 20 | 21 | #include "mediaparser.h" 22 | 23 | namespace mediascanner 24 | { 25 | 26 | class OGGParser : public MediaParser 27 | { 28 | public: 29 | const char * commonName() override { return "OGG"; } 30 | bool match(const QFileInfo& fileInfo) override; 31 | bool parse(MediaFile * file, MediaInfo * info, bool debug) override; 32 | 33 | private: 34 | typedef struct 35 | { 36 | unsigned char * buf; 37 | uint32_t size; 38 | unsigned char * data; 39 | uint32_t datalen; 40 | } packet_t; 41 | static bool resize_packet(packet_t * packet, uint32_t size); 42 | static bool fill_packet(packet_t * packet, uint32_t len, FILE * fp); 43 | static bool parse_identification(packet_t * packet, MediaInfo * info, bool debug); 44 | static bool parse_comment(packet_t * packet, MediaInfo * info, bool debug); 45 | }; 46 | 47 | } 48 | 49 | #endif /* OGGPARSER_H */ 50 | 51 | -------------------------------------------------------------------------------- /cmake/MSVCRuntime.cmake: -------------------------------------------------------------------------------- 1 | 2 | macro(configure_msvc_runtime) 3 | if(MSVC) 4 | # Default to statically-linked runtime. 5 | if("${MSVC_RUNTIME}" STREQUAL "") 6 | set(MSVC_RUNTIME "static") 7 | endif() 8 | 9 | # Set compiler options. 10 | set(variables 11 | CMAKE_C_FLAGS 12 | CMAKE_C_FLAGS_DEBUG 13 | CMAKE_C_FLAGS_MINSIZEREL 14 | CMAKE_C_FLAGS_RELEASE 15 | CMAKE_C_FLAGS_RELWITHDEBINFO 16 | CMAKE_CXX_FLAGS 17 | CMAKE_CXX_FLAGS_DEBUG 18 | CMAKE_CXX_FLAGS_MINSIZEREL 19 | CMAKE_CXX_FLAGS_RELEASE 20 | CMAKE_CXX_FLAGS_RELWITHDEBINFO) 21 | 22 | if(${MSVC_RUNTIME} STREQUAL "static") 23 | message(STATUS "MSVC: using statically-linked runtime (/MT and /MTd).") 24 | foreach(variable ${variables}) 25 | if(${variable} MATCHES "/MD") 26 | string(REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}") 27 | endif() 28 | endforeach() 29 | else() 30 | message(STATUS "MSVC: using dynamically-linked runtime (/MD and /MDd).") 31 | foreach(variable ${variables}) 32 | if(${variable} MATCHES "/MT") 33 | string(REGEX REPLACE "/MT" "/MD" ${variable} "${${variable}}") 34 | endif() 35 | endforeach() 36 | endif() 37 | 38 | foreach(variable ${variables}) 39 | if(${variable} MATCHES "/Ob0") 40 | string(REGEX REPLACE "/Ob0" "/Ob2" ${variable} "${${variable}}") 41 | endif() 42 | endforeach() 43 | 44 | foreach(variable ${variables}) 45 | if(${variable} MATCHES "/W3") 46 | string(REGEX REPLACE "/W3" "/W2" ${variable} "${${variable}}") 47 | endif() 48 | endforeach() 49 | 50 | foreach(variable ${variables}) 51 | set(${variable} "${${variable}}" CACHE STRING "MSVC_${variable}" FORCE) 52 | endforeach() 53 | endif() 54 | endmacro(configure_msvc_runtime) 55 | -------------------------------------------------------------------------------- /backend/NosonApp/future.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #include "future.h" 22 | #include "sonos.h" 23 | 24 | #include 25 | 26 | using namespace nosonapp; 27 | 28 | Promise::~Promise() 29 | { 30 | //qDebug("%s: free %p", __FUNCTION__, this); 31 | } 32 | 33 | Future::Future(Promise * promise, Sonos * sonos) 34 | : QObject(sonos) 35 | , m_promise(promise) 36 | , m_sonos(sonos) 37 | , m_longOp(true) 38 | { 39 | Q_ASSERT(m_promise); 40 | Q_ASSERT(m_sonos); 41 | QRunnable::setAutoDelete(false); 42 | } 43 | 44 | Future::~Future() 45 | { 46 | delete m_promise; 47 | } 48 | 49 | bool Future::start(bool longOp) 50 | { 51 | m_longOp = longOp; 52 | return m_sonos->startJob(this); 53 | } 54 | 55 | void Future::run() 56 | { 57 | bool lp = m_longOp; 58 | emit started(); 59 | if (lp) 60 | m_sonos->beginJob(); 61 | m_promise->run(); 62 | if (lp) 63 | m_sonos->endJob(); 64 | emit finished(m_promise->result()); 65 | deleteLater(); 66 | } 67 | -------------------------------------------------------------------------------- /gui/diskcache/cachereply.cpp: -------------------------------------------------------------------------------- 1 | #include "cachereply.h" 2 | 3 | CacheReply::CacheReply(QIODevice *cacheDev, const QNetworkRequest &req, 4 | QNetworkAccessManager::Operation op, QNetworkCacheMetaData meta, 5 | QObject *parent) 6 | : QNetworkReply(parent) 7 | , mCacheDev(cacheDev) 8 | { 9 | setRequest(req); 10 | setUrl(req.url()); 11 | setOperation(op); 12 | setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200); 13 | setFinished(true); 14 | QNetworkReply::open(QIODevice::ReadOnly); 15 | 16 | qint64 size = cacheDev->size(); 17 | foreach(QNetworkCacheMetaData::RawHeader header, meta.rawHeaders()) 18 | { 19 | setRawHeader(header.first, header.second); 20 | } 21 | QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection); 22 | QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection, 23 | Q_ARG(qint64, size), Q_ARG(qint64, size)); 24 | QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); 25 | QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); 26 | } 27 | 28 | CacheReply::~CacheReply() 29 | { 30 | close(); 31 | if (mCacheDev) 32 | { 33 | mCacheDev->close(); 34 | delete mCacheDev; 35 | } 36 | } 37 | 38 | void CacheReply::abort() 39 | { 40 | close(); 41 | } 42 | 43 | qint64 CacheReply::bytesAvailable() const 44 | { 45 | return mCacheDev->bytesAvailable(); 46 | } 47 | 48 | bool CacheReply::isSequential() const 49 | { 50 | return mCacheDev->isSequential(); 51 | } 52 | 53 | qint64 CacheReply::size() const 54 | { 55 | return mCacheDev->size(); 56 | } 57 | 58 | qint64 CacheReply::readData(char *data, qint64 maxlen) 59 | { 60 | return mCacheDev->read(data, maxlen); 61 | } 62 | -------------------------------------------------------------------------------- /gui/controls2_515/components/ServiceEmptyState.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | 24 | 25 | Rectangle { 26 | id: serviceEmptyState 27 | anchors.fill: parent 28 | color: styleMusic.view.backgroundColor 29 | 30 | property alias text: label.text 31 | 32 | Column { 33 | anchors.centerIn: parent 34 | spacing: units.gu(4) 35 | width: parent.width > units.gu(44) ? parent.width - units.gu(8) : units.gu(40) 36 | 37 | Label { 38 | id: label 39 | color: styleMusic.view.labelColor 40 | elide: Text.ElideRight 41 | font.pointSize: units.fs("x-large") 42 | horizontalAlignment: Text.AlignHCenter 43 | maximumLineCount: 6 44 | text: "" 45 | width: parent.width 46 | wrapMode: Text.WordWrap 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/thumbnailerjob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #include "thumbnailerjob.h" 22 | 23 | #include 24 | 25 | using namespace thumbnailer; 26 | 27 | Job::Job(AbstractWorker* worker, QObject* parent) 28 | : QObject(parent) 29 | , m_worker(worker) 30 | { 31 | worker->setParent(this); 32 | connect(m_worker, SIGNAL(finished()), this, SLOT(finishedWorker())); 33 | } 34 | 35 | Job::~Job() 36 | { 37 | // Job is owner of the worker 38 | } 39 | 40 | void Job::start() 41 | { 42 | m_worker->run(); 43 | } 44 | 45 | ReplyStatus Job::error() const 46 | { 47 | return m_worker->error(); 48 | } 49 | 50 | int Job::errorCode() const 51 | { 52 | return m_worker->errorCode(); 53 | } 54 | 55 | QString Job::errorString() const 56 | { 57 | return m_worker->errorString(); 58 | } 59 | 60 | const QByteArray& Job::image() const 61 | { 62 | return m_worker->image(); 63 | } 64 | 65 | bool Job::isCached() const 66 | { 67 | return m_worker->isCached(); 68 | } 69 | -------------------------------------------------------------------------------- /backend/cli/tokenizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-2015 Jean-Luc Barriere 3 | * 4 | * This library is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published 6 | * by the Free Software Foundation; either version 3, or (at your option) 7 | * any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; see the file COPYING. If not, write to 16 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #ifndef TOKENIZER_H 23 | #define TOKENIZER_H 24 | 25 | #include 26 | #include 27 | 28 | #define tokenize __tokenize 29 | inline void __tokenize(const std::string& str, const char *delimiters, std::vector& tokens, bool trimnull = false) 30 | { 31 | std::string::size_type pa = 0, pb = 0; 32 | unsigned n = 0; 33 | // Counter n will break infinite loop. Max count is 255 tokens 34 | while ((pb = str.find_first_of(delimiters, pb)) != std::string::npos && ++n < 255) 35 | { 36 | tokens.push_back(str.substr(pa, pb - pa)); 37 | do 38 | { 39 | pa = ++pb; 40 | } 41 | while (trimnull && str.find_first_of(delimiters, pb) == pb); 42 | } 43 | 44 | if (!trimnull || pa < str.size()) 45 | tokens.push_back(str.substr(pa)); 46 | } 47 | 48 | #endif /* TOKENIZER_H */ 49 | 50 | -------------------------------------------------------------------------------- /backend/NosonApp/future.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef NOSONAPPFUTURE_H 22 | #define NOSONAPPFUTURE_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | namespace nosonapp 29 | { 30 | 31 | class Sonos; 32 | 33 | class Promise : public QRunnable 34 | { 35 | public: 36 | virtual ~Promise(); 37 | 38 | const QVariant& result() const { return m_result; } 39 | 40 | protected: 41 | void setResult(const QVariant& result) { m_result = result; } 42 | 43 | private: 44 | QVariant m_result; 45 | }; 46 | 47 | class Future : public QObject, public QRunnable 48 | { 49 | Q_OBJECT 50 | public: 51 | explicit Future(Promise * promise, Sonos * sonos); 52 | virtual ~Future(); 53 | 54 | Q_INVOKABLE bool start(bool longOp = true); 55 | 56 | void run() override; 57 | 58 | signals: 59 | void started(); 60 | void finished(QVariant result); 61 | 62 | private: 63 | Promise * m_promise; 64 | Sonos * m_sonos; 65 | bool m_longOp; 66 | }; 67 | 68 | } 69 | 70 | #endif // NOSONAPPFUTURE_H 71 | -------------------------------------------------------------------------------- /gui/controls2_515/components/Flickables/MusicGridView.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015, 2016 3 | * Andrew Hayzen 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | 21 | GridView { 22 | id: gridView 23 | anchors { 24 | bottomMargin: units.gu(1) 25 | fill: parent 26 | leftMargin: units.gu(0) 27 | rightMargin: units.gu(0) 28 | } 29 | cellHeight: cellSize + heightOffset 30 | cellWidth: cellSize + widthOffset 31 | 32 | ScrollBar.vertical: ScrollBar { } 33 | 34 | readonly property int columns: parseInt(width / itemWidth) || 1 // never drop to 0 35 | readonly property int cellSize: width / columns 36 | property real itemWidth: units.gu(15) 37 | property real heightOffset: 0 38 | property real widthOffset: 0 39 | 40 | Component.onCompleted: { 41 | // Return values depending on the grid unit definition 42 | // for Flickable.maximumFlickVelocity and Flickable.flickDeceleration 43 | var scaleFactor = units.scaleFactor; 44 | maximumFlickVelocity = maximumFlickVelocity * scaleFactor; 45 | flickDeceleration = flickDeceleration * scaleFactor; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /gui/signalhandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "signalhandler.h" 5 | #include 6 | 7 | int SignalHandler::m_pipe[] = {0,0}; 8 | 9 | SignalHandler::SignalHandler(QObject *parent) 10 | : QObject(parent) 11 | { 12 | if (::socketpair(AF_UNIX, SOCK_STREAM, 0, m_pipe)) 13 | qFatal("Couldn't create signal socketpair."); 14 | else 15 | { 16 | m_notifier = new QSocketNotifier(m_pipe[1], QSocketNotifier::Read, this); 17 | connect(m_notifier, SIGNAL(activated(int)), this, SLOT(forward())); 18 | qDebug("Signal handler is enabled."); 19 | } 20 | } 21 | 22 | SignalHandler::~SignalHandler() 23 | { 24 | if (m_notifier) 25 | { 26 | disconnect(m_notifier, SIGNAL(activated(int)), this, SLOT(forward())); 27 | delete m_notifier; 28 | } 29 | qDebug("Signal handler is destroyed."); 30 | } 31 | 32 | bool SignalHandler::catchSignal(int signal) 33 | { 34 | struct sigaction act; 35 | memset(&act, '\0', sizeof(struct sigaction)); 36 | act.sa_sigaction = &handler; 37 | act.sa_flags |= SA_SIGINFO; 38 | sigemptyset(&act.sa_mask); 39 | return (sigaction(signal, &act, 0) == 0); 40 | } 41 | 42 | void SignalHandler::omitSignal(int signal) 43 | { 44 | struct sigaction act; 45 | memset(&act, '\0', sizeof(struct sigaction)); 46 | act.sa_handler = SIG_DFL; 47 | sigemptyset(&act.sa_mask); 48 | sigaction(signal, &act, 0); 49 | } 50 | 51 | void SignalHandler::forward() 52 | { 53 | int signal; 54 | m_notifier->setEnabled(false); 55 | size_t r = ::read(m_pipe[1], &signal, sizeof(signal)); 56 | (void)r; 57 | emit catched(signal); 58 | m_notifier->setEnabled(true); 59 | } 60 | 61 | void SignalHandler::handler(int signal, siginfo_t * info, void * data) 62 | { 63 | size_t w = ::write(m_pipe[0], &signal, sizeof(signal)); 64 | (void)w; 65 | (void)info; 66 | (void)data; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /backend/NosonApp/dbus/org.mpris.MediaPlayer2.Player.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /backend/NosonApp/tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016-2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef NOSONAPPTOOLS_H 22 | #define NOSONAPPTOOLS_H 23 | 24 | #include 25 | #include 26 | 27 | namespace nosonapp 28 | { 29 | 30 | static inline int roundDouble(double value) 31 | { 32 | return (int)std::floor(value + 0.5); 33 | } 34 | 35 | static inline QString normalizedString(const QString& str) 36 | { 37 | QString ret; 38 | QString tmp = str.normalized(QString::NormalizationForm_D); 39 | ret.reserve(tmp.size()); 40 | int pcat = QChar::Separator_Space; 41 | for (QString::const_iterator it = tmp.cbegin(); it != tmp.cend(); ++it) 42 | { 43 | int cat = it->category(); 44 | if (cat != QChar::Mark_NonSpacing && cat != QChar::Mark_SpacingCombining) 45 | { 46 | if (cat != QChar::Separator_Space || pcat != QChar::Separator_Space) 47 | ret.append(*it); 48 | pcat = cat; 49 | } 50 | } 51 | if (!ret.isEmpty() && pcat == QChar::Separator_Space) 52 | ret.truncate(ret.length() - 1); 53 | return ret; 54 | } 55 | 56 | } 57 | 58 | #endif /* NOSONAPPTOOLS_H */ 59 | 60 | -------------------------------------------------------------------------------- /gui/controls2_515/components/DataFailureState.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | 21 | 22 | Rectangle { 23 | id: dataFailureState 24 | anchors.fill: parent 25 | color: styleMusic.view.backgroundColor 26 | 27 | signal reloadClicked 28 | 29 | Column { 30 | anchors.centerIn: parent 31 | spacing: units.gu(4) 32 | width: parent.width > units.gu(44) ? parent.width - units.gu(8) : units.gu(40) 33 | 34 | Label { 35 | color: styleMusic.view.labelColor 36 | elide: Text.ElideRight 37 | font.pointSize: units.fs("x-large") 38 | horizontalAlignment: Text.AlignHCenter 39 | maximumLineCount: 2 40 | text: qsTr("Loading failed") 41 | width: parent.width 42 | wrapMode: Text.WordWrap 43 | } 44 | 45 | Icon { 46 | id: reload 47 | anchors.horizontalCenter: parent.horizontalCenter 48 | visible: true 49 | source: "qrc:/images/reload.svg" 50 | height: units.gu(5) 51 | onClicked: reloadClicked() 52 | label.text: qsTr("Retry") 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/listmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef LISTMODEL 19 | #define LISTMODEL 20 | 21 | #include "mediascanner.h" 22 | #include "locked.h" 23 | 24 | #include 25 | #include 26 | 27 | namespace mediascanner 28 | { 29 | 30 | class MediaScanner; 31 | 32 | class ListModel : public QAbstractListModel 33 | { 34 | Q_OBJECT 35 | 36 | public: 37 | ListModel(QObject * parent); 38 | virtual ~ListModel(); 39 | 40 | virtual void clear() = 0; 41 | virtual bool load() = 0; 42 | 43 | enum dataState { 44 | New = 0, 45 | NoData = 1, 46 | Loaded = 2, 47 | Synced = 3 48 | }; 49 | 50 | 51 | public slots: 52 | virtual void onFileAdded(const MediaFilePtr& file) = 0; 53 | virtual void onFileRemoved(const MediaFilePtr& file) = 0; 54 | 55 | protected: 56 | QRecursiveMutex * m_lock; 57 | MediaScanner * m_provider; 58 | dataState m_dataState; 59 | 60 | virtual bool init(bool fill = true); 61 | 62 | bool updateSignaled() { return m_updateSignaled.Load(); } 63 | void setUpdateSignaled(bool val) { m_updateSignaled.Store(val); } 64 | 65 | private: 66 | Locked m_updateSignaled; 67 | }; 68 | 69 | } 70 | 71 | #endif // LISTMODEL 72 | 73 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: noson-app 2 | Section: misc 3 | Priority: optional 4 | Maintainer: janbar 5 | Build-Depends: cmake, 6 | git, 7 | debhelper-compat (= 12), 8 | qtbase5-dev (>= 5.15), 9 | qttools5-dev, 10 | qttools5-dev-tools, 11 | qtdeclarative5-dev, 12 | qtdeclarative5-dev-tools, 13 | qtquickcontrols2-5-dev, 14 | libqt5svg5-dev, 15 | zlib1g-dev, 16 | libssl-dev, 17 | libpulse-dev, 18 | libflac-dev, 19 | libflac++-dev, 20 | libdbus-1-dev, 21 | qml-module-qt-labs-settings, 22 | qml-module-qtgraphicaleffects, 23 | qml-module-qtqml-models2, 24 | qml-module-qtquick2, 25 | qml-module-qtquick-controls2, 26 | qml-module-qtquick-layouts, 27 | qml-module-qtquick-particles2, 28 | qml-module-qtquick-templates2, 29 | qml-module-qtquick-window2, 30 | libqt5dbus5, 31 | libqt5svg5 32 | Standards-Version: 3.9.6 33 | Homepage: https://github.com/janbar/noson-app 34 | 35 | Package: noson-app 36 | Architecture: any 37 | Depends: qml-module-qt-labs-settings, 38 | qml-module-qtgraphicaleffects, 39 | qml-module-qtqml-models2, 40 | qml-module-qtquick2, 41 | qml-module-qtquick-controls2, 42 | qml-module-qtquick-layouts, 43 | qml-module-qtquick-particles2, 44 | qml-module-qtquick-templates2, 45 | qml-module-qtquick-window2, 46 | qttranslations5-l10n, 47 | libqt5dbus5, 48 | libqt5svg5, 49 | zlib1g, 50 | openssl, 51 | libpulse0, 52 | libdbus-1-3, 53 | ${shlibs:Depends}, ${misc:Depends} 54 | Description: SONOS controller for Linux 55 | Touch enabled SONOS controller for Linux 56 | 57 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/m4aparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #ifndef M4APARSER_H 19 | #define M4APARSER_H 20 | 21 | #include "mediaparser.h" 22 | 23 | namespace mediascanner 24 | { 25 | 26 | class M4AParser : public MediaParser 27 | { 28 | public: 29 | const char * commonName() override { return "M4A"; } 30 | bool match(const QFileInfo& fileInfo) override; 31 | bool parse(MediaFile * file, MediaInfo * info, bool debug) override; 32 | 33 | private: 34 | static int nextChild(unsigned char * buf, uint64_t * remaining, FILE * fp, unsigned * child, uint64_t * childSize); 35 | static int loadDataValue(uint64_t * remaining, FILE * fp, char ** alloc, unsigned * allocSize); 36 | static int loadUtf8Value(uint64_t * remaining, FILE * fp, QString& str); 37 | static int loadU32Value(uint64_t * remaining, FILE * fp, unsigned* u32); 38 | static int parse_ilst(uint64_t * remaining, FILE * fp, MediaInfo * info); 39 | static int parse_meta(uint64_t * remaining, FILE * fp, MediaInfo * info); 40 | static int parse_udta(uint64_t * remaining, FILE * fp, MediaInfo * info); 41 | static int parse_mvhd(uint64_t * remaining, FILE * fp, MediaInfo * info); 42 | static int parse_moov(uint64_t * remaining, FILE * fp, MediaInfo * info); 43 | }; 44 | 45 | } 46 | 47 | #endif /* M4APARSER_H */ 48 | 49 | -------------------------------------------------------------------------------- /gui/images/audio-volume.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 31 | 51 | 55 | 59 | 60 | -------------------------------------------------------------------------------- /gui/controls2_515/ThisDevice/ShuffleButton.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | import "../components" 21 | 22 | Icon { 23 | height: units.gu(5) 24 | width: units.gu(16) 25 | source: "qrc:/images/media-playlist-shuffle.svg" 26 | label { 27 | //: this appears in a button with limited space (around 14 characters) 28 | text: qsTr("Shuffle") 29 | font.pointSize: units.fs("small") 30 | width: width - units.gu(6) 31 | elide: Text.ElideRight 32 | } 33 | 34 | property var model 35 | 36 | onClicked: { 37 | delayShuffleModel.start() 38 | } 39 | 40 | Timer { 41 | id: delayShuffleModel 42 | interval: 100 43 | onTriggered: { 44 | var now = new Date(); 45 | var seed = now.getSeconds(); 46 | var index = Math.floor(model.count * Math.random(seed)); 47 | if (index < model.count) { 48 | var item = model.get(index); 49 | var payload = makeItemPayload(item); 50 | if (player.isPlaying) 51 | trackClicked({id: item.id, payload: payload}, false); 52 | else 53 | trackClicked({id: item.id, payload: payload}, true); // play track 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /gui/images/reload.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /gui/controls2_515/components/BlurredBackground.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013, 2014, 2015 3 | * Andrew Hayzen 4 | * Daniel Holm 5 | * Victor Thompson 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | import QtQuick 2.9 21 | import QtGraphicalEffects 1.0 22 | 23 | // Blurred background 24 | Item { 25 | width: parent.width 26 | 27 | property string art: player.currentMetaArt === "" ? "qrc:/images/no_cover.png" : player.currentMetaArt 28 | 29 | // dark layer 30 | Rectangle { 31 | anchors { 32 | fill: parent 33 | } 34 | color: styleMusic.playerControls.backgroundColor 35 | } 36 | 37 | // the album art 38 | Image { 39 | id: backgroundImage 40 | anchors.fill: parent 41 | asynchronous: true 42 | fillMode: Image.PreserveAspectCrop 43 | height: parent.height 44 | source: art 45 | visible: false 46 | width: Math.max(parent.height, parent.width) 47 | sourceSize.height: 512 48 | sourceSize.width: 512 49 | } 50 | 51 | // the blur 52 | FastBlur { 53 | id: backgroundBlur 54 | anchors.fill: backgroundImage 55 | source: backgroundImage 56 | radius: units.dp(64) 57 | opacity: 0.2 58 | cached: false 59 | transparentBorder: true 60 | } 61 | 62 | onArtChanged: { 63 | backgroundImage.source = art 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /backend/NosonApp/qmlfilterbehavior.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Canonical, Ltd. 3 | * 4 | * Authors: 5 | * Christian Dywan 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation; version 3. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #ifndef NOSONAPPFILTERBEHAVIOR_H 21 | #define NOSONAPPFILTERBEHAVIOR_H 22 | 23 | #include 24 | #if QT_VERSION < 0x050F00 //QT_VERSION_CHECK(5, 15, 0) 25 | #define REGEXP_TYPE QRegExp 26 | #define REGEXP_GETFILTER filterRegExp 27 | #define REGEXP_SETFILTER(a) setFilterRegExp(a) 28 | #else 29 | #include 30 | #define REGEXP_TYPE QRegularExpression 31 | #define REGEXP_GETFILTER filterRegularExpression 32 | #define REGEXP_SETFILTER(a) setFilterRegularExpression(a) 33 | #endif 34 | 35 | namespace nosonapp 36 | { 37 | 38 | class FilterBehavior : public QObject { 39 | Q_OBJECT 40 | 41 | Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged) 42 | Q_PROPERTY(REGEXP_TYPE pattern READ pattern WRITE setPattern NOTIFY patternChanged) 43 | 44 | public: 45 | explicit FilterBehavior(QObject *parent = 0); 46 | 47 | QString property() const; 48 | void setProperty(const QString& property); 49 | REGEXP_TYPE pattern() const; 50 | void setPattern(REGEXP_TYPE pattern); 51 | 52 | Q_SIGNALS: 53 | void propertyChanged(); 54 | void patternChanged(); 55 | 56 | private: 57 | QString m_property; 58 | REGEXP_TYPE m_pattern; 59 | }; 60 | 61 | } 62 | 63 | #endif // NOSONAPPFILTERBEHAVIOR_H 64 | -------------------------------------------------------------------------------- /gui/controls2_515/components/AlarmsEmptyState.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | 24 | 25 | Rectangle { 26 | id: alarmsEmptyState 27 | anchors.fill: parent 28 | color: styleMusic.view.backgroundColor 29 | 30 | Column { 31 | anchors.centerIn: parent 32 | spacing: units.gu(4) 33 | width: parent.width > units.gu(44) ? parent.width - units.gu(8) : units.gu(40) 34 | 35 | Label { 36 | color: styleMusic.view.labelColor 37 | elide: Text.ElideRight 38 | font.pointSize: units.fs("x-large") 39 | horizontalAlignment: Text.AlignHCenter 40 | maximumLineCount: 2 41 | text: qsTr("No alarms found") 42 | width: parent.width 43 | wrapMode: Text.WordWrap 44 | } 45 | 46 | Label { 47 | color: styleMusic.view.labelColor 48 | elide: Text.ElideRight 49 | font.pointSize: units.fs("large") 50 | horizontalAlignment: Text.AlignHCenter 51 | maximumLineCount: 6 52 | text: qsTr("Tapping the %1 icon to add alarms.").arg('"+"') 53 | width: parent.width 54 | wrapMode: Text.WordWrap 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /.github/workflows/appimage_ubuntu_jammy.yml: -------------------------------------------------------------------------------- 1 | name: appimage_amd64 2 | on: 3 | push: 4 | branches: [ master ] 5 | pull_request: 6 | branches: [ master ] 7 | 8 | jobs: 9 | build-appimage: 10 | runs-on: ubuntu-22.04 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - name: Install dependencies 15 | run: "sudo apt-get update && sudo apt-get install -y cmake 16 | qtbase5-dev qttools5-dev qttools5-dev-tools qtdeclarative5-dev 17 | qtdeclarative5-dev-tools qtquickcontrols2-5-dev libqt5svg5-dev 18 | qml-module-qt-labs-settings qml-module-qtgraphicaleffects 19 | qml-module-qtqml-models2 qml-module-qtquick2 qml-module-qtquick-controls2 20 | qml-module-qtquick-layouts qml-module-qtquick-particles2 21 | qml-module-qtquick-templates2 qml-module-qtquick-window2 22 | zlib1g-dev libssl-dev libflac-dev libflac++-dev libpulse-dev 23 | libdbus-1-dev libqt5dbus5" 24 | 25 | - name: Init submodules 26 | run: git submodule init && git submodule update 27 | 28 | - name: Configure 29 | run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr . 30 | 31 | - name: Build 32 | run: cd build && make -j`nproc` install DESTDIR=../AppDir 33 | 34 | - name: Download AppImage builder 35 | run: | 36 | sudo apt-get install -y binutils coreutils desktop-file-utils fakeroot fuse libgdk-pixbuf2.0-dev patchelf python3-pip python3-setuptools squashfs-tools strace util-linux zsync 37 | wget -O appimage-builder-x86_64.AppImage https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage 38 | chmod +x appimage-builder-x86_64.AppImage 39 | 40 | - name: Build AppImage 41 | run: ./appimage-builder-x86_64.AppImage --recipe appimage/builder_ubuntu_22.04.yml 42 | 43 | - name: Upload artifacts 44 | uses: actions/upload-artifact@v4 45 | with: 46 | name: AppImage 47 | path: './noson*.AppImage*' 48 | retention-days: 5 49 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailerimageresponse.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Canonical Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation; version 3. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU Lesser General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this program. If not, see . 15 | * 16 | * Authors: Xavi Garcia 17 | */ 18 | 19 | #ifndef THUMBNAILERIMAGERESPONSE_H 20 | #define THUMBNAILERIMAGERESPONSE_H 21 | 22 | #include 23 | 24 | #include "thumbnailer/thumbnailer.h" 25 | 26 | namespace thumbnailer 27 | { 28 | 29 | namespace qml 30 | { 31 | 32 | class ThumbnailerImageResponse : public QQuickImageResponse // LCOV_EXCL_LINE // False negative from gcovr 33 | { 34 | #ifdef __clang__ 35 | #pragma clang diagnostic push 36 | #pragma clang diagnostic ignored "-Winconsistent-missing-override" 37 | #endif 38 | Q_OBJECT 39 | #ifdef __clang__ 40 | #pragma clang diagnostic pop 41 | #endif 42 | public: 43 | Q_DISABLE_COPY(ThumbnailerImageResponse) 44 | 45 | ThumbnailerImageResponse(QSharedPointer const& request); 46 | ThumbnailerImageResponse(QString const& error_message); 47 | ~ThumbnailerImageResponse(); 48 | 49 | QQuickTextureFactory* textureFactory() const override; 50 | QString errorString() const override; 51 | void cancel() override; 52 | 53 | private 54 | Q_SLOTS: 55 | void requestFinished(); 56 | 57 | private: 58 | QSharedPointer request_; 59 | QString error_message_; 60 | }; 61 | 62 | } // namespace qml 63 | 64 | } // namespace thumbnailer 65 | #endif /* THUMBNAILERIMAGERESPONSE_H */ 66 | 67 | -------------------------------------------------------------------------------- /backend/NosonMediaScanner/plugin.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | * 17 | */ 18 | #include "plugin.h" 19 | #include "mediascanner.h" 20 | #include "aggregate/artists.h" 21 | #include "aggregate/genres.h" 22 | #include "aggregate/albums.h" 23 | #include "aggregate/tracks.h" 24 | #include "aggregate/composers.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define CACHE_SIZE 50000000L 32 | 33 | using namespace mediascanner; 34 | 35 | void MediaScannerPlugin::registerTypes(const char* uri) 36 | { 37 | // register the singleton 38 | qmlRegisterSingletonType(uri, 1, 0, "MediaScanner", MediaScannerPlugin::createMediaScanner); 39 | qmlRegisterType(uri, 1, 0, "ArtistList"); 40 | qmlRegisterType(uri, 1, 0, "GenreList"); 41 | qmlRegisterType(uri, 1, 0, "AlbumList"); 42 | qmlRegisterType(uri, 1, 0, "TrackList"); 43 | qmlRegisterType(uri, 1, 0, "ComposerList"); 44 | } 45 | 46 | void MediaScannerPlugin::initializeEngine(QQmlEngine* engine, const char* uri) 47 | { 48 | QQmlExtensionPlugin::initializeEngine(engine, uri); 49 | } 50 | 51 | QObject * MediaScannerPlugin::createMediaScanner(QQmlEngine *engine, QJSEngine *scriptEngine) 52 | { 53 | Q_UNUSED(scriptEngine) 54 | return MediaScanner::instance(engine); 55 | } 56 | -------------------------------------------------------------------------------- /gui/controls2_515/components/RadiosEmptyState.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | 24 | 25 | Rectangle { 26 | id: radiosEmptyState 27 | anchors.fill: parent 28 | color: styleMusic.view.backgroundColor 29 | 30 | Column { 31 | anchors.centerIn: parent 32 | spacing: units.gu(4) 33 | width: parent.width > units.gu(44) ? parent.width - units.gu(8) : units.gu(40) 34 | 35 | Label { 36 | color: styleMusic.view.labelColor 37 | elide: Text.ElideRight 38 | font.pointSize: units.fs("x-large") 39 | horizontalAlignment: Text.AlignHCenter 40 | maximumLineCount: 2 41 | text: qsTr("No radio found") 42 | width: parent.width 43 | wrapMode: Text.WordWrap 44 | } 45 | 46 | Label { 47 | color: styleMusic.view.labelColor 48 | elide: Text.ElideRight 49 | font.pointSize: units.fs("large") 50 | horizontalAlignment: Text.AlignHCenter 51 | maximumLineCount: 6 52 | text: qsTr("Get more out of Sonos by tapping the %1 icon to add radio stream.").arg('"+"') 53 | width: parent.width 54 | wrapMode: Text.WordWrap 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /gui/controls2_515/components/Dialog/DialogSettings.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Layouts 1.3 20 | import QtQuick.Controls 2.2 21 | import QtQml.Models 2.3 22 | 23 | DialogBase { 24 | id: dialog 25 | title: qsTr("Sonos settings") 26 | 27 | footer: Row { 28 | leftPadding: units.gu(1) 29 | rightPadding: units.gu(1) 30 | bottomPadding: units.gu(1) 31 | spacing: units.gu(1) 32 | layoutDirection: Qt.RightToLeft 33 | 34 | Button { 35 | flat: true 36 | text: qsTr("Close") 37 | onClicked: dialog.reject() 38 | } 39 | } 40 | 41 | Text { 42 | anchors.left: parent.left 43 | anchors.right: parent.right 44 | text: qsTr("Whenever you make changes to your music library, such as adding and removing tracks, or adjusting album artwork, you will need to update the music index on Sonos before these changes will show up in the Sonos controller.") 45 | wrapMode: Text.WordWrap 46 | color: styleMusic.dialog.foregroundColor 47 | font.pointSize: units.fs("medium") 48 | font.weight: Font.Normal 49 | } 50 | 51 | Button { 52 | height: units.gu(6) 53 | text: qsTr("Update music index now") 54 | onClicked: { 55 | updateMusicIndex(); 56 | dialog.accept() 57 | } 58 | enabled: !shareIndexInProgress 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /gui/controls2_515/components/PopInfo.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | 21 | Item { 22 | property string message: "" 23 | property alias backgroundColor: containerLayoutBackground.color 24 | property alias labelColor: label.color 25 | 26 | y: units.gu(2) 27 | x: (parent.width - popover.width) / 2 28 | 29 | Popup { 30 | id: popover 31 | width: label.paintedWidth + units.gu(6) 32 | 33 | background: Rectangle { 34 | id: containerLayoutBackground 35 | anchors.fill: parent 36 | color: styleMusic.popover.backgroundColor 37 | radius: units.gu(1) 38 | opacity: 0.7 39 | } 40 | 41 | Label { 42 | id: label 43 | text: message 44 | anchors.centerIn: parent 45 | verticalAlignment: Text.AlignVCenter 46 | horizontalAlignment: Text.AlignHCenter 47 | color: styleMusic.popover.labelColor 48 | font.pointSize: units.fs("small") 49 | font.weight: Font.Normal 50 | } 51 | 52 | onOpened: timer.start() 53 | } 54 | 55 | Timer { 56 | id: timer 57 | interval: 3000 58 | onTriggered: { 59 | popover.close(); 60 | } 61 | } 62 | 63 | function open(msgtxt) { 64 | message = msgtxt; 65 | popover.open(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /gui/controls2_515/components/PlaylistsEmptyState.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * Andrew Hayzen 5 | * Daniel Holm 6 | * Victor Thompson 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | import QtQuick 2.9 22 | import QtQuick.Controls 2.2 23 | 24 | 25 | Rectangle { 26 | id: playlistsEmptyState 27 | anchors.fill: parent 28 | color: styleMusic.view.backgroundColor 29 | 30 | Column { 31 | anchors.centerIn: parent 32 | spacing: units.gu(4) 33 | width: parent.width > units.gu(44) ? parent.width - units.gu(8) : units.gu(40) 34 | 35 | Label { 36 | color: styleMusic.view.labelColor 37 | elide: Text.ElideRight 38 | font.pointSize: units.fs("x-large") 39 | horizontalAlignment: Text.AlignHCenter 40 | maximumLineCount: 2 41 | text: qsTr("No playlists found") 42 | width: parent.width 43 | wrapMode: Text.WordWrap 44 | } 45 | 46 | Label { 47 | color: styleMusic.view.labelColor 48 | elide: Text.ElideRight 49 | font.pointSize: units.fs("large") 50 | horizontalAlignment: Text.AlignHCenter 51 | maximumLineCount: 6 52 | text: qsTr("Get more out of Sonos by tapping the %1 icon to start making playlists for every mood and occasion.").arg('"+"') 53 | width: parent.width 54 | wrapMode: Text.WordWrap 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /gui/controls2_515/components/Dialog/DialogRemovePlaylist.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Layouts 1.3 20 | import QtQuick.Controls 2.2 21 | import QtQml.Models 2.3 22 | 23 | DialogBase { 24 | id: dialog 25 | 26 | footer: Row { 27 | leftPadding: units.gu(1) 28 | rightPadding: units.gu(1) 29 | bottomPadding: units.gu(1) 30 | spacing: units.gu(1) 31 | layoutDirection: Qt.RightToLeft 32 | 33 | Button { 34 | flat: true 35 | text: qsTr("Cancel") 36 | onClicked: dialog.reject() 37 | } 38 | Button { 39 | flat: true 40 | text: qsTr("Ok") 41 | onClicked: dialog.accept() 42 | } 43 | } 44 | 45 | Label { 46 | anchors.left: parent.left 47 | anchors.right: parent.right 48 | //: this is a title of a dialog with a prompt to delete a playlist 49 | text: qsTr("Permanently delete playlist ?") 50 | wrapMode: Label.WordWrap 51 | color: styleMusic.dialog.labelColor 52 | font.pointSize: units.fs("large") 53 | font.bold: true 54 | } 55 | 56 | Text { 57 | anchors.left: parent.left 58 | anchors.right: parent.right 59 | text: qsTr("This cannot be undone.") 60 | wrapMode: Text.WordWrap 61 | color: styleMusic.dialog.foregroundColor 62 | font.pointSize: units.fs("medium") 63 | font.weight: Font.Normal 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /gui/controls2_515/components/ZoneControls.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016, 2017 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | 21 | Item { 22 | property string controlledZone: "" 23 | 24 | anchors { 25 | fill: parent 26 | } 27 | 28 | Rectangle { 29 | id: notImplemented 30 | anchors { 31 | fill: parent 32 | } 33 | color: styleMusic.view.backgroundColor 34 | 35 | Column { 36 | anchors.centerIn: parent 37 | spacing: units.gu(4) 38 | width: units.gu(36) 39 | 40 | Label { 41 | color: styleMusic.view.labelColor 42 | elide: Text.ElideRight 43 | font.pointSize: units.fs("x-large") 44 | horizontalAlignment: Text.AlignHCenter 45 | maximumLineCount: 2 46 | text: qsTr("Under construction") 47 | width: parent.width 48 | wrapMode: Text.WordWrap 49 | } 50 | 51 | Label { 52 | color: styleMusic.view.foregroundColor 53 | elide: Text.ElideRight 54 | font.pointSize: units.fs("large") 55 | horizontalAlignment: Text.AlignLeft 56 | maximumLineCount: 8 57 | text: qsTr("This feature will be added in a next version. Please rate the App.") 58 | width: parent.width 59 | wrapMode: Text.WordWrap 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /gui/controls2_515/components/Units.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016-2019 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | 20 | Item { 21 | property real scaleFactor: 1.0 22 | property real fontScaleFactor: 1.0 23 | property real gridUnit: 8.0 * scaleFactor 24 | 25 | function dp(p) { 26 | return scaleFactor * p; 27 | } 28 | 29 | function gu(u) { 30 | return gridUnit * u; 31 | } 32 | 33 | function fs(s) { 34 | if (Android) { 35 | if (s === "x-small") 36 | return 10.0 * scaleFactor * fontScaleFactor; 37 | if (s === "small") 38 | return 12.0 * scaleFactor * fontScaleFactor; 39 | if (s === "medium") 40 | return 14.0 * scaleFactor * fontScaleFactor; 41 | if (s === "large") 42 | return 18.0 * scaleFactor * fontScaleFactor; 43 | if (s === "x-large") 44 | return 22.0 * scaleFactor * fontScaleFactor; 45 | } else { 46 | if (s === "x-small") 47 | return 9.0 * scaleFactor * fontScaleFactor; 48 | if (s === "small") 49 | return 10.0 * scaleFactor * fontScaleFactor; 50 | if (s === "medium") 51 | return 12.0 * scaleFactor * fontScaleFactor; 52 | if (s === "large") 53 | return 14.0 * scaleFactor * fontScaleFactor; 54 | if (s === "x-large") 55 | return 16.0 * scaleFactor * fontScaleFactor; 56 | } 57 | return 0.0; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /gui/controls2_515/components/MusicFilter.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | import QtQuick.Layouts 1.3 21 | 22 | Rectangle { 23 | id: filter 24 | visible: true 25 | width: parent.width 26 | height: visible ? units.gu(6) : 0 27 | color: styleMusic.playerControls.backgroundColor 28 | 29 | property alias displayText: field.displayText 30 | 31 | RowLayout { 32 | spacing: 0 33 | anchors.fill: parent 34 | anchors.rightMargin: units.gu(1.5) 35 | 36 | Item { 37 | width: units.gu(6) 38 | height: width 39 | 40 | Icon { 41 | width: units.gu(5) 42 | height: width 43 | anchors.centerIn: parent 44 | source: "qrc:/images/edit-clear.svg" 45 | onClicked: { 46 | filter.visible = false; 47 | } 48 | } 49 | } 50 | 51 | TextField { 52 | id: field 53 | Layout.fillWidth: true 54 | font.pointSize: units.fs("large") 55 | inputMethodHints: Qt.ImhNoPredictiveText 56 | placeholderText: qsTr("Search music") 57 | EnterKey.type: Qt.EnterKeySearch 58 | } 59 | } 60 | 61 | onVisibleChanged: { 62 | if (visible) { 63 | field.enabled = true; 64 | field.forceActiveFocus(); 65 | } else { 66 | field.clear(); 67 | field.enabled = false; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/artistartgenerator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Canonical Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation; version 3. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU Lesser General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this program. If not, see . 15 | * 16 | * Authors: Jussi Pakkanen 17 | * James Henstridge 18 | * Pawel Stolowski 19 | * Jean-luc Barrière 20 | */ 21 | 22 | #include "artistartgenerator.h" 23 | 24 | #include 25 | #include 26 | 27 | #include "thumbnailerimageresponse.h" 28 | 29 | namespace thumbnailer 30 | { 31 | 32 | namespace qml 33 | { 34 | 35 | ArtistArtGenerator::ArtistArtGenerator(std::shared_ptr const& thumbnailer) 36 | : QQuickAsyncImageProvider() 37 | , thumbnailer(thumbnailer) 38 | { 39 | } 40 | 41 | QQuickImageResponse* ArtistArtGenerator::requestImageResponse(const QString& id, const QSize& requestedSize) 42 | { 43 | if (!thumbnailer->isValid()) 44 | { 45 | return new ThumbnailerImageResponse("Service unavailable"); 46 | } 47 | QUrlQuery query(id); 48 | if (!query.hasQueryItem(QStringLiteral("artist"))) 49 | { 50 | qWarning() << "ArtistArtGenerator::requestImageResponse(): Invalid artistart uri:" << id; 51 | return new ThumbnailerImageResponse("Invalid artistart ID: " + id); 52 | } 53 | 54 | const QString artist = query.queryItemValue(QStringLiteral("artist"), QUrl::FullyDecoded); 55 | 56 | auto request = thumbnailer->getArtistArt(artist, requestedSize); 57 | return new ThumbnailerImageResponse(request); 58 | } 59 | 60 | } // namespace qml 61 | 62 | } // namespace thumbnailer 63 | -------------------------------------------------------------------------------- /gui/controls2_515/components/Delegates/SimpleListItem.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016-2020 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | import QtQml.Models 2.3 21 | import "../" 22 | 23 | MouseArea { 24 | id: area 25 | 26 | property color color: styleMusic.view.backgroundColor 27 | property color highlightedColor: styleMusic.view.highlightedColor 28 | property var currentColor: highlighted ? highlightedColor : color 29 | property bool highlighted: false 30 | 31 | property alias column: row.column 32 | 33 | Component.onCompleted: { 34 | if (parent != null) { 35 | anchors.left = parent.left; 36 | anchors.right = parent.right; 37 | } 38 | } 39 | 40 | Rectangle { 41 | id: content 42 | anchors.fill: parent 43 | 44 | color: area.color 45 | Behavior on color { ColorAnimation { duration: 100 } } 46 | 47 | // highlight the current position 48 | Rectangle { 49 | anchors.fill: row 50 | visible: area.highlighted 51 | color: area.highlightedColor 52 | opacity: 0.2 53 | } 54 | 55 | SimpleRow { 56 | id: row 57 | anchors.fill: parent 58 | 59 | // Animate margin changes so it isn't noticible 60 | Behavior on anchors.leftMargin { 61 | NumberAnimation { 62 | 63 | } 64 | } 65 | 66 | Behavior on anchors.rightMargin { 67 | NumberAnimation { 68 | 69 | } 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/albumartgenerator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Canonical Ltd. 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published by 6 | * the Free Software Foundation; version 3. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU Lesser General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this program. If not, see . 15 | * 16 | * Authors: Jussi Pakkanen 17 | * James Henstridge 18 | */ 19 | 20 | #include "albumartgenerator.h" 21 | 22 | #include 23 | #include 24 | 25 | #include "thumbnailerimageresponse.h" 26 | 27 | namespace thumbnailer 28 | { 29 | 30 | namespace qml 31 | { 32 | 33 | AlbumArtGenerator::AlbumArtGenerator(std::shared_ptr const& thumbnailer) 34 | : QQuickAsyncImageProvider() 35 | , thumbnailer(thumbnailer) 36 | { 37 | } 38 | 39 | QQuickImageResponse* AlbumArtGenerator::requestImageResponse(const QString& id, const QSize& requestedSize) 40 | { 41 | if (!thumbnailer->isValid()) 42 | { 43 | return new ThumbnailerImageResponse("Service unavailable"); 44 | } 45 | QUrlQuery query(id); 46 | if (!query.hasQueryItem(QStringLiteral("artist")) || !query.hasQueryItem(QStringLiteral("album"))) 47 | { 48 | qWarning() << "AlbumArtGenerator::requestImageResponse(): Invalid albumart uri:" << id; 49 | return new ThumbnailerImageResponse("Invalid albumart ID: " + id); 50 | } 51 | 52 | const QString artist = query.queryItemValue(QStringLiteral("artist"), QUrl::FullyDecoded); 53 | const QString album = query.queryItemValue(QStringLiteral("album"), QUrl::FullyDecoded); 54 | 55 | auto request = thumbnailer->getAlbumArt(artist, album, requestedSize); 56 | return new ThumbnailerImageResponse(request); 57 | } 58 | 59 | } // namespace qml 60 | 61 | } // namespace thumbnailer 62 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/plugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef THUMBNAILERPLUGIN_H 22 | #define THUMBNAILERPLUGIN_H 23 | 24 | #include 25 | #include 26 | 27 | #include "thumbnailer/thumbnailer.h" 28 | 29 | #include 30 | 31 | class ThumbnailerPlugin : public QQmlExtensionPlugin 32 | { 33 | Q_OBJECT 34 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") 35 | 36 | public: 37 | ThumbnailerPlugin(QObject* parent = nullptr); 38 | 39 | virtual void registerTypes(const char* uri) override; 40 | virtual void initializeEngine(QQmlEngine* engine, const char* uri) override; 41 | 42 | static QObject* proxy(QQmlEngine *engine, QJSEngine *scriptEngine); 43 | 44 | private: 45 | static std::shared_ptr<::thumbnailer::Thumbnailer> g_thumbnailer; 46 | }; 47 | 48 | namespace thumbnailer 49 | { 50 | 51 | class Proxy : public QObject 52 | { 53 | Q_OBJECT 54 | 55 | public: 56 | Proxy(std::shared_ptr& thumbnailer, QObject* parent = nullptr); 57 | virtual ~Proxy() { } 58 | 59 | Q_INVOKABLE bool configure(const QString& apiName, const QString& apiKey); 60 | 61 | Q_INVOKABLE QString apiName() { return m_p->apiName(); } 62 | 63 | Q_INVOKABLE void setTrace(bool trace) { m_p->setTrace(trace); } 64 | 65 | Q_INVOKABLE void clearCache() { m_p->clearCache(); } 66 | 67 | Q_INVOKABLE void reset() { m_p->reset(); } 68 | 69 | private: 70 | std::shared_ptr m_p; 71 | }; 72 | 73 | } // namespace thumbnailer 74 | 75 | #endif /* THUMBNAILERPLUGIN_H */ 76 | 77 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/diskcachemanager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #include "diskcachemanager.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | using namespace thumbnailer; 30 | 31 | DiskCacheManager::DiskCacheManager(const QString& offlineStoragePath, 32 | qint64 maxCacheSize, QObject* parent) 33 | : QObject(parent) 34 | { 35 | m_cache = new QNetworkDiskCache(); 36 | m_cache->setCacheDirectory(offlineStoragePath + QDir::separator() + "thumbnailer"); 37 | m_cache->setMaximumCacheSize(maxCacheSize); 38 | } 39 | 40 | DiskCacheManager::~DiskCacheManager() 41 | { 42 | delete m_cache; 43 | } 44 | 45 | QIODevice* DiskCacheManager::queryData(const QUrl& url, bool noExpire /*=false*/) 46 | { 47 | QNetworkCacheMetaData meta = m_cache->metaData(url); 48 | if(meta.isValid()) 49 | { 50 | if (noExpire || meta.expirationDate() > QDateTime::currentDateTime()) 51 | return m_cache->data(url); 52 | m_cache->remove(url); 53 | } 54 | return nullptr; 55 | } 56 | 57 | QIODevice* DiskCacheManager::createData(const QUrl& url, const QDateTime& expirationDate) 58 | { 59 | QNetworkCacheMetaData metadata; 60 | metadata.setUrl(url); 61 | metadata.setExpirationDate(expirationDate); 62 | metadata.setSaveToDisk(true); 63 | QIODevice* dev = m_cache->prepare(metadata); 64 | return dev; 65 | } 66 | 67 | void DiskCacheManager::insertData(QIODevice* cacheDev) 68 | { 69 | m_cache->insert(cacheDev); 70 | } 71 | 72 | void DiskCacheManager::clear() 73 | { 74 | m_cache->clear(); 75 | } 76 | -------------------------------------------------------------------------------- /gui/controls2_515/components/MusicHeader.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | 21 | Item { 22 | anchors { 23 | left: parent.left 24 | right: parent.right 25 | } 26 | 27 | property alias coverSources: coversImage.covers 28 | property alias coverFlow: coversImage.flowModel 29 | property alias noCover: coversImage.noCover 30 | property alias rightColumn: rightColumnLoader.sourceComponent 31 | property alias firstSource: coversImage.firstSource 32 | property bool isFavorite: false 33 | readonly property real contentHeight: rightColumnLoader.item.height + 34 | coversImage.anchors.topMargin + 35 | coversImage.anchors.bottomMargin 36 | 37 | CoverGrid { 38 | id: coversImage 39 | anchors { 40 | left: parent.left 41 | top: parent.top 42 | margins: units.gu(1) 43 | } 44 | size: rightColumnLoader.item.height 45 | } 46 | 47 | /* Show starred */ 48 | Icon { 49 | id: starred 50 | anchors { 51 | bottom: coversImage.bottom 52 | right: coversImage.right 53 | } 54 | height: isFavorite ? (coversImage.size * 0.40) : 0 55 | width: height 56 | enabled: isFavorite 57 | source: "qrc:/images/starred.svg" 58 | color: styleMusic.card.foregroundColor 59 | } 60 | 61 | Loader { 62 | id: rightColumnLoader 63 | anchors { 64 | bottom: coversImage.bottom 65 | left: coversImage.right 66 | leftMargin: units.gu(2) 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /backend/cli/builtin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This library is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License as published 6 | * by the Free Software Foundation; either version 3, or (at your option) 7 | * any later version. 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; see the file COPYING. If not, write to 16 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #ifndef BUILTIN_H 23 | #define BUILTIN_H 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | static inline int string_to_int8(const char *str, int8_t *num) 31 | { 32 | int v = atoi(str); 33 | if (v > INT8_MAX || v < INT8_MIN) 34 | return -(ERANGE); 35 | *num = (int8_t) v; 36 | return 0; 37 | } 38 | 39 | static inline int string_to_uint8(const char *str, uint8_t *num) 40 | { 41 | int v = atoi(str); 42 | if (v > UINT8_MAX || v < 0) 43 | return -(ERANGE); 44 | *num = (uint8_t) v; 45 | return 0; 46 | } 47 | 48 | static inline int string_to_int16(const char *str, int16_t *num) 49 | { 50 | int v = atoi(str); 51 | if (v > INT16_MAX || v < INT16_MIN) 52 | return -(ERANGE); 53 | *num = (int16_t) v; 54 | return 0; 55 | } 56 | 57 | static inline int string_to_uint16(const char *str, uint16_t *num) 58 | { 59 | int v = atoi(str); 60 | if (v > UINT16_MAX || v < 0) 61 | return -(ERANGE); 62 | *num = (uint16_t) v; 63 | return 0; 64 | } 65 | 66 | static inline int string_to_int32(const char *str, int32_t *num) 67 | { 68 | long long v = atoll(str); 69 | if (v > INT32_MAX || v < INT32_MIN) 70 | return -(ERANGE); 71 | *num = (int32_t) v; 72 | return 0; 73 | } 74 | 75 | static inline int string_to_uint32(const char *str, uint32_t *num) 76 | { 77 | long long v = atoll(str); 78 | if (v > UINT32_MAX || v < 0) 79 | return -(ERANGE); 80 | *num = (uint32_t) v; 81 | return 0; 82 | } 83 | 84 | #endif /* BUILTIN_H */ 85 | -------------------------------------------------------------------------------- /gui/images/bell.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 41 | Svg Vector Icons : http://www.onlinewebfonts.com/icon image/svg+xml 45 | 52 | -------------------------------------------------------------------------------- /gui/images/nightmode-enabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xml 44 | 45 | 48 | 49 | 57 | 61 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /gui/controls2_515/components/MusicCheckBox.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | 21 | CheckBox { 22 | id: control 23 | property color color: styleMusic.view.foregroundColor 24 | property color controlDownColor: styleMusic.view.highlightedColor 25 | property real zoom: 1.0 26 | property alias textAlignment: label.horizontalAlignment 27 | 28 | opacity: checkable ? 1.0 : 0.1 29 | 30 | contentItem: Text { 31 | id: label 32 | rightPadding: control.indicator.width + control.spacing 33 | //leftPadding: control.indicator.width + control.spacing 34 | text: control.text 35 | font: control.font 36 | opacity: enabled ? 1.0 : 0.3 37 | color: control.down ? control.controlDownColor : control.color 38 | elide: Text.ElideRight 39 | horizontalAlignment: Text.AlignLeft 40 | verticalAlignment: Text.AlignVCenter 41 | } 42 | 43 | indicator: Rectangle { 44 | implicitWidth: units.gu(2.5 * zoom) 45 | implicitHeight: units.gu(2.5 * zoom) 46 | x: control.width - width - control.rightPadding 47 | //x: control.rightPadding 48 | y: control.topPadding + control.availableHeight / 2 - height / 2 49 | radius: units.dp(0) 50 | color: "transparent" 51 | border.color: control.down ? control.controlDownColor : control.color 52 | 53 | Rectangle { 54 | width: units.gu(1.5 * zoom) 55 | height: units.gu(1.5 * zoom) 56 | x: units.dp(4 * zoom) 57 | y: units.dp(4 * zoom) 58 | radius: units.dp(2 * zoom) 59 | color: control.down ? control.controlDownColor : control.color 60 | visible: control.checked 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /gui/images/select-none.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /gui/controls2_515/components/Dialog/DialogServiceLabel.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 3 | * Jean-Luc Barriere 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; version 3. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import QtQuick 2.9 19 | import QtQuick.Controls 2.2 20 | import QtQuick.Layouts 1.3 21 | 22 | DialogBase { 23 | id: dialog 24 | //: this is a title of a dialog to add a new service 25 | title: qsTr("Add Service") 26 | 27 | property alias label: inputLabel.text 28 | property string serviceType: "" 29 | property string serviceIcon: "" 30 | 31 | footer: Row { 32 | leftPadding: units.gu(1) 33 | rightPadding: units.gu(1) 34 | bottomPadding: units.gu(1) 35 | spacing: units.gu(1) 36 | layoutDirection: Qt.RightToLeft 37 | 38 | Button { 39 | flat: true 40 | text: qsTr("Ok") 41 | onClicked: dialog.accept() 42 | } 43 | } 44 | 45 | Image { 46 | source: serviceIcon 47 | visible: source !== "" 48 | height: units.gu(15) 49 | fillMode: Qt.KeepAspectRatio 50 | anchors.horizontalCenter: parent.horizontalCenter 51 | } 52 | 53 | Label { 54 | anchors.left: parent.left 55 | anchors.right: parent.right 56 | wrapMode: Text.WordWrap 57 | color: styleMusic.dialog.labelColor 58 | font.pointSize: units.fs("small") 59 | font.weight: Font.Normal 60 | text: qsTr("You can specify a label for the new service to differentiate it from an existing one for the same provider.") 61 | } 62 | 63 | TextField { 64 | id: inputLabel 65 | font.pointSize: units.fs("medium") 66 | placeholderText: qsTr("Enter the label") 67 | inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhUrlCharactersOnly 68 | EnterKey.type: Qt.EnterKeyDone 69 | } 70 | 71 | onOpened: { 72 | label = ""; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /gui/images/sync.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/abstractapi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #include "abstractapi.h" 22 | 23 | #include 24 | 25 | #include "lastfm/lastfm.h" 26 | #include "deezer/deezer.h" 27 | 28 | using namespace thumbnailer; 29 | 30 | AbstractAPI::Store AbstractAPI::apis; 31 | 32 | namespace { 33 | // registering APIs 34 | bool init() 35 | { 36 | AbstractAPI::registerMe(new LastfmAPI()); 37 | AbstractAPI::registerMe(new DeezerAPI()); 38 | return 0; 39 | } 40 | int dummy = init(); 41 | } 42 | 43 | AbstractAPI::Store::~Store() 44 | { 45 | for (auto& e : map) 46 | delete e; 47 | map.clear(); 48 | } 49 | 50 | bool AbstractAPI::registerMe(AbstractAPI* api) 51 | { 52 | qInfo().noquote() << "thumbnailer: register API [" + QString(api->name()) + "]"; 53 | QMap::iterator it = AbstractAPI::apis.map.insert(api->name(), api); 54 | return (it != apis.map.end()); 55 | } 56 | 57 | AbstractAPI* AbstractAPI::forName(const QString& apiName) 58 | { 59 | QMap::const_iterator it = apis.map.find(apiName); 60 | return (it != apis.map.end() ? *it : nullptr); 61 | } 62 | 63 | QString AbstractAPI::normalizeArtist(const QString &artist) 64 | { 65 | int s = artist.indexOf('/'); 66 | int b = artist.indexOf(' '); 67 | if (b >= 0 && s > b) 68 | return artist.mid(0, s).remove('"'); 69 | return QString(artist).remove('"'); 70 | } 71 | 72 | QString AbstractAPI::normalizeAlbum(const QString &album) 73 | { 74 | return QString(album).remove('"'); 75 | } 76 | 77 | AbstractArtistInfo::AbstractArtistInfo(const QString& artist) 78 | : m_artist(artist) 79 | { 80 | } 81 | 82 | AbstractAlbumInfo::AbstractAlbumInfo(const QString& artist, const QString& album) 83 | : m_artist(artist) 84 | , m_album(album) 85 | { 86 | } 87 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/thumbnailerjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef THUMBNAILERJOB_H 22 | #define THUMBNAILERJOB_H 23 | 24 | #include 25 | 26 | namespace thumbnailer 27 | { 28 | 29 | class Job; 30 | 31 | typedef enum { 32 | ReplySuccess = 0, 33 | ReplyNetworkError = 1, 34 | ReplyFatalError = 2, 35 | ReplyServerError = 3, 36 | ReplyInvalid = 4, 37 | ReplyNoDataFound = 6, 38 | ReplyQuotaExceeded = 7, 39 | } ReplyStatus; 40 | 41 | class AbstractWorker : public QObject 42 | { 43 | friend class Job; 44 | 45 | Q_OBJECT 46 | public: 47 | AbstractWorker(QObject* parent = 0) : QObject(parent) { } 48 | 49 | virtual ~AbstractWorker() { } 50 | 51 | virtual void run() = 0; 52 | 53 | virtual ReplyStatus error() const = 0; 54 | 55 | virtual int errorCode() const = 0; 56 | 57 | virtual QString errorString() const = 0; 58 | 59 | virtual const QByteArray& image() const = 0; 60 | 61 | virtual bool isCached() const = 0; 62 | 63 | signals: 64 | void finished(); 65 | 66 | }; 67 | 68 | class Job final : public QObject 69 | { 70 | Q_OBJECT 71 | 72 | public: 73 | Q_DISABLE_COPY(Job) 74 | 75 | Job(AbstractWorker* worker, QObject* parent = 0); 76 | ~Job(); 77 | 78 | void start(); 79 | ReplyStatus error() const; 80 | int errorCode() const; 81 | QString errorString() const; 82 | const QByteArray& image() const; 83 | bool isCached() const; 84 | 85 | signals: 86 | void finished(); 87 | 88 | private slots: 89 | void finishedWorker() { emit finished(); } 90 | 91 | private: 92 | AbstractWorker* m_worker; // the worker owned by this job 93 | }; 94 | 95 | } 96 | #endif /* THUMBNAILERJOB_H */ 97 | 98 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/jsonparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 Jean-Luc Barriere 3 | * 4 | * This Program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2, or (at your option) 7 | * any later version. 8 | * 9 | * This Program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; see the file COPYING. If not, write to 16 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 17 | * MA 02110-1301 USA 18 | * http://www.gnu.org/copyleft/gpl.html 19 | * 20 | */ 21 | 22 | #ifndef JSONPARSER_H 23 | #define JSONPARSER_H 24 | 25 | #include "sajson.h" 26 | 27 | #include 28 | 29 | /** 30 | * @namespace thumbnailer::JSON 31 | * @brief This namespace contains all operations to handle JSON content 32 | */ 33 | namespace thumbnailer 34 | { 35 | namespace JSON 36 | { 37 | class Node 38 | { 39 | public: 40 | Node(); 41 | Node(const sajson::value& value); 42 | ~Node() { } 43 | 44 | bool IsNull() const; 45 | bool IsObject() const; 46 | bool IsArray() const; 47 | bool IsString() const; 48 | bool IsDouble() const; 49 | bool IsInt() const; 50 | bool IsTrue() const; 51 | bool IsFalse() const; 52 | 53 | QString GetStringValue() const; 54 | size_t GetStringSize() const; 55 | double GetDoubleValue() const; 56 | int64_t GetBigIntValue() const; 57 | int32_t GetIntValue() const; 58 | 59 | size_t Size() const; 60 | Node GetArrayElement(size_t index) const; 61 | QString GetObjectKey(size_t index) const; 62 | Node GetObjectValue(size_t index) const; 63 | Node GetObjectValue(const char *key) const; 64 | 65 | private: 66 | sajson::value m_value; 67 | }; 68 | 69 | class Document 70 | { 71 | public: 72 | Document(const char* doc); 73 | ~Document() 74 | { 75 | if (m_document) 76 | delete m_document; 77 | } 78 | 79 | bool IsValid() const 80 | { 81 | return m_isValid; 82 | } 83 | 84 | Node GetRoot() const; 85 | 86 | private: 87 | bool m_isValid; 88 | sajson::document* m_document; 89 | }; 90 | } 91 | } 92 | 93 | #endif /* JSONPARSER_H */ 94 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/artistinfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef ARTISTINFO_H 22 | #define ARTISTINFO_H 23 | 24 | #include "abstractapi.h" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | namespace thumbnailer 33 | { 34 | 35 | class DiskCacheManager; 36 | class NetManager; 37 | class NetRequest; 38 | 39 | class ArtistInfo final : public AbstractWorker 40 | { 41 | Q_OBJECT 42 | 43 | public: 44 | ArtistInfo(DiskCacheManager* cache, NetManager* nam, AbstractAPI* api, const QString& artist, const QSize& requestedSize, bool cached, QObject* parent = 0); 45 | ~ArtistInfo(); 46 | 47 | void run(); 48 | 49 | ReplyStatus error() const; 50 | 51 | int errorCode() const; 52 | 53 | QString errorString() const; 54 | 55 | const QByteArray& image() const; 56 | 57 | bool isCached() const; 58 | 59 | private slots: 60 | void queryInfo(); 61 | void readInfo(); 62 | void processInfo(); 63 | void readImage(); 64 | void processImage(); 65 | 66 | private: 67 | AbstractAPI::Parse_Status parseInfo(); 68 | bool parseServerError(); 69 | void queryImage(const QUrl& url); 70 | void fakeImage(); 71 | 72 | DiskCacheManager* m_cache; 73 | NetManager* m_nam; 74 | AbstractAPI* m_api; 75 | QString m_artist; 76 | QSize m_requestedSize; 77 | bool m_cached; 78 | QUrl m_cacheUrl; 79 | int m_size; 80 | 81 | QIODevice* m_cacheDev; 82 | std::unique_ptr m_call; 83 | AbstractAPI::error_t m_error; 84 | QByteArray m_info; 85 | QByteArray m_image; 86 | AbstractArtistInfo::metadata_t m_meta; 87 | 88 | AbstractArtistInfo* m_p; 89 | int m_try; 90 | }; 91 | 92 | } 93 | #endif /* ARTISTINFO_H */ 94 | 95 | -------------------------------------------------------------------------------- /backend/NosonApp/qmlsortfiltermodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2014 Canonical, Ltd. 3 | * 4 | * Authors: 5 | * Michal Hruby 6 | * Christian Dywan 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published by 10 | * the Free Software Foundation; version 3. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef NOSONAPPQSORTFILTERPROXYMODELQML_H 22 | #define NOSONAPPQSORTFILTERPROXYMODELQML_H 23 | 24 | #include 25 | #include "qmlsortbehavior.h" 26 | #include "qmlfilterbehavior.h" 27 | 28 | namespace nosonapp 29 | { 30 | 31 | class Q_DECL_EXPORT QSortFilterProxyModelQML : public QSortFilterProxyModel 32 | { 33 | Q_OBJECT 34 | 35 | Q_PROPERTY(QAbstractItemModel* model READ sourceModel WRITE setModel NOTIFY modelChanged) 36 | Q_PROPERTY(int count READ count NOTIFY countChanged) 37 | Q_PROPERTY(SortBehavior* sort READ sortBehavior NOTIFY sortChanged) 38 | Q_PROPERTY(FilterBehavior* filter READ filterBehavior NOTIFY filterChanged) 39 | 40 | public: 41 | explicit QSortFilterProxyModelQML(QObject *parent = 0); 42 | 43 | Q_INVOKABLE QVariantMap get(int row); 44 | QVariant data(int row, int role); 45 | Q_INVOKABLE int count(); 46 | virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; 47 | 48 | /* getters */ 49 | QHash roleNames() const; 50 | 51 | /* setters */ 52 | void setFilterProperty(const QString& property); 53 | void setModel(QAbstractItemModel *model); 54 | 55 | Q_SIGNALS: 56 | void countChanged(); 57 | void modelChanged(); 58 | void sortChanged(); 59 | void filterChanged(); 60 | 61 | private: 62 | SortBehavior m_sortBehavior; 63 | SortBehavior* sortBehavior(); 64 | void sortChangedInternal(); 65 | FilterBehavior m_filterBehavior; 66 | FilterBehavior* filterBehavior(); 67 | void filterChangedInternal(); 68 | int roleByName(const QString& roleName) const; 69 | }; 70 | 71 | } 72 | 73 | #endif // NOSONAPPQSORTFILTERPROXYMODELQML_H 74 | -------------------------------------------------------------------------------- /backend/NosonThumbnailer/thumbnailer/albuminfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Jean-Luc Barriere 3 | * 4 | * This file is part of Noson-App 5 | * 6 | * Noson is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * Noson is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with Noson. If not, see . 18 | * 19 | */ 20 | 21 | #ifndef ALBUMINFO_H 22 | #define ALBUMINFO_H 23 | 24 | #include "abstractapi.h" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | namespace thumbnailer 33 | { 34 | 35 | class DiskCacheManager; 36 | class NetManager; 37 | class NetRequest; 38 | class AbstractAlbumInfo; 39 | 40 | class AlbumInfo final : public AbstractWorker 41 | { 42 | Q_OBJECT 43 | 44 | public: 45 | AlbumInfo(DiskCacheManager* cache, NetManager* nam, AbstractAPI* api, const QString& artist, const QString& album, const QSize& requestedSize, bool cached, QObject* parent = 0); 46 | ~AlbumInfo(); 47 | 48 | void run(); 49 | 50 | ReplyStatus error() const; 51 | 52 | int errorCode() const; 53 | 54 | QString errorString() const; 55 | 56 | const QByteArray& image() const; 57 | 58 | bool isCached() const; 59 | 60 | private slots: 61 | void queryInfo(); 62 | void readInfo(); 63 | void processInfo(); 64 | void readImage(); 65 | void processImage(); 66 | 67 | private: 68 | AbstractAPI::Parse_Status parseInfo(); 69 | bool parseServerError(); 70 | void queryImage(const QUrl& url); 71 | void fakeImage(); 72 | 73 | DiskCacheManager* m_cache; 74 | NetManager* m_nam; 75 | AbstractAPI* m_api; 76 | QString m_artist; 77 | QString m_album; 78 | QSize m_requestedSize; 79 | bool m_cached; 80 | QUrl m_cacheUrl; 81 | int m_size; 82 | 83 | QIODevice* m_cacheDev; 84 | std::unique_ptr m_call; 85 | AbstractAPI::error_t m_error; 86 | QByteArray m_info; 87 | QByteArray m_image; 88 | AbstractAlbumInfo::metadata_t m_meta; 89 | 90 | AbstractAlbumInfo* m_p; 91 | int m_try; 92 | }; 93 | 94 | } 95 | #endif /* ALBUMINFO_H */ 96 | 97 | -------------------------------------------------------------------------------- /gui/images/select.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | image/svg+xml 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | --------------------------------------------------------------------------------