├── .reuse └── dep5 ├── .tag ├── AUTHORS.md ├── CMakeLists.txt ├── LICENSES ├── BSD-3-Clause.txt ├── CC0-1.0.txt ├── GPL-3.0-or-later.txt └── LGPL-3.0-or-later.txt ├── README.md ├── cmake └── FindFlatpak.cmake ├── features.cmake ├── src ├── app │ ├── CMakeLists.txt │ ├── io.liri.AppCenter.appdata.xml │ ├── io.liri.AppCenter.appdata.xml.in │ ├── io.liri.AppCenter.desktop │ ├── io.liri.AppCenter.desktop.in │ ├── main.cpp │ └── qml │ │ ├── AddSourceDialog.qml │ │ ├── AllAppsTab.qml │ │ ├── AppPage.qml │ │ ├── InstalledAppsTab.qml │ │ ├── Main.qml │ │ ├── SourcesTab.qml │ │ ├── UpdatesTab.qml │ │ ├── app │ │ ├── Buttons.qml │ │ ├── Details.qml │ │ ├── Header.qml │ │ ├── HeaderRatings.qml │ │ ├── Icon.qml │ │ ├── Info.qml │ │ ├── RatingsReviews.qml │ │ ├── Review.qml │ │ ├── Screenshots.qml │ │ └── Transaction.qml │ │ ├── pages │ │ ├── AddReviewPage.qml │ │ └── ReviewsPage.qml │ │ └── ratings │ │ ├── RatingNumber.qml │ │ ├── RatingStar.qml │ │ ├── StarIcon.qml │ │ └── StarRatings.qml ├── framework │ ├── CMakeLists.txt │ ├── backend.cpp │ ├── backend.h │ ├── backendplugin.cpp │ ├── backendplugin.h │ ├── cachednetworkaccessmanager.cpp │ ├── cachednetworkaccessmanager_p.h │ ├── image.cpp │ ├── image.h │ ├── image_p.h │ ├── liriappcenterglobal.h │ ├── rating.cpp │ ├── rating.h │ ├── rating_p.h │ ├── resourceproxy.cpp │ ├── resourceproxy.h │ ├── resourceproxy_p.h │ ├── resourcesmodel.cpp │ ├── resourcesmodel.h │ ├── resourcesmodel_p.h │ ├── review.cpp │ ├── review.h │ ├── review_p.h │ ├── reviewsbackend.cpp │ ├── reviewsbackend.h │ ├── reviewsbackendplugin.cpp │ ├── reviewsbackendplugin.h │ ├── reviewsmodel.cpp │ ├── reviewsmodel.h │ ├── reviewsmodel_p.h │ ├── screenshotsmodel.cpp │ ├── screenshotsmodel.h │ ├── screenshotsmodel_p.h │ ├── softwaremanager.cpp │ ├── softwaremanager.h │ ├── softwaremanager_p.h │ ├── softwareresource.cpp │ ├── softwareresource.h │ ├── softwareresource_p.h │ ├── softwaresource.cpp │ ├── softwaresource.h │ ├── softwaresource_p.h │ ├── sourcesmodel.cpp │ ├── sourcesmodel.h │ ├── sourcesmodel_p.h │ ├── transaction.cpp │ ├── transaction.h │ ├── transaction_p.h │ ├── transactionsmanager.cpp │ ├── transactionsmanager.h │ └── transactionsmanager_p.h ├── imports │ └── appcenter │ │ ├── CMakeLists.txt │ │ ├── filteredresourcesmodel.cpp │ │ ├── filteredresourcesmodel.h │ │ ├── filteredreviewsmodel.cpp │ │ ├── filteredreviewsmodel.h │ │ ├── filteredsourcesmodel.cpp │ │ ├── filteredsourcesmodel.h │ │ ├── logging.cpp │ │ ├── logging.h │ │ ├── paginatemodel.cpp │ │ ├── paginatemodel.h │ │ └── plugin.cpp ├── notifier │ ├── CMakeLists.txt │ ├── io.liri.AppCenter.Notifier.desktop │ ├── io.liri.AppCenter.Notifier.desktop.in │ ├── main.cpp │ ├── updatenotifier.cpp │ └── updatenotifier.h └── plugins │ ├── flatpak │ ├── CMakeLists.txt │ ├── flatpak.json │ ├── flatpakappstreamjob.cpp │ ├── flatpakappstreamjob.h │ ├── flatpakbackend.cpp │ ├── flatpakbackend.h │ ├── flatpakplugin.cpp │ ├── flatpakplugin.h │ ├── flatpakpluginbase.h │ ├── flatpakresource.cpp │ ├── flatpakresource.h │ ├── flatpaksource.cpp │ ├── flatpaksource.h │ ├── flatpaktransaction.cpp │ ├── flatpaktransaction.h │ ├── flatpaktransactionjob.cpp │ ├── flatpaktransactionjob.h │ ├── flatpakutils.cpp │ ├── flatpakutils.h │ ├── internetcheck.cpp │ ├── internetcheck.h │ └── io.liri.AppCenter.Flatpak.desktop │ └── odrs │ ├── CMakeLists.txt │ ├── odrs.json │ ├── odrsbackend.cpp │ ├── odrsbackend.h │ ├── odrsplugin.cpp │ ├── odrsplugin.h │ ├── odrsutils.cpp │ └── odrsutils.h └── translations ├── app ├── appcenter.ts ├── appcenter_ar.ts ├── appcenter_da.ts ├── appcenter_es.ts ├── appcenter_es_MX.ts ├── appcenter_fr.ts ├── appcenter_id.ts ├── appcenter_it_IT.ts ├── appcenter_ja.ts ├── appcenter_ko.ts ├── appcenter_lt.ts ├── appcenter_nl.ts ├── appcenter_pl.ts ├── appcenter_pt_BR.ts ├── appcenter_ru.ts ├── appcenter_tr.ts ├── appcenter_zh_CN.ts └── appcenter_zh_TW.ts ├── appcenter.ts ├── data ├── desktop │ ├── ar.po │ ├── da.po │ ├── desktop.pot │ ├── es_MX.po │ ├── fr.po │ ├── id.po │ ├── it_IT.po │ ├── ja.po │ ├── ko.po │ ├── lt.po │ ├── nl.po │ ├── notifier │ │ ├── da.po │ │ ├── desktop.pot │ │ ├── es_MX.po │ │ ├── lt.po │ │ ├── nl.po │ │ ├── pt_BR.po │ │ ├── ru.po │ │ └── tr.po │ ├── pl.po │ ├── pt_BR.po │ ├── ru.po │ ├── tr.po │ ├── zh_CN.po │ └── zh_TW.po └── metainfo │ ├── da.po │ ├── es_MX.po │ ├── it_IT.po │ ├── ko.po │ ├── metainfo.pot │ ├── nl.po │ ├── pt_BR.po │ ├── ru.po │ └── tr.po ├── notifier.ts └── notifier ├── notifier.ts ├── notifier_ar.ts ├── notifier_da.ts ├── notifier_es_MX.ts ├── notifier_fr.ts ├── notifier_id.ts ├── notifier_it_IT.ts ├── notifier_ja.ts ├── notifier_ko.ts ├── notifier_lt.ts ├── notifier_nl.ts ├── notifier_pl.ts ├── notifier_pt_BR.ts ├── notifier_ru.ts ├── notifier_tr.ts ├── notifier_zh_CN.ts └── notifier_zh_TW.ts /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: App Center 3 | Source: https://github.com/lirios/appcenter 4 | 5 | Files: .tag 6 | Copyright: none 7 | License: CC0-1.0 8 | 9 | Files: .github/workflows/*.yml 10 | Copyright: none 11 | License: CC0-1.0 12 | 13 | Files: .tx/* 14 | Copyright: none 15 | License: CC0-1.0 16 | 17 | Files: translations/* 18 | Copyright: 2020 Liri Translators 19 | License: CC0-1.0 20 | 21 | Files: **/qmldir 22 | Copyright: none 23 | License: CC0-1.0 24 | 25 | Files: **/*.qmltypes 26 | Copyright: none 27 | License: CC0-1.0 28 | 29 | Files: **/*.qrc 30 | Copyright: none 31 | License: CC0-1.0 32 | 33 | Files: **/*.desktop 34 | Copyright: none 35 | License: CC0-1.0 36 | 37 | Files: **/*.desktop.in 38 | Copyright: none 39 | License: CC0-1.0 40 | 41 | Files: CMakeLists.txt 42 | Copyright: 2021 Pier Luigi Fiorini 43 | License: BSD-3-Clause 44 | 45 | Files: **/CMakeLists.txt 46 | Copyright: 2021 Pier Luigi Fiorini 47 | License: BSD-3-Clause 48 | 49 | Files: AUTHORS.md 50 | Copyright: 2021 Pier Luigi Fiorini 51 | License: CC0-1.0 52 | 53 | Files: README.md 54 | Copyright: 2021 Pier Luigi Fiorini 55 | License: CC0-1.0 56 | 57 | Files: src/plugins/flatpak/flatpak.json 58 | Copyright: none 59 | License: CC0-1.0 60 | 61 | Files: src/plugins/odrs/odrs.json 62 | Copyright: none 63 | License: CC0-1.0 64 | -------------------------------------------------------------------------------- /.tag: -------------------------------------------------------------------------------- 1 | 291c636257bde74399df0937ab4f42fc159706a9 2 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | App Center 2 | ========== 3 | 4 | # Core Developers 5 | 6 | * Pier Luigi Fiorini 7 | 8 | # Contributors 9 | 10 | You can see the list of contributors to this code base, 11 | and the number of their commits with: 12 | 13 | ```sh 14 | git shortlog -s -e -n 15 | ``` 16 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19) 2 | 3 | project("AppCenter" 4 | VERSION "0.1.0" 5 | DESCRIPTION "Software center" 6 | LANGUAGES CXX C 7 | ) 8 | 9 | ## Only build on the appropriate platforms. 10 | if(NOT UNIX OR ANDROID) 11 | message(NOTICE "\"${CMAKE_PROJECT_NAME}\" can be build only on UNIX-like systems, Android excluded") 12 | return() 13 | endif() 14 | 15 | ## Add some paths to check for CMake modules: 16 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 17 | 18 | ## ECM: 19 | find_package(ECM 5.245.0 REQUIRED NO_MODULE) 20 | list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) 21 | 22 | ## Installation directories: 23 | include(KDEInstallDirs) 24 | 25 | ## Compiler settings: 26 | set(KDE_SKIP_NULLPTR_WARNINGS_SETTINGS TRUE) 27 | include(KDECompilerSettings NO_POLICY_SCOPE) 28 | 29 | ## CMake settings: 30 | include(KDECMakeSettings) 31 | 32 | ## QML module: 33 | include(ECMQmlModule) 34 | 35 | ## Disable use of C++ API deprecated in Qt 5.15 36 | add_compile_definitions(QT_DISABLE_DEPRECATED_UP_TO=0x050F00) 37 | 38 | ## Enable C++17: 39 | set(CMAKE_CXX_STANDARD 17) 40 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 41 | 42 | ## Treat warnings as errors: 43 | add_compile_options(-Wall -Wextra -Werror) 44 | 45 | ## Shared macros and functions: 46 | if(NOT LIRI_LOCAL_ECM) 47 | find_package(LiriCMakeShared "2.0.99" REQUIRED NO_MODULE) 48 | list(APPEND CMAKE_MODULE_PATH "${LCS_MODULE_PATH}") 49 | endif() 50 | 51 | ## Liri specific setup common for all modules: 52 | include(LiriSetup) 53 | 54 | ## Features: 55 | include(features.cmake) 56 | 57 | ## QML import path: 58 | if(NOT QML_IMPORT_PATH) 59 | set(QML_IMPORT_PATH ${CMAKE_SOURCE_DIR}/bin CACHE STRING "" FORCE) 60 | endif() 61 | 62 | ## Add subdirectories: 63 | add_subdirectory(src/framework) 64 | add_subdirectory(src/app) 65 | add_subdirectory(src/notifier) 66 | add_subdirectory(src/imports/appcenter) 67 | if(LINUX AND NOT ANDROID AND TARGET PkgConfig::Flatpak) 68 | add_subdirectory(src/plugins/flatpak) 69 | endif() 70 | add_subdirectory(src/plugins/odrs) 71 | -------------------------------------------------------------------------------- /LICENSES/BSD-3-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) . All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | App Center 2 | ========== 3 | 4 | [![License](https://img.shields.io/badge/license-GPLv3.0-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.html) 5 | [![GitHub release](https://img.shields.io/github/release/lirios/appcenter.svg)](https://github.com/lirios/appcenter) 6 | [![GitHub issues](https://img.shields.io/github/issues/lirios/appcenter.svg)](https://github.com/lirios/appcenter/issues) 7 | [![CI](https://github.com/lirios/appcenter/workflows/CI/badge.svg?branch=develop&event=push)](https://github.com/lirios/appcenter/actions?query=workflow%3ACI) 8 | [![REUSE status](https://api.reuse.software/badge/github.com/lirios/appcenter)](https://api.reuse.software/info/github.com/lirios/appcenter) 9 | 10 | This is the App Center for Liri OS for installing, updating, and managing applications built using Flatpak. 11 | 12 | ## Dependencies 13 | 14 | Qt >= 6.7 with at least the following modules is required: 15 | 16 | * [qtbase](http://code.qt.io/cgit/qt/qtbase.git) 17 | * [qtdeclarative](http://code.qt.io/cgit/qt/qtdeclarative.git) 18 | 19 | The following modules and their dependencies are required: 20 | 21 | * [cmake](https://gitlab.kitware.com/cmake/cmake) >= 3.19.0 22 | * [extra-cmake-modules](https://invent.kde.org/frameworks/extra-cmake-modules) >= 5.245.0 23 | * [cmake-shared](https://github.com/lirios/cmake-shared.git) >= 2.0.99 24 | * [qtaccountsservice](https://github.com/lirios/qtaccountsservice.git) >= 2.0.0 25 | * [fluid](https://github.com/lirios/fluid) >= 2.0.0 26 | * [libliri](https://github.com/lirios/libliri) 27 | * [flatpak](https://github.com/flatpak/flatpak) 28 | * [AppStream](https://github.com/ximion/appstream) 29 | 30 | ## Installation 31 | 32 | ```sh 33 | mkdir build 34 | cd build 35 | cmake -DCMAKE_INSTALL_PREFIX=/path/to/prefix .. 36 | make 37 | make install # use sudo if necessary 38 | ``` 39 | 40 | Replace `/path/to/prefix` to your installation prefix. 41 | Default is `/usr/local`. 42 | 43 | ### Logging categories 44 | 45 | Qt 5.2 introduced logging categories and we take advantage of 46 | them to make debugging easier. 47 | 48 | Please refer to the [Qt](http://doc.qt.io/qt-5/qloggingcategory.html) documentation 49 | to learn how to enable them. 50 | 51 | ### Available categories 52 | 53 | * **liri.appcenter:** Library and application 54 | * **liri.appcenter.flatpak:** Flatpak backend 55 | * **liri.appcenter.odrs:** ODRS reviews backend 56 | 57 | ## Licensing 58 | 59 | Licensed under the terms of the GNU General Public License version 3 or, 60 | at your option, any later version. 61 | -------------------------------------------------------------------------------- /cmake/FindFlatpak.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | # 3 | # SPDX-License-Identifier: BSD-3-Clause 4 | 5 | find_package(PkgConfig REQUIRED) 6 | 7 | pkg_check_modules(Flatpak flatpak>=0.11.8 REQUIRED IMPORTED_TARGET) 8 | -------------------------------------------------------------------------------- /features.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Pier Luigi Fiorini 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ## Enable feature summary at the end of the configure run: 5 | include(FeatureSummary) 6 | 7 | ## Set minimum versions required: 8 | set(QT_MIN_VERSION "6.7.0") 9 | 10 | ## Find Qt: 11 | find_package(Qt6 "${QT_MIN_VERSION}" 12 | REQUIRED 13 | COMPONENTS 14 | Core 15 | Core5Compat 16 | DBus 17 | Concurrent 18 | Gui 19 | Qml 20 | QmlIntegration 21 | Quick 22 | QuickControls2 23 | LinguistTools 24 | ) 25 | 26 | ## Silence old policy warnings: 27 | qt6_policy(SET QTP0004 OLD) 28 | 29 | ## Find AppStreamQt: 30 | find_package(AppStreamQt REQUIRED) 31 | 32 | ## Find Flatpak: 33 | option(FEATURE_appcenter_flatpak "Flatpak support" ON) 34 | if(FEATURE_appcenter_flatpak) 35 | find_package(Flatpak QUIET) 36 | set_package_properties(Flatpak PROPERTIES 37 | TYPE RECOMMENDED 38 | PURPOSE "Flatpak support" 39 | ) 40 | if(NOT TARGET PkgConfig::Flatpak) 41 | message(WARNING "You need Flatpak for AppCenter::Flatpak") 42 | set(FEATURE_appcenter_flatpak OFF) 43 | endif() 44 | endif() 45 | add_feature_info("AppCenter::Flatpak" FEATURE_appcenter_flatpak "Build support for Flatpak") 46 | set(FEATURE_appcenter_flatpak "$") 47 | 48 | #### Features 49 | 50 | ## Features summary: 51 | if(NOT LIRI_SUPERBUILD) 52 | feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES) 53 | endif() 54 | -------------------------------------------------------------------------------- /src/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Translations 2 | #file(GLOB LiriAppCenter_TRANSLATIONS "${CMAKE_SOURCE_DIR}/translations/app/*_*.ts") 3 | #qt5_add_translation(LiriAppCenter_QM_FILES ${LiriAppCenter_TRANSLATIONS}) 4 | #install(FILES ${LiriAppCenter_QM_FILES} 5 | # DESTINATION "${INSTALL_DATADIR}/liri-appcenter/translations") 6 | 7 | qt6_add_executable(LiriAppCenter MANUAL_FINALIZATION main.cpp) 8 | set_target_properties(LiriAppCenter PROPERTIES OUTPUT_NAME "liri-appcenter") 9 | qt6_finalize_target(LiriAppCenter) 10 | 11 | target_compile_definitions(LiriAppCenter 12 | PRIVATE 13 | APPCENTER_VERSION="${PROJECT_VERSION}" 14 | QT_NO_CAST_FROM_ASCII 15 | QT_NO_FOREACH 16 | ) 17 | 18 | target_link_libraries(LiriAppCenter 19 | PRIVATE 20 | Qt6::Core 21 | Qt6::Gui 22 | Qt6::Qml 23 | Qt6::Quick 24 | Qt6::QuickControls2 25 | ) 26 | 27 | qt6_add_qml_module(LiriAppCenter 28 | URI io.liri.AppCenter 29 | VERSION 1.0 30 | QML_FILES 31 | qml/AddSourceDialog.qml 32 | qml/AllAppsTab.qml 33 | qml/AppPage.qml 34 | qml/InstalledAppsTab.qml 35 | qml/Main.qml 36 | qml/SourcesTab.qml 37 | qml/UpdatesTab.qml 38 | qml/app/Buttons.qml 39 | qml/app/Details.qml 40 | qml/app/Header.qml 41 | qml/app/HeaderRatings.qml 42 | qml/app/Icon.qml 43 | qml/app/Info.qml 44 | qml/app/RatingsReviews.qml 45 | qml/app/Review.qml 46 | qml/app/Screenshots.qml 47 | qml/app/Transaction.qml 48 | qml/pages/AddReviewPage.qml 49 | qml/pages/ReviewsPage.qml 50 | qml/ratings/RatingNumber.qml 51 | qml/ratings/RatingStar.qml 52 | qml/ratings/StarIcon.qml 53 | qml/ratings/StarRatings.qml 54 | ) 55 | 56 | install(TARGETS LiriAppCenter DESTINATION ${KDE_INSTALL_BINDIR}) 57 | 58 | install(FILES "io.liri.AppCenter.appdata.xml" 59 | DESTINATION ${KDE_INSTALL_METAINFODIR}) 60 | install(FILES "io.liri.AppCenter.desktop" 61 | DESTINATION ${KDE_INSTALL_APPDIR}) -------------------------------------------------------------------------------- /src/app/io.liri.AppCenter.appdata.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | io.liri.AppCenter.desktop 9 | CC0-1.0 10 | GPL-3.0+ 11 | App Center 12 | Programcenter 13 | Centro de aplicaciones 14 | Centro App 15 | 앱 센터 16 | Softwarecentrum 17 | Central de aplicativos 18 | Центр приложений 19 | Uygulama Merkezi 20 | Application manager for Liri OS 21 | Programhåndtering til Liri OS 22 | Administrador de aplicaciones para Liri OS 23 | Gestore applicazioni per Liri OS 24 | Liri OS 어플리케이션 관리자 25 | Softwarecentrum voor Liri OS 26 | Gerenciador de aplicativos para o Liri OS 27 | Менеджер приложений для Liri ОС 28 | Liri OS için uygulama yönetici 29 | 30 |

31 | App Center allows you to find and install new applications. 32 |

33 |

Programcenter giver dig mulighed for at finde og installere nye programmer.

34 |

Centro de aplicaciones le permite buscar e instalar nuevas aplicaciones.

35 |

Il Centro App ti permette di trovare ed installare nuove applicazioni.

36 |

앱 센터는 사용자가 새로운 어플리케이션을 찾고 설치할 수 있도록 해줍니다.

37 |

Met het softwarecentrum kunt je programma's installeren en updaten.

38 |

A central de aplicativos permite a você encontrar e instalar novos aplicativos.

39 |

Центр приложений позволяет вам найти и установить новые приложения.

40 |

Uygulama Merkezi yeni uygulamalar bulmanızı ve kurmanızı sağlar.

41 |
42 | 43 | https://liri.io 44 | info@liri.io 45 |
46 | -------------------------------------------------------------------------------- /src/app/io.liri.AppCenter.appdata.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | io.liri.AppCenter.desktop 9 | CC0-1.0 10 | GPL-3.0+ 11 | App Center 12 | Application manager for Liri OS 13 | 14 |

15 | App Center allows you to find and install new applications. 16 |

17 |
18 | 19 | https://liri.io 20 | info@liri.io 21 |
22 | -------------------------------------------------------------------------------- /src/app/io.liri.AppCenter.desktop: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | [Desktop Entry] 6 | Name=App Center 7 | Name[ar]=مركز التطبيقات 8 | Name[da]=Programcenter 9 | Name[es_MX]=Centro de aplicaciones 10 | Name[fr]=Centre d'applications 11 | Name[id]=Pusat Aplikasi 12 | Name[it_IT]=Centro App 13 | Name[ja]=App Center 14 | Name[ko]=앱 센터 15 | Name[lt]=Programų centras 16 | Name[nl]=Softwarecentrum 17 | Name[pl]=Centrum Aplikacji 18 | Name[pt_BR]=Central de aplicativos 19 | Name[ru]=Центр приложений 20 | Name[tr]=Uygulama Merkezi 21 | Name[zh_CN]=应用中心 22 | Name[zh_TW]=應用程式中心 23 | Comment=App Center for Liri 24 | Comment[ar]=مركز تطبيقات ليري 25 | Comment[da]=Programcenter til Liri 26 | Comment[es_MX]=Centro de aplicaciones para Liri 27 | Comment[fr]=Centre d'applications pour Liri 28 | Comment[id]=Pusat Aplikasi untuk Liri 29 | Comment[it_IT]=Centro applicazioni per Liri 30 | Comment[ja]=App Center for Liri 31 | Comment[ko]=Liri 앱 센터 32 | Comment[lt]=Liri programų centras 33 | Comment[nl]=Softwarecentrum voor Liri 34 | Comment[pl]=Centrum Aplikacji dla Liri 35 | Comment[pt_BR]=Central de aplicativos para o Liri 36 | Comment[ru]=Центр приложений для Liri 37 | Comment[tr]=Liri için Uygulama Merkezi 38 | Comment[zh_CN]=Liri应用中心 39 | Comment[zh_TW]=Liri應用程式中心 40 | Exec=liri-appcenter 41 | Icon=software-store 42 | Terminal=false 43 | Type=Application 44 | Categories=X-Liri;Qt;System;PackageManager; 45 | -------------------------------------------------------------------------------- /src/app/io.liri.AppCenter.desktop.in: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | [Desktop Entry] 6 | _Name=App Center 7 | _Comment=App Center for Liri 8 | Exec=liri-appcenter 9 | Icon=software-store 10 | Terminal=false 11 | Type=Application 12 | Categories=X-Liri;Qt;System;PackageManager; 13 | -------------------------------------------------------------------------------- /src/app/main.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2016 Michael Spencer 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace Qt::StringLiterals; 16 | 17 | #if 0 18 | static void loadQtTranslations() 19 | { 20 | #ifndef QT_NO_TRANSLATION 21 | QString locale = QLocale::system().name(); 22 | 23 | // Load Qt translations 24 | QTranslator *qtTranslator = new QTranslator(QCoreApplication::instance()); 25 | if (qtTranslator->load(QStringLiteral("qt_%1").arg(locale), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { 26 | qApp->installTranslator(qtTranslator); 27 | } else { 28 | delete qtTranslator; 29 | } 30 | #endif 31 | } 32 | 33 | static void loadAppTranslations() 34 | { 35 | #ifndef QT_NO_TRANSLATION 36 | QString locale = QLocale::system().name(); 37 | 38 | // Find the translations directory 39 | const QString path = QLatin1String("liri-appcenter/translations"); 40 | const QString translationsDir = 41 | QStandardPaths::locate(QStandardPaths::GenericDataLocation, 42 | path, 43 | QStandardPaths::LocateDirectory); 44 | 45 | // Load shell translations 46 | QTranslator *appTranslator = new QTranslator(QCoreApplication::instance()); 47 | if (appTranslator->load(QStringLiteral("%1/appcenter_%3").arg(translationsDir, locale))) { 48 | QCoreApplication::installTranslator(appTranslator); 49 | } else if (locale == QLatin1String("C") || 50 | locale.startsWith(QLatin1String("en"))) { 51 | // English is the default, it's translated anyway 52 | delete appTranslator; 53 | } 54 | #endif 55 | } 56 | #endif 57 | 58 | int main(int argc, char *argv[]) 59 | { 60 | // Set the X11 WML_CLASS so X11 desktops can find the desktop file 61 | qputenv("RESOURCE_NAME", QByteArrayLiteral("io.liri.AppCenter")); 62 | 63 | QGuiApplication app(argc, argv); 64 | app.setApplicationName("App Center"_L1); 65 | app.setOrganizationDomain("liri.io"_L1); 66 | app.setOrganizationName("Liri"_L1); 67 | app.setDesktopFileName("io.liri.AppCenter"_L1); 68 | 69 | QQuickStyle::setStyle("Material"_L1); 70 | 71 | #if 0 72 | // Load translations 73 | loadQtTranslations(); 74 | loadAppTranslations(); 75 | #endif 76 | 77 | QQmlApplicationEngine engine; 78 | QObject::connect( 79 | &engine, &QQmlApplicationEngine::objectCreationFailed, &app, 80 | []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); 81 | engine.loadFromModule("io.liri.AppCenter", "Main"); 82 | 83 | return app.exec(); 84 | } 85 | -------------------------------------------------------------------------------- /src/app/qml/AddSourceDialog.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import Fluid as Fluid 8 | 9 | Fluid.Dialog { 10 | id: addSourceDialog 11 | 12 | signal failed(string errorMessage) 13 | 14 | title: qsTr("Add Source") 15 | 16 | x: (parent.width - width) / 2 17 | y: (parent.height - height) / 2 18 | width: 500 19 | modal: true 20 | standardButtons: Dialog.Ok | Dialog.Cancel 21 | 22 | onVisibleChanged: { 23 | urlField.clear(); 24 | urlField.forceActiveFocus(); 25 | } 26 | 27 | onAccepted: { 28 | if (!softwareManager.addSource(urlField.text)) 29 | addSourceDialog.failed(qsTr("Failed to retrieve source")); 30 | } 31 | 32 | Fluid.TextField { 33 | id: urlField 34 | anchors.left: parent.left 35 | anchors.top: parent.top 36 | anchors.right: parent.right 37 | placeholderText: qsTr("URL") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/qml/AllAppsTab.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import Fluid as Fluid 8 | import Liri.AppCenter as AppCenter 9 | import "app" as App 10 | 11 | Fluid.Tab { 12 | title: qsTr("All Apps") 13 | 14 | AppCenter.FilteredResourcesModel { 15 | id: allAppsModel 16 | 17 | manager: softwareManager 18 | filter: AppCenter.FilteredResourcesModel.AllApps 19 | } 20 | 21 | Fluid.ScrollView { 22 | anchors.fill: parent 23 | clip: true 24 | 25 | Fluid.ScrollBar.horizontal.policy: ScrollBar.AlwaysOff 26 | 27 | ListView { 28 | header: Fluid.HeadlineLabel { 29 | text: qsTr("Available (%1)").arg(allAppsModel.count) 30 | padding: Fluid.Units.smallSpacing * 2 31 | } 32 | model: allAppsModel 33 | delegate: Fluid.ListItem { 34 | text: model.name 35 | subText: model.summary 36 | valueText: model.rating 37 | ? qsTr("Rating %1").arg((model.rating ? model.rating.rating : 0).toFixed(1).toLocaleString(Qt.locale())) 38 | : "" 39 | leftItem: App.Icon { 40 | anchors.verticalCenter: parent.verticalCenter 41 | iconName: model.iconName 42 | iconUrl: model.iconUrl 43 | iconSize: 48 44 | } 45 | rightItem: Fluid.Button { 46 | anchors.verticalCenter: parent.verticalCenter 47 | flat: true 48 | text: qsTr("Get") 49 | onClicked: { 50 | if (!model.proxy.install()) { 51 | console.error("Installation of", model.name, "has failed") 52 | return; 53 | } 54 | } 55 | } 56 | onClicked: { 57 | pageStack.push(Qt.resolvedUrl("AppPage.qml"), {app: model.proxy}); 58 | } 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/app/qml/InstalledAppsTab.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Controls.Material 8 | import QtQuick.Layouts 9 | import Fluid as Fluid 10 | import Liri.Core as LiriCore 11 | import Liri.AppCenter as AppCenter 12 | import "app" as App 13 | 14 | Fluid.Tab { 15 | title: qsTr("Installed Apps") 16 | 17 | AppCenter.FilteredResourcesModel { 18 | id: installedAppsModel 19 | 20 | manager: softwareManager 21 | filter: AppCenter.FilteredResourcesModel.InstalledApps 22 | } 23 | 24 | Fluid.ScrollView { 25 | anchors.fill: parent 26 | clip: true 27 | 28 | Fluid.ScrollBar.horizontal.policy: ScrollBar.AlwaysOff 29 | 30 | ListView { 31 | header: Fluid.HeadlineLabel { 32 | text: qsTr("On this device (%1)").arg(installedAppsModel.count) 33 | padding: Fluid.Units.smallSpacing * 2 34 | } 35 | model: installedAppsModel 36 | delegate: Fluid.ListItem { 37 | text: model.name 38 | subText: model.summary 39 | valueText: LiriCore.Formatter.formatByteSize(model.installedSize) 40 | leftItem: App.Icon { 41 | anchors.verticalCenter: parent.verticalCenter 42 | iconName: model.iconName 43 | iconUrl: model.iconUrl 44 | iconSize: 48 45 | } 46 | rightItem: Button { 47 | anchors.verticalCenter: parent.verticalCenter 48 | flat: true 49 | text: qsTr("Open") 50 | onClicked: { 51 | if (!model.proxy.launch()) { 52 | console.error("Execution of", model.name, "has failed") 53 | return; 54 | } 55 | } 56 | } 57 | onClicked: { 58 | pageStack.push(Qt.resolvedUrl("AppPage.qml"), {app: model.proxy}); 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/app/qml/Main.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Layouts 7 | import QtQuick.Controls 8 | import QtQuick.Controls.Material 9 | import Fluid as Fluid 10 | import Liri.AppCenter as AppCenter 11 | 12 | Fluid.ApplicationWindow { 13 | title: qsTr("App Center") 14 | 15 | width: 1024 16 | height: 768 17 | minimumWidth: 600 18 | minimumHeight: 600 19 | visible: true 20 | 21 | Material.primary: Material.color(Material.Green, Material.Shade800) 22 | Material.accent: Material.color(Material.Green, Material.Shade600) 23 | 24 | AppCenter.SoftwareManager { 25 | id: softwareManager 26 | 27 | onSourceAddFailed: snackBar.open(errorMessage) 28 | 29 | Component.onCompleted: softwareManager.initialize() 30 | } 31 | 32 | AddSourceDialog { 33 | id: addSourceDialog 34 | onFailed: snackBar.open(errorMessage) 35 | } 36 | 37 | Fluid.SnackBar { 38 | id: snackBar 39 | 40 | duration: 5000 41 | } 42 | 43 | initialPage: Fluid.TabbedPage { 44 | title: qsTr("App Center") 45 | 46 | actions: [ 47 | Fluid.Action { 48 | icon.source: Fluid.Utils.iconUrl("content/add") 49 | text: qsTr("Add source") 50 | toolTip: qsTr("Add a new source") 51 | onTriggered: addSourceDialog.open() 52 | }, 53 | Fluid.Action { 54 | icon.source: Fluid.Utils.iconUrl("navigation/refresh") 55 | text: qsTr("Check for updates") 56 | toolTip: qsTr("Check for updates") 57 | onTriggered: softwareManager.checkForUpdates() 58 | }, 59 | Fluid.Action { 60 | icon.source: Fluid.Utils.iconUrl("action/search") 61 | text: qsTr("Search") 62 | toolTip: qsTr("Search apps") 63 | } 64 | ] 65 | 66 | AllAppsTab {} 67 | InstalledAppsTab {} 68 | UpdatesTab {} 69 | SourcesTab {} 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/app/qml/SourcesTab.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import Fluid as Fluid 8 | 9 | Fluid.Tab { 10 | title: qsTr("Sources") 11 | 12 | Fluid.ScrollView { 13 | anchors.fill: parent 14 | 15 | ListView { 16 | model: softwareManager.sourcesModel 17 | section.delegate: Fluid.Subheader { 18 | text: section 19 | } 20 | section.property: "section" 21 | delegate: Fluid.ListItem { 22 | leftItem: CheckBox { 23 | anchors.verticalCenter: parent.verticalCenter 24 | checked: model.enabled 25 | onCheckedChanged: model.source.enabled = checked 26 | } 27 | rightItem: Row { 28 | anchors.verticalCenter: parent.verticalCenter 29 | 30 | Fluid.ToolButton { 31 | icon.source: Fluid.Utils.iconUrl("content/remove") 32 | onClicked: { 33 | softwareManager.removeSource(model.source); 34 | } 35 | 36 | ToolTip.text: qsTr("Remove") 37 | ToolTip.visible: hovered 38 | } 39 | } 40 | text: model.label 41 | subText: model.hostname 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/app/qml/UpdatesTab.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import Fluid as Fluid 8 | import Liri.Core as LiriCore 9 | import Liri.AppCenter as AppCenter 10 | import "app" as App 11 | 12 | Fluid.Tab { 13 | title: qsTr("Updates") 14 | 15 | AppCenter.FilteredResourcesModel { 16 | id: updatesModel 17 | 18 | manager: softwareManager 19 | filter: AppCenter.FilteredResourcesModel.Updates 20 | } 21 | 22 | Fluid.ScrollView { 23 | anchors.fill: parent 24 | clip: true 25 | 26 | Fluid.ScrollBar.horizontal.policy: ScrollBar.AlwaysOff 27 | 28 | ListView { 29 | header: Fluid.HeadlineLabel { 30 | text: qsTr("To update (%1)").arg(updatesModel.count) 31 | padding: Fluid.Units.smallSpacing * 2 32 | } 33 | model: updatesModel 34 | delegate: Fluid.ListItem { 35 | text: model.name 36 | subText: model.summary 37 | valueText: LiriCore.Formatter.formatByteSize(model.downloadSize) 38 | leftItem: App.Icon { 39 | anchors.verticalCenter: parent.verticalCenter 40 | iconName: model.iconName 41 | iconUrl: model.iconUrl 42 | iconSize: 48 43 | } 44 | rightItem: Fluid.Button { 45 | anchors.verticalCenter: parent.verticalCenter 46 | flat: true 47 | text: qsTr("Update") 48 | onClicked: { 49 | if (!model.proxy.update()) { 50 | console.error("Update of", model.name, "has failed") 51 | return; 52 | } 53 | } 54 | } 55 | onClicked: { 56 | pageStack.push(Qt.resolvedUrl("AppPage.qml"), {app: model.proxy}); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/app/qml/app/Header.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Controls.Material 8 | import QtQuick.Layouts 9 | import Fluid as Fluid 10 | import Liri.AppCenter as AppCenter 11 | 12 | ColumnLayout { 13 | property alias iconSize: icon.iconSize 14 | 15 | RowLayout { 16 | Layout.fillWidth: true 17 | Layout.alignment: Qt.AlignVCenter 18 | 19 | spacing: Fluid.Units.smallSpacing 20 | 21 | Icon { 22 | id: icon 23 | 24 | Layout.alignment: Qt.AlignVCenter 25 | 26 | iconSize: 256 27 | iconName: app.iconName 28 | iconUrl: app.iconUrl 29 | } 30 | 31 | ColumnLayout { 32 | Layout.alignment: Qt.AlignVCenter 33 | Layout.fillWidth: true 34 | 35 | ColumnLayout { 36 | Layout.fillWidth: true 37 | 38 | spacing: Fluid.Units.smallSpacing 39 | 40 | Fluid.HeadlineLabel { 41 | Layout.fillWidth: true 42 | 43 | text: app.name 44 | elide: Text.ElideRight 45 | } 46 | 47 | Fluid.SubheadingLabel { 48 | Layout.fillWidth: true 49 | Layout.fillHeight: true 50 | 51 | text: app.summary 52 | color: Material.secondaryTextColor 53 | wrapMode: Label.WordWrap 54 | elide: Text.ElideRight 55 | } 56 | 57 | Fluid.ComboBox { 58 | model: AppCenter.FilteredSourcesModel { 59 | sourcesModel: app ? app.sourcesModel : null 60 | showDisabled: false 61 | } 62 | textRole: "title" 63 | currentIndex: app ? app.defaultSourceIndex : 0 64 | visible: count > 1 65 | onCurrentIndexChanged: { 66 | if (app) 67 | app.defaultSource = app.sourcesModel.at(currentIndex); 68 | } 69 | } 70 | 71 | // FIXME: Finish this once we have the information to show 72 | /* 73 | Fluid.BodyLabel { 74 | text: "Developer" 75 | level: 2 76 | } 77 | */ 78 | 79 | Buttons { 80 | Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft 81 | } 82 | } 83 | 84 | Fluid.ThinDivider { 85 | Layout.fillWidth: true 86 | } 87 | 88 | HeaderRatings { 89 | Layout.fillWidth: true 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/app/qml/app/HeaderRatings.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Controls.Material 8 | import QtQuick.Layouts 9 | import Fluid as Fluid 10 | import "../ratings" as Ratings 11 | 12 | ColumnLayout { 13 | visible: app.rating 14 | 15 | RowLayout { 16 | Fluid.DisplayLabel { 17 | level: 1 18 | text: (app.rating ? app.rating.rating.toFixed(1) : 0.0.toFixed(1)).toLocaleString(Qt.locale()) 19 | color: Material.secondaryTextColor 20 | } 21 | 22 | RowLayout { 23 | Repeater { 24 | model: 5 25 | 26 | Ratings.RatingStar { 27 | Layout.alignment: Qt.AlignVCenter 28 | 29 | star: index + 1 30 | rating: app.rating ? app.rating.rating : 0 31 | size: 24 32 | color: Material.secondaryTextColor 33 | } 34 | } 35 | } 36 | } 37 | 38 | Fluid.BodyLabel { 39 | level: 2 40 | text: qsTr("%1 Ratings").arg(Number(app.rating ? app.rating.numVotes : 0).toFixed(0).toLocaleString(Qt.locale())) 41 | color: Material.secondaryTextColor 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/app/qml/app/Icon.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import Fluid as Fluid 7 | 8 | Item { 9 | id: iconItem 10 | 11 | property real iconSize: 80 12 | property alias iconName: icon.name 13 | property alias iconUrl: image.source 14 | 15 | width: iconSize 16 | height: iconSize 17 | 18 | Fluid.Icon { 19 | id: icon 20 | 21 | size: iconItem.iconSize 22 | visible: !image.visible 23 | } 24 | 25 | Image { 26 | id: image 27 | 28 | width: iconItem.iconSize 29 | height: width 30 | sourceSize.width: width 31 | sourceSize.height: height 32 | visible: source.toString() !== "" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/qml/app/Info.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Layouts 8 | import Fluid as Fluid 9 | 10 | ColumnLayout { 11 | Layout.fillWidth: true 12 | 13 | spacing: Fluid.Units.smallSpacing 14 | visible: descrLabel.visible && linksRow.visible 15 | 16 | Fluid.BodyLabel { 17 | Layout.fillWidth: true 18 | 19 | id: descrLabel 20 | 21 | text: app.description 22 | level: 2 23 | wrapMode: Label.WordWrap 24 | visible: text !== "" 25 | } 26 | 27 | RowLayout { 28 | id: linksRow 29 | 30 | spacing: Fluid.Units.smallSpacing * 2 31 | visible: visibleChildren.length > 0 32 | 33 | Fluid.BodyLabel { 34 | text: qsTr("Website").arg(app.homepageUrl) 35 | visible: app.homepageUrl.toString() !== "" 36 | onLinkActivated: Qt.openUrlExternally(link) 37 | } 38 | 39 | Fluid.BodyLabel { 40 | text: qsTr("Support").arg(app.bugtrackerUrl) 41 | visible: app.bugtrackerUrl.toString() !== "" 42 | onLinkActivated: Qt.openUrlExternally(link) 43 | } 44 | 45 | Fluid.BodyLabel { 46 | text: qsTr("Help").arg(app.helpUrl) 47 | visible: app.helpUrl.toString() !== "" 48 | onLinkActivated: Qt.openUrlExternally(link) 49 | } 50 | 51 | Fluid.BodyLabel { 52 | text: qsTr("FAQ").arg(app.faqUrl) 53 | visible: app.faqUrl.toString() !== "" 54 | onLinkActivated: Qt.openUrlExternally(link) 55 | } 56 | 57 | Fluid.BodyLabel { 58 | text: qsTr("Donate").arg(app.donationUrl) 59 | visible: app.donationUrl.toString() !== "" 60 | onLinkActivated: Qt.openUrlExternally(link) 61 | } 62 | } 63 | 64 | Fluid.ThinDivider { 65 | Layout.fillWidth: true 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/app/qml/app/Screenshots.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Layouts 8 | import Fluid as Fluid 9 | import Liri.AppCenter as AppCenter 10 | 11 | Fluid.ScrollView { 12 | Layout.fillWidth: true 13 | Layout.preferredHeight: screenshotsModel.maximumThumbnailSize.height / 2 14 | 15 | clip: true 16 | 17 | ListView { 18 | orientation: ListView.Horizontal 19 | spacing: Fluid.Units.smallSpacing 20 | visible: count > 0 21 | model: AppCenter.ScreenshotsModel { 22 | id: screenshotsModel 23 | 24 | app: appPage.app.selectedResource 25 | } 26 | delegate: Image { 27 | id: thumbnail 28 | 29 | source: model.thumbnailUrl 30 | sourceSize.width: model.thumbnailSize.width / 2 31 | sourceSize.height: model.thumbnailSize.height / 2 32 | width: model.thumbnailSize.width / 2 33 | height: model.thumbnailSize.height / 2 34 | visible: status !== Image.Error 35 | 36 | Fluid.BusyIndicator { 37 | anchors.centerIn: parent 38 | visible: thumbnail.status == Image.Loading 39 | } 40 | 41 | Fluid.Ripple { 42 | anchors.fill: parent 43 | onClicked: screenshotOverlay.show(model.screenshotUrl) 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/qml/app/Transaction.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Layouts 8 | import Fluid as Fluid 9 | import Liri.AppCenter as AppCenter 10 | 11 | RowLayout { 12 | id: transactionIndicator 13 | 14 | property AppCenter.Transaction transaction: null 15 | 16 | Layout.leftMargin: spacing 17 | Layout.rightMargin: spacing 18 | 19 | spacing: Fluid.Units.smallSpacing * 2 20 | 21 | visible: transaction && transaction.visible 22 | 23 | // Hide immediately when the transaction is finished 24 | Connections { 25 | target: transaction 26 | ignoreUnknownSignals: true 27 | 28 | function onSucceeded() { 29 | transaction = null; 30 | } 31 | 32 | function onFailed() { 33 | snackBar.open(transaction.errorMessage); 34 | transaction = null; 35 | } 36 | 37 | function onCancelled() { 38 | transaction = null; 39 | } 40 | } 41 | 42 | ColumnLayout { 43 | Fluid.ProgressBar { 44 | from: 0.0 45 | to: 100.0 46 | value: transaction ? transaction.progress : 0.0 47 | indeterminate: { 48 | if (!transaction) 49 | return false; 50 | 51 | switch (transaction.status) { 52 | case AppCenter.Transaction.Starting: 53 | case AppCenter.Transaction.Preparing: 54 | return true; 55 | default: 56 | return false; 57 | } 58 | } 59 | 60 | Layout.fillWidth: true 61 | } 62 | 63 | Fluid.Label { 64 | text: { 65 | if (!transaction) 66 | return ""; 67 | 68 | switch (transaction.status) { 69 | case AppCenter.Transaction.Failed: 70 | return transaction.errorMessage; 71 | default: 72 | return transaction.description; 73 | } 74 | } 75 | } 76 | 77 | Layout.fillWidth: true 78 | } 79 | 80 | Fluid.Button { 81 | text: qsTr("Cancel") 82 | flat: true 83 | enabled: { 84 | if (!transaction) 85 | return false; 86 | 87 | if (!transaction.cancellable) 88 | return false; 89 | 90 | switch (transaction.status) { 91 | case AppCenter.Transaction.Failed: 92 | case AppCenter.Transaction.Canceled: 93 | return false; 94 | default: 95 | return true; 96 | } 97 | } 98 | onClicked: { 99 | transaction.cancel(); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/app/qml/pages/ReviewsPage.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Controls.Material 8 | import QtQuick.Layouts 9 | import Fluid as Fluid 10 | import Liri.AppCenter as AppCenter 11 | import "../app" as App 12 | 13 | Fluid.Page { 14 | property alias resource: reviewsModel.resource 15 | 16 | title: qsTr("All reviews") 17 | 18 | Fluid.BusyIndicator { 19 | anchors.centerIn: parent 20 | visible: reviewsModel.count == 0 21 | } 22 | 23 | Fluid.ScrollView { 24 | anchors.fill: parent 25 | clip: true 26 | 27 | ListView { 28 | model: AppCenter.FilteredReviewsModel { 29 | id: reviewsModel 30 | } 31 | spacing: Fluid.Units.smallSpacing 32 | delegate: App.Review { 33 | width: ListView.view.width 34 | height: Math.max(150, implicitHeight) 35 | drawBorder: false 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/qml/ratings/RatingNumber.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQml 6 | import QtQuick 7 | import QtQuick.Controls 8 | import QtQuick.Controls.Material 9 | import Fluid as Fluid 10 | 11 | Column { 12 | spacing: Fluid.Units.smallSpacing / 2 13 | 14 | Fluid.DisplayLabel { 15 | level: 3 16 | text: (app.rating ? app.rating.rating.toFixed(1) : 0.0.toFixed(1)).toLocaleString(Qt.locale()) 17 | } 18 | 19 | Row { 20 | Repeater { 21 | model: 5 22 | 23 | RatingStar { 24 | star: index + 1 25 | rating: app.rating ? app.rating.rating : 0 26 | } 27 | } 28 | } 29 | 30 | Fluid.BodyLabel { 31 | text: qsTr("%1 Ratings").arg(Number(app.rating ? app.rating.numVotes : 0).toFixed(0).toLocaleString(Qt.locale())) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/app/qml/ratings/RatingStar.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Controls.Material 8 | import Fluid as Fluid 9 | 10 | StarIcon { 11 | property int star: 1 12 | property real rating: 0 13 | readonly property bool full: { 14 | return Math.floor(rating) >= star; 15 | } 16 | readonly property bool half: { 17 | if (star > Math.floor(rating) && star <= Math.ceil(rating)) 18 | return rating - Math.floor(rating) >= 0.5; 19 | return false; 20 | } 21 | 22 | source: Fluid.Utils.iconUrl("toggle/star" + (half ? "_half" : full ? "" : "_border")) 23 | color: full || half ? Material.accentColor : Material.secondaryTextColor 24 | } 25 | -------------------------------------------------------------------------------- /src/app/qml/ratings/StarIcon.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Controls.Material 8 | import Fluid as Fluid 9 | 10 | Fluid.Icon { 11 | source: Fluid.Utils.iconUrl("toggle/star") 12 | size: 18 13 | color: Material.secondaryTextColor 14 | } 15 | -------------------------------------------------------------------------------- /src/app/qml/ratings/StarRatings.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Controls.Material 8 | import Fluid as Fluid 9 | 10 | Grid { 11 | rows: 5 12 | columns: 2 13 | spacing: Fluid.Units.smallSpacing / 2 14 | horizontalItemAlignment: Grid.AlignRight 15 | verticalItemAlignment: Grid.AlignVCenter 16 | 17 | Row { 18 | Repeater { 19 | model: 5 20 | 21 | StarIcon {} 22 | } 23 | } 24 | 25 | Fluid.ProgressBar { 26 | from: 0 27 | to: app.rating ? app.rating.numVotes : 0 28 | value: app.rating ? app.rating.star5 : 0 29 | } 30 | 31 | /// 32 | 33 | Row { 34 | Repeater { 35 | model: 4 36 | 37 | StarIcon {} 38 | } 39 | } 40 | 41 | Fluid.ProgressBar { 42 | from: 0 43 | to: app.rating ? app.rating.numVotes : 0 44 | value: app.rating ? app.rating.star4 : 0 45 | } 46 | 47 | /// 48 | 49 | Row { 50 | Repeater { 51 | model: 3 52 | 53 | StarIcon {} 54 | } 55 | } 56 | 57 | Fluid.ProgressBar { 58 | from: 0 59 | to: app.rating ? app.rating.numVotes : 0 60 | value: app.rating ? app.rating.star3 : 0 61 | } 62 | 63 | /// 64 | 65 | Row { 66 | Repeater { 67 | model: 2 68 | 69 | StarIcon {} 70 | } 71 | } 72 | 73 | Fluid.ProgressBar { 74 | from: 0 75 | to: app.rating ? app.rating.numVotes : 0 76 | value: app.rating ? app.rating.star2 : 0 77 | } 78 | 79 | /// 80 | 81 | StarIcon {} 82 | 83 | Fluid.ProgressBar { 84 | from: 0 85 | to: app.rating ? app.rating.numVotes : 0 86 | value: app.rating ? app.rating.star1 : 0 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/framework/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | liri_add_module(AppCenter 2 | DESCRIPTION 3 | "AppCenter library" 4 | SOURCES 5 | backend.cpp backend.h 6 | backendplugin.cpp backendplugin.h 7 | cachednetworkaccessmanager.cpp cachednetworkaccessmanager_p.h 8 | image.cpp image.h image_p.h 9 | rating.cpp rating.h rating_p.h 10 | resourcesmodel.cpp resourcesmodel.h resourcesmodel_p.h 11 | resourceproxy.cpp resourceproxy.h resourceproxy_p.h 12 | review.cpp review.h review_p.h 13 | reviewsbackend.cpp reviewsbackend.h 14 | reviewsbackendplugin.cpp reviewsbackendplugin.h 15 | reviewsmodel.cpp reviewsmodel.h reviewsmodel_p.h 16 | screenshotsmodel.cpp screenshotsmodel.h screenshotsmodel_p.h 17 | softwaremanager.cpp softwaremanager.h softwaremanager_p.h 18 | softwareresource.cpp softwareresource.h softwareresource_p.h 19 | softwaresource.cpp softwaresource.h softwaresource_p.h 20 | sourcesmodel.cpp sourcesmodel.h sourcesmodel_p.h 21 | transaction.cpp transaction.h transaction_p.h 22 | transactionsmanager.cpp transactionsmanager.h transactionsmanager_p.h 23 | DEFINES 24 | QT_NO_CAST_FROM_ASCII 25 | QT_NO_FOREACH 26 | PUBLIC_LIBRARIES 27 | Qt6::Core 28 | Qt6::Network 29 | Qt6::QmlIntegration 30 | AppStreamQt 31 | NO_PKGCONFIG 32 | ) 33 | 34 | liri_finalize_module(AppCenter) 35 | -------------------------------------------------------------------------------- /src/framework/backend.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "backend.h" 6 | 7 | namespace Liri { 8 | 9 | namespace AppCenter { 10 | 11 | Backend::Backend(SoftwareManager *manager, QObject *parent) 12 | : QObject(parent) 13 | { 14 | Q_UNUSED(manager); 15 | } 16 | 17 | Backend::~Backend() 18 | { 19 | } 20 | 21 | } // namespace AppCenter 22 | 23 | } // namespace Liri 24 | -------------------------------------------------------------------------------- /src/framework/backend.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERBACKEND_H 6 | #define LIRIAPPCENTERBACKEND_H 7 | 8 | #include 9 | #include 10 | 11 | namespace Liri { 12 | 13 | namespace AppCenter { 14 | 15 | class SoftwareManager; 16 | 17 | class LIRIAPPCENTER_EXPORT Backend : public QObject 18 | { 19 | Q_OBJECT 20 | public: 21 | explicit Backend(SoftwareManager *manager, QObject *parent = nullptr); 22 | virtual ~Backend(); 23 | 24 | virtual void initialize() = 0; 25 | 26 | virtual void listSources() = 0; 27 | virtual void listAvailableApps() = 0; 28 | virtual void listInstalledApps() = 0; 29 | virtual void checkForUpdates() = 0; 30 | 31 | virtual QVector updates() const = 0; 32 | 33 | virtual bool addSource(const QString &source) = 0; 34 | virtual bool removeSource(SoftwareSource *source) = 0; 35 | 36 | virtual SoftwareResource *installAppFromPath(const QString &filePath) = 0; 37 | 38 | Q_SIGNALS: 39 | void updatesAvailable(uint count); 40 | }; 41 | 42 | } // namespace AppCenter 43 | 44 | } // namespace Liri 45 | 46 | #endif // LIRIAPPCENTERBACKEND_H 47 | -------------------------------------------------------------------------------- /src/framework/backendplugin.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "backendplugin.h" 6 | 7 | namespace Liri { 8 | 9 | namespace AppCenter { 10 | 11 | BackendPlugin::BackendPlugin(QObject *parent) 12 | : QObject(parent) 13 | { 14 | } 15 | 16 | } // namespace AppCenter 17 | 18 | } // namespace Liri 19 | -------------------------------------------------------------------------------- /src/framework/backendplugin.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERBACKENDPLUGIN_H 6 | #define LIRIAPPCENTERBACKENDPLUGIN_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace Liri { 13 | 14 | namespace AppCenter { 15 | 16 | class Backend; 17 | 18 | class LIRIAPPCENTER_EXPORT BackendPlugin : public QObject 19 | { 20 | Q_OBJECT 21 | public: 22 | explicit BackendPlugin(QObject *parent = nullptr); 23 | 24 | virtual Backend *create(SoftwareManager *manager) = 0; 25 | }; 26 | 27 | } // namespace AppCenter 28 | 29 | } // namespace Liri 30 | 31 | #define BackendPlugin_iid "io.liri.AppCenter.BackendPlugin" 32 | 33 | Q_DECLARE_INTERFACE(Liri::AppCenter::BackendPlugin, BackendPlugin_iid) 34 | 35 | #endif // LIRIAPPCENTERBACKENDPLUGIN_H 36 | -------------------------------------------------------------------------------- /src/framework/cachednetworkaccessmanager.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "cachednetworkaccessmanager_p.h" 12 | 13 | namespace Liri { 14 | 15 | namespace AppCenter { 16 | 17 | CachedNetworkAccessManager::CachedNetworkAccessManager(const QString &path, QObject *parent) 18 | : QNetworkAccessManager(parent) 19 | { 20 | const QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + 21 | QLatin1Char('/') + path; 22 | 23 | QStorageInfo storageInfo(cacheDir); 24 | QNetworkDiskCache *cache = new QNetworkDiskCache(this); 25 | cache->setCacheDirectory(cacheDir); 26 | cache->setMaximumCacheSize(qFloor(storageInfo.bytesAvailable() * 0.5f)); 27 | setCache(cache); 28 | } 29 | 30 | QNetworkReply *CachedNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, 31 | const QNetworkRequest &request, 32 | QIODevice *outgoingData) 33 | { 34 | QNetworkRequest cachedRequest(request); 35 | cachedRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); 36 | return QNetworkAccessManager::createRequest(op, cachedRequest, outgoingData); 37 | } 38 | 39 | } // namespace AppCenter 40 | 41 | } // namespace Liri 42 | -------------------------------------------------------------------------------- /src/framework/cachednetworkaccessmanager_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_CACHEDNETWORKACCESSMANAGER_H 6 | #define LIRI_APPCENTER_CACHEDNETWORKACCESSMANAGER_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | 21 | #include 22 | 23 | namespace Liri { 24 | 25 | namespace AppCenter { 26 | 27 | class LIRIAPPCENTER_EXPORT CachedNetworkAccessManager : public QNetworkAccessManager 28 | { 29 | public: 30 | explicit CachedNetworkAccessManager(const QString &path, QObject *parent = nullptr); 31 | 32 | protected: 33 | QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, 34 | QIODevice *outgoingData = nullptr) override; 35 | }; 36 | 37 | } // namespace AppCenter 38 | 39 | } // namespace Liri 40 | 41 | #endif // LIRI_APPCENTER_CACHEDNETWORKACCESSMANAGER_H 42 | -------------------------------------------------------------------------------- /src/framework/image.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "image.h" 6 | #include "image_p.h" 7 | 8 | namespace Liri { 9 | 10 | namespace AppCenter { 11 | 12 | ImagePrivate::ImagePrivate() 13 | { 14 | } 15 | 16 | Image::Image(const QUrl &url, const QSize &size) 17 | : d_ptr(new ImagePrivate()) 18 | { 19 | d_func()->url = url; 20 | d_func()->size = size; 21 | } 22 | 23 | Image::Image() 24 | : d_ptr(new ImagePrivate()) 25 | { 26 | } 27 | 28 | Image::Image(const Image &other) 29 | : d_ptr(new ImagePrivate()) 30 | { 31 | d_func()->url = other.url(); 32 | d_func()->size = other.size(); 33 | } 34 | 35 | Image::~Image() 36 | { 37 | delete d_ptr; 38 | } 39 | 40 | bool Image::isValid() const 41 | { 42 | Q_D(const Image); 43 | return d->url.isValid() && d->size.isValid(); 44 | } 45 | 46 | QUrl Image::url() const 47 | { 48 | Q_D(const Image); 49 | return d->url; 50 | } 51 | 52 | QSize Image::size() const 53 | { 54 | Q_D(const Image); 55 | return d->size; 56 | } 57 | 58 | Image &Image::operator=(const Image &other) 59 | { 60 | Q_D(Image); 61 | d->url = other.url(); 62 | d->size = other.size(); 63 | return *this; 64 | } 65 | 66 | } // namespace AppCenter 67 | 68 | } // namespace Liri 69 | -------------------------------------------------------------------------------- /src/framework/image.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERIMAGE_H 6 | #define LIRIAPPCENTERIMAGE_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace Liri { 14 | 15 | namespace AppCenter { 16 | 17 | class ImagePrivate; 18 | 19 | class LIRIAPPCENTER_EXPORT Image 20 | { 21 | Q_GADGET 22 | Q_PROPERTY(bool valid READ isValid CONSTANT) 23 | Q_PROPERTY(QUrl url READ url CONSTANT) 24 | Q_PROPERTY(QSize size READ size CONSTANT) 25 | Q_DECLARE_PRIVATE(Image) 26 | public: 27 | explicit Image(const QUrl &url, const QSize &size); 28 | Image(); 29 | Image(const Image &other); 30 | ~Image(); 31 | 32 | bool isValid() const; 33 | 34 | QUrl url() const; 35 | QSize size() const; 36 | 37 | Image &operator=(const Image &other); 38 | 39 | private: 40 | ImagePrivate *const d_ptr; 41 | }; 42 | 43 | } // namespace AppCenter 44 | 45 | } // namespace Liri 46 | 47 | #endif // LIRIAPPCENTERIMAGE_H 48 | -------------------------------------------------------------------------------- /src/framework/image_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERIMAGE_P_H 6 | #define LIRIAPPCENTERIMAGE_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | namespace Liri { 20 | 21 | namespace AppCenter { 22 | 23 | class ImagePrivate 24 | { 25 | public: 26 | ImagePrivate(); 27 | 28 | QUrl url; 29 | QSize size; 30 | }; 31 | 32 | } // namespace AppCenter 33 | 34 | } // namespace Liri 35 | 36 | #endif // LIRIAPPCENTERIMAGE_P_H 37 | -------------------------------------------------------------------------------- /src/framework/liriappcenterglobal.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERGLOBAL_H 6 | #define LIRIAPPCENTERGLOBAL_H 7 | 8 | #include 9 | 10 | #if defined(QT_BUILD_LIRIAPPCENTER_LIB) 11 | # define LIRIAPPCENTER_EXPORT Q_DECL_EXPORT 12 | #else 13 | # define LIRIAPPCENTER_EXPORT Q_DECL_IMPORT 14 | #endif 15 | #define LIRIAPPCENTER_NO_EXPORT Q_DECL_HIDDEN 16 | 17 | #endif // LIRIAPPCENTERGLOBAL_H 18 | -------------------------------------------------------------------------------- /src/framework/rating.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include 6 | 7 | #include "rating_p.h" 8 | 9 | namespace Liri { 10 | 11 | namespace AppCenter { 12 | 13 | Rating::Rating(const QString &appId, quint64 numVotes, 14 | qreal rating, QObject *parent) 15 | : QObject(parent) 16 | , d_ptr(new RatingPrivate()) 17 | { 18 | d_ptr->appId = appId; 19 | d_ptr->numVotes = numVotes; 20 | d_ptr->rating = rating; 21 | } 22 | 23 | Rating::Rating(const QString &appId, quint64 numVotes, 24 | const QVariantMap &data, QObject *parent) 25 | : QObject(parent) 26 | , d_ptr(new RatingPrivate()) 27 | { 28 | d_ptr->appId = appId; 29 | d_ptr->numVotes = numVotes; 30 | 31 | d_ptr->star0 = qMax(0, data.value(QStringLiteral("star0")).toInt()); 32 | d_ptr->star1 = qMax(0, data.value(QStringLiteral("star1")).toInt()); 33 | d_ptr->star2 = qMax(0, data.value(QStringLiteral("star2")).toInt()); 34 | d_ptr->star3 = qMax(0, data.value(QStringLiteral("star3")).toInt()); 35 | d_ptr->star4 = qMax(0, data.value(QStringLiteral("star4")).toInt()); 36 | d_ptr->star5 = qMax(0, data.value(QStringLiteral("star5")).toInt()); 37 | 38 | int stars = d_ptr->star1 + (d_ptr->star2 * 2) + (d_ptr->star3 * 3) + 39 | (d_ptr->star4 * 4) + (d_ptr->star5 * 5); 40 | d_ptr->rating = stars / qMax(1.0, qreal(numVotes)); 41 | } 42 | 43 | Rating::~Rating() 44 | { 45 | delete d_ptr; 46 | } 47 | 48 | QString Rating::appId() const 49 | { 50 | Q_D(const Rating); 51 | return d->appId; 52 | } 53 | 54 | quint64 Rating::numVotes() const 55 | { 56 | Q_D(const Rating); 57 | return d->numVotes; 58 | } 59 | 60 | qreal Rating::rating() const 61 | { 62 | Q_D(const Rating); 63 | return d->rating; 64 | } 65 | 66 | quint64 Rating::star0() const 67 | { 68 | Q_D(const Rating); 69 | return d->star0; 70 | } 71 | 72 | quint64 Rating::star1() const 73 | { 74 | Q_D(const Rating); 75 | return d->star1; 76 | } 77 | 78 | quint64 Rating::star2() const 79 | { 80 | Q_D(const Rating); 81 | return d->star2; 82 | } 83 | 84 | quint64 Rating::star3() const 85 | { 86 | Q_D(const Rating); 87 | return d->star3; 88 | } 89 | 90 | quint64 Rating::star4() const 91 | { 92 | Q_D(const Rating); 93 | return d->star4; 94 | } 95 | 96 | quint64 Rating::star5() const 97 | { 98 | Q_D(const Rating); 99 | return d->star5; 100 | } 101 | 102 | } // namespace AppCenter 103 | 104 | } // namespace Liri 105 | -------------------------------------------------------------------------------- /src/framework/rating.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_RATING_H 6 | #define LIRI_APPCENTER_RATING_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace Liri { 14 | 15 | namespace AppCenter { 16 | 17 | class RatingPrivate; 18 | 19 | class LIRIAPPCENTER_EXPORT Rating : public QObject 20 | { 21 | Q_OBJECT 22 | Q_DECLARE_PRIVATE(Rating) 23 | Q_PROPERTY(QString appId READ appId CONSTANT) 24 | Q_PROPERTY(quint64 numVotes READ numVotes CONSTANT) 25 | Q_PROPERTY(qreal rating READ rating CONSTANT) 26 | Q_PROPERTY(quint64 star0 READ star0 CONSTANT) 27 | Q_PROPERTY(quint64 star1 READ star1 CONSTANT) 28 | Q_PROPERTY(quint64 star2 READ star2 CONSTANT) 29 | Q_PROPERTY(quint64 star3 READ star3 CONSTANT) 30 | Q_PROPERTY(quint64 star4 READ star4 CONSTANT) 31 | Q_PROPERTY(quint64 star5 READ star5 CONSTANT) 32 | QML_ELEMENT 33 | QML_UNCREATABLE("Unable to instantiate Rating") 34 | public: 35 | explicit Rating(const QString &appId, 36 | quint64 numVotes, qreal rating, 37 | QObject *parent = nullptr); 38 | explicit Rating(const QString &appId, quint64 numVotes, 39 | const QVariantMap &data, 40 | QObject *parent = nullptr); 41 | ~Rating(); 42 | 43 | QString appId() const; 44 | quint64 numVotes() const; 45 | qreal rating() const; 46 | 47 | quint64 star0() const; 48 | quint64 star1() const; 49 | quint64 star2() const; 50 | quint64 star3() const; 51 | quint64 star4() const; 52 | quint64 star5() const; 53 | 54 | private: 55 | RatingPrivate *const d_ptr; 56 | }; 57 | 58 | } // namespace AppCenter 59 | 60 | } // namespace Liri 61 | 62 | #endif // LIRI_APPCENTER_RATING_H 63 | -------------------------------------------------------------------------------- /src/framework/rating_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_RATING_P_H 6 | #define LIRI_APPCENTER_RATING_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | 21 | namespace Liri { 22 | 23 | namespace AppCenter { 24 | 25 | class LIRIAPPCENTER_EXPORT RatingPrivate 26 | { 27 | public: 28 | RatingPrivate() = default; 29 | 30 | QString appId; 31 | quint64 numVotes = 0; 32 | qreal rating = 0.0; 33 | quint64 star0 = 0; 34 | quint64 star1 = 0; 35 | quint64 star2 = 0; 36 | quint64 star3 = 0; 37 | quint64 star4 = 0; 38 | quint64 star5 = 0; 39 | }; 40 | 41 | } // namespace AppCenter 42 | 43 | } // namespace Liri 44 | 45 | #endif // LIRI_APPCENTER_RATING_P_H 46 | -------------------------------------------------------------------------------- /src/framework/resourceproxy_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_RESOURCEPROXY_P_H 6 | #define LIRI_APPCENTER_RESOURCEPROXY_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | namespace Liri { 24 | 25 | namespace AppCenter { 26 | 27 | class LIRIAPPCENTER_EXPORT ResourceProxyPrivate 28 | { 29 | public: 30 | ResourceProxyPrivate(); 31 | ~ResourceProxyPrivate(); 32 | 33 | QString id; 34 | SoftwareSource *defaultSource = nullptr; 35 | SoftwareResource *selectedResource = nullptr; 36 | QList resources; 37 | SourcesModel *sourcesModel = nullptr; 38 | bool isInstalled = false; 39 | bool hasUpdatesAvailable = false; 40 | }; 41 | 42 | } // namespace AppCenter 43 | 44 | } // namespace Liri 45 | 46 | #endif // LIRI_APPCENTER_RESOURCEPROXY_P_H 47 | -------------------------------------------------------------------------------- /src/framework/resourcesmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERRESOURCESMODEL_H 6 | #define LIRIAPPCENTERRESOURCESMODEL_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace Liri { 14 | 15 | namespace AppCenter { 16 | 17 | class ResourcesModelPrivate; 18 | class SoftwareManager; 19 | class SoftwareResource; 20 | 21 | class LIRIAPPCENTER_EXPORT ResourcesModel : public QAbstractListModel 22 | { 23 | Q_OBJECT 24 | Q_DECLARE_PRIVATE(ResourcesModel) 25 | Q_DISABLE_COPY(ResourcesModel) 26 | Q_PROPERTY(SoftwareManager *manager READ manager WRITE setManager NOTIFY managerChanged) 27 | QML_ELEMENT 28 | public: 29 | enum Roles { 30 | ProxyRole = Qt::UserRole + 1, 31 | TypeRole, 32 | ProxyStateRole, 33 | ProxyUpdatesAvailableRole, 34 | ProxyInstalledRole, 35 | StateRole, 36 | AppIdRole, 37 | NameRole, 38 | SummaryRole, 39 | DescriptionRole, 40 | IconNameRole, 41 | IconUrlRole, 42 | PackageNameRole, 43 | ArchitectureRole, 44 | LicenseRole, 45 | CategoryRole, 46 | HomePageUrlRole, 47 | BugTrackerUrlRole, 48 | FaqUrlRole, 49 | HelpUrlRole, 50 | DonationUrlRole, 51 | TranslateUrlRole, 52 | VersionRole, 53 | InstalledVersionRole, 54 | AvailableVersionRole, 55 | UpdatesAvailableRole, 56 | DownloadSizeRole, 57 | InstalledSizeRole, 58 | SizeRole, 59 | ChangeLogRole, 60 | InstalledRole, 61 | LocalizedRole, 62 | KudosRole, 63 | KudosPercentageRole, 64 | RatingRole 65 | }; 66 | 67 | explicit ResourcesModel(QObject *parent = nullptr); 68 | ~ResourcesModel(); 69 | 70 | SoftwareManager *manager() const; 71 | void setManager(SoftwareManager *manager); 72 | 73 | QHash roleNames() const override; 74 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 75 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 76 | 77 | Q_SIGNALS: 78 | void managerChanged(); 79 | 80 | private: 81 | ResourcesModelPrivate *const d_ptr; 82 | 83 | Q_PRIVATE_SLOT(d_func(), void handlePopulated(QList)) 84 | Q_PRIVATE_SLOT(d_func(), void handleProxyRemoved(ResourceProxy*)) 85 | }; 86 | 87 | } // namespace AppCenter 88 | 89 | } // namespace Liri 90 | 91 | #endif // LIRIAPPCENTERRESOURCESMODEL_H 92 | -------------------------------------------------------------------------------- /src/framework/resourcesmodel_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERRESOURCESMODEL_P_H 6 | #define LIRIAPPCENTERRESOURCESMODEL_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace Liri { 26 | 27 | namespace AppCenter { 28 | 29 | class ResourcesModelPrivate 30 | { 31 | Q_DECLARE_PUBLIC(ResourcesModel) 32 | public: 33 | explicit ResourcesModelPrivate(ResourcesModel *self); 34 | 35 | void addProxies(QList list); 36 | 37 | void handlePopulated(QList list); 38 | void handleProxyRemoved(ResourceProxy *proxy); 39 | void handleProxyChanged(ResourceProxy *proxy); 40 | 41 | bool initialized = false; 42 | SoftwareManager *manager = nullptr; 43 | QHash connections; 44 | QList proxies; 45 | 46 | protected: 47 | ResourcesModel *q_ptr; 48 | }; 49 | 50 | } // namespace AppCenter 51 | 52 | } // namespace Liri 53 | 54 | #endif // LIRIAPPCENTERRESOURCESMODEL_P_H 55 | -------------------------------------------------------------------------------- /src/framework/review_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_REVIEW_P_H 6 | #define LIRI_APPCENTER_REVIEW_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | namespace Liri { 25 | 26 | namespace AppCenter { 27 | 28 | class LIRIAPPCENTER_EXPORT ReviewPrivate 29 | { 30 | Q_DECLARE_PUBLIC(Review) 31 | public: 32 | explicit ReviewPrivate(Review *self); 33 | 34 | void setResource(SoftwareResource *value); 35 | void setId(int value); 36 | void setCreationDate(const QDateTime &value); 37 | void setRating(int value); 38 | void setPriority(int value); 39 | void setKarmaUp(int value); 40 | void setKarmaDown(int value); 41 | void setReviewerId(const QString &value); 42 | void setReviewerName(const QString &value); 43 | void setSummary(const QString &value); 44 | void setDescription(const QString &value); 45 | void setVersion(const QString &value); 46 | void setSelfMade(bool value); 47 | void setAlreadyVoted(bool value); 48 | 49 | static ReviewPrivate *get(Review *review) { return review->d_func(); } 50 | 51 | ReviewsBackend *backend = nullptr; 52 | SoftwareResource *resource = nullptr; 53 | int id = 0; 54 | QDateTime dateCreated; 55 | int rating = 0; 56 | int priority = 0; 57 | int karmaUp = 0; 58 | int karmaDown = 0; 59 | QString reviewerId; 60 | QString reviewerName; 61 | QString summary; 62 | QString description; 63 | QString version; 64 | bool selfMade = false; 65 | bool alreadyVoted = false; 66 | QVariantMap metadata; 67 | 68 | protected: 69 | Review *q_ptr; 70 | }; 71 | 72 | } // namespace AppCenter 73 | 74 | } // namespace Liri 75 | 76 | #endif // LIRI_APPCENTER_REVIEW_P_H 77 | -------------------------------------------------------------------------------- /src/framework/reviewsbackend.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "reviewsbackend.h" 6 | 7 | namespace Liri { 8 | 9 | namespace AppCenter { 10 | 11 | ReviewsBackend::ReviewsBackend(SoftwareManager *manager, QObject *parent) 12 | : QObject(parent) 13 | { 14 | Q_UNUSED(manager); 15 | } 16 | 17 | ReviewsBackend::~ReviewsBackend() 18 | { 19 | } 20 | 21 | void ReviewsBackend::initialize() 22 | { 23 | } 24 | 25 | } // namespace AppCenter 26 | 27 | } // namespace Liri 28 | 29 | #include "moc_reviewsbackend.cpp" 30 | -------------------------------------------------------------------------------- /src/framework/reviewsbackend.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_REVIEWSBACKEND_H 6 | #define LIRI_APPCENTER_REVIEWSBACKEND_H 7 | 8 | #include 9 | 10 | namespace Liri { 11 | 12 | namespace AppCenter { 13 | 14 | class Rating; 15 | class Review; 16 | class SoftwareManager; 17 | 18 | class LIRIAPPCENTER_EXPORT ReviewsBackend : public QObject 19 | { 20 | Q_OBJECT 21 | Q_MOC_INCLUDE("review.h") 22 | public: 23 | explicit ReviewsBackend(SoftwareManager *manager, 24 | QObject *parent = nullptr); 25 | virtual ~ReviewsBackend(); 26 | 27 | virtual void initialize(); 28 | 29 | virtual void fetchRatings() = 0; 30 | virtual void fetchReviews(SoftwareResource *resource) = 0; 31 | 32 | virtual QList ratings() const = 0; 33 | virtual Rating *ratingForSofwareResource(SoftwareResource *resource) const = 0; 34 | 35 | virtual QList reviews() const = 0; 36 | 37 | virtual bool submitReview(SoftwareResource *resource, 38 | const QString &summary, 39 | const QString &description, 40 | int rating) = 0; 41 | virtual void reportReview(Review *review) = 0; 42 | virtual void upVoteReview(Review *review) = 0; 43 | virtual void downVoteReview(Review *review) = 0; 44 | virtual void dismissReview(Review *review) = 0; 45 | virtual void removeReview(Review *review) = 0; 46 | 47 | Q_SIGNALS: 48 | void ratingsFetched(); 49 | void ratingsReady(); 50 | void reviewAdded(Liri::AppCenter::Review *review); 51 | void reviewSubmitted(Liri::AppCenter::Review *review); 52 | void reviewReported(Liri::AppCenter::Review *review); 53 | void reviewUpVoted(Liri::AppCenter::Review *review); 54 | void reviewDownVoted(Liri::AppCenter::Review *review); 55 | void reviewDismissed(Liri::AppCenter::Review *review); 56 | void reviewRemoved(Liri::AppCenter::Review *review); 57 | }; 58 | 59 | } // namespace AppCenter 60 | 61 | } // namespace Liri 62 | 63 | #endif // LIRI_APPCENTER_REVIEWSBACKEND_H 64 | -------------------------------------------------------------------------------- /src/framework/reviewsbackendplugin.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "reviewsbackendplugin.h" 6 | 7 | namespace Liri { 8 | 9 | namespace AppCenter { 10 | 11 | ReviewsBackendPlugin::ReviewsBackendPlugin(QObject *parent) 12 | : QObject(parent) 13 | { 14 | } 15 | 16 | } // namespace AppCenter 17 | 18 | } // namespace Liri 19 | -------------------------------------------------------------------------------- /src/framework/reviewsbackendplugin.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_REVIEWSBACKENDPLUGIN_H 6 | #define LIRI_APPCENTER_REVIEWSBACKENDPLUGIN_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace Liri { 14 | 15 | namespace AppCenter { 16 | 17 | class LIRIAPPCENTER_EXPORT ReviewsBackendPlugin : public QObject 18 | { 19 | Q_OBJECT 20 | public: 21 | explicit ReviewsBackendPlugin(QObject *parent = nullptr); 22 | 23 | virtual ReviewsBackend *create(SoftwareManager *manager) = 0; 24 | }; 25 | 26 | } // namespace AppCenter 27 | 28 | } // namespace Liri 29 | 30 | #define ReviewsBackendPlugin_iid "io.liri.AppCenter.ReviewsBackendPlugin" 31 | 32 | Q_DECLARE_INTERFACE(Liri::AppCenter::ReviewsBackendPlugin, ReviewsBackendPlugin_iid) 33 | 34 | #endif // LIRI_APPCENTER_REVIEWSBACKENDPLUGIN_H 35 | -------------------------------------------------------------------------------- /src/framework/reviewsmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_REVIEWSMODEL_H 6 | #define LIRI_APPCENTER_REVIEWSMODEL_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace Liri { 13 | 14 | namespace AppCenter { 15 | 16 | class ReviewsModelPrivate; 17 | 18 | class LIRIAPPCENTER_EXPORT ReviewsModel : public QAbstractListModel 19 | { 20 | Q_OBJECT 21 | Q_DECLARE_PRIVATE(ReviewsModel) 22 | Q_DISABLE_COPY(ReviewsModel) 23 | Q_PROPERTY(SoftwareResource *resource READ resource WRITE setResource NOTIFY resourceChanged) 24 | Q_PROPERTY(int count READ rowCount NOTIFY countChanged) 25 | QML_ELEMENT 26 | public: 27 | enum Roles { 28 | ReviewRole = Qt::UserRole + 1, 29 | CreationDateRole, 30 | RatingRole, 31 | PriorityRole, 32 | KarmaUpRole, 33 | KarmaDownRole, 34 | ReviewerIdRole, 35 | ReviewerNameRole, 36 | SummaryRole, 37 | DescriptionRole, 38 | VersionRole, 39 | SelfMadeRole, 40 | HasAlreadyVotedRole, 41 | MetadataRole, 42 | }; 43 | 44 | explicit ReviewsModel(QObject *parent = nullptr); 45 | ~ReviewsModel(); 46 | 47 | QHash roleNames() const override; 48 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 49 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 50 | 51 | SoftwareResource *resource() const; 52 | void setResource(SoftwareResource *resource); 53 | 54 | Q_SIGNALS: 55 | void resourceChanged(); 56 | void countChanged(); 57 | void reviewsFetched(); 58 | 59 | private: 60 | ReviewsModelPrivate *const d_ptr; 61 | 62 | Q_PRIVATE_SLOT(d_func(), void handleReviewsFetched()) 63 | Q_PRIVATE_SLOT(d_func(), void handleReviewSubmitted(Review*)) 64 | Q_PRIVATE_SLOT(d_func(), void handleReviewRemoved(Review*)) 65 | }; 66 | 67 | } // namespace AppCenter 68 | 69 | } // namespace Liri 70 | 71 | #endif // LIRI_APPCENTER_REVIEWSMODEL_H 72 | -------------------------------------------------------------------------------- /src/framework/reviewsmodel_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_REVIEWSMODEL_P_H 6 | #define LIRI_APPCENTER_REVIEWSMODEL_P_H 7 | 8 | #include 9 | #include 10 | 11 | // 12 | // W A R N I N G 13 | // ------------- 14 | // 15 | // This file is not part of the Liri API. It exists purely as an 16 | // implementation detail. This header file may change from version to 17 | // version without notice, or even be removed. 18 | // 19 | // We mean it. 20 | // 21 | 22 | namespace Liri { 23 | 24 | namespace AppCenter { 25 | 26 | class LIRIAPPCENTER_EXPORT ReviewsModelPrivate 27 | { 28 | Q_DECLARE_PUBLIC(ReviewsModel) 29 | public: 30 | explicit ReviewsModelPrivate(ReviewsModel *self); 31 | 32 | void handleReviewsFetched(); 33 | void handleReviewSubmitted(Review *review); 34 | void handleReviewRemoved(Review *review); 35 | 36 | SoftwareResource *resource = nullptr; 37 | QList reviews; 38 | 39 | protected: 40 | ReviewsModel *q_ptr; 41 | }; 42 | 43 | } // namespace AppCenter 44 | 45 | } // namespace Liri 46 | 47 | #endif // LIRI_APPCENTER_REVIEWSMODEL_P_H 48 | -------------------------------------------------------------------------------- /src/framework/screenshotsmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERSCREENSHOTSMODEL_H 6 | #define LIRIAPPCENTERSCREENSHOTSMODEL_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace Liri { 14 | 15 | namespace AppCenter { 16 | 17 | class ScreenshotsModelPrivate; 18 | 19 | class LIRIAPPCENTER_EXPORT ScreenshotsModel : public QAbstractListModel 20 | { 21 | Q_OBJECT 22 | Q_PROPERTY(SoftwareResource *app READ app WRITE setApp NOTIFY appChanged) 23 | Q_PROPERTY(QSize maximumThumbnailSize READ maximumThumbnailSize NOTIFY appChanged) 24 | Q_PROPERTY(int count READ rowCount NOTIFY countChanged) 25 | Q_DECLARE_PRIVATE(ScreenshotsModel) 26 | Q_DISABLE_COPY(ScreenshotsModel) 27 | QML_ELEMENT 28 | public: 29 | enum Roles { 30 | ThumbnailUrlRole = Qt::UserRole + 1, 31 | ThumbnailSizeRole, 32 | ScreenshotUrlRole, 33 | ScreenshotSizeRole 34 | }; 35 | 36 | explicit ScreenshotsModel(QObject *parent = nullptr); 37 | ~ScreenshotsModel(); 38 | 39 | QHash roleNames() const override; 40 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 41 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 42 | 43 | SoftwareResource *app() const; 44 | void setApp(SoftwareResource *app); 45 | 46 | QSize maximumThumbnailSize() const; 47 | 48 | Q_INVOKABLE QUrl thumbnailUrlAt(int index) const; 49 | Q_INVOKABLE QUrl screenshotUrlAt(int index) const; 50 | 51 | Q_SIGNALS: 52 | void appChanged(); 53 | void countChanged(); 54 | 55 | private: 56 | ScreenshotsModelPrivate *const d_ptr; 57 | }; 58 | 59 | } // namespace AppCenter 60 | 61 | } // namespace Liri 62 | 63 | #endif // LIRIAPPCENTERSCREENSHOTSMODEL_H 64 | -------------------------------------------------------------------------------- /src/framework/screenshotsmodel_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERSCREENSHOTSMODEL_P_H 6 | #define LIRIAPPCENTERSCREENSHOTSMODEL_P_H 7 | 8 | #include 9 | 10 | // 11 | // W A R N I N G 12 | // ------------- 13 | // 14 | // This file is not part of the Liri API. It exists purely as an 15 | // implementation detail. This header file may change from version to 16 | // version without notice, or even be removed. 17 | // 18 | // We mean it. 19 | // 20 | 21 | namespace Liri { 22 | 23 | namespace AppCenter { 24 | 25 | class ScreenshotsModelPrivate 26 | { 27 | Q_DECLARE_PUBLIC(ScreenshotsModel) 28 | public: 29 | ScreenshotsModelPrivate(ScreenshotsModel *self); 30 | 31 | SoftwareResource *app = nullptr; 32 | QVector thumbnails; 33 | QVector screenshots; 34 | 35 | protected: 36 | ScreenshotsModel *q_ptr; 37 | }; 38 | 39 | } // namespace AppCenter 40 | 41 | } // namespace Liri 42 | 43 | #endif // LIRIAPPCENTERSCREENSHOTSMODEL_P_H 44 | -------------------------------------------------------------------------------- /src/framework/softwaremanager.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERSOFTWAREMANAGER_H 6 | #define LIRIAPPCENTERSOFTWAREMANAGER_H 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace Liri { 16 | 17 | namespace AppCenter { 18 | 19 | class ResourceProxy; 20 | class SoftwareManagerPrivate; 21 | 22 | class LIRIAPPCENTER_EXPORT SoftwareManager : public QObject 23 | { 24 | Q_OBJECT 25 | Q_PROPERTY(SourcesModel *sourcesModel READ sourcesModel CONSTANT) 26 | Q_PROPERTY(bool hasUpdates READ hasUpdates NOTIFY updatesAvailable) 27 | Q_PROPERTY(uint updatesCount READ updatesCount NOTIFY updatesAvailable) 28 | Q_DECLARE_PRIVATE(SoftwareManager) 29 | Q_DISABLE_COPY(SoftwareManager) 30 | QML_ELEMENT 31 | Q_MOC_INCLUDE("softwareresource.h") 32 | public: 33 | explicit SoftwareManager(QObject *parent = nullptr); 34 | ~SoftwareManager(); 35 | 36 | SourcesModel *sourcesModel() const; 37 | 38 | void addResource(const QString &id, SoftwareResource *resource); 39 | void removeResource(const QString &id, SoftwareResource *resource); 40 | 41 | QList resourceProxies() const; 42 | 43 | Q_INVOKABLE bool addSource(const QString &name); 44 | Q_INVOKABLE bool removeSource(Liri::AppCenter::SoftwareSource *source); 45 | 46 | SoftwareResources updates() const; 47 | bool hasUpdates() const; 48 | uint updatesCount() const; 49 | 50 | public Q_SLOTS: 51 | void initialize(); 52 | void checkForUpdates(); 53 | 54 | Q_SIGNALS: 55 | void initializationCompleted(); 56 | void sourceAdded(Liri::AppCenter::SoftwareSource *source); 57 | void sourceAddFailed(const QString &name, const QString &errorMessage); 58 | void updatesAvailable(uint count); 59 | void resourceProxiesAdded(QList proxies); 60 | void resourceProxyRemoved(Liri::AppCenter::ResourceProxy *proxy); 61 | void ratingAdded(Liri::AppCenter::Rating *rating); 62 | void reviewAdded(Liri::AppCenter::Review *review); 63 | 64 | private: 65 | SoftwareManagerPrivate *const d_ptr; 66 | }; 67 | 68 | } // namespace AppCenter 69 | 70 | } // namesapce Liri 71 | 72 | #endif // LIRIAPPCENTERSOFTWAREMANAGER_H 73 | -------------------------------------------------------------------------------- /src/framework/softwaremanager_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERSOFTWAREMANAGER_P_H 6 | #define LIRIAPPCENTERSOFTWAREMANAGER_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | Q_DECLARE_LOGGING_CATEGORY(lcAppCenter) 29 | 30 | namespace Liri { 31 | 32 | namespace AppCenter { 33 | 34 | class LIRIAPPCENTER_EXPORT SoftwareManagerPrivate 35 | { 36 | Q_DECLARE_PUBLIC(SoftwareManager) 37 | public: 38 | SoftwareManagerPrivate(SoftwareManager *self); 39 | ~SoftwareManagerPrivate(); 40 | 41 | void populate(); 42 | 43 | static SoftwareManagerPrivate *get(SoftwareManager *self) { return self->d_func(); } 44 | 45 | QList resourcesBackends; 46 | QList reviewsBackends; 47 | 48 | SourcesModel *sourcesModel = nullptr; 49 | uint updatesCount = 0; 50 | 51 | QList proxies; 52 | QHash proxiesMap; 53 | QList resources; 54 | 55 | protected: 56 | SoftwareManager *q_ptr; 57 | }; 58 | 59 | } // namespace AppCenter 60 | 61 | } // namesapce Liri 62 | 63 | #endif // LIRIAPPCENTERSOFTWAREMANAGER_P_H 64 | -------------------------------------------------------------------------------- /src/framework/softwareresource_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERSOFTWARERESOURCE_P_H 6 | #define LIRIAPPCENTERSOFTWARERESOURCE_P_H 7 | 8 | #include 9 | 10 | #include "softwareresource.h" 11 | 12 | // 13 | // W A R N I N G 14 | // ------------- 15 | // 16 | // This file is not part of the Liri API. It exists purely as an 17 | // implementation detail. This header file may change from version to 18 | // version without notice, or even be removed. 19 | // 20 | // We mean it. 21 | // 22 | 23 | #include 24 | #include 25 | 26 | namespace Liri { 27 | 28 | namespace AppCenter { 29 | 30 | class SoftwareSource; 31 | 32 | class SoftwareResourcePrivate 33 | { 34 | Q_DECLARE_PUBLIC(SoftwareResource) 35 | public: 36 | SoftwareResourcePrivate(SoftwareResource *self); 37 | 38 | void setRating(Rating *r); 39 | 40 | static SoftwareResourcePrivate *get(SoftwareResource *res) { return res->d_func(); } 41 | 42 | SoftwareManager *manager = nullptr; 43 | SoftwareSource *source = nullptr; 44 | QMap metadata; 45 | SoftwareResource::Kudos kudos; 46 | Rating *rating = nullptr; 47 | QList reviews; 48 | 49 | protected: 50 | SoftwareResource *q_ptr; 51 | }; 52 | 53 | } // namespace AppCenter 54 | 55 | } // namespace Liri 56 | 57 | #endif // LIRIAPPCENTERSOFTWARERESOURCE_P_H 58 | -------------------------------------------------------------------------------- /src/framework/softwaresource.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "softwaresource.h" 6 | #include "softwaresource_p.h" 7 | 8 | namespace Liri { 9 | 10 | namespace AppCenter { 11 | 12 | SoftwareSource::SoftwareSource(Backend *backend, QObject *parent) 13 | : QObject(parent) 14 | , d_ptr(new SoftwareSourcePrivate()) 15 | { 16 | d_ptr->backend = backend; 17 | } 18 | 19 | SoftwareSource::~SoftwareSource() 20 | { 21 | delete d_ptr; 22 | } 23 | 24 | Backend *SoftwareSource::backend() const 25 | { 26 | Q_D(const SoftwareSource); 27 | return d->backend; 28 | } 29 | 30 | QString SoftwareSource::hostname() const 31 | { 32 | return url().host(); 33 | } 34 | 35 | QVariantMap SoftwareSource::metadata() const 36 | { 37 | return QVariantMap(); 38 | } 39 | 40 | bool SoftwareSource::operator==(const SoftwareSource &other) const 41 | { 42 | return other.name() == name(); 43 | } 44 | 45 | } // namespace AppCenter 46 | 47 | } // namespace Liri 48 | -------------------------------------------------------------------------------- /src/framework/softwaresource_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERSOFTWARESOURCE_P_H 6 | #define LIRIAPPCENTERSOFTWARESOURCE_P_H 7 | 8 | #include 9 | 10 | // 11 | // W A R N I N G 12 | // ------------- 13 | // 14 | // This file is not part of the Liri API. It exists purely as an 15 | // implementation detail. This header file may change from version to 16 | // version without notice, or even be removed. 17 | // 18 | // We mean it. 19 | // 20 | 21 | namespace Liri { 22 | 23 | namespace AppCenter { 24 | 25 | class SoftwareSourcePrivate 26 | { 27 | public: 28 | SoftwareSourcePrivate() = default; 29 | 30 | Backend *backend = nullptr; 31 | }; 32 | 33 | } // namespace AppCenter 34 | 35 | } // namespace Liri 36 | 37 | #endif // LIRIAPPCENTERSOFTWARESOURCE_P_H 38 | -------------------------------------------------------------------------------- /src/framework/sourcesmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERSOURCESMODEL_H 6 | #define LIRIAPPCENTERSOURCESMODEL_H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace Liri { 14 | 15 | namespace AppCenter { 16 | 17 | class SoftwareSource; 18 | class SourcesModelPrivate; 19 | 20 | class LIRIAPPCENTER_EXPORT SourcesModel : public QAbstractListModel 21 | { 22 | Q_OBJECT 23 | Q_DECLARE_PRIVATE(SourcesModel) 24 | Q_DISABLE_COPY(SourcesModel) 25 | QML_ELEMENT 26 | public: 27 | enum Roles { 28 | SourceRole = Qt::UserRole + 1, 29 | SectionRole, 30 | NameRole, 31 | TitleRole, 32 | CommentRole, 33 | DescriptionRole, 34 | LabelRole, 35 | EnabledRole, 36 | GpgVerifyRole, 37 | UrlRole, 38 | HostNameRole, 39 | IconUrlRole, 40 | PriorityRole 41 | }; 42 | 43 | explicit SourcesModel(QObject *parent = nullptr); 44 | ~SourcesModel(); 45 | 46 | QHash roleNames() const override; 47 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 48 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 49 | 50 | void setItemRoleNames(const QHash &roles); 51 | 52 | void addSource(SoftwareSource *source); 53 | void removeSource(SoftwareSource *source); 54 | 55 | SoftwareSource *findSource(const QString &name) const; 56 | 57 | Q_INVOKABLE Liri::AppCenter::SoftwareSource *at(int index) const; 58 | 59 | private: 60 | SourcesModelPrivate *const d_ptr; 61 | }; 62 | 63 | } // namespace AppCenter 64 | 65 | } // namespace Liri 66 | 67 | #endif // LIRIAPPCENTERSOURCESMODEL_H 68 | -------------------------------------------------------------------------------- /src/framework/sourcesmodel_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERSOURCESMODEL_P_H 6 | #define LIRIAPPCENTERSOURCESMODEL_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | namespace Liri { 25 | 26 | namespace AppCenter { 27 | 28 | class LIRIAPPCENTER_EXPORT SourcesModelPrivate 29 | { 30 | Q_DECLARE_PUBLIC(SourcesModel) 31 | public: 32 | SourcesModelPrivate() = default; 33 | 34 | static SourcesModelPrivate *get(SourcesModel *q) { return q->d_func(); } 35 | 36 | QHash roles; 37 | QList sources; 38 | 39 | protected: 40 | SourcesModel *q_ptr; 41 | }; 42 | 43 | } // namespace AppCenter 44 | 45 | } // namespace Liri 46 | 47 | #endif // LIRIAPPCENTERSOURCESMODEL_P_H 48 | -------------------------------------------------------------------------------- /src/framework/transaction_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERTRANSACTION_P_H 6 | #define LIRIAPPCENTERTRANSACTION_P_H 7 | 8 | #include 9 | 10 | // 11 | // W A R N I N G 12 | // ------------- 13 | // 14 | // This file is not part of the Liri API. It exists purely as an 15 | // implementation detail. This header file may change from version to 16 | // version without notice, or even be removed. 17 | // 18 | // We mean it. 19 | // 20 | 21 | namespace Liri { 22 | 23 | namespace AppCenter { 24 | 25 | class TransactionPrivate 26 | { 27 | public: 28 | TransactionPrivate(); 29 | 30 | Transaction::Type type; 31 | QString name; 32 | QString description; 33 | SoftwareResource *resource = nullptr; 34 | Transaction::Status status = Transaction::Starting; 35 | QString errorMessage; 36 | bool cancellable = false; 37 | bool shouldCancel = true; 38 | int progress = 0; 39 | bool visible = true; 40 | }; 41 | 42 | } // namespace AppCenter 43 | 44 | } // namespace Liri 45 | 46 | #endif // LIRIAPPCENTERTRANSACTION_P_H 47 | -------------------------------------------------------------------------------- /src/framework/transactionsmanager.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "transactionsmanager_p.h" 6 | 7 | namespace Liri { 8 | 9 | namespace AppCenter { 10 | 11 | Q_GLOBAL_STATIC(TransactionsManager, s_transactionsManager) 12 | 13 | TransactionsManagerPrivate::TransactionsManagerPrivate() 14 | { 15 | } 16 | 17 | TransactionsManagerPrivate::~TransactionsManagerPrivate() 18 | { 19 | qDeleteAll(transactions); 20 | } 21 | 22 | TransactionsManager::TransactionsManager(QObject *parent) 23 | : QObject(parent) 24 | , d_ptr(new TransactionsManagerPrivate()) 25 | { 26 | } 27 | 28 | TransactionsManager::~TransactionsManager() 29 | { 30 | delete d_ptr; 31 | } 32 | 33 | TransactionsManager *TransactionsManager::instance() 34 | { 35 | return s_transactionsManager(); 36 | } 37 | 38 | void TransactionsManager::addTransaction(Transaction *transaction) 39 | { 40 | Q_D(TransactionsManager); 41 | 42 | if (d->transactions.contains(transaction)) 43 | return; 44 | 45 | d->transactions.append(transaction); 46 | Q_EMIT transactionAdded(transaction); 47 | } 48 | 49 | void TransactionsManager::removeTransaction(Transaction *transaction) 50 | { 51 | Q_D(TransactionsManager); 52 | 53 | if (!d->transactions.contains(transaction)) 54 | return; 55 | 56 | if (d->transactions.removeOne(transaction)) 57 | Q_EMIT transactionRemoved(transaction); 58 | } 59 | 60 | } // namespace AppCenter 61 | 62 | } // namespace Liri 63 | -------------------------------------------------------------------------------- /src/framework/transactionsmanager.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERTRANSACTIONSMANAGER_H 6 | #define LIRIAPPCENTERTRANSACTIONSMANAGER_H 7 | 8 | #include 9 | 10 | namespace Liri { 11 | 12 | namespace AppCenter { 13 | 14 | class TransactionsManagerPrivate; 15 | 16 | class LIRIAPPCENTER_EXPORT TransactionsManager : public QObject 17 | { 18 | Q_OBJECT 19 | Q_DECLARE_PRIVATE(TransactionsManager) 20 | Q_DISABLE_COPY(TransactionsManager) 21 | public: 22 | explicit TransactionsManager(QObject *parent = nullptr); 23 | ~TransactionsManager(); 24 | 25 | static TransactionsManager *instance(); 26 | 27 | void addTransaction(Transaction *transaction); 28 | void removeTransaction(Transaction *transaction); 29 | 30 | Q_SIGNALS: 31 | void transactionAdded(Liri::AppCenter::Transaction *transaction); 32 | void transactionRemoved(Liri::AppCenter::Transaction *transaction); 33 | 34 | private: 35 | TransactionsManagerPrivate *const d_ptr; 36 | }; 37 | 38 | } // namespace AppCenter 39 | 40 | } // namespace Liri 41 | 42 | #endif // LIRIAPPCENTERTRANSACTIONSMANAGER_H 43 | -------------------------------------------------------------------------------- /src/framework/transactionsmanager_p.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRIAPPCENTERTRANSACTIONSMANAGER_P_H 6 | #define LIRIAPPCENTERTRANSACTIONSMANAGER_P_H 7 | 8 | // 9 | // W A R N I N G 10 | // ------------- 11 | // 12 | // This file is not part of the Liri API. It exists purely as an 13 | // implementation detail. This header file may change from version to 14 | // version without notice, or even be removed. 15 | // 16 | // We mean it. 17 | // 18 | 19 | #include 20 | 21 | #include 22 | 23 | namespace Liri { 24 | 25 | namespace AppCenter { 26 | 27 | class Transaction; 28 | 29 | class TransactionsManagerPrivate 30 | { 31 | public: 32 | TransactionsManagerPrivate(); 33 | ~TransactionsManagerPrivate(); 34 | 35 | QVector transactions; 36 | }; 37 | 38 | } // namespace AppCenter 39 | 40 | } // namespace Liri 41 | 42 | #endif // LIRIAPPCENTERTRANSACTIONSMANAGER_P_H 43 | -------------------------------------------------------------------------------- /src/imports/appcenter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT TARGET Liri::Models) 2 | find_package(Liri1Models REQUIRED) 3 | endif() 4 | 5 | ecm_add_qml_module(AppCenterQmlPlugin 6 | URI 7 | "Liri.AppCenter" 8 | VERSION 9 | "1.0" 10 | NO_GENERATE_PLUGIN_SOURCE 11 | DEPENDENCIES 12 | "QtQuick" 13 | "QtQuick.Controls" 14 | "QtQuick.Layouts" 15 | "QtQuick.Templates" 16 | "QtQuick.Controls.Material" 17 | "Liri.Models" 18 | ) 19 | 20 | target_sources(AppCenterQmlPlugin 21 | PRIVATE 22 | filteredresourcesmodel.cpp filteredresourcesmodel.h 23 | filteredsourcesmodel.cpp filteredsourcesmodel.h 24 | filteredreviewsmodel.cpp filteredreviewsmodel.h 25 | logging.cpp logging.h 26 | paginatemodel.cpp paginatemodel.h 27 | plugin.cpp 28 | ) 29 | 30 | target_link_libraries(AppCenterQmlPlugin 31 | PUBLIC 32 | Qt6::Core 33 | Qt6::DBus 34 | Qt6::Qml 35 | Liri::Models 36 | Liri::AppCenter 37 | ) 38 | 39 | ecm_finalize_qml_module(AppCenterQmlPlugin) 40 | -------------------------------------------------------------------------------- /src/imports/appcenter/filteredresourcesmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef INSTALLEDAPPSPROXYMODEL_H 6 | #define INSTALLEDAPPSPROXYMODEL_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | class FilteredResourcesModel : public QSortFilterProxyModel 13 | { 14 | Q_OBJECT 15 | Q_PROPERTY(Liri::AppCenter::SoftwareManager *manager READ manager WRITE setManager NOTIFY managerChanged) 16 | Q_PROPERTY(Filter filter READ filter WRITE setFilter NOTIFY modelFilterChanged) 17 | Q_PROPERTY(int count READ rowCount NOTIFY countChanged) 18 | QML_ELEMENT 19 | public: 20 | enum Filter { 21 | AllApps, 22 | NotInstalledApps, 23 | InstalledApps, 24 | Updates 25 | }; 26 | Q_ENUM(Filter); 27 | 28 | explicit FilteredResourcesModel(QObject *parent = nullptr); 29 | 30 | Liri::AppCenter::SoftwareManager *manager() const; 31 | void setManager(Liri::AppCenter::SoftwareManager *manager); 32 | 33 | Filter filter() const; 34 | void setFilter(Filter filter); 35 | 36 | Q_SIGNALS: 37 | void managerChanged(); 38 | void modelFilterChanged(); 39 | void countChanged(); 40 | 41 | protected: 42 | bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; 43 | bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; 44 | 45 | private: 46 | Filter m_filter = InstalledApps; 47 | }; 48 | 49 | #endif // INSTALLEDAPPSPROXYMODEL_H 50 | -------------------------------------------------------------------------------- /src/imports/appcenter/filteredreviewsmodel.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include 6 | 7 | #include "filteredreviewsmodel.h" 8 | 9 | FilteredReviewsModel::FilteredReviewsModel(QObject *parent) 10 | : QSortFilterProxyModel(parent) 11 | , m_reviewsModel(new ReviewsModel(this)) 12 | { 13 | connect(this, &QAbstractListModel::rowsInserted, 14 | this, &FilteredReviewsModel::countChanged); 15 | connect(this, &QAbstractListModel::rowsRemoved, 16 | this, &FilteredReviewsModel::countChanged); 17 | connect(m_reviewsModel, &ReviewsModel::resourceChanged, 18 | this, &FilteredReviewsModel::resourceChanged); 19 | connect(m_reviewsModel, &ReviewsModel::reviewsFetched, 20 | this, &FilteredReviewsModel::reviewsFetched); 21 | 22 | setSourceModel(m_reviewsModel); 23 | setDynamicSortFilter(true); 24 | setSortRole(ReviewsModel::CreationDateRole); 25 | setSortLocaleAware(true); 26 | sort(0); 27 | } 28 | 29 | SoftwareResource *FilteredReviewsModel::resource() const 30 | { 31 | return m_reviewsModel->resource(); 32 | } 33 | 34 | void FilteredReviewsModel::setResource(SoftwareResource *resource) 35 | { 36 | m_reviewsModel->setResource(resource); 37 | } 38 | 39 | bool FilteredReviewsModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const 40 | { 41 | // Sort from the most recent to the least recent (descending order) 42 | auto leftDateTime = sourceModel()->data(source_left, sortRole()).toDateTime(); 43 | auto rightDateTime = sourceModel()->data(source_right, sortRole()).toDateTime(); 44 | return leftDateTime > rightDateTime; 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/imports/appcenter/filteredreviewsmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef FILTEREDREVIEWSMODEL_H 6 | #define FILTEREDREVIEWSMODEL_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | using namespace Liri::AppCenter; 14 | 15 | class FilteredReviewsModel : public QSortFilterProxyModel 16 | { 17 | Q_OBJECT 18 | Q_PROPERTY(SoftwareResource *resource READ resource WRITE setResource NOTIFY resourceChanged) 19 | Q_PROPERTY(int count READ rowCount NOTIFY countChanged) 20 | QML_ELEMENT 21 | public: 22 | explicit FilteredReviewsModel(QObject *parent = nullptr); 23 | 24 | SoftwareResource *resource() const; 25 | void setResource(SoftwareResource *resource); 26 | 27 | Q_SIGNALS: 28 | void resourceChanged(); 29 | void countChanged(); 30 | void reviewsFetched(); 31 | 32 | protected: 33 | bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; 34 | 35 | private: 36 | ReviewsModel *m_reviewsModel; 37 | }; 38 | 39 | #endif // FILTEREDREVIEWSMODEL_H 40 | -------------------------------------------------------------------------------- /src/imports/appcenter/filteredsourcesmodel.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "filteredsourcesmodel.h" 6 | 7 | using namespace Liri::AppCenter; 8 | 9 | FilteredSourcesModel::FilteredSourcesModel(QObject *parent) 10 | : QSortFilterProxyModel(parent) 11 | { 12 | setSortLocaleAware(true); 13 | sort(0); 14 | } 15 | 16 | SourcesModel *FilteredSourcesModel::sourcesModel() const 17 | { 18 | return m_sourcesModel; 19 | } 20 | 21 | void FilteredSourcesModel::setSourcesModel(SourcesModel *sourcesModel) 22 | { 23 | if (!sourcesModel || m_sourcesModel == sourcesModel) 24 | return; 25 | 26 | m_sourcesModel = sourcesModel; 27 | setSourceModel(m_sourcesModel); 28 | Q_EMIT sourcesModelChanged(); 29 | } 30 | 31 | bool FilteredSourcesModel::showDisabled() const 32 | { 33 | return m_showDisabled; 34 | } 35 | 36 | void FilteredSourcesModel::setShowDisabled(bool show) 37 | { 38 | if (m_showDisabled == show) 39 | return; 40 | 41 | m_showDisabled = show; 42 | Q_EMIT showDisabledChanged(); 43 | } 44 | 45 | bool FilteredSourcesModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const 46 | { 47 | if (!m_showDisabled) { 48 | QModelIndex index = sourceModel()->index(source_row, 0, source_parent); 49 | return sourceModel()->data(index, SourcesModel::EnabledRole).toBool(); 50 | } 51 | 52 | return true; 53 | } 54 | 55 | bool FilteredSourcesModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const 56 | { 57 | QVariant left = sourceModel()->data(source_left, SourcesModel::TitleRole); 58 | QVariant right = sourceModel()->data(source_right, SourcesModel::TitleRole); 59 | return QString::localeAwareCompare(left.toString(), right.toString()) < 0; 60 | } 61 | -------------------------------------------------------------------------------- /src/imports/appcenter/filteredsourcesmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef FILTEREDSOURCESMODEL_H 6 | #define FILTEREDSOURCESMODEL_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | class FilteredSourcesModel : public QSortFilterProxyModel 13 | { 14 | Q_OBJECT 15 | Q_PROPERTY(Liri::AppCenter::SourcesModel *sourcesModel READ sourcesModel WRITE setSourcesModel NOTIFY sourcesModelChanged) 16 | Q_PROPERTY(bool showDisabled READ showDisabled WRITE setShowDisabled NOTIFY showDisabledChanged) 17 | QML_ELEMENT 18 | public: 19 | explicit FilteredSourcesModel(QObject *parent = nullptr); 20 | 21 | Liri::AppCenter::SourcesModel *sourcesModel() const; 22 | void setSourcesModel(Liri::AppCenter::SourcesModel *sourcesModel); 23 | 24 | bool showDisabled() const; 25 | void setShowDisabled(bool show); 26 | 27 | Q_SIGNALS: 28 | void sourcesModelChanged(); 29 | void showDisabledChanged(); 30 | 31 | protected: 32 | bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; 33 | bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; 34 | 35 | private: 36 | Liri::AppCenter::SourcesModel *m_sourcesModel = nullptr; 37 | bool m_showDisabled = true; 38 | }; 39 | 40 | #endif // FILTEREDSOURCESMODEL_H 41 | -------------------------------------------------------------------------------- /src/imports/appcenter/logging.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "logging.h" 6 | 7 | Q_LOGGING_CATEGORY(lcAppCenter, "liri.appcenter") 8 | -------------------------------------------------------------------------------- /src/imports/appcenter/logging.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LOGGING_H 6 | #define LOGGING_H 7 | 8 | #include 9 | 10 | Q_DECLARE_LOGGING_CATEGORY(lcAppCenter) 11 | 12 | #endif // LOGGING_H 13 | -------------------------------------------------------------------------------- /src/imports/appcenter/plugin.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "filteredresourcesmodel.h" 21 | #include "filteredsourcesmodel.h" 22 | #include "filteredreviewsmodel.h" 23 | #include "paginatemodel.h" 24 | 25 | using namespace Liri::AppCenter; 26 | 27 | class LiriAppCenterPlugin : public QQmlExtensionPlugin 28 | { 29 | Q_OBJECT 30 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") 31 | public: 32 | void registerTypes(const char *uri) 33 | { 34 | // @uri Liri.AppCenter 35 | Q_ASSERT(QLatin1String(uri) == QLatin1String("Liri.AppCenter")); 36 | 37 | qmlRegisterType(uri, 1, 0, "FilteredResourcesModel"); 38 | qmlRegisterType(uri, 1, 0, "FilteredSourcesModel"); 39 | qmlRegisterType(uri, 1, 0, "FilteredReviewsModel"); 40 | qmlRegisterType(uri, 1, 0, "ScreenshotsModel"); 41 | qmlRegisterType(uri, 1, 0, "SoftwareManager"); 42 | qmlRegisterType(uri, 1, 0, "SourcesModel"); 43 | qmlRegisterType(uri, 1, 0, "PaginateModel"); 44 | qmlRegisterUncreatableType(uri, 1, 0, "Rating", 45 | QLatin1String("Unable to instantiate Rating")); 46 | qmlRegisterType(uri, 1, 0, "ResourcesModel"); 47 | qmlRegisterUncreatableType(uri, 1, 0, "ResourceProxy", 48 | QLatin1String("Unable to instantiate ResourceProxy")); 49 | qmlRegisterUncreatableType(uri, 1, 0, "Review", 50 | QLatin1String("Unable to instantiate Review")); 51 | qmlRegisterType(uri, 1, 0, "ReviewsModel"); 52 | qmlRegisterUncreatableType(uri, 1, 0, "SoftwareResource", QLatin1String("Unable to instantiate SoftwareResource")); 53 | qmlRegisterUncreatableType(uri, 1, 0, "SoftwareSource", QLatin1String("Unable to instantiate SoftwareSource")); 54 | qmlRegisterUncreatableType(uri, 1, 0, "Transaction", 55 | QLatin1String("Unable to instantiate Transaction")); 56 | } 57 | }; 58 | 59 | #include "plugin.moc" 60 | -------------------------------------------------------------------------------- /src/notifier/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT TARGET Liri::Notifications) 2 | find_package(Liri1Notifications REQUIRED) 3 | endif() 4 | 5 | # Translations 6 | file(GLOB LiriAppCenter_TRANSLATIONS "${CMAKE_SOURCE_DIR}/translations/notifier/*_*.ts") 7 | qt6_create_translation(LiriAppCenter_QM_FILES ${CMAKE_SOURCE_DIR} ${LiriAppCenter_TRANSLATIONS}) 8 | install(FILES ${LiriAppCenter_QM_FILES} 9 | DESTINATION "${KDE_INSTALL_DATADIR}/liri-appcenter/translations") 10 | 11 | set(LIBEXECDIR "${KDE_INSTALL_FULL_LIBEXECDIR}") 12 | configure_file( 13 | "io.liri.AppCenter.Notifier.desktop" 14 | "${CMAKE_CURRENT_BINARY_DIR}/io.liri.AppCenter.Notifier.desktop" 15 | @ONLY 16 | ) 17 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/io.liri.AppCenter.Notifier.desktop" 18 | DESTINATION "${KDE_INSTALL_AUTOSTARTDIR}") 19 | 20 | qt6_add_executable(LiriAppCenterNotifier 21 | main.cpp 22 | updatenotifier.cpp updatenotifier.h 23 | ${LiriAppCenter_QM_FILES} 24 | ) 25 | 26 | set_target_properties(LiriAppCenterNotifier PROPERTIES 27 | OUTPUT_NAME liri-appcenter-notifier 28 | ) 29 | 30 | qt6_finalize_target(LiriAppCenterNotifier) 31 | 32 | target_compile_definitions(LiriAppCenterNotifier 33 | PRIVATE 34 | QT_NO_CAST_FROM_ASCII 35 | QT_NO_FOREACH 36 | VERSION="${PROJECT_VERSION}" 37 | ) 38 | 39 | target_link_libraries(LiriAppCenterNotifier 40 | PRIVATE 41 | Qt6::Core 42 | Liri::AppCenter 43 | Liri::Notifications 44 | ) -------------------------------------------------------------------------------- /src/notifier/io.liri.AppCenter.Notifier.desktop: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | [Desktop Entry] 6 | Name=App Center 7 | Name[da]=Programcenter 8 | Name[es_MX]=Centro de aplicaciones 9 | Name[lt]=Programų centras 10 | Name[nl]=Softwarecentrum 11 | Name[pt_BR]=Central de aplicativos 12 | Name[ru]=App Center 13 | Name[tr]=Uygulama Merkezi 14 | Exec=@LIBEXECDIR@/liri-appcenter-notifier 15 | Icon=system-software-update 16 | Terminal=false 17 | Type=Application 18 | Categories=X-Liri;Qt;System;PackageManager; 19 | OnlyShowIn=X-Liri 20 | -------------------------------------------------------------------------------- /src/notifier/io.liri.AppCenter.Notifier.desktop.in: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | [Desktop Entry] 6 | _Name=App Center 7 | Exec=@LIBEXECDIR@/liri-appcenter-notifier 8 | Icon=system-software-update 9 | Terminal=false 10 | Type=Application 11 | Categories=X-Liri;Qt;System;PackageManager; 12 | OnlyShowIn=X-Liri 13 | -------------------------------------------------------------------------------- /src/notifier/main.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2016 Michael Spencer 2 | // 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "updatenotifier.h" 12 | 13 | static void loadQtTranslations() 14 | { 15 | #ifndef QT_NO_TRANSLATION 16 | QString locale = QLocale::system().name(); 17 | 18 | // Load Qt translations 19 | QTranslator *qtTranslator = new QTranslator(); 20 | if (qtTranslator->load(QStringLiteral("qt_%1").arg(locale), QLibraryInfo::path(QLibraryInfo::TranslationsPath))) { 21 | qApp->installTranslator(qtTranslator); 22 | } else { 23 | delete qtTranslator; 24 | } 25 | #endif 26 | } 27 | 28 | static void loadAppTranslations() 29 | { 30 | #ifndef QT_NO_TRANSLATION 31 | QString locale = QLocale::system().name(); 32 | 33 | // Find the translations directory 34 | const QString path = QLatin1String("liri-appcenter/translations"); 35 | const QString translationsDir = 36 | QStandardPaths::locate(QStandardPaths::GenericDataLocation, 37 | path, 38 | QStandardPaths::LocateDirectory); 39 | 40 | // Load shell translations 41 | QTranslator *appTranslator = new QTranslator(); 42 | if (appTranslator->load(QStringLiteral("%1/notifier_%3").arg(translationsDir, locale))) { 43 | QCoreApplication::installTranslator(appTranslator); 44 | } else if (locale == QLatin1String("C") || 45 | locale.startsWith(QLatin1String("en"))) { 46 | // English is the default, it's translated anyway 47 | delete appTranslator; 48 | } 49 | #endif 50 | } 51 | 52 | int main(int argc, char *argv[]) 53 | { 54 | QCoreApplication app(argc, argv); 55 | app.setApplicationName(QLatin1String("App Center")); 56 | app.setOrganizationDomain(QLatin1String("liri.io")); 57 | app.setOrganizationName(QLatin1String("Liri")); 58 | 59 | // Load translations 60 | loadQtTranslations(); 61 | loadAppTranslations(); 62 | 63 | UpdateNotifier notifier; 64 | notifier.initialize(); 65 | 66 | return app.exec(); 67 | } 68 | -------------------------------------------------------------------------------- /src/notifier/updatenotifier.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2016 Michael Spencer 2 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 3 | // 4 | // SPDX-License-Identifier: GPL-3.0-or-later 5 | 6 | #ifndef BACKEND_H 7 | #define BACKEND_H 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | Q_DECLARE_LOGGING_CATEGORY(lcUpdateNotifier) 16 | 17 | using namespace Liri; 18 | 19 | class UpdateNotifier : public QObject 20 | { 21 | Q_OBJECT 22 | public: 23 | explicit UpdateNotifier(QObject *parent = nullptr); 24 | 25 | void initialize(); 26 | 27 | private Q_SLOTS: 28 | void updatesAvailable(uint count); 29 | void appUpdated(); 30 | 31 | private: 32 | AppCenter::SoftwareManager *m_softwareManager = nullptr; 33 | 34 | QString updatesSummary(); 35 | }; 36 | 37 | #endif // BACKEND_H 38 | -------------------------------------------------------------------------------- /src/plugins/flatpak/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | qt6_add_plugin(AppCenterFlatpakPlugin 2 | CLASS_NAME FlatpakPlugin 3 | MANUAL_FINALIZATION 4 | flatpakappstreamjob.cpp flatpakappstreamjob.h 5 | flatpakbackend.cpp flatpakbackend.h 6 | flatpakpluginbase.h flatpakplugin.cpp flatpakplugin.h 7 | flatpakresource.cpp flatpakresource.h 8 | flatpaksource.cpp flatpaksource.h 9 | flatpaktransaction.cpp flatpaktransaction.h 10 | flatpaktransactionjob.cpp flatpaktransactionjob.h 11 | flatpakutils.cpp flatpakutils.h 12 | internetcheck.cpp internetcheck.h 13 | ) 14 | 15 | set_target_properties(AppCenterFlatpakPlugin PROPERTIES 16 | OUTPUT_NAME flatpak 17 | ) 18 | 19 | qt6_finalize_target(AppCenterFlatpakPlugin) 20 | 21 | target_compile_definitions(AppCenterFlatpakPlugin 22 | PRIVATE 23 | QT_NO_CAST_FROM_ASCII 24 | QT_NO_URL_CAST_FROM_STRING 25 | QT_NO_FOREACH 26 | QT_NO_KEYWORDS 27 | QT_NO_SIGNALS_SLOTS_KEYWORDS 28 | ) 29 | 30 | if(Flatpak_VERSION VERSION_LESS 1.1.2) 31 | target_compile_definitions(AppCenterFlatpakPlugin 32 | PRIVATE 33 | FLATPAK_EXTERNC_REQUIRED 34 | ) 35 | else() 36 | target_compile_definitions(AppCenterFlatpakPlugin 37 | PRIVATE 38 | FLATPAK_VERBOSE_PROGRESS 39 | FLATPAK_LIST_UNUSED_REFS 40 | ) 41 | endif() 42 | 43 | target_link_libraries(AppCenterFlatpakPlugin 44 | PRIVATE 45 | Qt6::Core 46 | Qt6::Concurrent 47 | Qt6::Network 48 | AppStreamQt 49 | PkgConfig::Flatpak 50 | Liri::AppCenter 51 | Liri::AppCenterPrivate 52 | ) 53 | 54 | install(TARGETS AppCenterFlatpakPlugin 55 | DESTINATION "${KDE_INSTALL_QTPLUGINDIR}/liri/appcenter/resources") 56 | 57 | install(FILES "io.liri.AppCenter.Flatpak.desktop" 58 | DESTINATION "${KDE_INSTALL_APPDIR}") 59 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpak.json: -------------------------------------------------------------------------------- 1 | { 2 | "Keys": [ "flatpak" ] 3 | } 4 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpakappstreamjob.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "flatpakappstreamjob.h" 6 | #include "flatpakplugin.h" 7 | 8 | FlatpakAppStreamJob::FlatpakAppStreamJob(FlatpakInstallation *installation, FlatpakRemote *remote, QObject *parent) 9 | : QThread(parent) 10 | , m_installation(installation) 11 | , m_remote(remote) 12 | , m_cancellable(g_cancellable_new()) 13 | { 14 | } 15 | 16 | FlatpakAppStreamJob::~FlatpakAppStreamJob() 17 | { 18 | g_object_unref(m_cancellable); 19 | } 20 | 21 | void FlatpakAppStreamJob::run() 22 | { 23 | g_autoptr(GError) error = nullptr; 24 | 25 | const char *name = flatpak_remote_get_name(m_remote); 26 | 27 | if (!flatpak_installation_update_remote_sync(m_installation, name, m_cancellable, &error)) { 28 | Q_EMIT failed(QString::fromUtf8(error->message)); 29 | return; 30 | } 31 | 32 | if (!flatpak_installation_update_appstream_full_sync(m_installation, name, nullptr, nullptr, nullptr, nullptr, m_cancellable, &error)) 33 | Q_EMIT failed(QString::fromUtf8(error->message)); 34 | else 35 | Q_EMIT succeeded(m_installation, m_remote); 36 | } 37 | 38 | void FlatpakAppStreamJob::cancel() 39 | { 40 | g_cancellable_cancel(m_cancellable); 41 | } 42 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpakappstreamjob.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_FLATPAKAPPSTREAMJOB_H 6 | #define LIRI_FLATPAKAPPSTREAMJOB_H 7 | 8 | #include 9 | 10 | #include "flatpakpluginbase.h" 11 | 12 | class FlatpakAppStreamJob : public QThread 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit FlatpakAppStreamJob(FlatpakInstallation *installation, 17 | FlatpakRemote *remote, 18 | QObject *parent = nullptr); 19 | ~FlatpakAppStreamJob(); 20 | 21 | void run() override; 22 | void cancel(); 23 | 24 | Q_SIGNALS: 25 | void succeeded(FlatpakInstallation *installation, FlatpakRemote *remote); 26 | void failed(const QString &errorMessage); 27 | 28 | private: 29 | FlatpakInstallation *m_installation = nullptr; 30 | FlatpakRemote *m_remote = nullptr; 31 | GCancellable *m_cancellable = nullptr; 32 | }; 33 | 34 | #endif // LIRI_FLATPAKAPPSTREAMJOB_H 35 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpakplugin.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "flatpakplugin.h" 6 | 7 | FlatpakPlugin::FlatpakPlugin(QObject *parent) 8 | : Liri::AppCenter::BackendPlugin(parent) 9 | { 10 | } 11 | 12 | Liri::AppCenter::Backend *FlatpakPlugin::create(Liri::AppCenter::SoftwareManager *manager) 13 | { 14 | return new FlatpakBackend(manager); 15 | } 16 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpakplugin.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_FLATPAKPLUGIN_H 6 | #define LIRI_FLATPAKPLUGIN_H 7 | 8 | #include 9 | 10 | #include "flatpakbackend.h" 11 | 12 | class FlatpakPlugin : public Liri::AppCenter::BackendPlugin 13 | { 14 | Q_OBJECT 15 | Q_PLUGIN_METADATA(IID BackendPlugin_iid FILE "flatpak.json") 16 | Q_INTERFACES(Liri::AppCenter::BackendPlugin) 17 | public: 18 | explicit FlatpakPlugin(QObject *parent = nullptr); 19 | 20 | Liri::AppCenter::Backend *create(Liri::AppCenter::SoftwareManager *manager) override; 21 | }; 22 | 23 | #endif // LIRI_FLATPAKPLUGIN_H 24 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpakpluginbase.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_FLATPAKPLUGINBASE_H 6 | #define LIRI_FLATPAKPLUGINBASE_H 7 | 8 | #undef signals 9 | 10 | #ifdef FLATPAK_EXTERNC_REQUIRED 11 | extern "C" { 12 | #endif 13 | #include 14 | #ifdef FLATPAK_EXTERNC_REQUIRED 15 | } 16 | #endif 17 | 18 | #include 19 | 20 | #endif // LIRI_FLATPAKPLUGINBASE_H 21 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpaksource.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_FLATPAKSOURCE_H 6 | #define LIRI_FLATPAKSOURCE_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include "flatpakpluginbase.h" 13 | 14 | class FlatpakSource : public Liri::AppCenter::SoftwareSource 15 | { 16 | Q_OBJECT 17 | public: 18 | explicit FlatpakSource(Liri::AppCenter::Backend *backend, 19 | FlatpakInstallation *installation, 20 | FlatpakRemote *remote, 21 | QObject *parent = nullptr); 22 | ~FlatpakSource(); 23 | 24 | QString name() const override; 25 | 26 | QString title() const override; 27 | void setTitle(const QString &value) override; 28 | 29 | QString comment() const override; 30 | void setComment(const QString &value) override; 31 | 32 | QString description() const override; 33 | void setDescription(const QString &value) override; 34 | 35 | QString section() const override; 36 | 37 | QString label() const override; 38 | 39 | bool isEnabled() const override; 40 | void setEnabled(bool value) override; 41 | 42 | bool gpgVerify() const override; 43 | void setGpgVerify(bool value) override; 44 | 45 | QUrl url() const override; 46 | void setUrl(const QUrl &value) override; 47 | 48 | QUrl iconUrl() const override; 49 | void setIconUrl(const QUrl &value) override; 50 | 51 | int priority() const override; 52 | void setPriority(int value) override; 53 | 54 | QVariantMap metadata() const override; 55 | 56 | FlatpakInstallation *installation() const; 57 | FlatpakRemote *remote() const; 58 | 59 | QDir appStreamDir() const; 60 | 61 | private: 62 | FlatpakInstallation *m_installation = nullptr; 63 | FlatpakRemote *m_remote = nullptr; 64 | GCancellable *m_cancellable = nullptr; 65 | QString m_name; 66 | bool m_isUser = false; 67 | QVariantMap m_metadata; 68 | }; 69 | 70 | #endif // LIRI_FLATPAKSOURCE_H 71 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpaktransaction.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "flatpaktransaction.h" 6 | 7 | using namespace Liri::AppCenter; 8 | 9 | LiriFlatpakTransaction::LiriFlatpakTransaction(Type type, const QString &name, 10 | const QString &description, 11 | SoftwareResource *resource, 12 | bool cancellable, 13 | QObject *parent) 14 | : Transaction(type, name, description, resource, cancellable, parent) 15 | , m_resource(qobject_cast(resource)) 16 | , m_job(new FlatpakTransactionJob(m_resource, this, cancellable)) 17 | { 18 | } 19 | 20 | void LiriFlatpakTransaction::run() 21 | { 22 | connect(m_job, &FlatpakTransactionJob::cancelled, this, [&] { 23 | setStatus(Transaction::Cancelled); 24 | }); 25 | connect(m_job, &FlatpakTransactionJob::succeeded, this, [&] { 26 | setStatus(Transaction::Succeeded); 27 | }); 28 | connect(m_job, &FlatpakTransactionJob::failed, this, [&](const QString &message) { 29 | setErrorMessage(message); 30 | setStatus(Transaction::Failed); 31 | }); 32 | m_job->start(); 33 | } 34 | 35 | void LiriFlatpakTransaction::cancel() 36 | { 37 | if (isCancellable()) 38 | m_job->cancel(); 39 | } 40 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpaktransaction.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_FLATPAKTRANSACTION_H 6 | #define LIRI_FLATPAKTRANSACTION_H 7 | 8 | #include 9 | 10 | #include "flatpakresource.h" 11 | #include "flatpaktransactionjob.h" 12 | 13 | class LiriFlatpakTransaction : public Liri::AppCenter::Transaction 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit LiriFlatpakTransaction(Liri::AppCenter::Transaction::Type type, 18 | const QString &name, 19 | const QString &description, 20 | Liri::AppCenter::SoftwareResource *resource, 21 | bool cancellable = true, 22 | QObject *parent = nullptr); 23 | 24 | Q_INVOKABLE void run() override; 25 | Q_INVOKABLE void cancel() override; 26 | 27 | private: 28 | FlatpakResource *m_resource = nullptr; 29 | FlatpakTransactionJob *m_job = nullptr; 30 | }; 31 | 32 | #endif // LIRI_FLATPAKTRANSACTION_H 33 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpaktransactionjob.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_FLATPAKTRANSACTIONJOB_H 6 | #define LIRI_FLATPAKTRANSACTIONJOB_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include "flatpakresource.h" 13 | 14 | class FlatpakTransactionJob : public QThread 15 | { 16 | Q_OBJECT 17 | Q_PROPERTY(Liri::AppCenter::SoftwareResource *resource READ resource CONSTANT) 18 | Q_PROPERTY(Liri::AppCenter::Transaction *transaction READ transaction CONSTANT) 19 | Q_PROPERTY(bool isCancellable READ isCancellable CONSTANT) 20 | public: 21 | explicit FlatpakTransactionJob(FlatpakResource *app, 22 | Liri::AppCenter::Transaction *transaction, 23 | bool cancellable = true, 24 | QObject *parent = nullptr); 25 | ~FlatpakTransactionJob(); 26 | 27 | Liri::AppCenter::SoftwareResource *resource() const; 28 | Liri::AppCenter::Transaction *transaction() const; 29 | bool isCancellable() const; 30 | 31 | void run() override; 32 | void cancel(); 33 | 34 | Q_SIGNALS: 35 | void succeeded(); 36 | void failed(const QString &message); 37 | void cancelled(); 38 | 39 | private: 40 | FlatpakResource *m_app = nullptr; 41 | Liri::AppCenter::Transaction *m_transaction = nullptr; 42 | GCancellable *m_cancellable = nullptr; 43 | int m_progress = 0; 44 | }; 45 | 46 | #endif // LIRI_FLATPAKTRANSACTIONJOB_H 47 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpakutils.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "flatpakbackend.h" 6 | #include "flatpakutils.h" 7 | 8 | QByteArray loadAppData(FlatpakInstalledRef *ref) 9 | { 10 | auto *name = flatpak_installed_ref_get_appdata_name(ref); 11 | 12 | g_autoptr(GCancellable) cancellable = g_cancellable_new(); 13 | g_autoptr(GError) error = nullptr; 14 | 15 | g_autoptr(GBytes) appstream_gz = flatpak_installed_ref_load_appdata(ref, cancellable, &error); 16 | if (!appstream_gz) { 17 | qCWarning(lcFlatpakBackend, "Failed to load appdata for \"%s\": %s", 18 | name, error->message); 19 | return QByteArray(); 20 | } 21 | g_autoptr(GZlibDecompressor) decompressor = 22 | g_zlib_decompressor_new(G_ZLIB_COMPRESSOR_FORMAT_GZIP); 23 | g_autoptr(GInputStream) stream_gz = 24 | g_memory_input_stream_new_from_bytes(appstream_gz); 25 | if (!stream_gz) { 26 | qCWarning(lcFlatpakBackend, "Failed to decommpress appdata for \"%s\": %s", 27 | name, error->message); 28 | return QByteArray(); 29 | } 30 | g_autoptr(GInputStream) stream_data = 31 | g_converter_input_stream_new(stream_gz, G_CONVERTER(decompressor)); 32 | g_autoptr(GBytes) appstream = 33 | g_input_stream_read_bytes(stream_data, 0x100000, cancellable, &error); 34 | if (!appstream) { 35 | qCWarning(lcFlatpakBackend, "Failed to read appdata for \"%s\": %s", 36 | name, error->message); 37 | return QByteArray(); 38 | } 39 | 40 | gsize size = 0; 41 | auto *data = g_bytes_get_data(appstream, &size); 42 | if (data) 43 | return QByteArray(static_cast(data), size); 44 | 45 | return QByteArray(); 46 | } 47 | -------------------------------------------------------------------------------- /src/plugins/flatpak/flatpakutils.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_FLATPAKUTILS_H 6 | #define LIRI_FLATPAKUTILS_H 7 | 8 | #include "flatpakpluginbase.h" 9 | 10 | QByteArray loadAppData(FlatpakInstalledRef *ref); 11 | 12 | #endif // LIRI_FLATPAKUTILS_H 13 | -------------------------------------------------------------------------------- /src/plugins/flatpak/internetcheck.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include 6 | #include 7 | 8 | #include "flatpakbackend.h" 9 | #include "internetcheck.h" 10 | 11 | InternetCheck::InternetCheck(QObject *parent) 12 | : QObject(parent) 13 | , m_manager(new QNetworkAccessManager(this)) 14 | { 15 | } 16 | 17 | bool InternetCheck::hasInternet() 18 | { 19 | if (syncGet(QUrl(QStringLiteral("http://google.com")))) 20 | return true; 21 | return false; 22 | } 23 | 24 | QNetworkReply *InternetCheck::asyncGet(const QUrl &url) 25 | { 26 | QNetworkRequest request(url); 27 | 28 | auto *reply = m_manager->get(request); 29 | if (reply->error()) { 30 | reply->deleteLater(); 31 | return reply; 32 | } 33 | 34 | auto *timer = new QTimer(reply); 35 | timer->setSingleShot(true); 36 | connect(timer, &QTimer::timeout, reply, &QNetworkReply::abort); 37 | timer->start(30000); 38 | 39 | return reply; 40 | } 41 | 42 | QNetworkReply *InternetCheck::syncGet(const QUrl &url) 43 | { 44 | auto *reply = asyncGet(url); 45 | if (!reply) 46 | return nullptr; 47 | 48 | QEventLoop loop; 49 | connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); 50 | loop.exec(); 51 | reply->deleteLater(); 52 | if (reply->isRunning()) { 53 | qCWarning(lcFlatpakBackend, "Timeout on request to %s", 54 | qPrintable(url.toString())); 55 | return nullptr; 56 | } else if (reply->error() != QNetworkReply::NoError) { 57 | qCWarning(lcFlatpakBackend, "Error on request to %s: %s", 58 | qPrintable(url.toString()), 59 | qPrintable(reply->errorString())); 60 | return nullptr; 61 | } 62 | 63 | return reply; 64 | } 65 | -------------------------------------------------------------------------------- /src/plugins/flatpak/internetcheck.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef INTERNETCHECK_H 6 | #define INTERNETCHECK_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | class InternetCheck : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit InternetCheck(QObject *parent = nullptr); 18 | 19 | bool hasInternet(); 20 | 21 | private: 22 | QNetworkAccessManager *m_manager = nullptr; 23 | 24 | QNetworkReply *asyncGet(const QUrl &url); 25 | QNetworkReply *syncGet(const QUrl &url); 26 | }; 27 | 28 | #endif // INTERNETCHECK_H 29 | -------------------------------------------------------------------------------- /src/plugins/flatpak/io.liri.AppCenter.Flatpak.desktop: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | [Desktop Entry] 6 | Name=Software Install 7 | Comment=Install the selected software on the system 8 | Exec=liri-appcenter --local-filename=%f 9 | Icon=software-store 10 | Terminal=false 11 | Type=Application 12 | Categories=X-Liri;Qt;System;PackageManager; 13 | StartupNotify=true 14 | NoDisplay=true 15 | MimeType=application/vnd.flatpak;application/vnd.flatpak.repo;application/vnd.flatpak.ref; 16 | -------------------------------------------------------------------------------- /src/plugins/odrs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT TARGET Liri::Qt6AccountsService) 2 | find_package(Qt6AccountsService REQUIRED) 3 | endif() 4 | if(NOT TARGET Liri::LocalDevice) 5 | find_package(Liri1LocalDevice REQUIRED) 6 | endif() 7 | 8 | qt6_add_plugin(AppCenterOdrsPlugin 9 | CLASS_NAME OdrsPlugin 10 | MANUAL_FINALIZATION 11 | odrsbackend.cpp odrsbackend.h 12 | odrsplugin.cpp odrsplugin.h 13 | odrsutils.cpp odrsutils.h 14 | ) 15 | 16 | set_target_properties(AppCenterOdrsPlugin PROPERTIES 17 | OUTPUT_NAME odrs 18 | ) 19 | 20 | qt6_finalize_target(AppCenterOdrsPlugin) 21 | 22 | target_link_libraries(AppCenterOdrsPlugin 23 | PRIVATE 24 | Qt6::Core 25 | Qt6::Network 26 | Liri::Qt6AccountsService 27 | Liri::LocalDevice 28 | Liri::AppCenter 29 | Liri::AppCenterPrivate 30 | ) 31 | 32 | install(TARGETS AppCenterOdrsPlugin 33 | DESTINATION "${KDE_INSTALL_QTPLUGINDIR}/liri/appcenter/reviews") 34 | -------------------------------------------------------------------------------- /src/plugins/odrs/odrs.json: -------------------------------------------------------------------------------- 1 | { 2 | "Keys": [ "odrs" ] 3 | } 4 | -------------------------------------------------------------------------------- /src/plugins/odrs/odrsbackend.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_ODRS_ODRSBACKEND_H 6 | #define LIRI_APPCENTER_ODRS_ODRSBACKEND_H 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | Q_DECLARE_LOGGING_CATEGORY(lcOdrsBackend) 14 | 15 | class QNetworkAccessManager; 16 | class QNetworkReply; 17 | 18 | namespace Liri { 19 | 20 | namespace AppCenter { 21 | 22 | class OdrsBackend : public ReviewsBackend 23 | { 24 | Q_OBJECT 25 | public: 26 | enum ReviewAction { 27 | SubmitReview = 0, 28 | ReportReview, 29 | UpVoteReview, 30 | DownVoteReview, 31 | DismissReview, 32 | RemoveReview 33 | }; 34 | Q_ENUM(ReviewAction) 35 | 36 | explicit OdrsBackend(SoftwareManager *manager, 37 | QObject *parent = nullptr); 38 | 39 | void fetchRatings() override; 40 | void fetchReviews(SoftwareResource *resource) override; 41 | 42 | QList ratings() const override; 43 | Rating *ratingForSofwareResource(SoftwareResource *resource) const override; 44 | 45 | QList reviews() const override; 46 | 47 | bool submitReview(SoftwareResource *resource, 48 | const QString &summary, 49 | const QString &description, 50 | int rating) override; 51 | void reportReview(Review *review) override; 52 | void upVoteReview(Review *review) override; 53 | void downVoteReview(Review *review) override; 54 | void dismissReview(Review *review) override; 55 | void removeReview(Review *review) override; 56 | 57 | private: 58 | CachedNetworkAccessManager *m_manager = nullptr; 59 | QHash m_ratings; 60 | QList m_reviews; 61 | 62 | void parseRatings(const QString &fileName); 63 | void postReview(ReviewAction action, Review *review); 64 | void parseReviews(const QJsonDocument &json, SoftwareResource *resource); 65 | }; 66 | 67 | } // namespace AppCenter 68 | 69 | } // namespace Liri 70 | 71 | #endif // LIRI_APPCENTER_ODRS_ODRSBACKEND_H 72 | -------------------------------------------------------------------------------- /src/plugins/odrs/odrsplugin.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include "odrsplugin.h" 6 | 7 | namespace Liri { 8 | 9 | namespace AppCenter { 10 | 11 | OdrsPlugin::OdrsPlugin(QObject *parent) 12 | : Liri::AppCenter::ReviewsBackendPlugin(parent) 13 | { 14 | } 15 | 16 | ReviewsBackend *OdrsPlugin::create(SoftwareManager *manager) 17 | { 18 | return new OdrsBackend(manager); 19 | } 20 | 21 | } // namespace AppCenter 22 | 23 | } // namespace Liri 24 | -------------------------------------------------------------------------------- /src/plugins/odrs/odrsplugin.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_ODRS_ODRSPLUGIN_H 6 | #define LIRI_APPCENTER_ODRS_ODRSPLUGIN_H 7 | 8 | #include 9 | 10 | #include "odrsbackend.h" 11 | 12 | namespace Liri { 13 | 14 | namespace AppCenter { 15 | 16 | class OdrsPlugin : public Liri::AppCenter::ReviewsBackendPlugin 17 | { 18 | Q_OBJECT 19 | Q_PLUGIN_METADATA(IID ReviewsBackendPlugin_iid FILE "odrs.json") 20 | Q_INTERFACES(Liri::AppCenter::ReviewsBackendPlugin) 21 | public: 22 | explicit OdrsPlugin(QObject *parent = nullptr); 23 | 24 | ReviewsBackend *create(SoftwareManager *manager) override; 25 | }; 26 | 27 | } // namespace AppCenter 28 | 29 | } // namespace Liri 30 | 31 | #endif // LIRI_APPCENTER_ODRS_ODRSPLUGIN_H 32 | -------------------------------------------------------------------------------- /src/plugins/odrs/odrsutils.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "odrsutils.h" 11 | 12 | namespace Liri { 13 | 14 | namespace AppCenter { 15 | 16 | QString getUserHash() 17 | { 18 | // Read machine-id 19 | QString machineId; 20 | QFile machineIdFile(QStringLiteral("/etc/machine-id")); 21 | if (machineIdFile.open(QFile::ReadOnly)) { 22 | machineId = QString::fromUtf8(machineIdFile.readAll()); 23 | machineIdFile.close(); 24 | } 25 | 26 | if (machineId.isEmpty()) 27 | return QString(); 28 | 29 | auto *account = new QtAccountsService::UserAccount(); 30 | QString salted = QStringLiteral("gnome-software[%1:%2]").arg(account->userName(), machineId); 31 | return QString::fromUtf8(QCryptographicHash::hash(salted.toUtf8(), QCryptographicHash::Sha1).toHex()); 32 | } 33 | 34 | } // namespace AppCenter 35 | 36 | } // namespace Liri 37 | -------------------------------------------------------------------------------- /src/plugins/odrs/odrsutils.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2020 Pier Luigi Fiorini 2 | // 3 | // SPDX-License-Identifier: LGPL-3.0-or-later 4 | 5 | #ifndef LIRI_APPCENTER_ODRS_ODRSUTILS_H 6 | #define LIRI_APPCENTER_ODRS_ODRSUTILS_H 7 | 8 | #include 9 | 10 | namespace Liri { 11 | 12 | namespace AppCenter { 13 | 14 | QString getUserHash(); 15 | 16 | } // namespace AppCenter 17 | 18 | } // namespace Liri 19 | 20 | 21 | #endif // LIRI_APPCENTER_ODRS_ODRSUTILS_H 22 | -------------------------------------------------------------------------------- /translations/data/desktop/ar.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Pier Luigi Fiorini , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2020-05-15 00:10+0000\n" 15 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 16 | "Last-Translator: Pier Luigi Fiorini , 2020\n" 17 | "Language-Team: Arabic (https://www.transifex.com/lirios/teams/71982/ar/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: ar\n" 22 | "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" 23 | 24 | #. (desktop-to-pot) Name 25 | #: io.liri.AppCenter.desktop.in:2 26 | msgid "App Center" 27 | msgstr "مركز التطبيقات" 28 | 29 | #. (desktop-to-pot) Comment 30 | #: io.liri.AppCenter.desktop.in:3 31 | msgid "App Center for Liri" 32 | msgstr "مركز تطبيقات ليري" 33 | -------------------------------------------------------------------------------- /translations/data/desktop/da.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # scootergrisen, 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 15 | "Last-Translator: scootergrisen, 2020\n" 16 | "Language-Team: Danish (https://www.transifex.com/lirios/teams/71982/da/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: da\n" 21 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Programcenter" 28 | 29 | #. (desktop-to-pot) "Comment" entry 30 | #: io.liri.AppCenter.desktop.in:7 31 | msgctxt "Comment entry" 32 | msgid "App Center for Liri" 33 | msgstr "Programcenter til Liri" 34 | -------------------------------------------------------------------------------- /translations/data/desktop/desktop.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "Language: \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #. (desktop-to-pot) "Name" entry 20 | #: io.liri.AppCenter.desktop.in:6 21 | msgctxt "Name entry" 22 | msgid "App Center" 23 | msgstr "" 24 | 25 | #. (desktop-to-pot) "Comment" entry 26 | #: io.liri.AppCenter.desktop.in:7 27 | msgctxt "Comment entry" 28 | msgid "App Center for Liri" 29 | msgstr "" 30 | -------------------------------------------------------------------------------- /translations/data/desktop/es_MX.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Wenceslao , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 15 | "Last-Translator: Wenceslao , 2020\n" 16 | "Language-Team: Spanish (Mexico) (https://www.transifex.com/lirios/teams/71982/es_MX/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: es_MX\n" 21 | "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Centro de aplicaciones" 28 | 29 | #. (desktop-to-pot) "Comment" entry 30 | #: io.liri.AppCenter.desktop.in:7 31 | msgctxt "Comment entry" 32 | msgid "App Center for Liri" 33 | msgstr "Centro de aplicaciones para Liri" 34 | -------------------------------------------------------------------------------- /translations/data/desktop/fr.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Pier Luigi Fiorini , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2020-05-15 00:10+0000\n" 15 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 16 | "Last-Translator: Pier Luigi Fiorini , 2020\n" 17 | "Language-Team: French (https://www.transifex.com/lirios/teams/71982/fr/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: fr\n" 22 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 23 | 24 | #. (desktop-to-pot) Name 25 | #: io.liri.AppCenter.desktop.in:2 26 | msgid "App Center" 27 | msgstr "Centre d'applications" 28 | 29 | #. (desktop-to-pot) Comment 30 | #: io.liri.AppCenter.desktop.in:3 31 | msgid "App Center for Liri" 32 | msgstr "Centre d'applications pour Liri" 33 | -------------------------------------------------------------------------------- /translations/data/desktop/id.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Pier Luigi Fiorini , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2020-05-15 00:10+0000\n" 15 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 16 | "Last-Translator: Pier Luigi Fiorini , 2020\n" 17 | "Language-Team: Indonesian (https://www.transifex.com/lirios/teams/71982/id/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: id\n" 22 | "Plural-Forms: nplurals=1; plural=0;\n" 23 | 24 | #. (desktop-to-pot) Name 25 | #: io.liri.AppCenter.desktop.in:2 26 | msgid "App Center" 27 | msgstr "Pusat Aplikasi" 28 | 29 | #. (desktop-to-pot) Comment 30 | #: io.liri.AppCenter.desktop.in:3 31 | msgid "App Center for Liri" 32 | msgstr "Pusat Aplikasi untuk Liri" 33 | -------------------------------------------------------------------------------- /translations/data/desktop/it_IT.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Man from Mars, 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 15 | "Last-Translator: Man from Mars, 2020\n" 16 | "Language-Team: Italian (Italy) (https://www.transifex.com/lirios/teams/71982/it_IT/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: it_IT\n" 21 | "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Centro App" 28 | 29 | #. (desktop-to-pot) "Comment" entry 30 | #: io.liri.AppCenter.desktop.in:7 31 | msgctxt "Comment entry" 32 | msgid "App Center for Liri" 33 | msgstr "Centro applicazioni per Liri" 34 | -------------------------------------------------------------------------------- /translations/data/desktop/ja.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Pier Luigi Fiorini , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2020-05-15 00:10+0000\n" 15 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 16 | "Last-Translator: Pier Luigi Fiorini , 2020\n" 17 | "Language-Team: Japanese (https://www.transifex.com/lirios/teams/71982/ja/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: ja\n" 22 | "Plural-Forms: nplurals=1; plural=0;\n" 23 | 24 | #. (desktop-to-pot) Name 25 | #: io.liri.AppCenter.desktop.in:2 26 | msgid "App Center" 27 | msgstr "App Center" 28 | 29 | #. (desktop-to-pot) Comment 30 | #: io.liri.AppCenter.desktop.in:3 31 | msgid "App Center for Liri" 32 | msgstr "App Center for Liri" 33 | -------------------------------------------------------------------------------- /translations/data/desktop/ko.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Seania Twix , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2020-05-15 00:10+0000\n" 15 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 16 | "Last-Translator: Seania Twix , 2020\n" 17 | "Language-Team: Korean (https://www.transifex.com/lirios/teams/71982/ko/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: ko\n" 22 | "Plural-Forms: nplurals=1; plural=0;\n" 23 | 24 | #. (desktop-to-pot) Name 25 | #: io.liri.AppCenter.desktop.in:2 26 | msgid "App Center" 27 | msgstr "앱 센터" 28 | 29 | #. (desktop-to-pot) Comment 30 | #: io.liri.AppCenter.desktop.in:3 31 | msgid "App Center for Liri" 32 | msgstr "Liri 앱 센터" 33 | -------------------------------------------------------------------------------- /translations/data/desktop/lt.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Moo, 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 15 | "Last-Translator: Moo, 2020\n" 16 | "Language-Team: Lithuanian (https://www.transifex.com/lirios/teams/71982/lt/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: lt\n" 21 | "Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Programų centras" 28 | 29 | #. (desktop-to-pot) "Comment" entry 30 | #: io.liri.AppCenter.desktop.in:7 31 | msgctxt "Comment entry" 32 | msgid "App Center for Liri" 33 | msgstr "Liri programų centras" 34 | -------------------------------------------------------------------------------- /translations/data/desktop/nl.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Heimen Stoffels , 2022 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 15 | "Last-Translator: Heimen Stoffels , 2022\n" 16 | "Language-Team: Dutch (https://www.transifex.com/lirios/teams/71982/nl/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: nl\n" 21 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Softwarecentrum" 28 | 29 | #. (desktop-to-pot) "Comment" entry 30 | #: io.liri.AppCenter.desktop.in:7 31 | msgctxt "Comment entry" 32 | msgid "App Center for Liri" 33 | msgstr "Softwarecentrum voor Liri" 34 | -------------------------------------------------------------------------------- /translations/data/desktop/notifier/da.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # scootergrisen, 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-08-18 16:37+0000\n" 15 | "Last-Translator: scootergrisen, 2020\n" 16 | "Language-Team: Danish (https://www.transifex.com/lirios/teams/71982/da/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: da\n" 21 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.Notifier.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Programcenter" 28 | -------------------------------------------------------------------------------- /translations/data/desktop/notifier/desktop.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12 | "Last-Translator: FULL NAME \n" 13 | "Language-Team: LANGUAGE \n" 14 | "Language: \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #. (desktop-to-pot) "Name" entry 20 | #: io.liri.AppCenter.Notifier.desktop.in:6 21 | msgctxt "Name entry" 22 | msgid "App Center" 23 | msgstr "" 24 | -------------------------------------------------------------------------------- /translations/data/desktop/notifier/es_MX.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Wenceslao , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-08-18 16:37+0000\n" 15 | "Last-Translator: Wenceslao , 2020\n" 16 | "Language-Team: Spanish (Mexico) (https://www.transifex.com/lirios/teams/71982/es_MX/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: es_MX\n" 21 | "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.Notifier.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Centro de aplicaciones" 28 | -------------------------------------------------------------------------------- /translations/data/desktop/notifier/lt.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Moo, 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-08-18 16:37+0000\n" 15 | "Last-Translator: Moo, 2020\n" 16 | "Language-Team: Lithuanian (https://www.transifex.com/lirios/teams/71982/lt/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: lt\n" 21 | "Plural-Forms: nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.Notifier.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Programų centras" 28 | -------------------------------------------------------------------------------- /translations/data/desktop/notifier/nl.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Heimen Stoffels , 2022 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-08-18 16:37+0000\n" 15 | "Last-Translator: Heimen Stoffels , 2022\n" 16 | "Language-Team: Dutch (https://www.transifex.com/lirios/teams/71982/nl/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: nl\n" 21 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.Notifier.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Softwarecentrum" 28 | -------------------------------------------------------------------------------- /translations/data/desktop/notifier/pt_BR.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Luiz Fernando Ranghetti , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-08-18 16:37+0000\n" 15 | "Last-Translator: Luiz Fernando Ranghetti , 2020\n" 16 | "Language-Team: Portuguese (Brazil) (https://www.transifex.com/lirios/teams/71982/pt_BR/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: pt_BR\n" 21 | "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.Notifier.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Central de aplicativos" 28 | -------------------------------------------------------------------------------- /translations/data/desktop/notifier/ru.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Irina Fedulova , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-08-18 16:37+0000\n" 15 | "Last-Translator: Irina Fedulova , 2020\n" 16 | "Language-Team: Russian (https://www.transifex.com/lirios/teams/71982/ru/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: ru\n" 21 | "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.Notifier.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "App Center" 28 | -------------------------------------------------------------------------------- /translations/data/desktop/notifier/tr.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Emin Tufan Çetin , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-08-18 16:37+0000\n" 15 | "Last-Translator: Emin Tufan Çetin , 2020\n" 16 | "Language-Team: Turkish (https://www.transifex.com/lirios/teams/71982/tr/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: tr\n" 21 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.Notifier.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Uygulama Merkezi" 28 | -------------------------------------------------------------------------------- /translations/data/desktop/pl.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Pier Luigi Fiorini , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2020-05-15 00:10+0000\n" 15 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 16 | "Last-Translator: Pier Luigi Fiorini , 2020\n" 17 | "Language-Team: Polish (https://www.transifex.com/lirios/teams/71982/pl/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: pl\n" 22 | "Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" 23 | 24 | #. (desktop-to-pot) Name 25 | #: io.liri.AppCenter.desktop.in:2 26 | msgid "App Center" 27 | msgstr "Centrum Aplikacji" 28 | 29 | #. (desktop-to-pot) Comment 30 | #: io.liri.AppCenter.desktop.in:3 31 | msgid "App Center for Liri" 32 | msgstr "Centrum Aplikacji dla Liri" 33 | -------------------------------------------------------------------------------- /translations/data/desktop/pt_BR.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Luiz Fernando Ranghetti , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 15 | "Last-Translator: Luiz Fernando Ranghetti , 2020\n" 16 | "Language-Team: Portuguese (Brazil) (https://www.transifex.com/lirios/teams/71982/pt_BR/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: pt_BR\n" 21 | "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Central de aplicativos" 28 | 29 | #. (desktop-to-pot) "Comment" entry 30 | #: io.liri.AppCenter.desktop.in:7 31 | msgctxt "Comment entry" 32 | msgid "App Center for Liri" 33 | msgstr "Central de aplicativos para o Liri" 34 | -------------------------------------------------------------------------------- /translations/data/desktop/ru.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Irina Fedulova , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 15 | "Last-Translator: Irina Fedulova , 2020\n" 16 | "Language-Team: Russian (https://www.transifex.com/lirios/teams/71982/ru/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: ru\n" 21 | "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Центр приложений" 28 | 29 | #. (desktop-to-pot) "Comment" entry 30 | #: io.liri.AppCenter.desktop.in:7 31 | msgctxt "Comment entry" 32 | msgid "App Center for Liri" 33 | msgstr "Центр приложений для Liri" 34 | -------------------------------------------------------------------------------- /translations/data/desktop/tr.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Emin Tufan Çetin , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 15 | "Last-Translator: Emin Tufan Çetin , 2020\n" 16 | "Language-Team: Turkish (https://www.transifex.com/lirios/teams/71982/tr/)\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Language: tr\n" 21 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 22 | 23 | #. (desktop-to-pot) "Name" entry 24 | #: io.liri.AppCenter.desktop.in:6 25 | msgctxt "Name entry" 26 | msgid "App Center" 27 | msgstr "Uygulama Merkezi" 28 | 29 | #. (desktop-to-pot) "Comment" entry 30 | #: io.liri.AppCenter.desktop.in:7 31 | msgctxt "Comment entry" 32 | msgid "App Center for Liri" 33 | msgstr "Liri için Uygulama Merkezi" 34 | -------------------------------------------------------------------------------- /translations/data/desktop/zh_CN.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Pier Luigi Fiorini , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2020-05-15 00:10+0000\n" 15 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 16 | "Last-Translator: Pier Luigi Fiorini , 2020\n" 17 | "Language-Team: Chinese (China) (https://www.transifex.com/lirios/teams/71982/zh_CN/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: zh_CN\n" 22 | "Plural-Forms: nplurals=1; plural=0;\n" 23 | 24 | #. (desktop-to-pot) Name 25 | #: io.liri.AppCenter.desktop.in:2 26 | msgid "App Center" 27 | msgstr "应用中心" 28 | 29 | #. (desktop-to-pot) Comment 30 | #: io.liri.AppCenter.desktop.in:3 31 | msgid "App Center for Liri" 32 | msgstr "Liri应用中心" 33 | -------------------------------------------------------------------------------- /translations/data/desktop/zh_TW.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | # Translators: 7 | # Pier Luigi Fiorini , 2020 8 | # 9 | #, fuzzy 10 | msgid "" 11 | msgstr "" 12 | "Project-Id-Version: PACKAGE VERSION\n" 13 | "Report-Msgid-Bugs-To: \n" 14 | "POT-Creation-Date: 2020-05-15 00:10+0000\n" 15 | "PO-Revision-Date: 2020-05-09 13:10+0000\n" 16 | "Last-Translator: Pier Luigi Fiorini , 2020\n" 17 | "Language-Team: Chinese (Taiwan) (https://www.transifex.com/lirios/teams/71982/zh_TW/)\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Language: zh_TW\n" 22 | "Plural-Forms: nplurals=1; plural=0;\n" 23 | 24 | #. (desktop-to-pot) Name 25 | #: io.liri.AppCenter.desktop.in:2 26 | msgid "App Center" 27 | msgstr "應用程式中心" 28 | 29 | #. (desktop-to-pot) Comment 30 | #: io.liri.AppCenter.desktop.in:3 31 | msgid "App Center for Liri" 32 | msgstr "Liri應用程式中心" 33 | -------------------------------------------------------------------------------- /translations/data/metainfo/da.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators: 3 | # scootergrisen, 2020 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "PO-Revision-Date: 2020-05-09 13:24+0000\n" 9 | "Last-Translator: scootergrisen, 2020\n" 10 | "Language-Team: Danish (https://www.transifex.com/lirios/teams/71982/da/)\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | "Language: da\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 16 | 17 | #. (itstool) path: component/name 18 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 19 | msgid "App Center" 20 | msgstr "Programcenter" 21 | 22 | #. (itstool) path: component/summary 23 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 24 | msgid "Application manager for Liri OS" 25 | msgstr "Programhåndtering til Liri OS" 26 | 27 | #. (itstool) path: description/p 28 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 29 | msgid "App Center allows you to find and install new applications." 30 | msgstr "" 31 | "Programcenter giver dig mulighed for at finde og installere nye programmer." 32 | -------------------------------------------------------------------------------- /translations/data/metainfo/es_MX.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators: 3 | # Wenceslao , 2020 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "PO-Revision-Date: 2020-05-09 13:24+0000\n" 9 | "Last-Translator: Wenceslao , 2020\n" 10 | "Language-Team: Spanish (Mexico) (https://www.transifex.com/lirios/teams/71982/es_MX/)\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | "Language: es_MX\n" 15 | "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 16 | 17 | #. (itstool) path: component/name 18 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 19 | msgid "App Center" 20 | msgstr "Centro de aplicaciones" 21 | 22 | #. (itstool) path: component/summary 23 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 24 | msgid "Application manager for Liri OS" 25 | msgstr "Administrador de aplicaciones para Liri OS" 26 | 27 | #. (itstool) path: description/p 28 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 29 | msgid "App Center allows you to find and install new applications." 30 | msgstr "" 31 | "Centro de aplicaciones le permite buscar e instalar nuevas aplicaciones." 32 | -------------------------------------------------------------------------------- /translations/data/metainfo/it_IT.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators: 3 | # Man from Mars, 2020 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "PO-Revision-Date: 2020-05-09 13:24+0000\n" 9 | "Last-Translator: Man from Mars, 2020\n" 10 | "Language-Team: Italian (Italy) (https://www.transifex.com/lirios/teams/71982/it_IT/)\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | "Language: it_IT\n" 15 | "Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 16 | 17 | #. (itstool) path: component/name 18 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 19 | msgid "App Center" 20 | msgstr "Centro App" 21 | 22 | #. (itstool) path: component/summary 23 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 24 | msgid "Application manager for Liri OS" 25 | msgstr "Gestore applicazioni per Liri OS" 26 | 27 | #. (itstool) path: description/p 28 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 29 | msgid "App Center allows you to find and install new applications." 30 | msgstr "" 31 | "Il Centro App ti permette di trovare ed installare nuove applicazioni." 32 | -------------------------------------------------------------------------------- /translations/data/metainfo/ko.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators: 3 | # Seania Twix , 2020 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "PO-Revision-Date: 2020-05-09 13:24+0000\n" 9 | "Last-Translator: Seania Twix , 2020\n" 10 | "Language-Team: Korean (https://www.transifex.com/lirios/teams/71982/ko/)\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | "Language: ko\n" 15 | "Plural-Forms: nplurals=1; plural=0;\n" 16 | 17 | #. (itstool) path: component/name 18 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 19 | msgid "App Center" 20 | msgstr "앱 센터" 21 | 22 | #. (itstool) path: component/summary 23 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 24 | msgid "Application manager for Liri OS" 25 | msgstr "Liri OS 어플리케이션 관리자" 26 | 27 | #. (itstool) path: description/p 28 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 29 | msgid "App Center allows you to find and install new applications." 30 | msgstr "앱 센터는 사용자가 새로운 어플리케이션을 찾고 설치할 수 있도록 해줍니다." 31 | -------------------------------------------------------------------------------- /translations/data/metainfo/metainfo.pot: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: PACKAGE VERSION\n" 4 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 5 | "Last-Translator: FULL NAME \n" 6 | "Language-Team: LANGUAGE \n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | 11 | #. (itstool) path: component/name 12 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 13 | msgid "App Center" 14 | msgstr "" 15 | 16 | #. (itstool) path: component/summary 17 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 18 | msgid "Application manager for Liri OS" 19 | msgstr "" 20 | 21 | #. (itstool) path: description/p 22 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 23 | msgid "App Center allows you to find and install new applications." 24 | msgstr "" 25 | 26 | -------------------------------------------------------------------------------- /translations/data/metainfo/nl.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators: 3 | # Heimen Stoffels , 2022 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "PO-Revision-Date: 2020-05-09 13:24+0000\n" 9 | "Last-Translator: Heimen Stoffels , 2022\n" 10 | "Language-Team: Dutch (https://www.transifex.com/lirios/teams/71982/nl/)\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | "Language: nl\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 16 | 17 | #. (itstool) path: component/name 18 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 19 | msgid "App Center" 20 | msgstr "Softwarecentrum" 21 | 22 | #. (itstool) path: component/summary 23 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 24 | msgid "Application manager for Liri OS" 25 | msgstr "Softwarecentrum voor Liri OS" 26 | 27 | #. (itstool) path: description/p 28 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 29 | msgid "App Center allows you to find and install new applications." 30 | msgstr "Met het softwarecentrum kunt je programma's installeren en updaten." 31 | -------------------------------------------------------------------------------- /translations/data/metainfo/pt_BR.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators: 3 | # Luiz Fernando Ranghetti , 2020 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "PO-Revision-Date: 2020-05-09 13:24+0000\n" 9 | "Last-Translator: Luiz Fernando Ranghetti , 2020\n" 10 | "Language-Team: Portuguese (Brazil) (https://www.transifex.com/lirios/teams/71982/pt_BR/)\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | "Language: pt_BR\n" 15 | "Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" 16 | 17 | #. (itstool) path: component/name 18 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 19 | msgid "App Center" 20 | msgstr "Central de aplicativos" 21 | 22 | #. (itstool) path: component/summary 23 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 24 | msgid "Application manager for Liri OS" 25 | msgstr "Gerenciador de aplicativos para o Liri OS" 26 | 27 | #. (itstool) path: description/p 28 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 29 | msgid "App Center allows you to find and install new applications." 30 | msgstr "" 31 | "A central de aplicativos permite a você encontrar e instalar novos " 32 | "aplicativos." 33 | -------------------------------------------------------------------------------- /translations/data/metainfo/ru.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators: 3 | # Irina Fedulova , 2020 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "PO-Revision-Date: 2020-05-09 13:24+0000\n" 9 | "Last-Translator: Irina Fedulova , 2020\n" 10 | "Language-Team: Russian (https://www.transifex.com/lirios/teams/71982/ru/)\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | "Language: ru\n" 15 | "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" 16 | 17 | #. (itstool) path: component/name 18 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 19 | msgid "App Center" 20 | msgstr "Центр приложений" 21 | 22 | #. (itstool) path: component/summary 23 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 24 | msgid "Application manager for Liri OS" 25 | msgstr "Менеджер приложений для Liri ОС" 26 | 27 | #. (itstool) path: description/p 28 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 29 | msgid "App Center allows you to find and install new applications." 30 | msgstr "Центр приложений позволяет вам найти и установить новые приложения." 31 | -------------------------------------------------------------------------------- /translations/data/metainfo/tr.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators: 3 | # Emin Tufan Çetin , 2020 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "PO-Revision-Date: 2020-05-09 13:24+0000\n" 9 | "Last-Translator: Emin Tufan Çetin , 2020\n" 10 | "Language-Team: Turkish (https://www.transifex.com/lirios/teams/71982/tr/)\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | "Language: tr\n" 15 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 16 | 17 | #. (itstool) path: component/name 18 | #: src/app/io.liri.AppCenter.appdata.xml.in:11 19 | msgid "App Center" 20 | msgstr "Uygulama Merkezi" 21 | 22 | #. (itstool) path: component/summary 23 | #: src/app/io.liri.AppCenter.appdata.xml.in:12 24 | msgid "Application manager for Liri OS" 25 | msgstr "Liri OS için uygulama yönetici" 26 | 27 | #. (itstool) path: description/p 28 | #: src/app/io.liri.AppCenter.appdata.xml.in:14 29 | msgid "App Center allows you to find and install new applications." 30 | msgstr "Uygulama Merkezi yeni uygulamalar bulmanızı ve kurmanızı sağlar." 31 | -------------------------------------------------------------------------------- /translations/notifier.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UpdateNotifier 6 | 7 | 8 | Updates available 9 | 10 | 11 | 12 | 13 | 14 | Install updates 15 | 16 | 17 | 18 | 19 | Not now 20 | 21 | 22 | 23 | 24 | No updates are available 25 | 26 | 27 | 28 | 29 | %1 is ready to update 30 | 31 | 32 | 33 | 34 | %1 and %2 are ready to update 35 | 36 | 37 | 38 | 39 | %1, %2, and one other app are ready to update 40 | 41 | 42 | 43 | 44 | %1, %2, and %3 other apps are ready to update 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /translations/notifier/notifier.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UpdateNotifier 6 | 7 | 8 | Updates available 9 | 10 | 11 | 12 | 13 | Install updates 14 | 15 | 16 | 17 | 18 | No updates are available 19 | 20 | 21 | 22 | 23 | %1 is ready to update 24 | 25 | 26 | 27 | 28 | %1 and %2 are ready to update 29 | 30 | 31 | 32 | 33 | %1, %2, and one other app are ready to update 34 | 35 | 36 | 37 | 38 | %1, %2, and %3 other apps are ready to update 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /translations/notifier/notifier_ar.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | يتوفر تحديثات 8 | 9 | 10 | 11 | Install updates 12 | ثبّت التحديثات 13 | 14 | 15 | 16 | No updates are available 17 | لا يوجد تحديثات متاحة 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 جاهز للتحديث 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 و %2 مستعدان للتحديث 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1 و 2% و تطبيق أخر مستعدون للتحديث 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | 1% و 2% و 3% تطبيقات أخرى مستعدة للتحديث 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_da.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Der findes opdateringer 8 | 9 | 10 | 11 | Install updates 12 | Installer opdateringer 13 | 14 | 15 | 16 | No updates are available 17 | Der findes ikke nogen opdateringer 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 er klar til opdatering 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 og %2 er klar til opdatering 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2 og ét andet program er klar til opdatering 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2 og %3 og andre programmer er klar til opdatering 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_es_MX.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Actualizaciones disponibles 8 | 9 | 10 | 11 | Install updates 12 | Instalar actualizaciones 13 | 14 | 15 | 16 | No updates are available 17 | No hay actualizaciones disponibles 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 esta listo para actualizarse 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 y %2 están listo para actualizarse 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2 y otra aplicación están listas para actualizarse 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2 y %3 otras aplicaciones están listas para actualizarse 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_fr.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Mises à jour disponibles 8 | 9 | 10 | 11 | Install updates 12 | Installer les mises à jour 13 | 14 | 15 | 16 | No updates are available 17 | Aucune mise à jour disponible 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 est prêt pour la mise à jour 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 et %2 sont prêts pour la mise à jour 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2, et une autre application sont prêts pour la mise à jour 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2 et %3 autres applications sont prêts pour la mise à jour 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_id.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Pembaruan tersedia 8 | 9 | 10 | 11 | Install updates 12 | Pasang pembaruan 13 | 14 | 15 | 16 | No updates are available 17 | Tidak ada pembaruan tersedia 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 siap untuk diperbarui 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 dan %2 siap untuk diperbarui 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2, dan satu aplikasi lainnya siap untuk diperbarui 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2, dan %3 aplikasi lainnya siap untuk diperbarui 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_it_IT.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Aggiornamenti disponibili 8 | 9 | 10 | 11 | Install updates 12 | Installa aggiornamenti 13 | 14 | 15 | 16 | No updates are available 17 | Nessun aggiornamento disponibile 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 è pronto per l'aggiornamento 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 e %2 sono pronti per l'aggiornamento 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2 e un'altra applicazione sono pronte per l'aggiornamento 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2 e %3 altre applicazioni sono pronte per l'aggiornamento 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_ja.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | アップデートを利用できます 8 | 9 | 10 | 11 | Install updates 12 | アップデートする 13 | 14 | 15 | 16 | No updates are available 17 | 最新の状態です 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 はアップデート可能 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 と %2 はアップデート可能 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1 、 %2 とあと1個のアプリがアップデート可能 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1 、 %2 、 %3 などのアプリがアップデート可能 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_ko.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | 업데이트 가능 8 | 9 | 10 | 11 | Install updates 12 | 업데이트 모두 설치 13 | 14 | 15 | 16 | No updates are available 17 | 가능한 업데이트 없음 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 업데이트 대기 중 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1과 %2이 업데이트 대기 중 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2, 그 외 하나의 앱이 업데이트 대기 중 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2, 그리고 %3 외 앱이 업데이트 대기 중 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_lt.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Yra prieinami atnaujinimai 8 | 9 | 10 | 11 | Install updates 12 | Įdiegti atnaujinimus 13 | 14 | 15 | 16 | No updates are available 17 | Nėra prieinamų atnaujinimų 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 yra paruošta atnaujinimui 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 ir %2 yra paruoštos atnaujinimui 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2 ir dar viena programa yra paruoštos atnaujinimui 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2, ir dar %3 programos yra paruoštos atnaujinimui 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_nl.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Er zijn updates beschikbaar 8 | 9 | 10 | 11 | Install updates 12 | Updates installeren 13 | 14 | 15 | 16 | No updates are available 17 | Er zijn geen updates beschikbaar 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 kan worden geüpdatet 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 en %2 kunnen worden geüpdatet 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2 en een ander programma kunnen worden geüpdatet 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2 en %3 andere programma's kunnen worden geüpdatet 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_pl.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Aktualizacje są dostępne 8 | 9 | 10 | 11 | Install updates 12 | Zainstaluj aktualizacje 13 | 14 | 15 | 16 | No updates are available 17 | Brak dostępnych aktualizacji. 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 jest gotowy do aktualizacji 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 i %2 są gotowe do aktualizacji 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2, i inna aplikacja są gotowe do aktualizacji 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2, i %3 innych aplikacji jest gotowych do aktualizacji 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_pt_BR.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Atualizações disponíveis 8 | 9 | 10 | 11 | Install updates 12 | Instalar atualizações 13 | 14 | 15 | 16 | No updates are available 17 | Nenhuma atualização disponível 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 está pronto para atualizar 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 e %2 estão prontos para atualizar 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2 e um outro aplicativo estão prontos para atualizar 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2 e %3 outros aplicativos estão prontos para atualizar 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_ru.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Обновления доступны 8 | 9 | 10 | 11 | Install updates 12 | Установить обновления 13 | 14 | 15 | 16 | No updates are available 17 | Нет доступных обновлений 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 готово к обновлению 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 и %2 готовы к обновлению 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2 и еще одно приложение готовы к обновлению 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2, и %3 других приложений готовы к обновлению 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_tr.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | Güncellemeler var 8 | 9 | 10 | 11 | Install updates 12 | Güncellemeleri kur 13 | 14 | 15 | 16 | No updates are available 17 | Güncelleme yok 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1 güncellemeye hazır 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 ve %2 güncellemeye hazır 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2 ve diğer bir uygulama güncellemeye hazır 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2 ve diğer %3 uygulama güncellemeye hazır 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_zh_CN.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | 有可用更新 8 | 9 | 10 | 11 | Install updates 12 | 安装更新 13 | 14 | 15 | 16 | No updates are available 17 | 无可用更新 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1更新准备就绪 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1和%2更新准备就绪 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1,%2和另一个应用更新准备就绪 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1,%2和%3以及其他应用更新准备就绪 38 | 39 | 40 | -------------------------------------------------------------------------------- /translations/notifier/notifier_zh_TW.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | UpdateNotifier 4 | 5 | 6 | Updates available 7 | 有可用的更新 8 | 9 | 10 | 11 | Install updates 12 | 安裝更新 13 | 14 | 15 | 16 | No updates are available 17 | 已更新至最新 18 | 19 | 20 | 21 | %1 is ready to update 22 | %1已經可以更新 23 | 24 | 25 | 26 | %1 and %2 are ready to update 27 | %1 及%2 更新已就緒 28 | 29 | 30 | 31 | %1, %2, and one other app are ready to update 32 | %1, %2和另外一個應用已經可以進行更新 33 | 34 | 35 | 36 | %1, %2, and %3 other apps are ready to update 37 | %1, %2, %3和另外一個應用已經可以進行更新 38 | 39 | 40 | --------------------------------------------------------------------------------