diff --git a/CMakeLists.txt b/CMakeLists.txt index 7036b561..caf11c86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,155 +1,160 @@ cmake_minimum_required(VERSION 3.5) project(elisa) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 14) set(REQUIRED_QT_VERSION "5.10.0") find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Core Network Qml Quick Test Sql Multimedia Svg Gui Widgets QuickTest Concurrent) set(REQUIRED_KF5_VERSION "5.45.0") find_package(ECM ${REQUIRED_KF5_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMInstallIcons) include(FeatureSummary) include(ECMAddAppIcon) include(ECMAddTests) if (NOT WIN32) find_package(Qt5DBus ${REQUIRED_QT_VERSION} CONFIG QUIET) set_package_properties(Qt5DBus PROPERTIES DESCRIPTION "Qt5 DBus is needed to provide MPris2 interface to allow remote control by the desktop workspace." TYPE OPTIONAL) endif() find_package(Qt5QuickWidgets ${REQUIRED_QT_VERSION} CONFIG QUIET) set_package_properties(Qt5QuickWidgets PROPERTIES DESCRIPTION "Qt5 Quick Widgets is needed at runtime to provide the interface." TYPE RUNTIME) find_package(Qt5QuickControls2 ${REQUIRED_QT_VERSION} CONFIG QUIET) set_package_properties(Qt5QuickControls2 PROPERTIES DESCRIPTION "Qt5 Quick Controls version 2 is needed at runtime to provide the interface." TYPE RUNTIME) if (ANDROID) find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG QUIET OPTIONAL_COMPONENTS AndroidExtras) endif() find_package(KF5I18n ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5I18n PROPERTIES DESCRIPTION "KF5 text internationalization library." TYPE REQUIRED) find_package(KF5Declarative ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Declarative PROPERTIES DESCRIPTION "Integration of QML and KDE work spaces." TYPE RECOMMENDED) find_package(KF5CoreAddons ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5CoreAddons PROPERTIES DESCRIPTION "Qt addon library with a collection of non-GUI utilities." TYPE REQUIRED) find_package(KF5Baloo ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "Baloo provides file searching and indexing." TYPE RECOMMENDED) find_package(KF5FileMetaData ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5FileMetaData PROPERTIES DESCRIPTION "Provides a simple library for extracting metadata." TYPE REQUIRED) find_package(KF5DocTools ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5DocTools PROPERTIES DESCRIPTION "Create documentation from DocBook library." TYPE OPTIONAL) find_package(KF5XmlGui ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5XmlGui PROPERTIES DESCRIPTION "Framework for managing menu and toolbar actions." TYPE RECOMMENDED) find_package(KF5Config ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Config PROPERTIES DESCRIPTION "Persistent platform-independent application settings." TYPE REQUIRED) find_package(KF5ConfigWidgets ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5ConfigWidgets PROPERTIES DESCRIPTION "Widgets for configuration dialogs." TYPE RECOMMENDED) find_package(KF5Crash ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Crash PROPERTIES DESCRIPTION "Graceful handling of application crashes." TYPE OPTIONAL) if (NOT WIN32) find_package(KF5DBusAddons ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5DBusAddons PROPERTIES DESCRIPTION "Convenience classes for D-Bus." TYPE OPTIONAL) endif() find_package(KF5KCMUtils ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5KCMUtils PROPERTIES DESCRIPTION "KF5 Utilities for KDE System Settings modules library." TYPE RECOMMENDED) find_package(KF5Package ${REQUIRED_KF5_VERSION} CONFIG QUIET) set_package_properties(KF5Package PROPERTIES DESCRIPTION "KF5 package management library needed to get the configuration dialogs." TYPE RECOMMENDED) +find_package(KF5KIO ${REQUIRED_KF5_VERSION} CONFIG QUIET) +set_package_properties(KF5KIO PROPERTIES + DESCRIPTION "File management libraries used for file browsing." + TYPE REQUIRED) + find_package(UPNPQT CONFIG QUIET) set_package_properties(UPNPQT PROPERTIES DESCRIPTION "UPNP layer build with Qt 5. UPnP support is currently broken. You should probably avoid this dependency." URL "https://gitlab.com/homeautomationqt/upnp-player-qt" TYPE OPTIONAL) if (UPNPQT_FOUND) message(WARNING "UPnP support is experimental and may not work.") endif() include(FeatureSummary) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(CMakePackageConfigHelpers) if (CMAKE_SYSTEM_NAME STREQUAL Android) set(QT_QMAKE_EXECUTABLE "$ENV{Qt5_android}/bin/qmake") endif() configure_file(config-upnp-qt.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-upnp-qt.h ) add_subdirectory(src) add_subdirectory(icons) if (BUILD_TESTING) add_subdirectory(autotests) endif() add_subdirectory(doc) install( PROGRAMS org.kde.elisa.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) install( FILES org.kde.elisa.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ki18n_install(po) endif() feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b2e0790b..7d42f4a1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,291 +1,295 @@ include_directories(${elisa_BINARY_DIR}) set(elisaLib_SOURCES mediaplaylist.cpp musicalbum.cpp musicaudiotrack.cpp musicartist.cpp progressindicator.cpp databaseinterface.cpp musiclistenersmanager.cpp managemediaplayercontrol.cpp manageheaderbar.cpp manageaudioplayer.cpp trackslistener.cpp elisaapplication.cpp audiowrapper.cpp notificationitem.cpp topnotificationmanager.cpp elisautils.cpp trackdatahelper.cpp abstractfile/abstractfilelistener.cpp abstractfile/abstractfilelisting.cpp file/filelistener.cpp file/localfilelisting.cpp models/albummodel.cpp models/allalbumsmodel.cpp models/allartistsmodel.cpp models/alltracksmodel.cpp models/abstractmediaproxymodel.cpp models/allalbumsproxymodel.cpp models/allartistsproxymodel.cpp models/alltracksproxymodel.cpp models/singleartistproxymodel.cpp models/singlealbumproxymodel.cpp + models/filebrowsermodel.cpp + models/filebrowserproxymodel.cpp ) if (KF5Baloo_FOUND) if (Qt5DBus_FOUND) set(elisaLib_SOURCES ${elisaLib_SOURCES} baloo/localbaloofilelisting.cpp baloo/baloolistener.cpp ) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.fileindexer.xml baloo/fileindexer) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.scheduler.xml baloo/scheduler) endif() endif() if (Qt5DBus_FOUND) set(elisaLib_SOURCES ${elisaLib_SOURCES} mpris2/mpris2.cpp mpris2/mediaplayer2.cpp mpris2/mediaplayer2player.cpp ) endif() if (UPNPQT_FOUND) set(elisaLib_SOURCES ${elisaLib_SOURCES} upnp/upnpcontrolcontentdirectory.cpp upnp/upnpcontentdirectorymodel.cpp upnp/upnpcontrolconnectionmanager.cpp upnp/upnpcontrolmediaserver.cpp upnp/didlparser.cpp upnp/upnplistener.cpp upnp/upnpdiscoverallmusic.cpp ) endif() if (KF5Baloo_FOUND) if (Qt5DBus_FOUND) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.fileindexer.xml baloo/fileindexer) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.scheduler.xml baloo/scheduler) set(elisaLib_SOURCES ${elisaLib_SOURCES} ../src/baloo/baloolistener.cpp ../src/baloo/localbaloofilelisting.cpp ) endif() endif() kconfig_add_kcfg_files(elisaLib_SOURCES ../src/elisa_settings.kcfgc ) set(elisaLib_SOURCES ${elisaLib_SOURCES} ../src/elisa_core.kcfg ) add_library(elisaLib ${elisaLib_SOURCES}) target_link_libraries(elisaLib LINK_PUBLIC - Qt5::Multimedia + Qt5::Multimedia KF5::KIOCore KF5::KIOFileWidgets KF5::KIOWidgets LINK_PRIVATE Qt5::Core Qt5::Sql Qt5::Widgets KF5::I18n Qt5::Concurrent Qt5::Qml KF5::ConfigCore KF5::ConfigGui KF5::FileMetaData) if (KF5XmlGui_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::XmlGui ) endif() if (KF5ConfigWidgets_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::ConfigWidgets ) endif() if (KF5KCMUtils_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::KCMUtils ) endif() if (KF5Baloo_FOUND) if (Qt5DBus_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::Baloo ) endif() endif() if (Qt5DBus_FOUND) target_link_libraries(elisaLib LINK_PUBLIC Qt5::DBus ) if (KF5DBusAddons_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::DBusAddons ) endif() endif() generate_export_header(elisaLib BASE_NAME ElisaLib EXPORT_FILE_NAME elisaLib_export.h) set_target_properties(elisaLib PROPERTIES VERSION 0.1 SOVERSION 0 EXPORT_NAME ElisaLib ) install(TARGETS elisaLib ${INSTALL_TARGETS_DEFAULT_ARGS}) set(elisaqmlplugin_SOURCES elisaqmlplugin.cpp elisautils.cpp ) add_library(elisaqmlplugin SHARED ${elisaqmlplugin_SOURCES}) target_link_libraries(elisaqmlplugin LINK_PRIVATE Qt5::Quick Qt5::Widgets KF5::FileMetaData KF5::ConfigCore KF5::ConfigGui elisaLib ) set_target_properties(elisaqmlplugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/org/kde/elisa) install(TARGETS elisaqmlplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/elisa/) install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/elisa) add_custom_target(copy) add_custom_target(copy2) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/org/kde/elisa) add_custom_command(TARGET copy PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_BINARY_DIR}/bin/org/kde/elisa/) add_custom_command(TARGET copy2 PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/plugins.qmltypes ${CMAKE_BINARY_DIR}/bin/org/kde/elisa/) add_dependencies(elisaqmlplugin copy copy2) if (Qt5Quick_FOUND AND Qt5Widgets_FOUND AND KF5Declarative_FOUND) set(elisa_SOURCES main.cpp windows/WindowsTheme.qml windows/PlatformIntegration.qml android/ElisaMainWindow.qml android/AndroidTheme.qml android/PlatformIntegration.qml qml/ElisaMainWindow.qml qml/ApplicationMenu.qml qml/Theme.qml qml/PlatformIntegration.qml qml/LabelWithToolTip.qml qml/RatingStar.qml qml/PlayListEntry.qml qml/MediaBrowser.qml qml/DraggableItem.qml qml/PassiveNotification.qml qml/TopNotification.qml qml/TopNotificationItem.qml qml/TrackImportNotification.qml qml/HeaderBar.qml qml/NavigationActionBar.qml qml/MediaPlayerControl.qml qml/ContextView.qml qml/ContentView.qml qml/ViewSelector.qml qml/MediaPlayListView.qml qml/MediaTrackDelegate.qml qml/MediaAlbumTrackDelegate.qml qml/MediaTrackMetadataView.qml qml/GridBrowserView.qml qml/GridBrowserDelegate.qml qml/ListBrowserView.qml + qml/FileBrowserDelegate.qml + qml/FileBrowserView.qml ) qt5_add_resources(elisa_SOURCES resources.qrc) set_property(SOURCE qrc_resources.cpp PROPERTY SKIP_AUTOMOC ON) set(elisa_ICONS_PNG ../icons/128-apps-elisa.png ../icons/64-apps-elisa.png ../icons/48-apps-elisa.png ../icons/32-apps-elisa.png ../icons/22-apps-elisa.png ../icons/16-apps-elisa.png ) # add icons to application sources, to have them bundled ecm_add_app_icon(elisa_SOURCES ICONS ${elisa_ICONS_PNG}) add_executable(elisa ${elisa_SOURCES}) target_include_directories(elisa PRIVATE ${KDSoap_INCLUDE_DIRS}) target_link_libraries(elisa LINK_PRIVATE elisaLib Qt5::Widgets KF5::Declarative KF5::I18n KF5::Crash KF5::ConfigCore KF5::ConfigGui ) endif() install(TARGETS elisa ${INSTALL_TARGETS_DEFAULT_ARGS}) if (KF5ConfigWidgets_FOUND) add_subdirectory(localFileConfiguration) endif() set(elisaImport_SOURCES elisaimport.cpp elisaimportapplication.cpp ) kconfig_add_kcfg_files(elisaImport_SOURCES ../src/elisa_settings.kcfgc ) set(elisaImport_SOURCES ${elisaImport_SOURCES} ../src/elisa_core.kcfg ) add_executable(elisaImport ${elisaImport_SOURCES}) target_link_libraries(elisaImport LINK_PRIVATE KF5::ConfigCore KF5::ConfigGui KF5::FileMetaData elisaLib ) set(QML_IMPORT_PATH ${CMAKE_BINARY_DIR}/bin CACHE INTERNAL "qml import path" FORCE) diff --git a/src/elisaapplication.cpp b/src/elisaapplication.cpp index b600e814..262aa5ee 100644 --- a/src/elisaapplication.cpp +++ b/src/elisaapplication.cpp @@ -1,477 +1,487 @@ /* * Copyright 2017 Matthieu Gallien * Copyright (C) 2012 Aleix Pol Gonzalez * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "elisaapplication.h" #include "musiclistenersmanager.h" #include "models/allalbumsproxymodel.h" #include "models/alltracksproxymodel.h" #include "models/allartistsproxymodel.h" #include "models/singleartistproxymodel.h" #include "models/singlealbumproxymodel.h" +#include "models/filebrowserproxymodel.h" #include "mediaplaylist.h" #include "audiowrapper.h" #include "manageaudioplayer.h" #include "managemediaplayercontrol.h" #include "manageheaderbar.h" #include "elisa_settings.h" #include #if defined KF5ConfigWidgets_FOUND && KF5ConfigWidgets_FOUND #include #endif #if defined KF5XmlGui_FOUND && KF5XmlGui_FOUND #include #include #include #include #include #endif #if defined KF5KCMUtils_FOUND && KF5KCMUtils_FOUND #include #endif #include #include #include #include #include #include #include #include #include #include #include #include class ElisaApplicationPrivate { public: explicit ElisaApplicationPrivate(QObject *parent) #if defined KF5XmlGui_FOUND && KF5XmlGui_FOUND : mCollection(parent) #endif { Q_UNUSED(parent) auto configurationFileName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); configurationFileName += QStringLiteral("/elisarc"); Elisa::ElisaConfiguration::instance(configurationFileName); Elisa::ElisaConfiguration::self()->load(); Elisa::ElisaConfiguration::self()->save(); } #if defined KF5XmlGui_FOUND && KF5XmlGui_FOUND KActionCollection mCollection; #endif QStringList mArguments; std::unique_ptr mMusicManager; std::unique_ptr mAllAlbumsProxyModel; std::unique_ptr mAllArtistsProxyModel; std::unique_ptr mAllTracksProxyModel; std::unique_ptr mSingleArtistProxyModel; std::unique_ptr mSingleAlbumProxyModel; + std::unique_ptr mFileBrowserProxyModel; + std::unique_ptr mMediaPlayList; std::unique_ptr mAudioWrapper; std::unique_ptr mAudioControl; std::unique_ptr mPlayerControl; std::unique_ptr mManageHeaderBar; }; ElisaApplication::ElisaApplication(QObject *parent) : QObject(parent), d(std::make_unique(this)) { } ElisaApplication::~ElisaApplication() = default; void ElisaApplication::setupActions(const QString &actionName) { #if defined KF5XmlGui_FOUND && KF5XmlGui_FOUND if (actionName == QStringLiteral("file_quit")) { auto quitAction = KStandardAction::quit(QCoreApplication::instance(), &QCoreApplication::quit, &d->mCollection); d->mCollection.addAction(actionName, quitAction); } if (actionName == QStringLiteral("help_contents") && KAuthorized::authorizeAction(actionName)) { auto handBookAction = KStandardAction::helpContents(this, &ElisaApplication::appHelpActivated, &d->mCollection); d->mCollection.addAction(handBookAction->objectName(), handBookAction); } if (actionName == QStringLiteral("help_report_bug") && KAuthorized::authorizeAction(actionName) && !KAboutData::applicationData().bugAddress().isEmpty()) { auto reportBugAction = KStandardAction::reportBug(this, &ElisaApplication::reportBug, &d->mCollection); d->mCollection.addAction(reportBugAction->objectName(), reportBugAction); } if (actionName == QStringLiteral("help_about_app") && KAuthorized::authorizeAction(actionName)) { auto aboutAppAction = KStandardAction::aboutApp(this, &ElisaApplication::aboutApplication, this); d->mCollection.addAction(aboutAppAction->objectName(), aboutAppAction); } if (actionName == QStringLiteral("options_configure") && KAuthorized::authorizeAction(actionName)) { auto preferencesAction = KStandardAction::preferences(this, &ElisaApplication::configureElisa, this); d->mCollection.addAction(preferencesAction->objectName(), preferencesAction); } if (actionName == QStringLiteral("options_configure_keybinding") && KAuthorized::authorizeAction(actionName)) { auto keyBindingsAction = KStandardAction::keyBindings(this, &ElisaApplication::configureShortcuts, this); d->mCollection.addAction(keyBindingsAction->objectName(), keyBindingsAction); } if (actionName == QStringLiteral("go_back") && KAuthorized::authorizeAction(actionName)) { auto goBackAction = KStandardAction::back(this, &ElisaApplication::goBack, this); d->mCollection.addAction(goBackAction->objectName(), goBackAction); } if (actionName == QStringLiteral("edit_find") && KAuthorized::authorizeAction(actionName)) { auto findAction = KStandardAction::find(this, &ElisaApplication::find, this); d->mCollection.addAction(findAction->objectName(), findAction); } d->mCollection.readSettings(); #endif } void ElisaApplication::setArguments(const QStringList &newArguments) { if (d->mArguments == newArguments) { return; } d->mArguments = checkFileListAndMakeAbsolute(newArguments, QDir::currentPath()); Q_EMIT argumentsChanged(); if (!d->mArguments.isEmpty()) { Q_EMIT enqueue(d->mArguments); } } void ElisaApplication::activateActionRequested(const QString &actionName, const QVariant ¶meter) { Q_UNUSED(actionName) Q_UNUSED(parameter) } void ElisaApplication::activateRequested(const QStringList &arguments, const QString &workingDirectory) { auto realArguments = arguments; if (realArguments.size() > 1) { realArguments.removeFirst(); Q_EMIT enqueue(checkFileListAndMakeAbsolute(realArguments, workingDirectory)); } } void ElisaApplication::openRequested(const QList &uris) { Q_UNUSED(uris) } void ElisaApplication::appHelpActivated() { QDesktopServices::openUrl(QUrl(QStringLiteral("help:/"))); } void ElisaApplication::aboutApplication() { #if defined KF5XmlGui_FOUND && KF5XmlGui_FOUND static QPointer dialog; if (!dialog) { dialog = new KAboutApplicationDialog(KAboutData::applicationData(), nullptr); dialog->setAttribute(Qt::WA_DeleteOnClose); } dialog->show(); #endif } void ElisaApplication::reportBug() { #if defined KF5XmlGui_FOUND && KF5XmlGui_FOUND static QPointer dialog; if (!dialog) { dialog = new KBugReport(KAboutData::applicationData(), nullptr); dialog->setAttribute(Qt::WA_DeleteOnClose); } dialog->show(); #endif } void ElisaApplication::configureShortcuts() { #if defined KF5XmlGui_FOUND && KF5XmlGui_FOUND KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, nullptr); dlg.setModal(true); dlg.addCollection(&d->mCollection); dlg.configure(); #endif } void ElisaApplication::configureElisa() { #if defined KF5KCMUtils_FOUND && KF5KCMUtils_FOUND KCMultiDialog configurationDialog; configurationDialog.addModule(QStringLiteral("kcm_elisa_local_file")); configurationDialog.setModal(true); configurationDialog.exec(); #endif } void ElisaApplication::goBack() {} void ElisaApplication::find() {} QStringList ElisaApplication::checkFileListAndMakeAbsolute(const QStringList &filesList, const QString &workingDirectory) const { QStringList filesToOpen; for (const auto &oneFile : filesList) { auto newFile = QFileInfo(oneFile); if (newFile.isRelative()) { newFile = QFileInfo(workingDirectory + QStringLiteral("/") + oneFile); } if (newFile.exists()) { filesToOpen.push_back(newFile.canonicalFilePath()); } } return filesToOpen; } void ElisaApplication::initialize() { initializeModels(); initializePlayer(); } void ElisaApplication::initializeModels() { d->mMusicManager = std::make_unique(); Q_EMIT musicManagerChanged(); d->mAllAlbumsProxyModel = std::make_unique(); Q_EMIT allAlbumsProxyModelChanged(); d->mAllArtistsProxyModel = std::make_unique(); Q_EMIT allArtistsProxyModelChanged(); d->mAllTracksProxyModel = std::make_unique(); Q_EMIT allTracksProxyModelChanged(); d->mSingleArtistProxyModel = std::make_unique(); Q_EMIT singleArtistProxyModelChanged(); d->mSingleAlbumProxyModel = std::make_unique(); Q_EMIT singleAlbumProxyModelChanged(); + d->mFileBrowserProxyModel = std::make_unique(); + Q_EMIT fileBrowserProxyModelChanged(); d->mMediaPlayList = std::make_unique(); Q_EMIT mediaPlayListChanged(); d->mMusicManager->setElisaApplication(this); d->mMediaPlayList->setMusicListenersManager(d->mMusicManager.get()); QObject::connect(this, &ElisaApplication::enqueue, d->mMediaPlayList.get(), &MediaPlayList::enqueueAndPlay); d->mAllAlbumsProxyModel->setSourceModel(d->mMusicManager->allAlbumsModel()); d->mAllArtistsProxyModel->setSourceModel(d->mMusicManager->allArtistsModel()); d->mAllTracksProxyModel->setSourceModel(d->mMusicManager->allTracksModel()); d->mSingleArtistProxyModel->setSourceModel(d->mMusicManager->allAlbumsModel()); d->mSingleAlbumProxyModel->setSourceModel(d->mMusicManager->albumModel()); QObject::connect(d->mAllAlbumsProxyModel.get(), &AllAlbumsProxyModel::albumToEnqueue, d->mMediaPlayList.get(), static_cast &, ElisaUtils::PlayListEnqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayList::enqueue)); QObject::connect(d->mAllArtistsProxyModel.get(), &AllArtistsProxyModel::artistToEnqueue, d->mMediaPlayList.get(), &MediaPlayList::enqueueArtists); QObject::connect(d->mAllTracksProxyModel.get(), &AllTracksProxyModel::trackToEnqueue, d->mMediaPlayList.get(), static_cast &, ElisaUtils::PlayListEnqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayList::enqueue)); QObject::connect(d->mSingleArtistProxyModel.get(), &SingleArtistProxyModel::albumToEnqueue, d->mMediaPlayList.get(), static_cast &, ElisaUtils::PlayListEnqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayList::enqueue)); QObject::connect(d->mSingleAlbumProxyModel.get(), &SingleAlbumProxyModel::trackToEnqueue, d->mMediaPlayList.get(), static_cast &, ElisaUtils::PlayListEnqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayList::enqueue)); } void ElisaApplication::initializePlayer() { d->mAudioWrapper = std::make_unique(); Q_EMIT audioPlayerChanged(); d->mAudioControl = std::make_unique(); Q_EMIT audioControlChanged(); d->mPlayerControl = std::make_unique(); Q_EMIT playerControlChanged(); d->mManageHeaderBar = std::make_unique(); Q_EMIT manageHeaderBarChanged(); d->mAudioControl->setAlbumNameRole(MediaPlayList::AlbumRole); d->mAudioControl->setArtistNameRole(MediaPlayList::ArtistRole); d->mAudioControl->setTitleRole(MediaPlayList::TitleRole); d->mAudioControl->setUrlRole(MediaPlayList::ResourceRole); d->mAudioControl->setIsPlayingRole(MediaPlayList::IsPlayingRole); d->mAudioControl->setPlayListModel(d->mMediaPlayList.get()); QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::playerPlay, d->mAudioWrapper.get(), &AudioWrapper::play); QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::playerPause, d->mAudioWrapper.get(), &AudioWrapper::pause); QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::playerStop, d->mAudioWrapper.get(), &AudioWrapper::stop); QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::seek, d->mAudioWrapper.get(), &AudioWrapper::seek); QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::skipNextTrack, d->mMediaPlayList.get(), &MediaPlayList::skipNextTrack); QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::sourceInError, d->mMediaPlayList.get(), &MediaPlayList::trackInError); QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::sourceInError, d->mMusicManager.get(), &MusicListenersManager::playBackError); QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::playerSourceChanged, d->mAudioWrapper.get(), &AudioWrapper::setSource); QObject::connect(d->mMediaPlayList.get(), &MediaPlayList::ensurePlay, d->mAudioControl.get(), &ManageAudioPlayer::ensurePlay); QObject::connect(d->mMediaPlayList.get(), &MediaPlayList::playListFinished, d->mAudioControl.get(), &ManageAudioPlayer::playListFinished); QObject::connect(d->mMediaPlayList.get(), &MediaPlayList::currentTrackChanged, d->mAudioControl.get(), &ManageAudioPlayer::setCurrentTrack); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::playbackStateChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerPlaybackState); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::statusChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerStatus); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::errorChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerError); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::durationChanged, d->mAudioControl.get(), &ManageAudioPlayer::setAudioDuration); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::seekableChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerIsSeekable); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::positionChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerPosition); d->mPlayerControl->setPlayListModel(d->mMediaPlayList.get()); QObject::connect(d->mMediaPlayList.get(), &MediaPlayList::currentTrackChanged, d->mPlayerControl.get(), &ManageMediaPlayerControl::setCurrentTrack); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::playing, d->mPlayerControl.get(), &ManageMediaPlayerControl::playerPlaying); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::paused, d->mPlayerControl.get(), &ManageMediaPlayerControl::playerPaused); QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::stopped, d->mPlayerControl.get(), &ManageMediaPlayerControl::playerStopped); d->mManageHeaderBar->setTitleRole(MediaPlayList::TitleRole); d->mManageHeaderBar->setAlbumRole(MediaPlayList::AlbumRole); d->mManageHeaderBar->setArtistRole(MediaPlayList::ArtistRole); d->mManageHeaderBar->setImageRole(MediaPlayList::ImageRole); d->mManageHeaderBar->setIsValidRole(MediaPlayList::IsValidRole); d->mManageHeaderBar->setPlayListModel(d->mMediaPlayList.get()); QObject::connect(d->mMediaPlayList.get(), &MediaPlayList::currentTrackChanged, d->mManageHeaderBar.get(), &ManageHeaderBar::setCurrentTrack); if (!d->mArguments.isEmpty()) { Q_EMIT enqueue(d->mArguments); } } QAction * ElisaApplication::action(const QString& name) { #if defined KF5XmlGui_FOUND && KF5XmlGui_FOUND auto resultAction = d->mCollection.action(name); if (!resultAction) { setupActions(name); resultAction = d->mCollection.action(name); } return resultAction; #else Q_UNUSED(name); return new QAction(); #endif } QString ElisaApplication::iconName(const QIcon& icon) { return icon.name(); } const QStringList &ElisaApplication::arguments() const { return d->mArguments; } MusicListenersManager *ElisaApplication::musicManager() const { return d->mMusicManager.get(); } AllAlbumsProxyModel *ElisaApplication::allAlbumsProxyModel() const { return d->mAllAlbumsProxyModel.get(); } AllArtistsProxyModel *ElisaApplication::allArtistsProxyModel() const { return d->mAllArtistsProxyModel.get(); } AllTracksProxyModel *ElisaApplication::allTracksProxyModel() const { return d->mAllTracksProxyModel.get(); } SingleArtistProxyModel *ElisaApplication::singleArtistProxyModel() const { return d->mSingleArtistProxyModel.get(); } SingleAlbumProxyModel *ElisaApplication::singleAlbumProxyModel() const { return d->mSingleAlbumProxyModel.get(); } +FileBrowserProxyModel *ElisaApplication::fileBrowserProxyModel() const +{ + return d->mFileBrowserProxyModel.get(); +} + MediaPlayList *ElisaApplication::mediaPlayList() const { return d->mMediaPlayList.get(); } AudioWrapper *ElisaApplication::audioPlayer() const { return d->mAudioWrapper.get(); } ManageAudioPlayer *ElisaApplication::audioControl() const { return d->mAudioControl.get(); } ManageMediaPlayerControl *ElisaApplication::playerControl() const { return d->mPlayerControl.get(); } ManageHeaderBar *ElisaApplication::manageHeaderBar() const { return d->mManageHeaderBar.get(); } #include "moc_elisaapplication.cpp" diff --git a/src/elisaapplication.h b/src/elisaapplication.h index 1b305d4d..9c348969 100644 --- a/src/elisaapplication.h +++ b/src/elisaapplication.h @@ -1,204 +1,213 @@ /* * Copyright 2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef ELISAAPPLICATION_H #define ELISAAPPLICATION_H #include "elisaLib_export.h" #include "config-upnp-qt.h" #include #include #include class QIcon; class QAction; class MusicListenersManager; class AllAlbumsProxyModel; class AllArtistsProxyModel; class AllTracksProxyModel; class SingleArtistProxyModel; class SingleAlbumProxyModel; +class FileBrowserProxyModel; class MediaPlayList; class AudioWrapper; class ManageAudioPlayer; class ManageMediaPlayerControl; class ManageHeaderBar; class ElisaApplicationPrivate; class ELISALIB_EXPORT ElisaApplication : public QObject { Q_OBJECT Q_PROPERTY(QStringList arguments READ arguments WRITE setArguments NOTIFY argumentsChanged) Q_PROPERTY(MusicListenersManager *musicManager READ musicManager NOTIFY musicManagerChanged) Q_PROPERTY(AllAlbumsProxyModel *allAlbumsProxyModel READ allAlbumsProxyModel NOTIFY allAlbumsProxyModelChanged) Q_PROPERTY(AllArtistsProxyModel *allArtistsProxyModel READ allArtistsProxyModel NOTIFY allArtistsProxyModelChanged) Q_PROPERTY(AllTracksProxyModel *allTracksProxyModel READ allTracksProxyModel NOTIFY allTracksProxyModelChanged) Q_PROPERTY(SingleArtistProxyModel *singleArtistProxyModel READ singleArtistProxyModel NOTIFY singleArtistProxyModelChanged) Q_PROPERTY(SingleAlbumProxyModel *singleAlbumProxyModel READ singleAlbumProxyModel NOTIFY singleAlbumProxyModelChanged) + Q_PROPERTY(FileBrowserProxyModel *fileBrowserProxyModel + READ fileBrowserProxyModel + NOTIFY fileBrowserProxyModelChanged) + Q_PROPERTY(MediaPlayList *mediaPlayList READ mediaPlayList NOTIFY mediaPlayListChanged) Q_PROPERTY(AudioWrapper *audioPlayer READ audioPlayer NOTIFY audioPlayerChanged) Q_PROPERTY(ManageAudioPlayer *audioControl READ audioControl NOTIFY audioControlChanged) Q_PROPERTY(ManageMediaPlayerControl *playerControl READ playerControl NOTIFY playerControlChanged) Q_PROPERTY(ManageHeaderBar *manageHeaderBar READ manageHeaderBar NOTIFY manageHeaderBarChanged) public: explicit ElisaApplication(QObject *parent = nullptr); ~ElisaApplication() override; Q_INVOKABLE QAction* action(const QString& name); Q_INVOKABLE QString iconName(const QIcon& icon); const QStringList &arguments() const; MusicListenersManager *musicManager() const; AllAlbumsProxyModel *allAlbumsProxyModel() const; AllArtistsProxyModel *allArtistsProxyModel() const; AllTracksProxyModel *allTracksProxyModel() const; SingleArtistProxyModel *singleArtistProxyModel() const; SingleAlbumProxyModel *singleAlbumProxyModel() const; + FileBrowserProxyModel *fileBrowserProxyModel() const; + MediaPlayList *mediaPlayList() const; AudioWrapper *audioPlayer() const; ManageAudioPlayer *audioControl() const; ManageMediaPlayerControl *playerControl() const; ManageHeaderBar *manageHeaderBar() const; Q_SIGNALS: void argumentsChanged(); void musicManagerChanged(); void allAlbumsProxyModelChanged(); void allArtistsProxyModelChanged(); void allTracksProxyModelChanged(); void singleArtistProxyModelChanged(); void singleAlbumProxyModelChanged(); + void fileBrowserProxyModelChanged(); + void mediaPlayListChanged(); void audioPlayerChanged(); void audioControlChanged(); void playerControlChanged(); void manageHeaderBarChanged(); void enqueue(const QStringList &files); public Q_SLOTS: void appHelpActivated(); void aboutApplication(); void reportBug(); void configureShortcuts(); void configureElisa(); void setArguments(const QStringList &newArguments); void activateActionRequested(const QString &actionName, const QVariant ¶meter); void activateRequested(const QStringList &arguments, const QString &workingDirectory); void openRequested(const QList< QUrl > &uris); void initialize(); private Q_SLOTS: void goBack(); void find(); private: void initializeModels(); void initializePlayer(); void setupActions(const QString &actionName); QStringList checkFileListAndMakeAbsolute(const QStringList &filesList, const QString &workingDirectory) const; std::unique_ptr d; }; #endif // ELISAAPPLICATION_H diff --git a/src/elisaqmlplugin.cpp b/src/elisaqmlplugin.cpp index 7016cd2b..884c172a 100644 --- a/src/elisaqmlplugin.cpp +++ b/src/elisaqmlplugin.cpp @@ -1,143 +1,146 @@ /* * Copyright 2018 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "elisaqmlplugin.h" #if defined UPNPQT_FOUND && UPNPQT_FOUND #include "upnp/upnpcontrolconnectionmanager.h" #include "upnp/upnpcontrolmediaserver.h" #include "upnp/upnpcontrolcontentdirectory.h" #include "upnp/upnpcontentdirectorymodel.h" #include "upnpdevicedescription.h" #include "upnp/didlparser.h" #include "upnp/upnpdiscoverallmusic.h" #include "upnpssdpengine.h" #include "upnpabstractservice.h" #include "upnpcontrolabstractdevice.h" #include "upnpcontrolabstractservice.h" #include "upnpbasictypes.h" #endif #include "elisaapplication.h" #include "progressindicator.h" #include "mediaplaylist.h" #include "managemediaplayercontrol.h" #include "manageheaderbar.h" #include "manageaudioplayer.h" #include "musicaudiotrack.h" #include "musiclistenersmanager.h" #include "models/allalbumsmodel.h" #include "models/albummodel.h" #include "models/allartistsmodel.h" #include "models/alltracksmodel.h" #include "models/allalbumsproxymodel.h" #include "models/alltracksproxymodel.h" #include "models/allartistsproxymodel.h" #include "models/singleartistproxymodel.h" #include "models/singlealbumproxymodel.h" +#include "models/filebrowserproxymodel.h" #include "audiowrapper.h" #include "notificationitem.h" #include "topnotificationmanager.h" #include "trackdatahelper.h" #include "elisautils.h" #if defined Qt5DBus_FOUND && Qt5DBus_FOUND #include "mpris2/mpris2.h" #include "mpris2/mediaplayer2player.h" #endif #include #include #include #include #include void ElisaQmlTestPlugin::initializeEngine(QQmlEngine *engine, const char *uri) { QQmlExtensionPlugin::initializeEngine(engine, uri); } void ElisaQmlTestPlugin::registerTypes(const char *uri) { #if defined UPNPQT_FOUND && UPNPQT_FOUND qmlRegisterType(uri, 1, 0, "UpnpSsdpEngine"); qmlRegisterType(uri, 1, 0, "UpnpDiscoverAllMusic"); qmlRegisterType(uri, 1, 0, "UpnpAbstractDevice"); qmlRegisterType(uri, 1, 0, "UpnpAbstractService"); qmlRegisterType(uri, 1, 0, "UpnpControlAbstractDevice"); qmlRegisterType(uri, 1, 0, "UpnpControlAbstractService"); qmlRegisterType(uri, 1, 0, "UpnpControlConnectionManager"); qmlRegisterType(uri, 1, 0, "UpnpControlMediaServer"); qmlRegisterType(uri, 1, 0, "UpnpContentDirectoryModel"); qmlRegisterType(uri, 1, 0, "DidlParser"); qmlRegisterType(uri, 1, 0, "UpnpControlContentDirectory"); qmlRegisterType(uri, 1, 0, "UpnpDeviceDescription"); qRegisterMetaType(); qRegisterMetaType >(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); #endif qmlRegisterType(uri, 1, 0, "MediaPlayList"); qmlRegisterType(uri, 1, 0, "ManageMediaPlayerControl"); qmlRegisterType(uri, 1, 0, "ManageHeaderBar"); qmlRegisterType(uri, 1, 0, "ManageAudioPlayer"); qmlRegisterType(uri, 1, 0, "ProgressIndicator"); qmlRegisterType(uri, 1, 0, "MusicListenersManager"); qmlRegisterType(uri, 1, 0, "AllAlbumsProxyModel"); qmlRegisterType(uri, 1, 0, "AllArtistsProxyModel"); qmlRegisterType(uri, 1, 0, "AllTracksProxyModel"); qmlRegisterType(uri, 1, 0, "SingleAlbumProxyModel"); qmlRegisterType(uri, 1, 0, "SingleArtistProxyModel"); + qmlRegisterType(uri, 1, 0, "FileBrowserProxyModel"); qmlRegisterType(uri, 1, 0, "AudioWrapper"); qmlRegisterType(uri, 1, 0, "TopNotificationManager"); qmlRegisterType(uri, 1, 0, "TrackDataHelper"); #if defined Qt5DBus_FOUND && Qt5DBus_FOUND qmlRegisterType(uri, 1, 0, "Mpris2"); qRegisterMetaType(); #endif qRegisterMetaType(); + qRegisterMetaType(); qRegisterMetaType>("QHash"); qRegisterMetaType>("QHash"); qRegisterMetaType>("QList"); qRegisterMetaType>("QVector"); qRegisterMetaType>("QList"); qRegisterMetaType>("QList"); qRegisterMetaType>("QVector"); qRegisterMetaType>("QHash"); qRegisterMetaType("MusicAlbum"); qRegisterMetaType("MusicArtist"); qRegisterMetaType>(); qRegisterMetaType(); qRegisterMetaType("NotificationItem"); qRegisterMetaType>("QMap"); qRegisterMetaType("ElisaUtils::PlayListEnqueueMode"); qRegisterMetaType("ElisaUtils::PlayListEnqueueTriggerPlay"); qRegisterMetaTypeStreamOperators("PlayListControler::PlayerState"); qmlRegisterUncreatableType(uri, 1, 0, "ElisaApplication", QStringLiteral("only one and done in c++")); } diff --git a/src/plugins.qmltypes b/src/plugins.qmltypes deleted file mode 100644 index a7bf45b9..00000000 --- a/src/plugins.qmltypes +++ /dev/null @@ -1,1021 +0,0 @@ -import QtQuick.tooling 1.2 - -// This file describes the plugin-supplied types contained in the library. -// It is used for QML tooling purposes only. -// -// This file was auto-generated by: -// 'qmlplugindump -nonrelocatable org.kde.elisa 1.0 .' - -Module { - dependencies: ["QtQuick 2.8"] - Component { - name: "AbstractMediaProxyModel" - prototype: "QSortFilterProxyModel" - Property { name: "filterText"; type: "string" } - Property { name: "filterRating"; type: "int" } - Signal { - name: "filterTextChanged" - Parameter { name: "filterText"; type: "string" } - } - Signal { - name: "filterRatingChanged" - Parameter { name: "filterRating"; type: "int" } - } - Method { - name: "setFilterText" - Parameter { name: "filterText"; type: "string" } - } - Method { - name: "setFilterRating" - Parameter { name: "filterRating"; type: "int" } - } - } - Component { - name: "AllAlbumsProxyModel" - prototype: "AbstractMediaProxyModel" - exports: ["org.kde.elisa/AllAlbumsProxyModel 1.0"] - exportMetaObjectRevisions: [0] - Signal { - name: "albumToEnqueue" - Parameter { name: "newAlbums"; type: "QList" } - Parameter { name: "enqueueMode"; type: "ElisaUtils::PlayListEnqueueMode" } - Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" } - } - Method { name: "enqueueToPlayList" } - Method { name: "replaceAndPlayOfPlayList" } - } - Component { - name: "AllArtistsProxyModel" - prototype: "AbstractMediaProxyModel" - exports: ["org.kde.elisa/AllArtistsProxyModel 1.0"] - exportMetaObjectRevisions: [0] - Signal { - name: "artistToEnqueue" - Parameter { name: "artistNames"; type: "QList" } - Parameter { name: "enqueueMode"; type: "ElisaUtils::PlayListEnqueueMode" } - Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" } - } - Method { name: "enqueueToPlayList" } - Method { name: "replaceAndPlayOfPlayList" } - } - Component { - name: "AllTracksProxyModel" - prototype: "AbstractMediaProxyModel" - exports: ["org.kde.elisa/AllTracksProxyModel 1.0"] - exportMetaObjectRevisions: [0] - Signal { - name: "trackToEnqueue" - Parameter { name: "newTracks"; type: "QList" } - Parameter { name: "enqueueMode"; type: "ElisaUtils::PlayListEnqueueMode" } - Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" } - } - Method { name: "enqueueToPlayList" } - Method { name: "replaceAndPlayOfPlayList" } - } - Component { - name: "AudioWrapper" - prototype: "QObject" - exports: ["org.kde.elisa/AudioWrapper 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "muted"; type: "bool" } - Property { name: "volume"; type: "double" } - Property { name: "source"; type: "QUrl" } - Property { name: "status"; type: "QMediaPlayer::MediaStatus"; isReadonly: true } - Property { name: "playbackState"; type: "QMediaPlayer::State"; isReadonly: true } - Property { name: "error"; type: "QMediaPlayer::Error"; isReadonly: true } - Property { name: "duration"; type: "qlonglong"; isReadonly: true } - Property { name: "position"; type: "qlonglong" } - Property { name: "seekable"; type: "bool"; isReadonly: true } - Property { name: "audioRole"; type: "QAudio::Role" } - Signal { name: "playing" } - Signal { name: "paused" } - Signal { name: "stopped" } - Method { - name: "setMuted" - Parameter { name: "muted"; type: "bool" } - } - Method { - name: "setVolume" - Parameter { name: "volume"; type: "double" } - } - Method { - name: "setSource" - Parameter { name: "source"; type: "QUrl" } - } - Method { - name: "setPosition" - Parameter { name: "position"; type: "qlonglong" } - } - Method { name: "play" } - Method { name: "pause" } - Method { name: "stop" } - Method { - name: "seek" - Parameter { name: "position"; type: "int" } - } - Method { - name: "setAudioRole" - Parameter { name: "audioRole"; type: "QAudio::Role" } - } - } - Component { - name: "ElisaApplication" - prototype: "QObject" - exports: ["org.kde.elisa/ElisaApplication 1.0"] - isCreatable: false - exportMetaObjectRevisions: [0] - Property { name: "arguments"; type: "QStringList" } - Property { - name: "musicManager" - type: "MusicListenersManager" - isReadonly: true - isPointer: true - } - Property { - name: "allAlbumsProxyModel" - type: "AllAlbumsProxyModel" - isReadonly: true - isPointer: true - } - Property { - name: "allArtistsProxyModel" - type: "AllArtistsProxyModel" - isReadonly: true - isPointer: true - } - Property { - name: "allTracksProxyModel" - type: "AllTracksProxyModel" - isReadonly: true - isPointer: true - } - Property { - name: "singleArtistProxyModel" - type: "SingleArtistProxyModel" - isReadonly: true - isPointer: true - } - Property { - name: "singleAlbumProxyModel" - type: "SingleAlbumProxyModel" - isReadonly: true - isPointer: true - } - Property { name: "mediaPlayList"; type: "MediaPlayList"; isReadonly: true; isPointer: true } - Property { name: "audioPlayer"; type: "AudioWrapper"; isReadonly: true; isPointer: true } - Signal { - name: "enqueue" - Parameter { name: "files"; type: "QStringList" } - } - Method { name: "appHelpActivated" } - Method { name: "aboutApplication" } - Method { name: "reportBug" } - Method { name: "configureShortcuts" } - Method { name: "configureElisa" } - Method { - name: "setArguments" - Parameter { name: "newArguments"; type: "QStringList" } - } - Method { - name: "activateActionRequested" - Parameter { name: "actionName"; type: "string" } - Parameter { name: "parameter"; type: "QVariant" } - } - Method { - name: "activateRequested" - Parameter { name: "arguments"; type: "QStringList" } - Parameter { name: "workingDirectory"; type: "string" } - } - Method { - name: "openRequested" - Parameter { name: "uris"; type: "QList" } - } - Method { name: "initialize" } - Method { - name: "action" - type: "QAction*" - Parameter { name: "name"; type: "string" } - } - Method { - name: "iconName" - type: "string" - Parameter { name: "icon"; type: "QIcon" } - } - } - Component { - name: "ManageAudioPlayer" - prototype: "QObject" - exports: ["org.kde.elisa/ManageAudioPlayer 1.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "PlayerPlaybackState" - values: { - "PlayingState": 1, - "PausedState": 2, - "StoppedState": 0 - } - } - Property { name: "currentTrack"; type: "QPersistentModelIndex" } - Property { name: "playListModel"; type: "QAbstractItemModel"; isPointer: true } - Property { name: "playerSource"; type: "QUrl"; isReadonly: true } - Property { name: "titleRole"; type: "int" } - Property { name: "artistNameRole"; type: "int" } - Property { name: "albumNameRole"; type: "int" } - Property { name: "urlRole"; type: "int" } - Property { name: "isPlayingRole"; type: "int" } - Property { name: "playerStatus"; type: "QMediaPlayer::MediaStatus" } - Property { name: "playerPlaybackState"; type: "int" } - Property { name: "playerError"; type: "QMediaPlayer::Error" } - Property { name: "audioDuration"; type: "int" } - Property { name: "playerIsSeekable"; type: "bool" } - Property { name: "playerPosition"; type: "int" } - Property { name: "playControlPosition"; type: "int" } - Property { name: "persistentState"; type: "QVariantMap" } - Signal { name: "playerPlay" } - Signal { name: "playerPause" } - Signal { name: "playerStop" } - Signal { name: "skipNextTrack" } - Signal { - name: "seek" - Parameter { name: "position"; type: "int" } - } - Signal { - name: "sourceInError" - Parameter { name: "source"; type: "QUrl" } - Parameter { name: "playerError"; type: "QMediaPlayer::Error" } - } - Signal { - name: "displayTrackError" - Parameter { name: "fileName"; type: "string" } - } - Method { - name: "setCurrentTrack" - Parameter { name: "currentTrack"; type: "QPersistentModelIndex" } - } - Method { - name: "setPlayListModel" - Parameter { name: "aPlayListModel"; type: "QAbstractItemModel"; isPointer: true } - } - Method { - name: "setUrlRole" - Parameter { name: "value"; type: "int" } - } - Method { - name: "setIsPlayingRole" - Parameter { name: "value"; type: "int" } - } - Method { - name: "setPlayerStatus" - Parameter { name: "playerStatus"; type: "QMediaPlayer::MediaStatus" } - } - Method { - name: "setPlayerPlaybackState" - Parameter { name: "playerPlaybackState"; type: "int" } - } - Method { - name: "setPlayerError" - Parameter { name: "playerError"; type: "QMediaPlayer::Error" } - } - Method { name: "ensurePause" } - Method { name: "ensurePlay" } - Method { name: "playPause" } - Method { - name: "setAudioDuration" - Parameter { name: "audioDuration"; type: "int" } - } - Method { - name: "setPlayerIsSeekable" - Parameter { name: "playerIsSeekable"; type: "bool" } - } - Method { - name: "setPlayerPosition" - Parameter { name: "playerPosition"; type: "int" } - } - Method { - name: "setPlayControlPosition" - Parameter { name: "playerPosition"; type: "int" } - } - Method { - name: "setPersistentState" - Parameter { name: "persistentStateValue"; type: "QVariantMap" } - } - Method { - name: "playerSeek" - Parameter { name: "position"; type: "int" } - } - Method { name: "playListFinished" } - Method { - name: "tracksDataChanged" - Parameter { name: "topLeft"; type: "QModelIndex" } - Parameter { name: "bottomRight"; type: "QModelIndex" } - Parameter { name: "roles"; type: "QVector" } - } - Method { - name: "setTitleRole" - Parameter { name: "titleRole"; type: "int" } - } - Method { - name: "setArtistNameRole" - Parameter { name: "artistNameRole"; type: "int" } - } - Method { - name: "setAlbumNameRole" - Parameter { name: "albumNameRole"; type: "int" } - } - } - Component { - name: "ManageHeaderBar" - prototype: "QObject" - exports: ["org.kde.elisa/ManageHeaderBar 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "currentTrack"; type: "QPersistentModelIndex" } - Property { name: "playListModel"; type: "QAbstractItemModel"; isPointer: true } - Property { name: "artistRole"; type: "int" } - Property { name: "titleRole"; type: "int" } - Property { name: "albumRole"; type: "int" } - Property { name: "imageRole"; type: "int" } - Property { name: "isValidRole"; type: "int" } - Property { name: "artist"; type: "QVariant"; isReadonly: true } - Property { name: "title"; type: "QVariant"; isReadonly: true } - Property { name: "album"; type: "QVariant"; isReadonly: true } - Property { name: "image"; type: "QUrl"; isReadonly: true } - Property { name: "isValid"; type: "bool"; isReadonly: true } - Property { name: "remainingTracks"; type: "int"; isReadonly: true } - Method { - name: "setCurrentTrack" - Parameter { name: "currentTrack"; type: "QPersistentModelIndex" } - } - Method { - name: "setPlayListModel" - Parameter { name: "aPlayListModel"; type: "QAbstractItemModel"; isPointer: true } - } - Method { - name: "setArtistRole" - Parameter { name: "value"; type: "int" } - } - Method { - name: "setTitleRole" - Parameter { name: "value"; type: "int" } - } - Method { - name: "setAlbumRole" - Parameter { name: "value"; type: "int" } - } - Method { - name: "setImageRole" - Parameter { name: "value"; type: "int" } - } - Method { - name: "setIsValidRole" - Parameter { name: "isValidRole"; type: "int" } - } - Method { - name: "playListLayoutChanged" - Parameter { name: "parents"; type: "QList" } - Parameter { name: "hint"; type: "QAbstractItemModel::LayoutChangeHint" } - } - Method { - name: "tracksInserted" - Parameter { name: "parent"; type: "QModelIndex" } - Parameter { name: "first"; type: "int" } - Parameter { name: "last"; type: "int" } - } - Method { - name: "tracksDataChanged" - Parameter { name: "topLeft"; type: "QModelIndex" } - Parameter { name: "bottomRight"; type: "QModelIndex" } - Parameter { name: "roles"; type: "QVector" } - } - Method { - name: "tracksAboutToBeMoved" - Parameter { name: "parent"; type: "QModelIndex" } - Parameter { name: "start"; type: "int" } - Parameter { name: "end"; type: "int" } - Parameter { name: "destination"; type: "QModelIndex" } - Parameter { name: "row"; type: "int" } - } - Method { - name: "tracksMoved" - Parameter { name: "parent"; type: "QModelIndex" } - Parameter { name: "start"; type: "int" } - Parameter { name: "end"; type: "int" } - Parameter { name: "destination"; type: "QModelIndex" } - Parameter { name: "row"; type: "int" } - } - Method { - name: "tracksRemoved" - Parameter { name: "parent"; type: "QModelIndex" } - Parameter { name: "first"; type: "int" } - Parameter { name: "last"; type: "int" } - } - } - Component { - name: "ManageMediaPlayerControl" - prototype: "QObject" - exports: ["org.kde.elisa/ManageMediaPlayerControl 1.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "PlayerState" - values: { - "Playing": 0, - "Paused": 1, - "Stopped": 2 - } - } - Property { name: "playControlEnabled"; type: "bool"; isReadonly: true } - Property { name: "skipBackwardControlEnabled"; type: "bool"; isReadonly: true } - Property { name: "skipForwardControlEnabled"; type: "bool"; isReadonly: true } - Property { name: "musicPlaying"; type: "bool"; isReadonly: true } - Property { name: "playListModel"; type: "QAbstractItemModel"; isPointer: true } - Property { name: "currentTrack"; type: "QPersistentModelIndex" } - Property { name: "randomOrContinuePlay"; type: "bool" } - Method { - name: "setPlayListModel" - Parameter { name: "aPlayListModel"; type: "QAbstractItemModel"; isPointer: true } - } - Method { name: "playerPaused" } - Method { name: "playerPlaying" } - Method { name: "playerStopped" } - Method { - name: "setCurrentTrack" - Parameter { name: "currentTrack"; type: "QPersistentModelIndex" } - } - Method { - name: "setRandomOrContinuePlay" - Parameter { name: "randomOrContinuePlay"; type: "bool" } - } - } - Component { - name: "MediaPlayList" - prototype: "QAbstractListModel" - exports: ["org.kde.elisa/MediaPlayList 1.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "ColumnsRoles" - values: { - "IsValidRole": 257, - "TitleRole": 258, - "DurationRole": 259, - "MilliSecondsDurationRole": 260, - "TrackDataRole": 261, - "ArtistRole": 262, - "AlbumArtistRole": 263, - "AlbumRole": 264, - "TrackNumberRole": 265, - "DiscNumberRole": 266, - "RatingRole": 267, - "GenreRole": 268, - "LyricistRole": 269, - "ComposerRole": 270, - "CommentRole": 271, - "YearRole": 272, - "ChannelsRole": 273, - "BitRateRole": 274, - "SampleRateRole": 275, - "ImageRole": 276, - "ResourceRole": 277, - "CountRole": 278, - "IsPlayingRole": 279, - "HasAlbumHeader": 280, - "IsSingleDiscAlbumHeader": 281, - "SecondaryTextRole": 282, - "ImageUrlRole": 283, - "ShadowForImageRole": 284 - } - } - Enum { - name: "PlayState" - values: { - "NotPlaying": 0, - "IsPlaying": 1, - "IsPaused": 2 - } - } - Property { name: "persistentState"; type: "QVariantMap" } - Property { name: "musicListenersManager"; type: "MusicListenersManager"; isPointer: true } - Property { name: "tracksCount"; type: "int"; isReadonly: true } - Property { name: "currentTrack"; type: "QPersistentModelIndex"; isReadonly: true } - Property { name: "currentTrackRow"; type: "int"; isReadonly: true } - Property { name: "randomPlay"; type: "bool" } - Property { name: "repeatPlay"; type: "bool" } - Signal { - name: "newTrackByNameInList" - Parameter { name: "title"; type: "string" } - Parameter { name: "artist"; type: "string" } - Parameter { name: "album"; type: "string" } - Parameter { name: "trackNumber"; type: "int" } - Parameter { name: "discNumber"; type: "int" } - } - Signal { - name: "newTrackByFileNameInList" - Parameter { name: "fileName"; type: "QUrl" } - } - Signal { - name: "newTrackByIdInList" - Parameter { name: "newTrackId"; type: "qulonglong" } - } - Signal { - name: "newArtistInList" - Parameter { name: "artist"; type: "string" } - } - Signal { - name: "trackHasBeenAdded" - Parameter { name: "title"; type: "string" } - Parameter { name: "image"; type: "QUrl" } - } - Signal { name: "playListFinished" } - Signal { name: "playListLoaded" } - Signal { name: "playListLoadFailed" } - Signal { name: "ensurePlay" } - Method { - name: "setPersistentState" - Parameter { name: "persistentState"; type: "QVariantMap" } - } - Method { - name: "removeSelection" - Parameter { name: "selection"; type: "QList" } - } - Method { - name: "albumAdded" - Parameter { name: "tracks"; type: "QList" } - } - Method { - name: "trackChanged" - Parameter { name: "track"; type: "MusicAudioTrack" } - } - Method { - name: "trackRemoved" - Parameter { name: "trackId"; type: "qulonglong" } - } - Method { - name: "setMusicListenersManager" - Parameter { name: "musicListenersManager"; type: "MusicListenersManager"; isPointer: true } - } - Method { - name: "setRandomPlay" - Parameter { name: "value"; type: "bool" } - } - Method { - name: "setRepeatPlay" - Parameter { name: "value"; type: "bool" } - } - Method { name: "skipNextTrack" } - Method { name: "skipPreviousTrack" } - Method { - name: "seedRandomGenerator" - Parameter { name: "seed"; type: "uint" } - } - Method { - name: "switchTo" - Parameter { name: "row"; type: "int" } - } - Method { - name: "loadPlaylist" - Parameter { name: "fileName"; type: "QUrl" } - } - Method { - name: "enqueue" - Parameter { name: "newTrackId"; type: "qulonglong" } - } - Method { - name: "enqueue" - Parameter { name: "newTrack"; type: "MusicAudioTrack" } - } - Method { - name: "enqueue" - Parameter { name: "newEntry"; type: "MediaPlayListEntry" } - Parameter { name: "audioTrack"; type: "MusicAudioTrack" } - } - Method { - name: "enqueue" - Parameter { name: "newEntry"; type: "MediaPlayListEntry" } - } - Method { - name: "enqueue" - Parameter { name: "album"; type: "MusicAlbum" } - } - Method { - name: "enqueue" - Parameter { name: "artist"; type: "MusicArtist" } - } - Method { - name: "enqueue" - Parameter { name: "artistName"; type: "string" } - } - Method { - name: "enqueue" - Parameter { name: "fileName"; type: "QUrl" } - } - Method { - name: "enqueue" - Parameter { name: "files"; type: "QStringList" } - } - Method { - name: "enqueue" - Parameter { name: "newTrackId"; type: "QList" } - } - Method { - name: "enqueue" - Parameter { name: "albums"; type: "QList" } - Parameter { name: "enqueueMode"; type: "ElisaUtils::PlayListEnqueueMode" } - Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" } - } - Method { - name: "enqueue" - Parameter { name: "tracks"; type: "QList" } - Parameter { name: "enqueueMode"; type: "ElisaUtils::PlayListEnqueueMode" } - Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" } - } - Method { - name: "enqueueArtists" - Parameter { name: "artistName"; type: "QList" } - Parameter { name: "enqueueMode"; type: "ElisaUtils::PlayListEnqueueMode" } - Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" } - } - Method { - name: "enqueueAndPlay" - Parameter { name: "files"; type: "QStringList" } - } - Method { - name: "replaceAndPlay" - Parameter { name: "newTrackId"; type: "qulonglong" } - } - Method { - name: "replaceAndPlay" - Parameter { name: "newTrack"; type: "MusicAudioTrack" } - } - Method { - name: "replaceAndPlay" - Parameter { name: "album"; type: "MusicAlbum" } - } - Method { - name: "replaceAndPlay" - Parameter { name: "artist"; type: "MusicArtist" } - } - Method { - name: "replaceAndPlay" - Parameter { name: "artistName"; type: "string" } - } - Method { - name: "replaceAndPlay" - Parameter { name: "fileName"; type: "QUrl" } - } - Method { - name: "trackInError" - Parameter { name: "sourceInError"; type: "QUrl" } - Parameter { name: "playerError"; type: "QMediaPlayer::Error" } - } - Method { - name: "removeRows" - type: "bool" - Parameter { name: "row"; type: "int" } - Parameter { name: "count"; type: "int" } - Parameter { name: "parent"; type: "QModelIndex" } - } - Method { - name: "removeRows" - type: "bool" - Parameter { name: "row"; type: "int" } - Parameter { name: "count"; type: "int" } - } - Method { - name: "moveRows" - type: "bool" - Parameter { name: "sourceParent"; type: "QModelIndex" } - Parameter { name: "sourceRow"; type: "int" } - Parameter { name: "count"; type: "int" } - Parameter { name: "destinationParent"; type: "QModelIndex" } - Parameter { name: "destinationChild"; type: "int" } - } - Method { - name: "move" - Parameter { name: "from"; type: "int" } - Parameter { name: "to"; type: "int" } - Parameter { name: "n"; type: "int" } - } - Method { name: "clearPlayList" } - Method { - name: "savePlaylist" - type: "bool" - Parameter { name: "fileName"; type: "QUrl" } - } - } - Component { - name: "Mpris2" - prototype: "QObject" - exports: ["org.kde.elisa/Mpris2 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "playerName"; type: "string" } - Property { name: "playListModel"; type: "QAbstractItemModel"; isPointer: true } - Property { name: "playListControler"; type: "MediaPlayList"; isPointer: true } - Property { name: "audioPlayerManager"; type: "ManageAudioPlayer"; isPointer: true } - Property { name: "manageMediaPlayerControl"; type: "ManageMediaPlayerControl"; isPointer: true } - Property { name: "headerBarManager"; type: "ManageHeaderBar"; isPointer: true } - Property { name: "audioPlayer"; type: "AudioWrapper"; isPointer: true } - Signal { name: "raisePlayer" } - Method { - name: "setPlayerName" - Parameter { name: "playerName"; type: "string" } - } - Method { - name: "setPlayListModel" - Parameter { name: "playListModel"; type: "QAbstractItemModel"; isPointer: true } - } - Method { - name: "setPlayListControler" - Parameter { name: "playListControler"; type: "MediaPlayList"; isPointer: true } - } - Method { - name: "setAudioPlayerManager" - Parameter { name: "audioPlayerManager"; type: "ManageAudioPlayer"; isPointer: true } - } - Method { - name: "setManageMediaPlayerControl" - Parameter { name: "manageMediaPlayerControl"; type: "ManageMediaPlayerControl"; isPointer: true } - } - Method { - name: "setHeaderBarManager" - Parameter { name: "headerBarManager"; type: "ManageHeaderBar"; isPointer: true } - } - Method { - name: "setAudioPlayer" - Parameter { name: "audioPlayer"; type: "AudioWrapper"; isPointer: true } - } - } - Component { - name: "MusicListenersManager" - prototype: "QObject" - exports: ["org.kde.elisa/MusicListenersManager 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "viewDatabase"; type: "DatabaseInterface"; isReadonly: true; isPointer: true } - Property { name: "importedTracksCount"; type: "int"; isReadonly: true } - Property { name: "indexingRunning"; type: "bool"; isReadonly: true } - Property { name: "elisaApplication"; type: "ElisaApplication"; isPointer: true } - Property { name: "allAlbumsModel"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true } - Property { - name: "allArtistsModel" - type: "QAbstractItemModel" - isReadonly: true - isPointer: true - } - Property { name: "allTracksModel"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true } - Property { name: "albumModel"; type: "QAbstractItemModel"; isReadonly: true; isPointer: true } - Property { name: "indexerBusy"; type: "bool"; isReadonly: true } - Signal { - name: "artistAdded" - Parameter { name: "newArtist"; type: "MusicArtist" } - } - Signal { - name: "trackAdded" - Parameter { name: "id"; type: "qulonglong" } - } - Signal { - name: "tracksAdded" - Parameter { name: "allTracks"; type: "QList" } - } - Signal { - name: "artistRemoved" - Parameter { name: "removedArtist"; type: "MusicArtist" } - } - Signal { - name: "albumRemoved" - Parameter { name: "removedAlbum"; type: "MusicAlbum" } - Parameter { name: "removedAlbumId"; type: "qulonglong" } - } - Signal { - name: "trackRemoved" - Parameter { name: "id"; type: "qulonglong" } - } - Signal { - name: "artistModified" - Parameter { name: "modifiedArtist"; type: "MusicArtist" } - } - Signal { - name: "albumModified" - Parameter { name: "modifiedAlbum"; type: "MusicAlbum" } - Parameter { name: "modifiedAlbumId"; type: "qulonglong" } - } - Signal { - name: "trackModified" - Parameter { name: "modifiedTrack"; type: "MusicAudioTrack" } - } - Signal { name: "applicationIsTerminating" } - Signal { - name: "newNotification" - Parameter { name: "notification"; type: "NotificationItem" } - } - Signal { - name: "closeNotification" - Parameter { name: "notificationId"; type: "string" } - } - Signal { - name: "removeTracksInError" - Parameter { name: "tracks"; type: "QList" } - } - Signal { - name: "displayTrackError" - Parameter { name: "fileName"; type: "string" } - } - Method { name: "databaseReady" } - Method { name: "applicationAboutToQuit" } - Method { name: "showConfiguration" } - Method { name: "resetImportedTracksCounter" } - Method { - name: "setElisaApplication" - Parameter { name: "elisaApplication"; type: "ElisaApplication"; isPointer: true } - } - Method { - name: "playBackError" - Parameter { name: "sourceInError"; type: "QUrl" } - Parameter { name: "playerError"; type: "QMediaPlayer::Error" } - } - } - Component { - name: "ProgressIndicator" - prototype: "QObject" - exports: ["org.kde.elisa/ProgressIndicator 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "position"; type: "int" } - Property { name: "progressDuration"; type: "string"; isReadonly: true } - Method { - name: "setPosition" - Parameter { name: "position"; type: "int" } - } - } - Component { - name: "QAbstractProxyModel" - prototype: "QAbstractItemModel" - Property { name: "sourceModel"; type: "QAbstractItemModel"; isPointer: true } - Method { - name: "mapToSource" - type: "QModelIndex" - Parameter { name: "proxyIndex"; type: "QModelIndex" } - } - Method { - name: "mapFromSource" - type: "QModelIndex" - Parameter { name: "sourceIndex"; type: "QModelIndex" } - } - Method { - name: "mapSelectionToSource" - type: "QItemSelection" - Parameter { name: "selection"; type: "QItemSelection" } - } - Method { - name: "mapSelectionFromSource" - type: "QItemSelection" - Parameter { name: "selection"; type: "QItemSelection" } - } - } - Component { - name: "QSortFilterProxyModel" - prototype: "QAbstractProxyModel" - Property { name: "filterRegExp"; type: "QRegExp" } - Property { name: "filterKeyColumn"; type: "int" } - Property { name: "dynamicSortFilter"; type: "bool" } - Property { name: "filterCaseSensitivity"; type: "Qt::CaseSensitivity" } - Property { name: "sortCaseSensitivity"; type: "Qt::CaseSensitivity" } - Property { name: "isSortLocaleAware"; type: "bool" } - Property { name: "sortRole"; type: "int" } - Property { name: "filterRole"; type: "int" } - Method { - name: "setFilterRegExp" - Parameter { name: "pattern"; type: "string" } - } - Method { - name: "setFilterWildcard" - Parameter { name: "pattern"; type: "string" } - } - Method { - name: "setFilterFixedString" - Parameter { name: "pattern"; type: "string" } - } - Method { name: "clear" } - Method { name: "invalidate" } - } - Component { - name: "SingleAlbumProxyModel" - prototype: "AbstractMediaProxyModel" - exports: ["org.kde.elisa/SingleAlbumProxyModel 1.0"] - exportMetaObjectRevisions: [0] - Signal { - name: "trackToEnqueue" - Parameter { name: "newTracks"; type: "QList" } - Parameter { name: "enqueueMode"; type: "ElisaUtils::PlayListEnqueueMode" } - Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" } - } - Method { name: "enqueueToPlayList" } - Method { name: "replaceAndPlayOfPlayList" } - Method { - name: "loadAlbumData" - Parameter { name: "databaseId"; type: "qulonglong" } - } - } - Component { - name: "SingleArtistProxyModel" - prototype: "AbstractMediaProxyModel" - exports: ["org.kde.elisa/SingleArtistProxyModel 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "artistFilter"; type: "string" } - Signal { - name: "albumToEnqueue" - Parameter { name: "newAlbums"; type: "QList" } - Parameter { name: "enqueueMode"; type: "ElisaUtils::PlayListEnqueueMode" } - Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" } - } - Signal { - name: "artistFilterTextChanged" - Parameter { name: "filterText"; type: "string" } - } - Method { name: "enqueueToPlayList" } - Method { name: "replaceAndPlayOfPlayList" } - Method { - name: "setArtistFilterText" - Parameter { name: "filterText"; type: "string" } - } - } - Component { - name: "TopNotificationManager" - prototype: "QAbstractListModel" - exports: ["org.kde.elisa/TopNotificationManager 1.0"] - exportMetaObjectRevisions: [0] - Enum { - name: "ColumnsRoles" - values: { - "MessageRole": 257, - "MainButtonTextRole": 258, - "MainButtonIconNameRole": 259, - "SecondaryButtonTextRole": 260, - "SecondaryButtonIconNameRole": 261 - } - } - Property { name: "countNotifications"; type: "int"; isReadonly: true } - Property { name: "notificationMessage"; type: "string"; isReadonly: true } - Property { name: "notificationMainButtonText"; type: "string"; isReadonly: true } - Property { name: "notificationMainButtonIconName"; type: "string"; isReadonly: true } - Property { name: "notificationSecondaryButtonText"; type: "string"; isReadonly: true } - Property { name: "notificationSecondaryButtonIconName"; type: "string"; isReadonly: true } - Method { - name: "addNotification" - Parameter { name: "notification"; type: "NotificationItem" } - } - Method { - name: "closeNotification" - Parameter { name: "index"; type: "int" } - } - Method { - name: "closeNotificationById" - Parameter { name: "notificationId"; type: "string" } - } - Method { - name: "triggerMainButton" - Parameter { name: "index"; type: "int" } - } - Method { - name: "triggerSecondaryButton" - Parameter { name: "index"; type: "int" } - } - } - Component { - name: "TrackDataHelper" - prototype: "QObject" - exports: ["org.kde.elisa/TrackDataHelper 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "trackData"; type: "MusicAudioTrack" } - Property { name: "title"; type: "string"; isReadonly: true } - Property { name: "artist"; type: "string"; isReadonly: true } - Property { name: "albumName"; type: "string"; isReadonly: true } - Property { name: "albumArtist"; type: "string"; isReadonly: true } - Property { name: "genre"; type: "string"; isReadonly: true } - Property { name: "composer"; type: "string"; isReadonly: true } - Property { name: "lyricist"; type: "string"; isReadonly: true } - Property { name: "comment"; type: "string"; isReadonly: true } - Property { name: "year"; type: "string"; isReadonly: true } - Property { name: "trackNumber"; type: "string"; isReadonly: true } - Property { name: "discNumber"; type: "string"; isReadonly: true } - Property { name: "channels"; type: "string"; isReadonly: true } - Property { name: "bitRate"; type: "string"; isReadonly: true } - Property { name: "sampleRate"; type: "string"; isReadonly: true } - Property { name: "resourceURI"; type: "string"; isReadonly: true } - Property { name: "duration"; type: "string"; isReadonly: true } - Property { name: "rating"; type: "int"; isReadonly: true } - Property { name: "albumCover"; type: "QUrl"; isReadonly: true } - Property { name: "databaseId"; type: "qulonglong"; isReadonly: true } - Method { name: "hasValidTitle"; type: "bool" } - Method { name: "hasValidArtist"; type: "bool" } - Method { name: "hasValidAlbumName"; type: "bool" } - Method { name: "hasValidAlbumArtist"; type: "bool" } - Method { name: "hasValidGenre"; type: "bool" } - Method { name: "hasValidComposer"; type: "bool" } - Method { name: "hasValidLyricist"; type: "bool" } - Method { name: "hasValidComment"; type: "bool" } - Method { name: "hasValidTrackNumber"; type: "bool" } - Method { name: "hasValidDiscNumber"; type: "bool" } - Method { name: "hasValidChannels"; type: "bool" } - Method { name: "hasValidRating"; type: "bool" } - Method { name: "hasValidBitRate"; type: "bool" } - Method { name: "hasValidSampleRate"; type: "bool" } - Method { name: "hasValidYear"; type: "bool" } - Method { name: "hasValidAlbumCover"; type: "bool" } - } -} diff --git a/src/qml/ContentView.qml b/src/qml/ContentView.qml index dc2bbf1b..cb4b16ab 100644 --- a/src/qml/ContentView.qml +++ b/src/qml/ContentView.qml @@ -1,711 +1,799 @@ /* * Copyright 2016-2018 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.2 import QtQuick.Window 2.2 import org.kde.elisa 1.0 RowLayout { id: contentViewContainer spacing: 0 signal toggleSearch() function goBack() { localAlbums.goBack() localArtists.goBack() } ViewSelector { id: listViews Layout.fillHeight: true Layout.preferredWidth: mainWindow.width * 0.11 Layout.maximumWidth: mainWindow.width * 0.11 } Rectangle { id: viewSelectorSeparatorItem border.width: 1 border.color: myPalette.mid color: myPalette.mid visible: true Layout.bottomMargin: elisaTheme.layoutVerticalMargin Layout.topMargin: elisaTheme.layoutVerticalMargin Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.fillHeight: true Layout.preferredWidth: 1 Layout.minimumWidth: 1 Layout.maximumWidth: 1 } ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true spacing: 0 TopNotification { id: invalidBalooConfiguration Layout.fillWidth: true musicManager: elisa.musicManager focus: true } Item { Layout.fillHeight: true Layout.fillWidth: true RowLayout { anchors.fill: parent spacing: 0 id: contentZone FocusScope { id: mainContentView focus: true Layout.fillHeight: true Layout.minimumWidth: 0 Layout.maximumWidth: 0 Layout.preferredWidth: 0 visible: Layout.minimumWidth != 0 Rectangle { border { color: (mainContentView.activeFocus ? myPalette.highlight : myPalette.base) width: 1 } radius: 3 color: myPalette.base anchors.fill: parent Loader { anchors.fill: parent anchors.leftMargin: parent.width / 3 anchors.rightMargin: parent.width / 3 anchors.topMargin: parent.height / 3 anchors.bottomMargin: parent.height / 3 z: 2 sourceComponent: BusyIndicator { id: busyScanningMusic hoverEnabled: false anchors.fill: parent opacity: 0.8 visible: true running: true z: 2 } active: elisa.musicManager.indexerBusy } Loader { id: localAlbumsLoader active: opacity > 0 visible: opacity > 0 anchors.fill: parent sourceComponent: MediaBrowser { id: localAlbums focus: true anchors { fill: parent leftMargin: elisaTheme.layoutHorizontalMargin rightMargin: elisaTheme.layoutHorizontalMargin } firstPage: GridBrowserView { id: allAlbumsView focus: true contentModel: elisa.allAlbumsProxyModel image: elisaTheme.albumIcon mainTitle: i18nc("Title of the view of all albums", "Albums") onOpen: { elisa.singleAlbumProxyModel.loadAlbumData(databaseId) localAlbums.stackView.push(albumView, { mainTitle: innerMainTitle, secondaryTitle: innerSecondaryTitle, image: innerImage, stackView: localAlbums.stackView, }) } onGoBack: localAlbums.stackView.pop() Binding { target: allAlbumsView property: 'expandedFilterView' value: persistentSettings.expandedFilterView } onFilterViewChanged: persistentSettings.expandedFilterView = expandedFilterView } } } Loader { id: localArtistsLoader active: opacity > 0 visible: opacity > 0 anchors.fill: parent sourceComponent: MediaBrowser { id: localArtists focus: true anchors { fill: parent leftMargin: elisaTheme.layoutHorizontalMargin rightMargin: elisaTheme.layoutHorizontalMargin } firstPage: GridBrowserView { id: allArtistsView focus: true showRating: false delegateDisplaySecondaryText: false contentModel: elisa.allArtistsProxyModel image: elisaTheme.artistIcon mainTitle: i18nc("Title of the view of all artists", "Artists") onOpen: { elisa.singleArtistProxyModel.setArtistFilterText(innerMainTitle) localArtists.stackView.push(innerAlbumView, { mainTitle: innerMainTitle, secondaryTitle: innerSecondaryTitle, image: innerImage, }) } onGoBack: localArtists.stackView.pop() Binding { target: allArtistsView property: 'expandedFilterView' value: persistentSettings.expandedFilterView } onFilterViewChanged: persistentSettings.expandedFilterView = expandedFilterView } } } Loader { id: localTracksLoader active: opacity > 0 visible: opacity > 0 anchors.fill: parent sourceComponent: MediaBrowser { id: localTracks focus: true anchors { fill: parent leftMargin: elisaTheme.layoutHorizontalMargin rightMargin: elisaTheme.layoutHorizontalMargin } firstPage: ListBrowserView { id: allTracksView focus: true contentModel: elisa.allTracksProxyModel delegate: MediaTrackDelegate { id: entry width: allTracksView.delegateWidth height: elisaTheme.trackDelegateHeight focus: true trackData: model.containerData isFirstTrackOfDisc: false isSingleDiscAlbum: model.isSingleDiscAlbum onEnqueue: elisa.mediaPlayList.enqueue(data) onReplaceAndPlay: elisa.mediaPlayList.replaceAndPlay(data) onClicked: contentDirectoryView.currentIndex = index } image: elisaTheme.tracksIcon mainTitle: i18nc("Title of the view of all tracks", "Tracks") Binding { target: allTracksView property: 'expandedFilterView' value: persistentSettings.expandedFilterView } onFilterViewChanged: persistentSettings.expandedFilterView = expandedFilterView } } } + FileBrowserView { + id: localFiles + + focus: true + + anchors { + fill: parent + + leftMargin: elisaTheme.layoutHorizontalMargin + rightMargin: elisaTheme.layoutHorizontalMargin + } + + contentModel: elisa.fileBrowserProxyModel + + Binding { + target: localFiles + property: 'expandedFilterView' + value: persistentSettings.expandedFilterView + } + + visible: opacity > 0 + onFilterViewChanged: persistentSettings.expandedFilterView = expandedFilterView + } + Behavior on border.color { ColorAnimation { duration: 300 } } } } Rectangle { id: firstViewSeparatorItem border.width: 1 border.color: myPalette.mid color: myPalette.mid visible: true Layout.bottomMargin: elisaTheme.layoutVerticalMargin Layout.topMargin: elisaTheme.layoutVerticalMargin Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.fillHeight: true Layout.preferredWidth: 1 Layout.minimumWidth: 1 Layout.maximumWidth: 1 } MediaPlayListView { id: playList playListModel: elisa.mediaPlayList Layout.fillHeight: true Layout.leftMargin: elisaTheme.layoutHorizontalMargin Layout.rightMargin: elisaTheme.layoutHorizontalMargin Layout.minimumWidth: contentZone.width Layout.maximumWidth: contentZone.width Layout.preferredWidth: contentZone.width onStartPlayback: elisa.audioControl.ensurePlay() onPausePlayback: elisa.audioControl.playPause() onDisplayError: messageNotification.showNotification(errorText) } Rectangle { id: viewSeparatorItem border.width: 1 border.color: myPalette.mid color: myPalette.mid visible: Layout.minimumWidth != 0 Layout.bottomMargin: elisaTheme.layoutVerticalMargin Layout.topMargin: elisaTheme.layoutVerticalMargin Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.fillHeight: true Layout.preferredWidth: 1 Layout.minimumWidth: 1 Layout.maximumWidth: 1 } ContextView { id: albumContext Layout.fillHeight: true Layout.minimumWidth: contentZone.width Layout.maximumWidth: contentZone.width Layout.preferredWidth: contentZone.width visible: Layout.minimumWidth != 0 artistName: elisa.manageHeaderBar.artist albumName: elisa.manageHeaderBar.album albumArtUrl: elisa.manageHeaderBar.image } } } states: [ - State { - name: 'full' - when: listViews.currentIndex === 0 - PropertyChanges { - target: mainContentView - Layout.fillWidth: false - Layout.minimumWidth: 0 - Layout.maximumWidth: 0 - Layout.preferredWidth: 0 - } - PropertyChanges { - target: firstViewSeparatorItem - Layout.minimumWidth: 0 - Layout.maximumWidth: 0 - Layout.preferredWidth: 0 - } - PropertyChanges { - target: playList - Layout.minimumWidth: contentZone.width / 2 - Layout.maximumWidth: contentZone.width / 2 - Layout.preferredWidth: contentZone.width / 2 - } - PropertyChanges { - target: viewSeparatorItem - Layout.minimumWidth: 1 - Layout.maximumWidth: 1 - Layout.preferredWidth: 1 - } - PropertyChanges { - target: albumContext - Layout.minimumWidth: contentZone.width / 2 - Layout.maximumWidth: contentZone.width / 2 - Layout.preferredWidth: contentZone.width / 2 - } - PropertyChanges { - target: localAlbumsLoader - opacity: 0 - } - PropertyChanges { - target: localArtistsLoader - opacity: 0 - } - PropertyChanges { - target: localTracksLoader - opacity: 0 - } - }, - State { - name: 'allAlbums' - when: listViews.currentIndex === 1 - StateChangeScript { - script: { - if (localAlbumsLoader.localAlbums) - localAlbumsLoader.localAlbums.stackView.pop({item: null, immediate: true}) - } - } - PropertyChanges { - target: mainContentView - Layout.fillWidth: true - Layout.minimumWidth: contentZone.width * 0.66 - Layout.maximumWidth: contentZone.width * 0.68 - Layout.preferredWidth: contentZone.width * 0.68 - } - PropertyChanges { - target: firstViewSeparatorItem - Layout.minimumWidth: 1 - Layout.maximumWidth: 1 - Layout.preferredWidth: 1 - } - PropertyChanges { - target: playList - Layout.minimumWidth: contentZone.width * 0.33 - Layout.maximumWidth: contentZone.width * 0.33 - Layout.preferredWidth: contentZone.width * 0.33 - } - PropertyChanges { - target: viewSeparatorItem - Layout.minimumWidth: 0 - Layout.maximumWidth: 0 - Layout.preferredWidth: 0 - } - PropertyChanges { - target: albumContext - Layout.minimumWidth: 0 - Layout.maximumWidth: 0 - Layout.preferredWidth: 0 - } - PropertyChanges { - target: localAlbumsLoader - opacity: 1 - } - PropertyChanges { - target: localArtistsLoader - opacity: 0 - } - PropertyChanges { - target: localTracksLoader - opacity: 0 - } - }, - State { - name: 'allArtists' - when: listViews.currentIndex === 2 - StateChangeScript { - script: { - if (localArtistsLoader.localArtists) - localArtistsLoader.localArtists.stackView.pop({item: null, immediate: true}) - } - } - PropertyChanges { - target: mainContentView - Layout.fillWidth: true - Layout.minimumWidth: contentZone.width * 0.66 - Layout.maximumWidth: contentZone.width * 0.68 - Layout.preferredWidth: contentZone.width * 0.68 - } - PropertyChanges { - target: firstViewSeparatorItem - Layout.minimumWidth: 1 - Layout.maximumWidth: 1 - Layout.preferredWidth: 1 - } - PropertyChanges { - target: playList - Layout.minimumWidth: contentZone.width * 0.33 - Layout.maximumWidth: contentZone.width * 0.33 - Layout.preferredWidth: contentZone.width * 0.33 - } - PropertyChanges { - target: viewSeparatorItem - Layout.minimumWidth: 0 - Layout.maximumWidth: 0 - Layout.preferredWidth: 0 - } - PropertyChanges { - target: albumContext - Layout.minimumWidth: 0 - Layout.maximumWidth: 0 - Layout.preferredWidth: 0 - } - PropertyChanges { - target: localAlbumsLoader - opacity: 0 - } - PropertyChanges { - target: localArtistsLoader - opacity: 1 - } - PropertyChanges { - target: localTracksLoader - opacity: 0 - } - }, - State { - name: 'allTracks' - when: listViews.currentIndex === 3 - PropertyChanges { - target: mainContentView - Layout.fillWidth: true - Layout.minimumWidth: contentZone.width * 0.66 - Layout.maximumWidth: contentZone.width * 0.68 - Layout.preferredWidth: contentZone.width * 0.68 - } - PropertyChanges { - target: firstViewSeparatorItem - Layout.minimumWidth: 1 - Layout.maximumWidth: 1 - Layout.preferredWidth: 1 - } - PropertyChanges { - target: playList - Layout.minimumWidth: contentZone.width * 0.33 - Layout.maximumWidth: contentZone.width * 0.33 - Layout.preferredWidth: contentZone.width * 0.33 - } - PropertyChanges { - target: viewSeparatorItem - Layout.minimumWidth: 0 - Layout.maximumWidth: 0 - Layout.preferredWidth: 0 - } - PropertyChanges { - target: albumContext - Layout.minimumWidth: 0 - Layout.maximumWidth: 0 - Layout.preferredWidth: 0 - } - PropertyChanges { - target: localAlbumsLoader - opacity: 0 - } - PropertyChanges { - target: localArtistsLoader - opacity: 0 - } - PropertyChanges { - target: localTracksLoader - opacity: 1 - } - } - ] - transitions: Transition { - NumberAnimation { - properties: "Layout.minimumWidth, Layout.maximumWidth, Layout.preferredWidth, opacity" - easing.type: Easing.InOutQuad - duration: 300 - } - } - } - + State { + name: 'full' + when: listViews.currentIndex === 0 + PropertyChanges { + target: mainContentView + Layout.fillWidth: false + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: firstViewSeparatorItem + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: playList + Layout.minimumWidth: contentZone.width / 2 + Layout.maximumWidth: contentZone.width / 2 + Layout.preferredWidth: contentZone.width / 2 + } + PropertyChanges { + target: viewSeparatorItem + Layout.minimumWidth: 1 + Layout.maximumWidth: 1 + Layout.preferredWidth: 1 + } + PropertyChanges { + target: albumContext + Layout.minimumWidth: contentZone.width / 2 + Layout.maximumWidth: contentZone.width / 2 + Layout.preferredWidth: contentZone.width / 2 + } + PropertyChanges { + target: localAlbums + opacity: 0 + } + PropertyChanges { + target: localArtists + opacity: 0 + } + PropertyChanges { + target: localTracks + opacity: 0 + } + PropertyChanges { + target: localFiles + opacity: 0 + } + }, + State { + name: 'allAlbums' + when: listViews.currentIndex === 1 + StateChangeScript { + script: { + localAlbums.stackView.pop({item: null, immediate: true}) + } + } + PropertyChanges { + target: mainContentView + Layout.fillWidth: true + Layout.minimumWidth: contentZone.width * 0.66 + Layout.maximumWidth: contentZone.width * 0.68 + Layout.preferredWidth: contentZone.width * 0.68 + } + PropertyChanges { + target: firstViewSeparatorItem + Layout.minimumWidth: 1 + Layout.maximumWidth: 1 + Layout.preferredWidth: 1 + } + PropertyChanges { + target: playList + Layout.minimumWidth: contentZone.width * 0.33 + Layout.maximumWidth: contentZone.width * 0.33 + Layout.preferredWidth: contentZone.width * 0.33 + } + PropertyChanges { + target: viewSeparatorItem + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: albumContext + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: localAlbums + opacity: 1 + } + PropertyChanges { + target: localArtists + opacity: 0 + } + PropertyChanges { + target: localTracks + opacity: 0 + } + PropertyChanges { + target: localFiles + opacity: 0 + } + }, + State { + name: 'allArtists' + when: listViews.currentIndex === 2 + StateChangeScript { + script: { + localArtists.stackView.pop({item: null, immediate: true}) + } + } + PropertyChanges { + target: mainContentView + Layout.fillWidth: true + Layout.minimumWidth: contentZone.width * 0.66 + Layout.maximumWidth: contentZone.width * 0.68 + Layout.preferredWidth: contentZone.width * 0.68 + } + PropertyChanges { + target: firstViewSeparatorItem + Layout.minimumWidth: 1 + Layout.maximumWidth: 1 + Layout.preferredWidth: 1 + } + PropertyChanges { + target: playList + Layout.minimumWidth: contentZone.width * 0.33 + Layout.maximumWidth: contentZone.width * 0.33 + Layout.preferredWidth: contentZone.width * 0.33 + } + PropertyChanges { + target: viewSeparatorItem + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: albumContext + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: localAlbums + opacity: 0 + } + PropertyChanges { + target: localArtists + opacity: 1 + } + PropertyChanges { + target: localTracks + opacity: 0 + } + PropertyChanges { + target: localFiles + opacity: 0 + } + }, + State { + name: 'allTracks' + when: listViews.currentIndex === 3 + PropertyChanges { + target: mainContentView + Layout.fillWidth: true + Layout.minimumWidth: contentZone.width * 0.66 + Layout.maximumWidth: contentZone.width * 0.68 + Layout.preferredWidth: contentZone.width * 0.68 + } + PropertyChanges { + target: firstViewSeparatorItem + Layout.minimumWidth: 1 + Layout.maximumWidth: 1 + Layout.preferredWidth: 1 + } + PropertyChanges { + target: playList + Layout.minimumWidth: contentZone.width * 0.33 + Layout.maximumWidth: contentZone.width * 0.33 + Layout.preferredWidth: contentZone.width * 0.33 + } + PropertyChanges { + target: viewSeparatorItem + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: albumContext + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: localAlbums + opacity: 0 + } + PropertyChanges { + target: localArtists + opacity: 0 + } + PropertyChanges { + target: localTracks + opacity: 1 + } + PropertyChanges { + target: localFiles + opacity: 0 + } + }, + State { + name: 'files' + when: listViews.currentIndex === 4 + PropertyChanges { + target: mainContentView + Layout.fillWidth: true + Layout.minimumWidth: contentZone.width * 0.66 + Layout.maximumWidth: contentZone.width * 0.68 + Layout.preferredWidth: contentZone.width * 0.68 + } + PropertyChanges { + target: firstViewSeparatorItem + Layout.minimumWidth: 1 + Layout.maximumWidth: 1 + Layout.preferredWidth: 1 + } + PropertyChanges { + target: playList + Layout.minimumWidth: contentZone.width * 0.33 + Layout.maximumWidth: contentZone.width * 0.33 + Layout.preferredWidth: contentZone.width * 0.33 + } + PropertyChanges { + target: viewSeparatorItem + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: albumContext + Layout.minimumWidth: 0 + Layout.maximumWidth: 0 + Layout.preferredWidth: 0 + } + PropertyChanges { + target: localAlbums + opacity: 0 + } + PropertyChanges { + target: localArtists + opacity: 0 + } + PropertyChanges { + target: localTracks + opacity: 0 + } + PropertyChanges { + target: localFiles + opacity: 1 + } + } + ] + transitions: Transition { + NumberAnimation { + properties: "Layout.minimumWidth, Layout.maximumWidth, Layout.preferredWidth, opacity" + easing.type: Easing.InOutQuad + duration: 300 + } + } + } Component { id: innerAlbumView GridBrowserView { id: innerAlbumGridView contentModel: elisa.singleArtistProxyModel isSubPage: true onOpen: { elisa.singleAlbumProxyModel.loadAlbumData(databaseId) localArtists.stackView.push(albumView, { mainTitle: innerMainTitle, secondaryTitle: innerSecondaryTitle, image: innerImage, stackView: localArtists.stackView, }) } onGoBack: localArtists.stackView.pop() Binding { target: innerAlbumGridView property: 'expandedFilterView' value: persistentSettings.expandedFilterView } onFilterViewChanged: persistentSettings.expandedFilterView = expandedFilterView } } Component { id: albumView ListBrowserView { id: albumGridView property var stackView contentModel: elisa.singleAlbumProxyModel isSubPage: true delegate: MediaAlbumTrackDelegate { id: entry width: albumGridView.delegateWidth height: ((model.isFirstTrackOfDisc && !isSingleDiscAlbum) ? elisaTheme.delegateHeight*2 : elisaTheme.delegateHeight) focus: true mediaTrack.trackData: model.containerData mediaTrack.isFirstTrackOfDisc: model.isFirstTrackOfDisc mediaTrack.isSingleDiscAlbum: model.isSingleDiscAlbum mediaTrack.onEnqueue: elisa.mediaPlayList.enqueue(data) mediaTrack.onReplaceAndPlay: elisa.mediaPlayList.replaceAndPlay(data) mediaTrack.isAlternateColor: (index % 2) === 1 mediaTrack.onClicked: contentDirectoryView.currentIndex = index } allowArtistNavigation: true onShowArtist: { listViews.currentIndex = 2 if (localArtists.stackView.depth === 3) { localArtists.stackView.pop() } if (localArtists.stackView.depth === 2) { var artistPage = localArtists.stackView.get(1) if (artistPage.mainTitle === name) { return } else { localArtists.stackView.pop() } } allArtistsView.open(name, name, elisaTheme.defaultArtistImage, '') } onGoBack: stackView.pop() expandedFilterView: true Binding { target: albumGridView property: 'expandedFilterView' value: persistentSettings.expandedFilterView } onFilterViewChanged: persistentSettings.expandedFilterView = expandedFilterView } } } diff --git a/src/qml/Theme.qml b/src/qml/Theme.qml index 3d972d0d..682bb36b 100644 --- a/src/qml/Theme.qml +++ b/src/qml/Theme.qml @@ -1,95 +1,96 @@ /* * Copyright 2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Controls 2.2 Item { function dp(pixel) { // 96 - common, "base" DPI value return Math.round(pixel * logicalDpi / 96); } property string defaultAlbumImage: 'image://icon/media-optical-audio' property string defaultArtistImage: 'image://icon/view-media-artist' property string defaultBackgroundImage: 'qrc:///background.png' property string artistIcon: 'image://icon/view-media-artist' property string albumIcon: 'image://icon/media-album-cover-manager-amarok' property string playlistIcon: 'image://icon/amarok_playlist' property string tracksIcon: 'image://icon/media-album-track' property string clearIcon: 'image://icon/edit-clear' property string skipBackwardIcon: 'image://icon/media-skip-backward' property string pauseIcon: 'image://icon/media-playback-pause' property string playIcon: 'image://icon/media-playback-start' property string skipForwardIcon: 'image://icon/media-skip-forward' property string playerVolumeMutedIcon: 'image://icon/player-volume-muted' property string playerVolumeIcon: 'image://icon/player-volume' property string ratingIcon: 'image://icon/rating' property string ratingUnratedIcon: 'image://icon/rating-unrated' property string errorIcon: 'image://icon/error' property string playIndicatorIcon: 'image://icon/audio-volume-high' property string repeatIcon: 'image://icon/media-repeat-all' property string shuffleIcon: 'image://icon/media-playlist-shuffle' property string noRepeatIcon: 'image://icon/media-repeat-none' property string noShuffleIcon: 'image://icon/media-playlist-normal' + property string folderIcon: 'image://icon/document-open-folder' property int layoutHorizontalMargin: dp(8) property int layoutVerticalMargin: dp(6) property int delegateHeight: dp(28) property int delegateWithHeaderHeight: dp(68) property int trackDelegateHeight: dp(45) property int coverImageSize: dp(180) property int smallImageSize: dp(32) property int trackMetadataWidth: dp(300) property int tooltipRadius: dp(3) property int shadowOffset: dp(2) property int delegateToolButtonSize: dp(34) property int smallDelegateToolButtonSize: dp(20) property int ratingStarSize: dp(15) property int mediaPlayerControlHeight: dp(42) property int mediaPlayerHorizontalMargin: dp(10) property real mediaPlayerControlOpacity: 0.6 property int smallControlButtonSize: dp(22) property int volumeSliderWidth: dp(100) property int dragDropPlaceholderHeight: dp(28) property int navigationBarHeight: dp(100) property int navigationBarFilterHeight: dp(44) property int gridDelegateHeight: dp(100) + layoutVerticalMargin + fontSize.height * 2 property int gridDelegateWidth: dp(100) property int viewSelectorDelegateHeight: dp(24) property int filterClearButtonMargin: layoutVerticalMargin property alias defaultFontPointSize: fontSize.font.pointSize Label { id: fontSize } } diff --git a/src/qml/ViewSelector.qml b/src/qml/ViewSelector.qml index fcb35aba..50777b2b 100644 --- a/src/qml/ViewSelector.qml +++ b/src/qml/ViewSelector.qml @@ -1,182 +1,183 @@ /* * Copyright 2016-2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQml.Models 2.2 import QtGraphicalEffects 1.0 FocusScope { id: rootFocusScope property alias currentIndex: viewModeView.currentIndex Rectangle { anchors.fill: parent color: myPalette.base border { color: (rootFocusScope.activeFocus ? myPalette.highlight : "transparent") width: 1 } ScrollView { focus: true anchors.fill: parent clip: true ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ListView { id: viewModeView focus: true z: 2 anchors.topMargin: elisaTheme.layoutHorizontalMargin * 2 model: DelegateModel { id: pageDelegateModel model: ListModel { id: pageModel } delegate: MouseArea { id: item height: elisaTheme.viewSelectorDelegateHeight * 1.4 width: viewModeView.width hoverEnabled: true acceptedButtons: Qt.LeftButton Image { id: viewIcon z: 2 anchors { verticalCenter: parent.verticalCenter leftMargin: elisaTheme.layoutHorizontalMargin left: parent.left } height: elisaTheme.viewSelectorDelegateHeight width: elisaTheme.viewSelectorDelegateHeight sourceSize { width: elisaTheme.viewSelectorDelegateHeight height: elisaTheme.viewSelectorDelegateHeight } source: iconName visible: false } ColorOverlay { source: viewIcon z: 2 anchors { verticalCenter: parent.verticalCenter leftMargin: elisaTheme.layoutHorizontalMargin left: parent.left } height: elisaTheme.viewSelectorDelegateHeight width: elisaTheme.viewSelectorDelegateHeight color: (index === viewModeView.currentIndex || item.containsMouse ? myPalette.highlight : "transparent") Behavior on color { ColorAnimation { duration: 300 } } } LabelWithToolTip { id: nameLabel z: 2 anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: elisaTheme.layoutHorizontalMargin anchors.left: viewIcon.right anchors.right: parent.right anchors.rightMargin: elisaTheme.layoutHorizontalMargin verticalAlignment: "AlignVCenter" font.pointSize: elisaTheme.defaultFontPointSize * 1.4 text: model.name elide: Text.ElideRight color: (viewModeView.currentIndex === index || item.containsMouse ? myPalette.highlight : myPalette.text) Behavior on color { ColorAnimation { duration: 300 } } } onClicked: { viewModeView.currentIndex = index rootFocusScope.focus = true } } Component.onCompleted: { pageModel.insert(0, {"name": i18nc("Title of the view of the playlist", "Now Playing"), "iconName": elisaTheme.playlistIcon}) pageModel.insert(1, {"name": i18nc("Title of the view of all albums", "Albums"), "iconName": elisaTheme.albumIcon}) pageModel.insert(2, {"name": i18nc("Title of the view of all artists", "Artists"), "iconName": elisaTheme.artistIcon}) pageModel.insert(3, {"name": i18nc("Title of the view of all tracks", "Tracks"), "iconName": elisaTheme.tracksIcon}) + pageModel.insert(4, {"name": i18nc("Title of the file browser view", "Files"), "iconName": elisaTheme.folderIcon}) viewModeView.currentIndex = 1 } } footer: MouseArea { width: viewModeView.width height: viewModeView.height - y acceptedButtons: Qt.LeftButton onClicked: { rootFocusScope.focus = true } } } } Behavior on border.color { ColorAnimation { duration: 300 } } } } diff --git a/src/resources.qrc b/src/resources.qrc index c84f7112..ef00dd0e 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -1,42 +1,44 @@ qml/MediaPlayerControl.qml qml/RatingStar.qml qml/MediaPlayListView.qml qml/ElisaMainWindow.qml qml/ApplicationMenu.qml qml/HeaderBar.qml qml/ContextView.qml qml/ContentView.qml qml/DraggableItem.qml qml/PassiveNotification.qml qml/NavigationActionBar.qml qml/PlayListEntry.qml qml/MediaBrowser.qml qml/Theme.qml qml/PlatformIntegration.qml qml/LabelWithToolTip.qml qml/TopNotification.qml qml/TrackImportNotification.qml qml/TopNotificationItem.qml qml/ViewSelector.qml qml/MediaTrackDelegate.qml qml/MediaAlbumTrackDelegate.qml qml/MediaTrackMetadataView.qml qml/GridBrowserView.qml qml/GridBrowserDelegate.qml qml/ListBrowserView.qml + qml/FileBrowserDelegate.qml + qml/FileBrowserView.qml qtquickcontrols2.conf background.png windows/WindowsTheme.qml windows/PlatformIntegration.qml windows/LabelWithToolTip.qml android/ElisaMainWindow.qml android/AndroidTheme.qml android/PlatformIntegration.qml diff --git a/src/windows/WindowsTheme.qml b/src/windows/WindowsTheme.qml index d24e37d4..450f24d2 100644 --- a/src/windows/WindowsTheme.qml +++ b/src/windows/WindowsTheme.qml @@ -1,85 +1,86 @@ /* * Copyright 2017 Matthieu Gallien * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Controls 1.4 Item { property string defaultAlbumImage: 'image://icon/media-optical-audio' property string defaultArtistImage: 'image://icon/view-media-artist' property string defaultBackgroundImage: 'qrc:///background.png' property string artistIcon: 'image://icon/view-media-artist' property string albumIcon: 'image://icon/media-album-cover-manager-amarok' property string playlistIcon: 'image://icon/amarok_playlist' property string tracksIcon: 'image://icon/media-album-track' property string clearIcon: 'image://icon/edit-clear' property string skipBackwardIcon: 'image://icon/media-skip-backward' property string pauseIcon: 'image://icon/media-playback-pause' property string playIcon: 'image://icon/media-playback-start' property string skipForwardIcon: 'image://icon/media-skip-forward' property string playerVolumeMutedIcon: 'image://icon/player-volume-muted' property string playerVolumeIcon: 'image://icon/player-volume' property string ratingIcon: 'image://icon/rating' property string ratingUnratedIcon: 'image://icon/rating-unrated' property string errorIcon: 'image://icon/error' + property string folderIcon: 'image://icon/document-open-folder' property int layoutHorizontalMargin: 8 property int layoutVerticalMargin: 6 property int delegateHeight: 28 property int delegateWithHeaderHeight: 68 property int trackDelegateHeight: 45 property int coverImageSize: 180 property int smallImageSize: 32 property int trackMetadataWidth: 300 property int tooltipRadius: 3 property int shadowOffset: 2 property int delegateToolButtonSize: 34 property int smallDelegateToolButtonSize: 20 property int ratingStarSize: 15 property int mediaPlayerControlHeight: 48 property real mediaPlayerControlOpacity: 0.8 property int smallControlButtonHeight: 32 property int bigControlButtonHeight: 44 property int volumeSliderWidth: 140 property int dragDropPlaceholderHeight: 28 property int navigationBarHeight: 100 property int navigationBarFilterHeight: 44 property int gridDelegateHeight: 100 + layoutVerticalMargin + fontSize.height * 2 property int gridDelegateWidth: 100 property int viewSelectorDelegateHeight: 32 property int filterClearButtonMargin: 1 property alias defaultFontPointSize: fontSize.font.pointSize Label { id: fontSize } }