From 4951ff9dbafaf48722a183ae426e2401b31c1745 Mon Sep 17 00:00:00 2001 From: Maximiliano Curia Date: Fri, 30 Dec 2016 17:46:21 +0000 Subject: [PATCH 1/1] Import plasma-discover_5.8.5.orig.tar.xz [dgit import orig plasma-discover_5.8.5.orig.tar.xz] --- .arcconfig | 4 + .reviewboardrc | 4 + CMakeLists.txt | 86 + CMakeLists.txt.user | 999 +++ COPYING | 676 ++ COPYING.GFDL | 397 ++ COPYING.LIB | 502 ++ DiscoverVersion.h.in | 27 + Messages.sh | 8 + TODO | 10 + cmake/FindPackageKitQt2.cmake | 57 + cmake/FindQtOAuth.cmake | 58 + discover/CMakeLists.txt | 37 + discover/DiscoverMainWindow.cpp | 376 + discover/DiscoverMainWindow.h | 107 + discover/IconColors.cpp | 100 + discover/IconColors.h | 50 + discover/PaginateModel.cpp | 393 ++ discover/PaginateModel.h | 120 + discover/SystemFonts.cpp | 56 + discover/SystemFonts.h | 47 + discover/UnityLauncher.cpp | 84 + discover/UnityLauncher.h | 56 + discover/autotests/CMakeLists.txt | 14 + discover/autotests/DiscoverTest.qml | 106 + discover/autotests/IconColorsTest.cpp | 70 + discover/autotests/PaginateModelTest.cpp | 129 + discover/autotests/appstreamUrl.qml | 12 + discover/autotests/categoryArg.qml | 12 + discover/autotests/install.qml | 45 + discover/autotests/missingResource.qml | 10 + discover/autotests/packageArgument.qml | 12 + discover/autotests/toplevels.qml | 83 + discover/autotests/wrongInput.qml | 8 + discover/featured.json | 17 + discover/icons/128-apps-plasmadiscover.png | Bin 0 -> 18930 bytes discover/icons/16-apps-plasmadiscover.png | Bin 0 -> 798 bytes discover/icons/22-apps-plasmadiscover.png | Bin 0 -> 1221 bytes discover/icons/32-apps-plasmadiscover.png | Bin 0 -> 2045 bytes discover/icons/48-apps-plasmadiscover.png | Bin 0 -> 3466 bytes discover/icons/CMakeLists.txt | 11 + discover/icons/banner.svg | 194 + discover/icons/installedcrop.jpg | Bin 0 -> 448647 bytes discover/icons/sc-apps-plasmadiscover.svgz | Bin 0 -> 240726 bytes discover/icons/updatescrop.jpg | Bin 0 -> 271389 bytes discover/main.cpp | 149 + discover/org.kde.discover.appdata.xml | 161 + discover/org.kde.discover.desktop | 115 + discover/plasmadiscoverui.rc | 10 + discover/qml/ActionBridge.qml | 39 + discover/qml/AddSourceDialog.qml | 55 + discover/qml/AddonsView.qml | 97 + discover/qml/ApplicationDelegate.qml | 124 + discover/qml/ApplicationHeader.qml | 50 + discover/qml/ApplicationIndicator.qml | 33 + discover/qml/ApplicationPage.qml | 202 + discover/qml/ApplicationScreenshots.qml | 75 + discover/qml/ApplicationsListPage.qml | 91 + discover/qml/ApplicationsTop.qml | 65 + discover/qml/AwesomeGrid.qml | 64 + discover/qml/Breadcrumbs.qml | 62 + discover/qml/BrowsingPage.qml | 57 + discover/qml/CategoryBreadcrumbs.qml | 60 + discover/qml/CategoryDisplay.qml | 39 + discover/qml/ConditionalLoader.qml | 32 + discover/qml/DefaultBanner.qml | 33 + discover/qml/DiscoverDrawer.qml | 217 + discover/qml/DiscoverPage.qml | 74 + discover/qml/DiscoverSystemPalette.qml | 5 + discover/qml/DiscoverWindow.qml | 208 + discover/qml/FeaturedBanner.qml | 144 + discover/qml/FeaturedImage.qml | 56 + discover/qml/FeaturedModel.qml | 84 + discover/qml/Heading.qml | 6 + discover/qml/Helpers.qml | 16 + discover/qml/Information.qml | 34 + discover/qml/InstallApplicationButton.qml | 71 + discover/qml/InstalledPage.qml | 26 + discover/qml/JustMessageAction.qml | 13 + discover/qml/LabelBackground.qml | 56 + discover/qml/LinkButton.qml | 29 + discover/qml/Main.qml | 34 + discover/qml/MessageAction.qml | 56 + discover/qml/PageHeader.qml | 156 + discover/qml/ProgressView.qml | 107 + discover/qml/Rating.qml | 66 + discover/qml/ReviewDelegate.qml | 89 + discover/qml/ReviewDialog.qml | 49 + discover/qml/ReviewsPage.qml | 58 + discover/qml/SourcesPage.qml | 163 + discover/qml/TopLevelPageData.qml | 35 + discover/qml/UpdatesPage.qml | 253 + discover/qml/navigation.js | 63 + discover/resources.qrc | 52 + exporter/CMakeLists.txt | 5 + exporter/MuonExporter.cpp | 102 + exporter/MuonExporter.h | 49 + exporter/main.cpp | 61 + libdiscover/ApplicationAddonsModel.cpp | 153 + libdiscover/ApplicationAddonsModel.h | 73 + libdiscover/CMakeLists.txt | 61 + libdiscover/Category/CategoriesReader.cpp | 96 + libdiscover/Category/CategoriesReader.h | 40 + libdiscover/Category/Category.cpp | 229 + libdiscover/Category/Category.h | 90 + libdiscover/Category/CategoryModel.cpp | 161 + libdiscover/Category/CategoryModel.h | 66 + libdiscover/DiscoverBackendsFactory.cpp | 132 + libdiscover/DiscoverBackendsFactory.h | 47 + libdiscover/MessageActionsModel.cpp | 79 + libdiscover/MessageActionsModel.h | 50 + libdiscover/MuonDataSources.kcfgc | 6 + .../ReviewsBackend/AbstractLoginBackend.cpp | 25 + .../ReviewsBackend/AbstractLoginBackend.h | 48 + .../ReviewsBackend/AbstractReviewsBackend.cpp | 35 + .../ReviewsBackend/AbstractReviewsBackend.h | 64 + libdiscover/ReviewsBackend/PopConParser.cpp | 56 + libdiscover/ReviewsBackend/PopConParser.h | 35 + libdiscover/ReviewsBackend/Rating.cpp | 163 + libdiscover/ReviewsBackend/Rating.h | 58 + libdiscover/ReviewsBackend/Review.cpp | 128 + libdiscover/ReviewsBackend/Review.h | 77 + libdiscover/ReviewsBackend/ReviewsModel.cpp | 186 + libdiscover/ReviewsBackend/ReviewsModel.h | 88 + libdiscover/ScreenshotsModel.cpp | 100 + libdiscover/ScreenshotsModel.h | 62 + libdiscover/Transaction/AddonList.cpp | 72 + libdiscover/Transaction/AddonList.h | 54 + libdiscover/Transaction/Transaction.cpp | 100 + libdiscover/Transaction/Transaction.h | 167 + .../Transaction/TransactionListener.cpp | 173 + libdiscover/Transaction/TransactionListener.h | 74 + libdiscover/Transaction/TransactionModel.cpp | 212 + libdiscover/Transaction/TransactionModel.h | 82 + libdiscover/UpdateModel/UpdateItem.cpp | 93 + libdiscover/UpdateModel/UpdateItem.h | 67 + libdiscover/UpdateModel/UpdateModel.cpp | 287 + libdiscover/UpdateModel/UpdateModel.h | 97 + .../ApplicationBackend/Application.cpp | 546 ++ .../backends/ApplicationBackend/Application.h | 114 + .../ApplicationBackend/ApplicationBackend.cpp | 676 ++ .../ApplicationBackend/ApplicationBackend.h | 128 + .../ApplicationNotifier.cpp | 172 + .../ApplicationBackend/ApplicationNotifier.h | 60 + .../ApplicationBackend/ApplicationUpdates.cpp | 467 ++ .../ApplicationBackend/ApplicationUpdates.h | 97 + .../ApplicationBackend/AptSourcesBackend.cpp | 244 + .../ApplicationBackend/AptSourcesBackend.h | 60 + .../ApplicationBackend/CMakeLists.txt | 53 + .../ApplicationBackend/ReviewsBackend.cpp | 411 ++ .../ApplicationBackend/ReviewsBackend.h | 105 + .../ApplicationBackend/UbuntuLoginBackend.cpp | 147 + .../ApplicationBackend/UbuntuLoginBackend.h | 57 + .../distupgradeevent/releasechecker | 46 + .../libmuonapt/AddRepositoryHelper.cpp | 41 + .../libmuonapt/AddRepositoryHelper.h | 15 + .../libmuonapt/CMakeLists.txt | 26 + .../libmuonapt/ChangesDialog.cpp | 118 + .../libmuonapt/ChangesDialog.h | 45 + .../HistoryView/HistoryProxyModel.cpp | 85 + .../HistoryView/HistoryProxyModel.h | 52 + .../libmuonapt/HistoryView/HistoryView.cpp | 238 + .../libmuonapt/HistoryView/HistoryView.h | 79 + .../libmuonapt/MuonStrings.cpp | 167 + .../libmuonapt/MuonStrings.h | 56 + .../libmuonapt/QAptActions.cpp | 537 ++ .../libmuonapt/QAptActions.h | 110 + .../policies/org.kde.muon.repo.action | 5 + .../muonapplicationnotifier.notifyrc | 112 + .../qapt-backend-categories.xml | 559 ++ .../ApplicationBackend/qapt-backend.desktop | 114 + .../ApplicationBackend/qoauth/CMakeLists.txt | 5 + .../qoauth/src/interface.cpp | 1084 +++ .../ApplicationBackend/qoauth/src/interface.h | 119 + .../qoauth/src/interface_p.h | 127 + .../qoauth/src/qoauth_global.h | 39 + .../qoauth/src/qoauth_namespace.h | 180 + .../tests/ApplicationBackendTest.cpp | 154 + .../tests/ApplicationBackendTest.h | 45 + .../ApplicationBackend/tests/CMakeLists.txt | 13 + .../ApplicationBackend/tests/NotifierTest.cpp | 41 + .../ApplicationBackend/tests/NotifierTest.h | 37 + .../ApplicationBackend/tests/ReviewsTest.cpp | 90 + .../ApplicationBackend/tests/ReviewsTest.h | 52 + .../ApplicationBackend/tests/SourcesTest.cpp | 101 + .../ApplicationBackend/tests/SourcesTest.h | 48 + .../tests/popcontestratings.txt | Bin 0 -> 111487 bytes .../tests/rnrtestratings.txt | 6253 +++++++++++++++++ .../ubuntu_sso_dbus_interface.xml | 73 + libdiscover/backends/CMakeLists.txt | 30 + .../backends/DummyBackend/CMakeLists.txt | 22 + .../backends/DummyBackend/DummyBackend.cpp | 189 + .../backends/DummyBackend/DummyBackend.h | 68 + .../backends/DummyBackend/DummyNotifier.cpp | 53 + .../backends/DummyBackend/DummyNotifier.h | 40 + .../backends/DummyBackend/DummyResource.cpp | 185 + .../backends/DummyBackend/DummyResource.h | 70 + .../DummyBackend/DummyReviewsBackend.cpp | 74 + .../DummyBackend/DummyReviewsBackend.h | 58 + .../DummyBackend/DummySourcesBackend.cpp | 68 + .../DummyBackend/DummySourcesBackend.h | 44 + .../DummyBackend/DummyTransaction.cpp | 78 + .../backends/DummyBackend/DummyTransaction.h | 45 + .../DummyBackend/dummy-backend-categories.xml | 86 + .../DummyBackend/dummy-backend.desktop | 114 + .../DummyBackend/tests/CMakeLists.txt | 6 + .../backends/DummyBackend/tests/DummyTest.cpp | 229 + .../backends/DummyBackend/tests/DummyTest.h | 52 + .../DummyBackend/tests/UpdateDummyTest.cpp | 127 + .../backends/KNSBackend/CMakeLists.txt | 34 + .../backends/KNSBackend/KNSBackend.cpp | 222 + libdiscover/backends/KNSBackend/KNSBackend.h | 85 + .../backends/KNSBackend/KNSResource.cpp | 180 + libdiscover/backends/KNSBackend/KNSResource.h | 67 + .../backends/KNSBackend/KNSReviews.cpp | 182 + libdiscover/backends/KNSBackend/KNSReviews.h | 65 + ...scover_ktexteditor_codesnippets_core.knsrc | 29 + .../knscomic-backend-categories.xml | 23 + .../KNSBackend/knscomic-backend.desktop | 6 + ...r_codesnippets_core-backend-categories.xml | 23 + .../KNSBackend/knsintegrate/CMakeLists.txt | 2 + .../backends/KNSBackend/knsintegrate/main.cpp | 102 + ...r_codesnippets_core-backend-categories.xml | 22 + .../knsplasmoids-backend-categories.xml | 23 + .../backends/KNSBackend/tests/CMakeLists.txt | 11 + .../KNSBackend/tests/KNSBackendTest.cpp | 119 + .../KNSBackend/tests/KNSBackendTest.h | 50 + .../tests/knscorrect-backend.desktop | 42 + .../KNSBackend/tests/knswrong-backend.desktop | 42 + .../KNSBackend/tests/testplasmoids.knsrc | 6 + .../AppPackageKitResource.cpp | 274 + .../PackageKitBackend/AppPackageKitResource.h | 61 + .../PackageKitBackend/AppstreamReviews.cpp | 93 + .../PackageKitBackend/AppstreamReviews.h | 63 + .../backends/PackageKitBackend/CMakeLists.txt | 36 + .../PackageKitBackend/PKTransaction.cpp | 229 + .../PackageKitBackend/PKTransaction.h | 61 + .../PackageKitBackend/PackageKitBackend.cpp | 561 ++ .../PackageKitBackend/PackageKitBackend.h | 134 + .../PackageKitBackend/PackageKitMessages.cpp | 333 + .../PackageKitBackend/PackageKitMessages.h | 36 + .../PackageKitBackend/PackageKitNotifier.cpp | 108 + .../PackageKitBackend/PackageKitNotifier.h | 59 + .../PackageKitBackend/PackageKitResource.cpp | 255 + .../PackageKitBackend/PackageKitResource.h | 99 + .../PackageKitSourcesBackend.cpp | 141 + .../PackageKitSourcesBackend.h | 55 + .../PackageKitBackend/PackageKitUpdater.cpp | 360 + .../PackageKitBackend/PackageKitUpdater.h | 104 + .../categoryimages/CMakeLists.txt | 18 + .../categoryimages/accesscropped.jpg | Bin 0 -> 804054 bytes .../categoryimages/accessoriescrop.jpg | Bin 0 -> 624453 bytes .../categoryimages/applicationcrop.jpg | Bin 0 -> 632885 bytes .../categoryimages/educationcrop.jpg | Bin 0 -> 508333 bytes .../categoryimages/fontcrop.jpg | Bin 0 -> 585769 bytes .../categoryimages/gamecrop.jpg | Bin 0 -> 346065 bytes .../categoryimages/graphiccrop.jpg | Bin 0 -> 539565 bytes .../categoryimages/internetcrop.jpg | Bin 0 -> 683718 bytes .../categoryimages/multimediacrop.jpg | Bin 0 -> 537927 bytes .../categoryimages/musiccrop.jpg | Bin 0 -> 512699 bytes .../categoryimages/officecrop.jpg | Bin 0 -> 448787 bytes .../categoryimages/sciencecrop.jpg | Bin 0 -> 722011 bytes .../categoryimages/settingscrop.jpg | Bin 0 -> 494345 bytes .../categoryimages/toolcrop.jpg | Bin 0 -> 438013 bytes .../PackageKitBackend/config-paths.h.cmake | 1 + .../packagekit-backend-categories.xml | 502 ++ .../packagekit-backend.desktop | 112 + .../runservice/CMakeLists.txt | 3 + .../PackageKitBackend/runservice/main.cpp | 43 + .../ApplicationProxyModelHelper.cpp | 78 + .../declarative/ApplicationProxyModelHelper.h | 59 + libdiscover/declarative/CMakeLists.txt | 8 + .../declarative/DiscoverDeclarativePlugin.cpp | 75 + .../declarative/DiscoverDeclarativePlugin.h | 34 + libdiscover/declarative/qmldir | 3 + libdiscover/muondatasources.kcfg | 12 + .../notifiers/BackendNotifierModule.cpp | 29 + libdiscover/notifiers/BackendNotifierModule.h | 56 + libdiscover/notifiers/CMakeLists.txt | 12 + .../resources/AbstractBackendUpdater.cpp | 39 + .../resources/AbstractBackendUpdater.h | 209 + libdiscover/resources/AbstractKDEDModule.cpp | 0 libdiscover/resources/AbstractKDEDModule.h | 0 libdiscover/resources/AbstractResource.cpp | 225 + libdiscover/resources/AbstractResource.h | 206 + .../resources/AbstractResourcesBackend.cpp | 53 + .../resources/AbstractResourcesBackend.h | 240 + .../resources/AbstractSourcesBackend.cpp | 27 + .../resources/AbstractSourcesBackend.h | 52 + libdiscover/resources/PackageState.cpp | 57 + libdiscover/resources/PackageState.h | 52 + libdiscover/resources/ResourcesModel.cpp | 476 ++ libdiscover/resources/ResourcesModel.h | 131 + libdiscover/resources/ResourcesProxyModel.cpp | 292 + libdiscover/resources/ResourcesProxyModel.h | 114 + .../resources/ResourcesUpdatesModel.cpp | 266 + libdiscover/resources/ResourcesUpdatesModel.h | 95 + libdiscover/resources/SourcesModel.cpp | 91 + libdiscover/resources/SourcesModel.h | 60 + .../resources/StandardBackendUpdater.cpp | 223 + .../resources/StandardBackendUpdater.h | 78 + .../discoverabstractnotifier.notifyrc | 112 + libdiscover/tests/CMakeLists.txt | 2 + libdiscover/tests/CategoriesTest.cpp | 69 + libdiscover/tests/PopConParserTest.cpp | 60 + libdiscover/tests/modeltest.cpp | 552 ++ libdiscover/tests/modeltest.h | 94 + libdiscover/utils.h | 35 + notifier/BackendNotifierFactory.cpp | 51 + notifier/BackendNotifierFactory.h | 37 + notifier/CMakeLists.txt | 21 + notifier/DiscoverNotifier.cpp | 189 + notifier/DiscoverNotifier.h | 81 + .../DiscoverNotifierDeclarativePlugin.cpp | 28 + notifier/DiscoverNotifierDeclarativePlugin.h | 33 + notifier/plasmoid/Messages.sh | 2 + notifier/plasmoid/contents/ui/Full.qml | 62 + notifier/plasmoid/contents/ui/main.qml | 47 + notifier/plasmoid/metadata.desktop | 96 + notifier/qmldir | 3 + po/ar/libdiscover.po | 2672 +++++++ po/ar/plasma-discover-notifier.po | 100 + po/ar/plasma-discover.po | 483 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/ast/libdiscover.po | 2130 ++++++ po/ast/plasma-discover-notifier.po | 80 + po/ast/plasma-discover.po | 480 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/bg/libdiscover.po | 2260 ++++++ po/bs/libdiscover.po | 2209 ++++++ po/bs/plasma-discover.po | 475 ++ .../plasma_applet_org.kde.discovernotifier.po | 36 + po/ca/libdiscover.po | 2200 ++++++ po/ca/plasma-discover-notifier.po | 83 + po/ca/plasma-discover.po | 458 ++ .../plasma_applet_org.kde.discovernotifier.po | 36 + po/ca@valencia/libdiscover.po | 2200 ++++++ po/ca@valencia/plasma-discover-notifier.po | 83 + po/ca@valencia/plasma-discover.po | 458 ++ .../plasma_applet_org.kde.discovernotifier.po | 36 + po/cs/libdiscover.po | 2171 ++++++ po/cs/plasma-discover-notifier.po | 84 + po/cs/plasma-discover.po | 452 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/da/libdiscover.po | 2184 ++++++ po/da/plasma-discover-notifier.po | 80 + po/da/plasma-discover.po | 453 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/de/libdiscover.po | 2203 ++++++ po/de/plasma-discover-notifier.po | 78 + po/de/plasma-discover.po | 461 ++ .../plasma_applet_org.kde.discovernotifier.po | 30 + po/el/libdiscover.po | 2201 ++++++ po/el/plasma-discover-notifier.po | 80 + po/el/plasma-discover.po | 461 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/en_GB/libdiscover.po | 2191 ++++++ po/en_GB/plasma-discover-notifier.po | 80 + po/en_GB/plasma-discover.po | 452 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/es/libdiscover.po | 2201 ++++++ po/es/plasma-discover-notifier.po | 82 + po/es/plasma-discover.po | 459 ++ .../plasma_applet_org.kde.discovernotifier.po | 35 + po/et/libdiscover.po | 2186 ++++++ po/et/plasma-discover-notifier.po | 80 + po/et/plasma-discover.po | 461 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/fi/libdiscover.po | 2628 +++++++ po/fi/plasma-discover-notifier.po | 80 + po/fi/plasma-discover.po | 587 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/fr/libdiscover.po | 2201 ++++++ po/fr/plasma-discover-notifier.po | 84 + po/fr/plasma-discover.po | 465 ++ .../plasma_applet_org.kde.discovernotifier.po | 36 + po/ga/libdiscover.po | 2266 ++++++ po/ga/plasma-discover.po | 466 ++ po/gl/libdiscover.po | 2201 ++++++ po/gl/plasma-discover-notifier.po | 81 + po/gl/plasma-discover.po | 485 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/he/libdiscover.po | 2133 ++++++ po/he/plasma-discover-notifier.po | 80 + po/he/plasma-discover.po | 468 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/hu/libdiscover.po | 2207 ++++++ po/hu/plasma-discover-notifier.po | 84 + po/hu/plasma-discover.po | 481 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/ia/plasma-discover.po | 459 ++ po/id/libdiscover.po | 2187 ++++++ po/id/plasma-discover.po | 480 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/it/libdiscover.po | 2191 ++++++ po/it/plasma-discover-notifier.po | 81 + po/it/plasma-discover.po | 457 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/ja/libdiscover.po | 2127 ++++++ po/ja/plasma-discover-notifier.po | 77 + po/ja/plasma-discover.po | 447 ++ .../plasma_applet_org.kde.discovernotifier.po | 30 + po/kk/libdiscover.po | 2271 ++++++ po/kk/plasma-discover.po | 479 ++ po/ko/libdiscover.po | 2167 ++++++ po/ko/plasma-discover-notifier.po | 76 + po/ko/plasma-discover.po | 455 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/lt/libdiscover.po | 2271 ++++++ po/lt/plasma-discover-notifier.po | 93 + po/lt/plasma-discover.po | 485 ++ .../plasma_applet_org.kde.discovernotifier.po | 36 + po/mr/libdiscover.po | 2247 ++++++ po/mr/plasma-discover.po | 478 ++ po/nb/libdiscover.po | 2186 ++++++ po/nb/plasma-discover-notifier.po | 82 + po/nb/plasma-discover.po | 452 ++ po/nds/libdiscover.po | 2405 +++++++ po/nds/plasma-discover.po | 481 ++ po/nl/libdiscover.po | 2196 ++++++ po/nl/plasma-discover-notifier.po | 80 + po/nl/plasma-discover.po | 457 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/nn/libdiscover.po | 2186 ++++++ po/nn/plasma-discover-notifier.po | 83 + po/nn/plasma-discover.po | 455 ++ .../plasma_applet_org.kde.discovernotifier.po | 35 + po/pa/libdiscover.po | 2246 ++++++ po/pa/plasma-discover-notifier.po | 80 + po/pa/plasma-discover.po | 471 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/pl/libdiscover.po | 2201 ++++++ po/pl/plasma-discover-notifier.po | 85 + po/pl/plasma-discover.po | 459 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/pt/libdiscover.po | 2198 ++++++ po/pt/plasma-discover-notifier.po | 80 + po/pt/plasma-discover.po | 461 ++ .../plasma_applet_org.kde.discovernotifier.po | 28 + po/pt_BR/libdiscover.po | 2194 ++++++ po/pt_BR/plasma-discover-notifier.po | 81 + po/pt_BR/plasma-discover.po | 483 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/ro/libdiscover.po | 2267 ++++++ po/ro/plasma-discover-notifier.po | 89 + po/ro/plasma-discover.po | 480 ++ .../plasma_applet_org.kde.discovernotifier.po | 35 + po/ru/libdiscover.po | 2209 ++++++ po/ru/plasma-discover-notifier.po | 89 + po/ru/plasma-discover.po | 558 ++ .../plasma_applet_org.kde.discovernotifier.po | 36 + po/sk/libdiscover.po | 2191 ++++++ po/sk/plasma-discover-notifier.po | 82 + po/sk/plasma-discover.po | 454 ++ .../plasma_applet_org.kde.discovernotifier.po | 31 + po/sl/libdiscover.po | 2202 ++++++ po/sl/plasma-discover-notifier.po | 89 + po/sl/plasma-discover.po | 455 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/sr/libdiscover.po | 2219 ++++++ po/sr/plasma-discover-notifier.po | 89 + po/sr/plasma-discover.po | 459 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/sr@ijekavian/libdiscover.po | 2219 ++++++ po/sr@ijekavian/plasma-discover-notifier.po | 89 + po/sr@ijekavian/plasma-discover.po | 459 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/sr@ijekavianlatin/libdiscover.po | 2220 ++++++ .../plasma-discover-notifier.po | 89 + po/sr@ijekavianlatin/plasma-discover.po | 459 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/sr@latin/libdiscover.po | 2220 ++++++ po/sr@latin/plasma-discover-notifier.po | 89 + po/sr@latin/plasma-discover.po | 459 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/sv/libdiscover.po | 2187 ++++++ po/sv/plasma-discover-notifier.po | 80 + po/sv/plasma-discover.po | 453 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/tr/libdiscover.po | 2201 ++++++ po/tr/plasma-discover.po | 483 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + po/ug/libdiscover.po | 2219 ++++++ po/ug/plasma-discover.po | 469 ++ po/uk/libdiscover.po | 2215 ++++++ po/uk/plasma-discover-notifier.po | 91 + po/uk/plasma-discover.po | 461 ++ .../plasma_applet_org.kde.discovernotifier.po | 36 + po/vi/libdiscover.po | 2334 ++++++ po/vi/plasma-discover.po | 472 ++ po/zh_CN/libdiscover.po | 2158 ++++++ po/zh_CN/plasma-discover-notifier.po | 76 + po/zh_CN/plasma-discover.po | 456 ++ .../plasma_applet_org.kde.discovernotifier.po | 34 + po/zh_TW/libdiscover.po | 2155 ++++++ po/zh_TW/plasma-discover-notifier.po | 77 + po/zh_TW/plasma-discover.po | 455 ++ .../plasma_applet_org.kde.discovernotifier.po | 33 + 498 files changed, 175510 insertions(+) create mode 100644 .arcconfig create mode 100644 .reviewboardrc create mode 100644 CMakeLists.txt create mode 100644 CMakeLists.txt.user create mode 100644 COPYING create mode 100644 COPYING.GFDL create mode 100644 COPYING.LIB create mode 100644 DiscoverVersion.h.in create mode 100644 Messages.sh create mode 100644 TODO create mode 100644 cmake/FindPackageKitQt2.cmake create mode 100644 cmake/FindQtOAuth.cmake create mode 100644 discover/CMakeLists.txt create mode 100644 discover/DiscoverMainWindow.cpp create mode 100644 discover/DiscoverMainWindow.h create mode 100644 discover/IconColors.cpp create mode 100644 discover/IconColors.h create mode 100644 discover/PaginateModel.cpp create mode 100644 discover/PaginateModel.h create mode 100644 discover/SystemFonts.cpp create mode 100644 discover/SystemFonts.h create mode 100644 discover/UnityLauncher.cpp create mode 100644 discover/UnityLauncher.h create mode 100644 discover/autotests/CMakeLists.txt create mode 100644 discover/autotests/DiscoverTest.qml create mode 100644 discover/autotests/IconColorsTest.cpp create mode 100644 discover/autotests/PaginateModelTest.cpp create mode 100644 discover/autotests/appstreamUrl.qml create mode 100644 discover/autotests/categoryArg.qml create mode 100644 discover/autotests/install.qml create mode 100644 discover/autotests/missingResource.qml create mode 100644 discover/autotests/packageArgument.qml create mode 100644 discover/autotests/toplevels.qml create mode 100644 discover/autotests/wrongInput.qml create mode 100644 discover/featured.json create mode 100644 discover/icons/128-apps-plasmadiscover.png create mode 100644 discover/icons/16-apps-plasmadiscover.png create mode 100644 discover/icons/22-apps-plasmadiscover.png create mode 100644 discover/icons/32-apps-plasmadiscover.png create mode 100644 discover/icons/48-apps-plasmadiscover.png create mode 100644 discover/icons/CMakeLists.txt create mode 100644 discover/icons/banner.svg create mode 100644 discover/icons/installedcrop.jpg create mode 100644 discover/icons/sc-apps-plasmadiscover.svgz create mode 100644 discover/icons/updatescrop.jpg create mode 100644 discover/main.cpp create mode 100644 discover/org.kde.discover.appdata.xml create mode 100644 discover/org.kde.discover.desktop create mode 100644 discover/plasmadiscoverui.rc create mode 100644 discover/qml/ActionBridge.qml create mode 100644 discover/qml/AddSourceDialog.qml create mode 100644 discover/qml/AddonsView.qml create mode 100644 discover/qml/ApplicationDelegate.qml create mode 100644 discover/qml/ApplicationHeader.qml create mode 100644 discover/qml/ApplicationIndicator.qml create mode 100644 discover/qml/ApplicationPage.qml create mode 100644 discover/qml/ApplicationScreenshots.qml create mode 100644 discover/qml/ApplicationsListPage.qml create mode 100644 discover/qml/ApplicationsTop.qml create mode 100644 discover/qml/AwesomeGrid.qml create mode 100644 discover/qml/Breadcrumbs.qml create mode 100644 discover/qml/BrowsingPage.qml create mode 100644 discover/qml/CategoryBreadcrumbs.qml create mode 100644 discover/qml/CategoryDisplay.qml create mode 100644 discover/qml/ConditionalLoader.qml create mode 100644 discover/qml/DefaultBanner.qml create mode 100644 discover/qml/DiscoverDrawer.qml create mode 100644 discover/qml/DiscoverPage.qml create mode 100644 discover/qml/DiscoverSystemPalette.qml create mode 100644 discover/qml/DiscoverWindow.qml create mode 100644 discover/qml/FeaturedBanner.qml create mode 100644 discover/qml/FeaturedImage.qml create mode 100644 discover/qml/FeaturedModel.qml create mode 100644 discover/qml/Heading.qml create mode 100644 discover/qml/Helpers.qml create mode 100644 discover/qml/Information.qml create mode 100644 discover/qml/InstallApplicationButton.qml create mode 100644 discover/qml/InstalledPage.qml create mode 100644 discover/qml/JustMessageAction.qml create mode 100644 discover/qml/LabelBackground.qml create mode 100644 discover/qml/LinkButton.qml create mode 100644 discover/qml/Main.qml create mode 100644 discover/qml/MessageAction.qml create mode 100644 discover/qml/PageHeader.qml create mode 100644 discover/qml/ProgressView.qml create mode 100644 discover/qml/Rating.qml create mode 100644 discover/qml/ReviewDelegate.qml create mode 100644 discover/qml/ReviewDialog.qml create mode 100644 discover/qml/ReviewsPage.qml create mode 100644 discover/qml/SourcesPage.qml create mode 100644 discover/qml/TopLevelPageData.qml create mode 100644 discover/qml/UpdatesPage.qml create mode 100644 discover/qml/navigation.js create mode 100644 discover/resources.qrc create mode 100644 exporter/CMakeLists.txt create mode 100644 exporter/MuonExporter.cpp create mode 100644 exporter/MuonExporter.h create mode 100644 exporter/main.cpp create mode 100644 libdiscover/ApplicationAddonsModel.cpp create mode 100644 libdiscover/ApplicationAddonsModel.h create mode 100644 libdiscover/CMakeLists.txt create mode 100644 libdiscover/Category/CategoriesReader.cpp create mode 100644 libdiscover/Category/CategoriesReader.h create mode 100644 libdiscover/Category/Category.cpp create mode 100644 libdiscover/Category/Category.h create mode 100644 libdiscover/Category/CategoryModel.cpp create mode 100644 libdiscover/Category/CategoryModel.h create mode 100644 libdiscover/DiscoverBackendsFactory.cpp create mode 100644 libdiscover/DiscoverBackendsFactory.h create mode 100644 libdiscover/MessageActionsModel.cpp create mode 100644 libdiscover/MessageActionsModel.h create mode 100644 libdiscover/MuonDataSources.kcfgc create mode 100644 libdiscover/ReviewsBackend/AbstractLoginBackend.cpp create mode 100644 libdiscover/ReviewsBackend/AbstractLoginBackend.h create mode 100644 libdiscover/ReviewsBackend/AbstractReviewsBackend.cpp create mode 100644 libdiscover/ReviewsBackend/AbstractReviewsBackend.h create mode 100644 libdiscover/ReviewsBackend/PopConParser.cpp create mode 100644 libdiscover/ReviewsBackend/PopConParser.h create mode 100644 libdiscover/ReviewsBackend/Rating.cpp create mode 100644 libdiscover/ReviewsBackend/Rating.h create mode 100644 libdiscover/ReviewsBackend/Review.cpp create mode 100644 libdiscover/ReviewsBackend/Review.h create mode 100644 libdiscover/ReviewsBackend/ReviewsModel.cpp create mode 100644 libdiscover/ReviewsBackend/ReviewsModel.h create mode 100644 libdiscover/ScreenshotsModel.cpp create mode 100644 libdiscover/ScreenshotsModel.h create mode 100644 libdiscover/Transaction/AddonList.cpp create mode 100644 libdiscover/Transaction/AddonList.h create mode 100644 libdiscover/Transaction/Transaction.cpp create mode 100644 libdiscover/Transaction/Transaction.h create mode 100644 libdiscover/Transaction/TransactionListener.cpp create mode 100644 libdiscover/Transaction/TransactionListener.h create mode 100644 libdiscover/Transaction/TransactionModel.cpp create mode 100644 libdiscover/Transaction/TransactionModel.h create mode 100644 libdiscover/UpdateModel/UpdateItem.cpp create mode 100644 libdiscover/UpdateModel/UpdateItem.h create mode 100644 libdiscover/UpdateModel/UpdateModel.cpp create mode 100644 libdiscover/UpdateModel/UpdateModel.h create mode 100644 libdiscover/backends/ApplicationBackend/Application.cpp create mode 100644 libdiscover/backends/ApplicationBackend/Application.h create mode 100644 libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp create mode 100644 libdiscover/backends/ApplicationBackend/ApplicationBackend.h create mode 100644 libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp create mode 100644 libdiscover/backends/ApplicationBackend/ApplicationNotifier.h create mode 100644 libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp create mode 100644 libdiscover/backends/ApplicationBackend/ApplicationUpdates.h create mode 100644 libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp create mode 100644 libdiscover/backends/ApplicationBackend/AptSourcesBackend.h create mode 100644 libdiscover/backends/ApplicationBackend/CMakeLists.txt create mode 100644 libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp create mode 100644 libdiscover/backends/ApplicationBackend/ReviewsBackend.h create mode 100644 libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp create mode 100644 libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h create mode 100644 libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h create mode 100644 libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action create mode 100644 libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc create mode 100644 libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml create mode 100644 libdiscover/backends/ApplicationBackend/qapt-backend.desktop create mode 100644 libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt create mode 100644 libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp create mode 100644 libdiscover/backends/ApplicationBackend/qoauth/src/interface.h create mode 100644 libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h create mode 100644 libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h create mode 100644 libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h create mode 100644 libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp create mode 100644 libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h create mode 100644 libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt create mode 100644 libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp create mode 100644 libdiscover/backends/ApplicationBackend/tests/NotifierTest.h create mode 100644 libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp create mode 100644 libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h create mode 100644 libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp create mode 100644 libdiscover/backends/ApplicationBackend/tests/SourcesTest.h create mode 100644 libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt create mode 100644 libdiscover/backends/ApplicationBackend/tests/rnrtestratings.txt create mode 100644 libdiscover/backends/ApplicationBackend/ubuntu_sso_dbus_interface.xml create mode 100644 libdiscover/backends/CMakeLists.txt create mode 100644 libdiscover/backends/DummyBackend/CMakeLists.txt create mode 100644 libdiscover/backends/DummyBackend/DummyBackend.cpp create mode 100644 libdiscover/backends/DummyBackend/DummyBackend.h create mode 100644 libdiscover/backends/DummyBackend/DummyNotifier.cpp create mode 100644 libdiscover/backends/DummyBackend/DummyNotifier.h create mode 100644 libdiscover/backends/DummyBackend/DummyResource.cpp create mode 100644 libdiscover/backends/DummyBackend/DummyResource.h create mode 100644 libdiscover/backends/DummyBackend/DummyReviewsBackend.cpp create mode 100644 libdiscover/backends/DummyBackend/DummyReviewsBackend.h create mode 100644 libdiscover/backends/DummyBackend/DummySourcesBackend.cpp create mode 100644 libdiscover/backends/DummyBackend/DummySourcesBackend.h create mode 100644 libdiscover/backends/DummyBackend/DummyTransaction.cpp create mode 100644 libdiscover/backends/DummyBackend/DummyTransaction.h create mode 100644 libdiscover/backends/DummyBackend/dummy-backend-categories.xml create mode 100644 libdiscover/backends/DummyBackend/dummy-backend.desktop create mode 100644 libdiscover/backends/DummyBackend/tests/CMakeLists.txt create mode 100644 libdiscover/backends/DummyBackend/tests/DummyTest.cpp create mode 100644 libdiscover/backends/DummyBackend/tests/DummyTest.h create mode 100644 libdiscover/backends/DummyBackend/tests/UpdateDummyTest.cpp create mode 100644 libdiscover/backends/KNSBackend/CMakeLists.txt create mode 100644 libdiscover/backends/KNSBackend/KNSBackend.cpp create mode 100644 libdiscover/backends/KNSBackend/KNSBackend.h create mode 100644 libdiscover/backends/KNSBackend/KNSResource.cpp create mode 100644 libdiscover/backends/KNSBackend/KNSResource.h create mode 100644 libdiscover/backends/KNSBackend/KNSReviews.cpp create mode 100644 libdiscover/backends/KNSBackend/KNSReviews.h create mode 100644 libdiscover/backends/KNSBackend/custom/discover_ktexteditor_codesnippets_core.knsrc create mode 100644 libdiscover/backends/KNSBackend/knscomic-backend-categories.xml create mode 100644 libdiscover/backends/KNSBackend/knscomic-backend.desktop create mode 100644 libdiscover/backends/KNSBackend/knsdiscover_ktexteditor_codesnippets_core-backend-categories.xml create mode 100644 libdiscover/backends/KNSBackend/knsintegrate/CMakeLists.txt create mode 100644 libdiscover/backends/KNSBackend/knsintegrate/main.cpp create mode 100644 libdiscover/backends/KNSBackend/knsktexteditor_codesnippets_core-backend-categories.xml create mode 100644 libdiscover/backends/KNSBackend/knsplasmoids-backend-categories.xml create mode 100644 libdiscover/backends/KNSBackend/tests/CMakeLists.txt create mode 100644 libdiscover/backends/KNSBackend/tests/KNSBackendTest.cpp create mode 100644 libdiscover/backends/KNSBackend/tests/KNSBackendTest.h create mode 100644 libdiscover/backends/KNSBackend/tests/knscorrect-backend.desktop create mode 100644 libdiscover/backends/KNSBackend/tests/knswrong-backend.desktop create mode 100644 libdiscover/backends/KNSBackend/tests/testplasmoids.knsrc create mode 100644 libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp create mode 100644 libdiscover/backends/PackageKitBackend/AppPackageKitResource.h create mode 100644 libdiscover/backends/PackageKitBackend/AppstreamReviews.cpp create mode 100644 libdiscover/backends/PackageKitBackend/AppstreamReviews.h create mode 100644 libdiscover/backends/PackageKitBackend/CMakeLists.txt create mode 100644 libdiscover/backends/PackageKitBackend/PKTransaction.cpp create mode 100644 libdiscover/backends/PackageKitBackend/PKTransaction.h create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitBackend.h create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitMessages.cpp create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitMessages.h create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitNotifier.cpp create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitNotifier.h create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitResource.cpp create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitResource.h create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitSourcesBackend.cpp create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitSourcesBackend.h create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitUpdater.cpp create mode 100644 libdiscover/backends/PackageKitBackend/PackageKitUpdater.h create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/CMakeLists.txt create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/accesscropped.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/accessoriescrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/applicationcrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/educationcrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/fontcrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/gamecrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/graphiccrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/internetcrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/multimediacrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/musiccrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/officecrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/sciencecrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/settingscrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/categoryimages/toolcrop.jpg create mode 100644 libdiscover/backends/PackageKitBackend/config-paths.h.cmake create mode 100644 libdiscover/backends/PackageKitBackend/packagekit-backend-categories.xml create mode 100644 libdiscover/backends/PackageKitBackend/packagekit-backend.desktop create mode 100644 libdiscover/backends/PackageKitBackend/runservice/CMakeLists.txt create mode 100644 libdiscover/backends/PackageKitBackend/runservice/main.cpp create mode 100644 libdiscover/declarative/ApplicationProxyModelHelper.cpp create mode 100644 libdiscover/declarative/ApplicationProxyModelHelper.h create mode 100644 libdiscover/declarative/CMakeLists.txt create mode 100644 libdiscover/declarative/DiscoverDeclarativePlugin.cpp create mode 100644 libdiscover/declarative/DiscoverDeclarativePlugin.h create mode 100644 libdiscover/declarative/qmldir create mode 100644 libdiscover/muondatasources.kcfg create mode 100644 libdiscover/notifiers/BackendNotifierModule.cpp create mode 100644 libdiscover/notifiers/BackendNotifierModule.h create mode 100644 libdiscover/notifiers/CMakeLists.txt create mode 100644 libdiscover/resources/AbstractBackendUpdater.cpp create mode 100644 libdiscover/resources/AbstractBackendUpdater.h create mode 100644 libdiscover/resources/AbstractKDEDModule.cpp create mode 100644 libdiscover/resources/AbstractKDEDModule.h create mode 100644 libdiscover/resources/AbstractResource.cpp create mode 100644 libdiscover/resources/AbstractResource.h create mode 100644 libdiscover/resources/AbstractResourcesBackend.cpp create mode 100644 libdiscover/resources/AbstractResourcesBackend.h create mode 100644 libdiscover/resources/AbstractSourcesBackend.cpp create mode 100644 libdiscover/resources/AbstractSourcesBackend.h create mode 100644 libdiscover/resources/PackageState.cpp create mode 100644 libdiscover/resources/PackageState.h create mode 100644 libdiscover/resources/ResourcesModel.cpp create mode 100644 libdiscover/resources/ResourcesModel.h create mode 100644 libdiscover/resources/ResourcesProxyModel.cpp create mode 100644 libdiscover/resources/ResourcesProxyModel.h create mode 100644 libdiscover/resources/ResourcesUpdatesModel.cpp create mode 100644 libdiscover/resources/ResourcesUpdatesModel.h create mode 100644 libdiscover/resources/SourcesModel.cpp create mode 100644 libdiscover/resources/SourcesModel.h create mode 100644 libdiscover/resources/StandardBackendUpdater.cpp create mode 100644 libdiscover/resources/StandardBackendUpdater.h create mode 100644 libdiscover/resources/discoverabstractnotifier.notifyrc create mode 100644 libdiscover/tests/CMakeLists.txt create mode 100644 libdiscover/tests/CategoriesTest.cpp create mode 100644 libdiscover/tests/PopConParserTest.cpp create mode 100644 libdiscover/tests/modeltest.cpp create mode 100644 libdiscover/tests/modeltest.h create mode 100644 libdiscover/utils.h create mode 100644 notifier/BackendNotifierFactory.cpp create mode 100644 notifier/BackendNotifierFactory.h create mode 100644 notifier/CMakeLists.txt create mode 100644 notifier/DiscoverNotifier.cpp create mode 100644 notifier/DiscoverNotifier.h create mode 100644 notifier/DiscoverNotifierDeclarativePlugin.cpp create mode 100644 notifier/DiscoverNotifierDeclarativePlugin.h create mode 100755 notifier/plasmoid/Messages.sh create mode 100644 notifier/plasmoid/contents/ui/Full.qml create mode 100644 notifier/plasmoid/contents/ui/main.qml create mode 100644 notifier/plasmoid/metadata.desktop create mode 100644 notifier/qmldir create mode 100644 po/ar/libdiscover.po create mode 100644 po/ar/plasma-discover-notifier.po create mode 100644 po/ar/plasma-discover.po create mode 100644 po/ar/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ast/libdiscover.po create mode 100644 po/ast/plasma-discover-notifier.po create mode 100644 po/ast/plasma-discover.po create mode 100644 po/ast/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/bg/libdiscover.po create mode 100644 po/bs/libdiscover.po create mode 100644 po/bs/plasma-discover.po create mode 100644 po/bs/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ca/libdiscover.po create mode 100644 po/ca/plasma-discover-notifier.po create mode 100644 po/ca/plasma-discover.po create mode 100644 po/ca/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ca@valencia/libdiscover.po create mode 100644 po/ca@valencia/plasma-discover-notifier.po create mode 100644 po/ca@valencia/plasma-discover.po create mode 100644 po/ca@valencia/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/cs/libdiscover.po create mode 100644 po/cs/plasma-discover-notifier.po create mode 100644 po/cs/plasma-discover.po create mode 100644 po/cs/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/da/libdiscover.po create mode 100644 po/da/plasma-discover-notifier.po create mode 100644 po/da/plasma-discover.po create mode 100644 po/da/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/de/libdiscover.po create mode 100644 po/de/plasma-discover-notifier.po create mode 100644 po/de/plasma-discover.po create mode 100644 po/de/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/el/libdiscover.po create mode 100644 po/el/plasma-discover-notifier.po create mode 100644 po/el/plasma-discover.po create mode 100644 po/el/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/en_GB/libdiscover.po create mode 100644 po/en_GB/plasma-discover-notifier.po create mode 100644 po/en_GB/plasma-discover.po create mode 100644 po/en_GB/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/es/libdiscover.po create mode 100644 po/es/plasma-discover-notifier.po create mode 100644 po/es/plasma-discover.po create mode 100644 po/es/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/et/libdiscover.po create mode 100644 po/et/plasma-discover-notifier.po create mode 100644 po/et/plasma-discover.po create mode 100644 po/et/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/fi/libdiscover.po create mode 100644 po/fi/plasma-discover-notifier.po create mode 100644 po/fi/plasma-discover.po create mode 100644 po/fi/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/fr/libdiscover.po create mode 100644 po/fr/plasma-discover-notifier.po create mode 100644 po/fr/plasma-discover.po create mode 100644 po/fr/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ga/libdiscover.po create mode 100644 po/ga/plasma-discover.po create mode 100644 po/gl/libdiscover.po create mode 100644 po/gl/plasma-discover-notifier.po create mode 100644 po/gl/plasma-discover.po create mode 100644 po/gl/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/he/libdiscover.po create mode 100644 po/he/plasma-discover-notifier.po create mode 100644 po/he/plasma-discover.po create mode 100644 po/he/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/hu/libdiscover.po create mode 100644 po/hu/plasma-discover-notifier.po create mode 100644 po/hu/plasma-discover.po create mode 100644 po/hu/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ia/plasma-discover.po create mode 100644 po/id/libdiscover.po create mode 100644 po/id/plasma-discover.po create mode 100644 po/id/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/it/libdiscover.po create mode 100644 po/it/plasma-discover-notifier.po create mode 100644 po/it/plasma-discover.po create mode 100644 po/it/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ja/libdiscover.po create mode 100644 po/ja/plasma-discover-notifier.po create mode 100644 po/ja/plasma-discover.po create mode 100644 po/ja/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/kk/libdiscover.po create mode 100644 po/kk/plasma-discover.po create mode 100644 po/ko/libdiscover.po create mode 100644 po/ko/plasma-discover-notifier.po create mode 100644 po/ko/plasma-discover.po create mode 100644 po/ko/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/lt/libdiscover.po create mode 100644 po/lt/plasma-discover-notifier.po create mode 100644 po/lt/plasma-discover.po create mode 100644 po/lt/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/mr/libdiscover.po create mode 100644 po/mr/plasma-discover.po create mode 100644 po/nb/libdiscover.po create mode 100644 po/nb/plasma-discover-notifier.po create mode 100644 po/nb/plasma-discover.po create mode 100644 po/nds/libdiscover.po create mode 100644 po/nds/plasma-discover.po create mode 100644 po/nl/libdiscover.po create mode 100644 po/nl/plasma-discover-notifier.po create mode 100644 po/nl/plasma-discover.po create mode 100644 po/nl/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/nn/libdiscover.po create mode 100644 po/nn/plasma-discover-notifier.po create mode 100644 po/nn/plasma-discover.po create mode 100644 po/nn/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/pa/libdiscover.po create mode 100644 po/pa/plasma-discover-notifier.po create mode 100644 po/pa/plasma-discover.po create mode 100644 po/pa/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/pl/libdiscover.po create mode 100644 po/pl/plasma-discover-notifier.po create mode 100644 po/pl/plasma-discover.po create mode 100644 po/pl/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/pt/libdiscover.po create mode 100644 po/pt/plasma-discover-notifier.po create mode 100644 po/pt/plasma-discover.po create mode 100644 po/pt/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/pt_BR/libdiscover.po create mode 100644 po/pt_BR/plasma-discover-notifier.po create mode 100644 po/pt_BR/plasma-discover.po create mode 100644 po/pt_BR/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ro/libdiscover.po create mode 100644 po/ro/plasma-discover-notifier.po create mode 100644 po/ro/plasma-discover.po create mode 100644 po/ro/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ru/libdiscover.po create mode 100644 po/ru/plasma-discover-notifier.po create mode 100644 po/ru/plasma-discover.po create mode 100644 po/ru/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/sk/libdiscover.po create mode 100644 po/sk/plasma-discover-notifier.po create mode 100644 po/sk/plasma-discover.po create mode 100644 po/sk/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/sl/libdiscover.po create mode 100644 po/sl/plasma-discover-notifier.po create mode 100644 po/sl/plasma-discover.po create mode 100644 po/sl/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/sr/libdiscover.po create mode 100644 po/sr/plasma-discover-notifier.po create mode 100644 po/sr/plasma-discover.po create mode 100644 po/sr/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/sr@ijekavian/libdiscover.po create mode 100644 po/sr@ijekavian/plasma-discover-notifier.po create mode 100644 po/sr@ijekavian/plasma-discover.po create mode 100644 po/sr@ijekavian/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/sr@ijekavianlatin/libdiscover.po create mode 100644 po/sr@ijekavianlatin/plasma-discover-notifier.po create mode 100644 po/sr@ijekavianlatin/plasma-discover.po create mode 100644 po/sr@ijekavianlatin/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/sr@latin/libdiscover.po create mode 100644 po/sr@latin/plasma-discover-notifier.po create mode 100644 po/sr@latin/plasma-discover.po create mode 100644 po/sr@latin/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/sv/libdiscover.po create mode 100644 po/sv/plasma-discover-notifier.po create mode 100644 po/sv/plasma-discover.po create mode 100644 po/sv/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/tr/libdiscover.po create mode 100644 po/tr/plasma-discover.po create mode 100644 po/tr/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/ug/libdiscover.po create mode 100644 po/ug/plasma-discover.po create mode 100644 po/uk/libdiscover.po create mode 100644 po/uk/plasma-discover-notifier.po create mode 100644 po/uk/plasma-discover.po create mode 100644 po/uk/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/vi/libdiscover.po create mode 100644 po/vi/plasma-discover.po create mode 100644 po/zh_CN/libdiscover.po create mode 100644 po/zh_CN/plasma-discover-notifier.po create mode 100644 po/zh_CN/plasma-discover.po create mode 100644 po/zh_CN/plasma_applet_org.kde.discovernotifier.po create mode 100644 po/zh_TW/libdiscover.po create mode 100644 po/zh_TW/plasma-discover-notifier.po create mode 100644 po/zh_TW/plasma-discover.po create mode 100644 po/zh_TW/plasma_applet_org.kde.discovernotifier.po diff --git a/.arcconfig b/.arcconfig new file mode 100644 index 0000000..bc0df43 --- /dev/null +++ b/.arcconfig @@ -0,0 +1,4 @@ +{ + "phabricator.uri" : "https://phabricator.kde.org/" +} + diff --git a/.reviewboardrc b/.reviewboardrc new file mode 100644 index 0000000..ad6b582 --- /dev/null +++ b/.reviewboardrc @@ -0,0 +1,4 @@ +REPOSITORY = "git://anongit.kde.org/discover" +REVIEWBOARD_URL = "https://git.reviewboard.kde.org" +TARGET_GROUPS = "muon, kubuntu" +BRANCH = "master" diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a65c9b0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,86 @@ +project(discover) +set(PROJECT_VERSION "5.8.5") +set(PROJECT_VERSION_MAJOR 5) + +cmake_minimum_required(VERSION 2.8.12) + +find_package(ECM REQUIRED NO_MODULE) + +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} "${CMAKE_SOURCE_DIR}/cmake") + +find_package(Qt5 5.2.0 REQUIRED CONFIG COMPONENTS Widgets Test Network Xml Concurrent DBus Quick) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) +include(ECMInstallIcons) +include(ECMMarkAsTest) +include(ECMAddTests) +include(GenerateExportHeader) + +find_package(KF5 5.24 REQUIRED CoreAddons Config Crash DBusAddons I18n Archive Declarative XmlGui) +find_package(KF5Kirigami 1.1) + +find_package(packagekitqt5) +if (NOT packagekitqt5_FOUND) + find_package(QApt 3.0.0) + if(QApt_FOUND) + find_package(DebconfKDE 1.0.0 REQUIRED) + find_package(KF5 REQUIRED IconThemes Notifications KIO) + endif() +endif() +find_package(AppStreamQt 0.10) +if (NOT AppstreamQt_FOUND) + find_package(AppstreamQt 0.10 QUIET) +endif() +find_package(KF5Attica 5.23) +find_package(KF5NewStuff 5.23) + +configure_file(DiscoverVersion.h.in DiscoverVersion.h) + +add_subdirectory(libdiscover) +add_subdirectory(discover) +add_subdirectory(exporter) + +option(WITH_NOTIFIER "Build and install the notifier plasmoid" ON) +if(WITH_NOTIFIER) + find_package(KF5 REQUIRED Notifications KIO) + add_subdirectory(notifier) +endif() + +set_package_properties(QApt PROPERTIES + DESCRIPTION "Qt wrapper around the libapt-pkg library" + PURPOSE "Used to support apt-based distribution systems" + TYPE OPTIONAL) + +set_package_properties(KF5Attica PROPERTIES + DESCRIPTION "KDE Framework that implements the Open Collaboration Services API" + PURPOSE "Required to build the KNewStuff3 backend" + TYPE OPTIONAL) +set_package_properties(KF5Kirigami PROPERTIES + DESCRIPTION "KDE’s lightweight user interface framework for mobile and convergent applications" + URL "https://techbase.kde.org/Kirigami" + PURPOSE "Required by discover qml components" + TYPE RUNTIME) +set_package_properties(KF5NewStuff PROPERTIES + DESCRIPTION "Qt library that allows to interact with KNewStuff implementations" + PURPOSE "Required to build the KNS backend" + TYPE OPTIONAL) +set_package_properties(Bodega PROPERTIES + DESCRIPTION "Library that exposes Bodega resources" + PURPOSE "Required to build the Bodega backend" + TYPE OPTIONAL) +set_package_properties(packagekitqt5 PROPERTIES + DESCRIPTION "Library that exposes PackageKit resources" + URL "http://www.packagekit.org" + PURPOSE "Required to build the PackageKit backend" + TYPE OPTIONAL) +set_package_properties(AppstreamQt PROPERTIES + DESCRIPTION "Library that lists Appstream resources" + URL "http://www.freedesktop.org" + PURPOSE "Required to build the PackageKit backend" + TYPE OPTIONAL) + +feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) + +find_package(KF5I18n CONFIG REQUIRED) +ki18n_install(po) diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user new file mode 100644 index 0000000..b7617a9 --- /dev/null +++ b/CMakeLists.txt.user @@ -0,0 +1,999 @@ + + + + + + EnvironmentId + {ce02e609-3c7f-44c2-82a7-72ae2d7301ca} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {144018c4-5a3a-4d23-a863-dcb5c6f5fb5e} + 0 + 0 + 4 + + + CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable} + QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} + + /home/apol/devel/frameworks/build-discover-Desktop-Default + + + + + all + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + + + clean + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Default + Default + CMakeProjectManager.CMakeBuildConfiguration + + + + CMAKE_BUILD_TYPE:STRING=Debug + CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable} + QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} + + /home/apol/devel/frameworks/build-discover-Desktop-Debug + + + + + all + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + + + clean + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + CMakeProjectManager.CMakeBuildConfiguration + + + + CMAKE_BUILD_TYPE:STRING=Release + CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable} + QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} + + /home/apol/devel/frameworks/build-discover-Desktop-Release + + + + + + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + + + clean + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + CMakeProjectManager.CMakeBuildConfiguration + + + + CMAKE_BUILD_TYPE:STRING=RelWithDebInfo + CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable} + QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} + + /home/apol/devel/frameworks/build-discover-Desktop-Release with Debug Information + + + + + + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + + + clean + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release with Debug Information + Release with Debug Information + CMakeProjectManager.CMakeBuildConfiguration + + + + CMAKE_BUILD_TYPE:STRING=MinSizeRel + CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable} + QT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable} + + /home/apol/devel/frameworks/build-discover-Desktop-Minimum Size Release + + + + + + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + + + clean + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Minimum Size Release + Minimum Size Release + CMakeProjectManager.CMakeBuildConfiguration + + 5 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + knsintegrate + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/libdiscover/backends/KNSBackend/knsintegrate + 2 + + knsintegrate + + CMakeProjectManager.CMakeRunConfiguration.knsintegrate + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + knsbackendtest + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/libdiscover/backends/KNSBackend/tests + 2 + + knsbackendtest + + CMakeProjectManager.CMakeRunConfiguration.knsbackendtest + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + muon-exporter + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/exporter + -1 + + muon-exporter (disabled) + + CMakeProjectManager.CMakeRunConfiguration.muon-exporter + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + plasma-discover-updater + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/updater + -1 + + plasma-discover-updater (disabled) + + CMakeProjectManager.CMakeRunConfiguration.plasma-discover-updater + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + CategoriesTest + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/libdiscover/tests + 2 + + CategoriesTest + + CMakeProjectManager.CMakeRunConfiguration.CategoriesTest + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + PopConParserTest + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/libdiscover/tests + 2 + + PopConParserTest + + CMakeProjectManager.CMakeRunConfiguration.PopConParserTest + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + plasma-discover + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/discover + 2 + + plasma-discover + + CMakeProjectManager.CMakeRunConfiguration.plasma-discover + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + IconColorsTest + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/discover/autotests + 2 + + IconColorsTest + + CMakeProjectManager.CMakeRunConfiguration.IconColorsTest + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + PaginateModelTest + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/discover/autotests + 2 + + PaginateModelTest + + CMakeProjectManager.CMakeRunConfiguration.PaginateModelTest + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + plasma-discover-exporter + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/exporter + 2 + + plasma-discover-exporter + + CMakeProjectManager.CMakeRunConfiguration.plasma-discover-exporter + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + muon-updater + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/updater + -1 + + muon-updater (disabled) + + CMakeProjectManager.CMakeRunConfiguration.muon-updater + 3768 + false + true + false + false + true + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + muon-discover + + + /home/apol/devel/frameworks/build-discover-Desktop-Default/discover + -1 + + muon-discover (disabled) + + CMakeProjectManager.CMakeRunConfiguration.muon-discover + 3768 + false + true + false + false + true + + 12 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..4432540 --- /dev/null +++ b/COPYING @@ -0,0 +1,676 @@ + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + diff --git a/COPYING.GFDL b/COPYING.GFDL new file mode 100644 index 0000000..4a0fe1c --- /dev/null +++ b/COPYING.GFDL @@ -0,0 +1,397 @@ + GNU Free Documentation License + Version 1.2, November 2002 + + + Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (Thus, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/DiscoverVersion.h.in b/DiscoverVersion.h.in new file mode 100644 index 0000000..f9f74e3 --- /dev/null +++ b/DiscoverVersion.h.in @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef DISCOVERVERSION_H +#define DISCOVERVERSION_H + +#include + +static QLatin1String version("@PROJECT_VERSION@"); + +#endif diff --git a/Messages.sh b/Messages.sh new file mode 100644 index 0000000..1eb9549 --- /dev/null +++ b/Messages.sh @@ -0,0 +1,8 @@ +#! /usr/bin/env bash + +$EXTRACTRC --context="Category" --tag-group=none --tag=Name `find libdiscover -name "*-categories.xml"` >> categoriesxml.cpp +$XGETTEXT categoriesxml.cpp `find libdiscover -name \*.cpp` -o $podir/libdiscover.pot +$XGETTEXT `find discover -name \*.cpp -o -name \*.qml -o -name \*.js` -o $podir/plasma-discover.pot +$XGETTEXT `find notifier -name \*.cpp` -o $podir/plasma-discover-notifier.pot +rm -f muonrc.cpp +rm -f categoriesxml.cpp diff --git a/TODO b/TODO new file mode 100644 index 0000000..c127c4f --- /dev/null +++ b/TODO @@ -0,0 +1,10 @@ +Legend: + - [MUM] = Update Manager + - [MSC] = Muon Software Center + +-[MSC] Commercial app support. (See: software-center/db/update.py, backends/restfulclient.py) + Example URL: https://software-center.ubuntu.com/api/2.0/applications/en/ubuntu/precise/amd64/ +-[MSC] Review submittal (Use KIO::storedHttpPost) +-[MSC] Add an on-hover magnifying graphic to the screenshot preview +-[MSC] Include addons size in Total size calculation +-[MSC] When going back from a child breadcrumb, hide the crumb, but still be able to go forward diff --git a/cmake/FindPackageKitQt2.cmake b/cmake/FindPackageKitQt2.cmake new file mode 100644 index 0000000..0887e8f --- /dev/null +++ b/cmake/FindPackageKitQt2.cmake @@ -0,0 +1,57 @@ +# - Try to find the PackageKitQt2 library +# Once done this will define +# +# PACKAGEKITQT2_FOUND - system has the PackageKitQt2 library +# PACKAGEKITQT2_INCLUDEDIR - the PackageKitQt2 include directory +# PACKAGEKITQT2_LIBRARY - Link this to use the PackageKitQt2 +# +# Copyright © 2010, Mehrdad Momeny +# Copyright © 2010, Harald Sitter +# Copyright © 2013, Lukas Appelhans +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 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. +# 3. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + +if (NOT WIN32) + find_package(PkgConfig) + pkg_check_modules(QPACKAGEKIT2 packagekit-qt2>=0.8) +endif() + +set(PackageKitQt2_FOUND FALSE) +if(QPACKAGEKIT2_FOUND) + find_library(PACKAGEKITQT2_LIBRARY NAMES packagekit-qt2 + HINTS ${QPACKAGEKIT2_LIBRARIES} + ) + + find_path(PACKAGEKITQT2_INCLUDEDIR PackageKit/packagekit-qt2/daemon.h + HINTS ${QPACKAGEKIT2_INCLUDEDIR} + ) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(PackageKitQt2 DEFAULT_MSG PACKAGEKITQT2_LIBRARY PACKAGEKITQT2_INCLUDEDIR) + if(PACKAGEKITQT2_LIBRARY AND PACKAGEKITQT2_INCLUDEDIR) + mark_as_advanced(PACKAGEKITQT2_INCLUDEDIR PACKAGEKITQT2_LIBRARY) + set(PackageKitQt2_FOUND TRUE) + endif() +endif() diff --git a/cmake/FindQtOAuth.cmake b/cmake/FindQtOAuth.cmake new file mode 100644 index 0000000..9bec3a5 --- /dev/null +++ b/cmake/FindQtOAuth.cmake @@ -0,0 +1,58 @@ +# - Try to find the QtOAuth library +# Once done this will define +# +# QTOAUTH_FOUND - system has the QtOAuth library +# QTOAUTH_INCLUDE_DIR - the QtOAuth include directory +# QTOAUTH_LIBRARY - Link this to use the QtOAuth +# QTOAUTH_DEFINITIONS - Compiler switches required for using QOAuth +# +# Copyright © 2010, Mehrdad Momeny +# Copyright © 2010, Harald Sitter +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 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. +# 3. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + +if (QTOAUTH_INCLUDE_DIR AND QTOAUTH_LIBRARY) + # in cache already + set(QTOAUTH_FOUND TRUE) +else (QTOAUTH_INCLUDE_DIR AND QTOAUTH_LIBRARY) + if (NOT WIN32) + find_package(PkgConfig) + pkg_check_modules(PC_QTOAUTH QUIET qoauth) + set(QTOAUTH_DEFINITIONS ${PC_QTOAUTH_CFLAGS_OTHER}) + endif(NOT WIN32) + + find_library(QTOAUTH_LIBRARY NAMES qoauth + HINTS ${PC_QTOAUTH_LIBDIR} ${PC_QTOAUTH_LIBRARY_DIRS} + ) + + find_path(QTOAUTH_INCLUDE_DIR QtOAuth/interface.h + HINTS ${PC_QTOAUTH_INCLUDEDIR} ${PC_QTOAUTH_INCLUDE_DIRS} + ) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(QtOAuth DEFAULT_MSG QTOAUTH_LIBRARY QTOAUTH_INCLUDE_DIR) + + mark_as_advanced(QTOAUTH_INCLUDE_DIR QTOAUTH_LIBRARY) +endif (QTOAUTH_INCLUDE_DIR AND QTOAUTH_LIBRARY) diff --git a/discover/CMakeLists.txt b/discover/CMakeLists.txt new file mode 100644 index 0000000..34e61b0 --- /dev/null +++ b/discover/CMakeLists.txt @@ -0,0 +1,37 @@ +add_subdirectory(icons) +add_subdirectory(autotests) + +include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/..) + +set(plasma_discover_SRCS + main.cpp + DiscoverMainWindow.cpp + + PaginateModel.cpp + SystemFonts.cpp + IconColors.cpp + UnityLauncher.cpp +) + +qt5_add_resources(plasma_discover_SRCS resources.qrc) + +add_executable(plasma-discover ${plasma_discover_SRCS}) +add_executable(Plasma::Discover ALIAS plasma-discover) +set_target_properties(plasma-discover PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/plasma-discover) + +target_link_libraries(plasma-discover LINK_PUBLIC + KF5::Crash + KF5::DBusAddons + KF5::I18n + KF5::XmlGui + KF5::Declarative + Qt5::Quick + Discover::Common +) + +install(TARGETS plasma-discover ${INSTALL_TARGETS_DEFAULT_ARGS} ) + +install(PROGRAMS org.kde.discover.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) +install(FILES featured.json DESTINATION ${DATA_INSTALL_DIR}/plasmadiscover) +install(FILES plasmadiscoverui.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/plasmadiscover) +install( FILES org.kde.discover.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR} ) diff --git a/discover/DiscoverMainWindow.cpp b/discover/DiscoverMainWindow.cpp new file mode 100644 index 0000000..06ba5b6 --- /dev/null +++ b/discover/DiscoverMainWindow.cpp @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "DiscoverMainWindow.h" +#include "PaginateModel.h" +#include "SystemFonts.h" +#include "IconColors.h" +#include "UnityLauncher.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// KDE includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include + +// DiscoverCommon includes +#include +#include +#include +#include + +#include +#include + +DiscoverMainWindow::DiscoverMainWindow(CompactMode mode) + : QObject() + , m_collection(this) + , m_engine(new QQmlApplicationEngine) + , m_mode(mode) +{ + ResourcesModel *m = ResourcesModel::global(); + m->integrateActions(actionCollection()); + + setObjectName(QStringLiteral("DiscoverMain")); + KDeclarative::KDeclarative kdeclarative; + kdeclarative.setDeclarativeEngine(m_engine); + kdeclarative.setupBindings(); + + qmlRegisterType("org.kde.discover.app", 1, 0, "UnityLauncher"); + qmlRegisterType("org.kde.discover.app", 1, 0, "PaginateModel"); + qmlRegisterType("org.kde.discover.app", 1, 0, "IconColors"); + qmlRegisterSingletonType("org.kde.discover.app", 1, 0, "SystemFonts", ([](QQmlEngine*, QJSEngine*) -> QObject* { return new SystemFonts; })); + qmlRegisterSingletonType(QUrl(QStringLiteral("qrc:/qml/DiscoverSystemPalette.qml")), "org.kde.discover.app", 1, 0, "DiscoverSystemPalette"); + qmlRegisterSingletonType(QUrl(QStringLiteral("qrc:/qml/Helpers.qml")), "org.kde.discover.app", 1, 0, "Helpers"); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterType(); + qmlRegisterUncreatableType("org.kde.discover.app", 1, 0, "DiscoverMainWindow", QStringLiteral("don't do that")); + setupActions(); + + //Here we set up a cache for the screenshots + m_engine->rootContext()->setContextProperty(QStringLiteral("app"), this); + + connect(m_engine, &QQmlApplicationEngine::objectCreated, this, &DiscoverMainWindow::integrateObject); + m_engine->load(QUrl(QStringLiteral("qrc:/qml/DiscoverWindow.qml"))); +} + +DiscoverMainWindow::~DiscoverMainWindow() +{ + delete m_engine; +} + +bool DiscoverMainWindow::isRoot() +{ + return ::getuid() == 0; +} + +QStringList DiscoverMainWindow::modes() const +{ + QStringList ret; + QObject* obj = rootObject(); + for(int i = obj->metaObject()->propertyOffset(); imetaObject()->propertyCount(); i++) { + QMetaProperty p = obj->metaObject()->property(i); + QByteArray compName = p.name(); + if(compName.startsWith("top") && compName.endsWith("Comp")) { + ret += QString::fromLatin1(compName.mid(3, compName.length()-7)); + } + } + return ret; +} + +void DiscoverMainWindow::openMode(const QString& _mode) +{ + if(!modes().contains(_mode)) + qWarning() << "unknown mode" << _mode; + + QString mode = _mode; + mode[0] = mode[0].toUpper(); + + QObject* obj = rootObject(); + const QByteArray propertyName = "top"+mode.toLatin1()+"Comp"; + const QVariant modeComp = obj->property(propertyName.constData()); + if (!modeComp.isValid()) + qWarning() << "couldn't open mode" << _mode; + else + obj->setProperty("currentTopLevel", modeComp); +} + +void DiscoverMainWindow::openMimeType(const QString& mime) +{ + emit listMimeInternal(mime); +} + +void DiscoverMainWindow::openCategory(const QString& category) +{ + Category* cat = CategoryModel::findCategoryByName(category); + Q_ASSERT(cat); + emit listCategoryInternal(cat); +} + +void DiscoverMainWindow::openApplication(const QString& app) +{ + m_appToBeOpened = app; + if(!m_appToBeOpened.isEmpty()) { + rootObject()->setProperty("defaultStartup", false); + + if (ResourcesModel::global()->isFetching() || ResourcesModel::global()->backends().isEmpty()) { + connect(ResourcesModel::global(), &ResourcesModel::rowsInserted, this, &DiscoverMainWindow::triggerOpenApplication); + connect(ResourcesModel::global(), &ResourcesModel::allInitialized, this, &DiscoverMainWindow::triggerOpenApplication); + } else { + triggerOpenApplication(); + } + } +} + +void DiscoverMainWindow::triggerOpenApplication() +{ + AbstractResource* app = ResourcesModel::global()->resourceByPackageName(m_appToBeOpened); + if(app) { + emit openApplicationInternal(app); + m_appToBeOpened.clear(); + disconnect(ResourcesModel::global(), &ResourcesModel::rowsInserted, this, &DiscoverMainWindow::triggerOpenApplication); + disconnect(ResourcesModel::global(), &ResourcesModel::allInitialized, this, &DiscoverMainWindow::triggerOpenApplication); + } else { + qDebug() << "couldn't find" << m_appToBeOpened; + if (!ResourcesModel::global()->isFetching()) { + Q_EMIT unableToFind(m_appToBeOpened); + disconnect(ResourcesModel::global(), &ResourcesModel::rowsInserted, this, &DiscoverMainWindow::triggerOpenApplication); + disconnect(ResourcesModel::global(), &ResourcesModel::allInitialized, this, &DiscoverMainWindow::triggerOpenApplication); + } + } +} + +QUrl DiscoverMainWindow::featuredSource() const +{ + return MuonDataSources::featuredSource(); +} + +QUrl DiscoverMainWindow::prioritaryFeaturedSource() const +{ + return QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("plasmadiscover/featured.json"))); +} + +void DiscoverMainWindow::integrateObject(QObject* object) +{ + Q_ASSERT(object == rootObject()); + + KConfigGroup window(KSharedConfig::openConfig(), "Window"); + if (window.hasKey("geometry")) + rootObject()->setGeometry(window.readEntry("geometry", QRect())); + if (window.hasKey("visibility")) { + QWindow::Visibility visibility(QWindow::Visibility(window.readEntry("visibility", QWindow::Windowed))); + rootObject()->setVisibility(qMax(visibility, QQuickView::AutomaticVisibility)); + } + + object->installEventFilter(this); +} + +bool DiscoverMainWindow::eventFilter(QObject * object, QEvent * event) +{ + if (object!=rootObject()) + return false; + + if (event->type() == QEvent::Close) { + if (ResourcesModel::global()->isBusy()) { + qWarning() << "not closing because there's still pending tasks"; + Q_EMIT preventedClose(); + return true; + } + + KConfigGroup window(KSharedConfig::openConfig(), "Window"); + window.writeEntry("geometry", rootObject()->geometry()); + window.writeEntry("visibility", rootObject()->visibility()); + } + return false; +} + +void DiscoverMainWindow::setupActions() +{ + QAction *quitAction = KStandardAction::quit(QCoreApplication::instance(), SLOT(quit()), actionCollection()); + actionCollection()->addAction(QStringLiteral("file_quit"), quitAction); + + if (KAuthorized::authorizeAction(QStringLiteral("help_contents"))) { + auto mHandBookAction = KStandardAction::helpContents(this, SLOT(appHelpActivated()), this); + actionCollection()->addAction(mHandBookAction->objectName(), mHandBookAction); + } + + if (KAuthorized::authorizeAction(QStringLiteral("help_report_bug")) && !KAboutData::applicationData().bugAddress().isEmpty()) { + auto mReportBugAction = KStandardAction::reportBug(this, SLOT(reportBug()), this); + actionCollection()->addAction(mReportBugAction->objectName(), mReportBugAction); + } + + if (KAuthorized::authorizeAction(QStringLiteral("switch_application_language"))) { +// if (KLocalizedString::availableApplicationTranslations().count() > 1) { + auto mSwitchApplicationLanguageAction = KStandardAction::create(KStandardAction::SwitchApplicationLanguage, this, SLOT(switchApplicationLanguage()), this); + actionCollection()->addAction(mSwitchApplicationLanguageAction->objectName(), mSwitchApplicationLanguageAction); +// } + } + + if (KAuthorized::authorizeAction(QStringLiteral("help_about_app"))) { + auto mAboutAppAction = KStandardAction::aboutApp(this, SLOT(aboutApplication()), this); + actionCollection()->addAction(mAboutAppAction->objectName(), mAboutAppAction); + } + auto mKeyBindignsAction = KStandardAction::keyBindings(this, SLOT(configureShortcuts()), this); + actionCollection()->addAction(mKeyBindignsAction->objectName(), mKeyBindignsAction); +} + +QAction * DiscoverMainWindow::action(const QString& name) +{ + return actionCollection()->action(name); +} + +QString DiscoverMainWindow::iconName(const QIcon& icon) +{ + return icon.name(); +} + +void DiscoverMainWindow::appHelpActivated() +{ + QDesktopServices::openUrl(QUrl(QStringLiteral("help:/"))); +} + +void DiscoverMainWindow::aboutApplication() +{ + static QPointer dialog; + if (!dialog) { + dialog = new KAboutApplicationDialog(KAboutData::applicationData(), nullptr); + dialog->setAttribute(Qt::WA_DeleteOnClose); + } + dialog->show(); +} + +void DiscoverMainWindow::reportBug() +{ + static QPointer dialog; + if (!dialog) { + dialog = new KBugReport(KAboutData::applicationData(), nullptr); + dialog->setAttribute(Qt::WA_DeleteOnClose); + } + dialog->show(); +} + +void DiscoverMainWindow::switchApplicationLanguage() +{ +// auto langDialog = new KSwitchLanguageDialog(nullptr); +// connect(langDialog, SIGNAL(finished(int)), this, SLOT(dialogFinished())); +// langDialog->show(); +} + +void DiscoverMainWindow::configureShortcuts() +{ + KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, nullptr); + dlg.setModal(true); + dlg.addCollection(actionCollection()); + qDebug() << "saving shortcuts..." << dlg.configure(/*bSaveSettings*/); +} + +void DiscoverMainWindow::setCompactMode(DiscoverMainWindow::CompactMode mode) +{ + if (m_mode != mode) { + m_mode = mode; + Q_EMIT compactModeChanged(m_mode); + } +} + +class DiscoverTestExecutor : public QObject +{ +public: + DiscoverTestExecutor(QObject* rootObject, QQmlEngine* engine, const QUrl &url) + : QObject(engine) + { + connect(engine, &QQmlEngine::quit, this, &DiscoverTestExecutor::finish, Qt::QueuedConnection); + + QQmlComponent* component = new QQmlComponent(engine, url, engine); + m_testObject = component->create(engine->rootContext()); + + if (!m_testObject) { + qWarning() << "error loading test" << url << m_testObject << component->errors(); + Q_ASSERT(false); + } + + m_testObject->setProperty("appRoot", QVariant::fromValue(rootObject)); + connect(engine, &QQmlEngine::warnings, this, &DiscoverTestExecutor::processWarnings); + } + + void processWarnings(const QList &warnings) { + foreach(const QQmlError &warning, warnings) { + if (warning.url().path().endsWith(QLatin1String("DiscoverTest.qml"))) { + qWarning() << "Test failed!" << warnings; + qGuiApp->exit(1); + } + } + m_warnings << warnings; + } + + void finish() { + //The CI doesn't seem to have icons, remove when it's not an issue anymore + m_warnings.erase(std::remove_if(m_warnings.begin(), m_warnings.end(), [](const QQmlError& err) -> bool { + return err.description().contains(QLatin1String("QML Image: Failed to get image from provider: image://icon/")); + })); + + if (m_warnings.isEmpty()) + qDebug() << "cool no warnings!"; + else + qDebug() << "test finished succesfully despite" << m_warnings; + qGuiApp->exit(m_warnings.count()); + } + +private: + QObject* m_testObject; + QList m_warnings; +}; + +void DiscoverMainWindow::loadTest(const QUrl& url) +{ + new DiscoverTestExecutor(rootObject(), engine(), url); +} + +QWindow* DiscoverMainWindow::rootObject() const +{ + return qobject_cast(m_engine->rootObjects().at(0)); +} + +void DiscoverMainWindow::showPassiveNotification(const QString& msg) +{ + QTimer::singleShot(100, this, [this, msg](){ + QMetaObject::invokeMethod(rootObject(), "showPassiveNotification", Qt::QueuedConnection, Q_ARG(QVariant, msg), Q_ARG(QVariant, {}), Q_ARG(QVariant, {}), Q_ARG(QVariant, {})); + }); +} diff --git a/discover/DiscoverMainWindow.h b/discover/DiscoverMainWindow.h new file mode 100644 index 0000000..9e0cf77 --- /dev/null +++ b/discover/DiscoverMainWindow.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MUONDISCOVERMAINWINDOW_H +#define MUONDISCOVERMAINWINDOW_H + +#include + +#include +#include + +class QQmlEngine; +class QLineEdit; +class QAptIntegration; +class AbstractResource; +class Category; +class QQuickWidget; +class QWindow; +class QQmlApplicationEngine; + +class DiscoverMainWindow : public QObject +{ + Q_OBJECT + Q_PROPERTY(QUrl prioritaryFeaturedSource READ prioritaryFeaturedSource CONSTANT) + Q_PROPERTY(QUrl featuredSource READ featuredSource CONSTANT) + Q_PROPERTY(CompactMode compactMode READ compactMode WRITE setCompactMode NOTIFY compactModeChanged) + Q_PROPERTY(bool isRoot READ isRoot CONSTANT) + public: + enum CompactMode { Auto, Compact, Full }; + Q_ENUM(CompactMode) + + explicit DiscoverMainWindow(CompactMode mode); + ~DiscoverMainWindow() override; + + QStringList modes() const; + void setupActions(); + + QUrl prioritaryFeaturedSource() const; + QUrl featuredSource() const; + + CompactMode compactMode() const { return m_mode; } + void setCompactMode(CompactMode mode); + + bool eventFilter(QObject * object, QEvent * event) override; + + Q_SCRIPTABLE QAction * action(const QString& name); + Q_SCRIPTABLE QString iconName(const QIcon& icon); + + void loadTest(const QUrl& url); + + static bool isRoot(); + QWindow* rootObject() const; + void showPassiveNotification(const QString &msg); + + public Q_SLOTS: + void openApplication(const QString& app); + void openMimeType(const QString& mime); + void openCategory(const QString& category); + void openMode(const QString& mode); + + private Q_SLOTS: + void triggerOpenApplication(); + void appHelpActivated(); + void reportBug(); + void switchApplicationLanguage(); + void aboutApplication(); + void configureShortcuts(); + + Q_SIGNALS: + void openApplicationInternal(AbstractResource* app); + void listMimeInternal(const QString& mime); + void listCategoryInternal(Category* cat); + + void compactModeChanged(CompactMode compactMode); + void preventedClose(); + void unableToFind(const QString &resid); + + private: + void integrateObject(QObject* object); + QQmlApplicationEngine* engine() const { return m_engine; } + + KActionCollection* actionCollection() { return &m_collection; } + + QString m_appToBeOpened; + KActionCollection m_collection; + QQmlApplicationEngine * const m_engine; + + CompactMode m_mode; +}; + +#endif // MUONINSTALLERDECLARATIVEVIEW_H diff --git a/discover/IconColors.cpp b/discover/IconColors.cpp new file mode 100644 index 0000000..e5cdfaf --- /dev/null +++ b/discover/IconColors.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "IconColors.h" +#include +#include +#include + +// #define OUTPUT_PIXMAP_DEBUG + +IconColors::IconColors(QObject* parent) + : QObject(parent) +{} + +QString IconColors::iconName() const +{ + return m_icon.name(); +} + +void IconColors::setIconName(const QString& name) +{ + if (m_icon.name() != name) { + m_icon = QIcon::fromTheme(name); + } +} + +QColor IconColors::dominantColor() const +{ + const QImage img = m_icon.pixmap({32, 32}).toImage(); + if(img.isNull()) { + qWarning() << "wrong icon" << m_icon << m_icon.name(); + return QColor(Qt::black); + } + const int tolerance = 10; + QVector hue(360/tolerance, 0); + +#ifdef OUTPUT_PIXMAP_DEBUG + QImage thing(img.size()+QSize(0,1), QImage::Format_ARGB32); + thing.fill(Qt::white); +#endif + + for (int w=0, cw=img.width(); w= QT_VERSION_CHECK(5, 6, 0) + const QColor c = img.pixelColor(w, h).toHsv(); +#else + const QColor c(img.pixel(w, h)); +#endif + + if (c.value()>150 && c.saturation()>20 && c.hue()>=0 && c.alpha()>200) { + hue[c.hue()/tolerance]++; + +#ifdef OUTPUT_PIXMAP_DEBUG +// qDebug() << "adopting" << w << "x" << h << c.name() << c.hue(); +// thing.setPixelColor(w, h, c); + thing.setPixelColor(w, h, QColor::fromHsv(tolerance*(c.hue()/tolerance), 220, 220)); +#endif + } + } + } + + uint dominantHue = 0, biggestAmount = 0; + for(int i=0; ibiggestAmount) { + biggestAmount = hue[i]; + dominantHue = i; + } + } + + QColor ret = QColor::fromHsv((dominantHue*tolerance + tolerance/2) % 360, 255, 255); + +#ifdef OUTPUT_PIXMAP_DEBUG + qDebug() << "dominant" << dominantHue << hue[dominantHue] << "~=" << ((100*hue[dominantHue])/(img.width()*img.height())) << "% " << iconName(); + thing.setPixelColor(0, img.height(), ret); + thing.save("/tmp/"+iconName()+".png"); +#endif + + return ret; +} + +void IconColors::setIcon(const QIcon& icon) +{ + m_icon = icon; +} diff --git a/discover/IconColors.h b/discover/IconColors.h new file mode 100644 index 0000000..6336ea4 --- /dev/null +++ b/discover/IconColors.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef ICONCOLORS_H +#define ICONCOLORS_H + +#include +#include +#include + +class IconColors : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString iconName READ iconName WRITE setIconName) + Q_PROPERTY(QColor dominantColor READ dominantColor NOTIFY dominantColorChanged STORED false) +public: + explicit IconColors(QObject* parent = Q_NULLPTR); + + QString iconName() const; + void setIconName(const QString& name); + + void setIcon(const QIcon &icon); + QIcon icon() const { return m_icon; } + + QColor dominantColor() const; + +Q_SIGNALS: + void dominantColorChanged(const QColor &dominantColor); + +private: + QIcon m_icon; +}; + +#endif // ICONCOLORS_H diff --git a/discover/PaginateModel.cpp b/discover/PaginateModel.cpp new file mode 100644 index 0000000..b563731 --- /dev/null +++ b/discover/PaginateModel.cpp @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2014 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "PaginateModel.h" +#include +#include + +PaginateModel::PaginateModel(QObject* object) + : QAbstractListModel(object) + , m_firstItem(0) + , m_pageSize(10) + , m_sourceModel(nullptr) + , m_hasStaticRowCount(false) +{ +} + +PaginateModel::~PaginateModel() +{ +} + +int PaginateModel::firstItem() const +{ + return m_firstItem; +} + +void PaginateModel::setFirstItem(int row) +{ + Q_ASSERT(row>=0 && rowrowCount()); + if (row!=m_firstItem) { + beginResetModel(); + m_firstItem = row; + endResetModel(); + emit firstItemChanged(); + } +} + +int PaginateModel::pageSize() const +{ + return m_pageSize; +} + +void PaginateModel::setPageSize(int count) +{ + if (count != m_pageSize) { + const int oldSize = rowsByPageSize(m_pageSize); + const int newSize = rowsByPageSize(count); + const int difference = newSize - oldSize; + if (difference==0) { + m_pageSize = count; + } else if(difference>0) { + beginInsertRows(QModelIndex(), m_pageSize, m_pageSize+difference-1); + m_pageSize = count; + endInsertRows(); + } else { + beginRemoveRows(QModelIndex(), m_pageSize+difference, m_pageSize-1); + m_pageSize = count; + endRemoveRows(); + } + emit pageSizeChanged(); + } +} + +QAbstractItemModel* PaginateModel::sourceModel() const +{ + return m_sourceModel; +} + +void PaginateModel::setSourceModel(QAbstractItemModel* model) +{ + if(m_sourceModel) { + disconnect(m_sourceModel, nullptr, this, nullptr); + } + + if(model!=m_sourceModel) { + beginResetModel(); + m_sourceModel = model; + if(model) { + connect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeInserted, this, &PaginateModel::_k_sourceRowsAboutToBeInserted); + connect(m_sourceModel, &QAbstractItemModel::rowsInserted, this, &PaginateModel::_k_sourceRowsInserted); + connect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &PaginateModel::_k_sourceRowsAboutToBeRemoved); + connect(m_sourceModel, &QAbstractItemModel::rowsRemoved, this, &PaginateModel::_k_sourceRowsRemoved); + connect(m_sourceModel, &QAbstractItemModel::rowsAboutToBeMoved, this, &PaginateModel::_k_sourceRowsAboutToBeMoved); + connect(m_sourceModel, &QAbstractItemModel::rowsMoved, this, &PaginateModel::_k_sourceRowsMoved); + + connect(m_sourceModel, &QAbstractItemModel::columnsAboutToBeInserted, this, &PaginateModel::_k_sourceColumnsAboutToBeInserted); + connect(m_sourceModel, &QAbstractItemModel::columnsInserted, this, &PaginateModel::_k_sourceColumnsInserted); + connect(m_sourceModel, &QAbstractItemModel::columnsAboutToBeRemoved, this, &PaginateModel::_k_sourceColumnsAboutToBeRemoved); + connect(m_sourceModel, &QAbstractItemModel::columnsRemoved, this, &PaginateModel::_k_sourceColumnsRemoved); + connect(m_sourceModel, &QAbstractItemModel::columnsAboutToBeMoved, this, &PaginateModel::_k_sourceColumnsAboutToBeMoved); + connect(m_sourceModel, &QAbstractItemModel::columnsMoved, this, &PaginateModel::_k_sourceColumnsMoved); + + connect(m_sourceModel, &QAbstractItemModel::dataChanged, this, &PaginateModel::_k_sourceDataChanged); + connect(m_sourceModel, &QAbstractItemModel::headerDataChanged, this, &PaginateModel::_k_sourceHeaderDataChanged); + + connect(m_sourceModel, &QAbstractItemModel::modelAboutToBeReset, this, &PaginateModel::_k_sourceModelAboutToBeReset); + connect(m_sourceModel, &QAbstractItemModel::modelReset, this, &PaginateModel::_k_sourceModelReset); + + connect(m_sourceModel, &QAbstractItemModel::rowsInserted, this, &PaginateModel::pageCountChanged); + connect(m_sourceModel, &QAbstractItemModel::rowsRemoved, this, &PaginateModel::pageCountChanged); + connect(m_sourceModel, &QAbstractItemModel::modelReset, this, &PaginateModel::pageCountChanged); + } + endResetModel(); + emit sourceModelChanged(); + } +} + +QHash< int, QByteArray > PaginateModel::roleNames() const +{ + return m_sourceModel ? m_sourceModel->roleNames() : QAbstractItemModel::roleNames(); +} + +int PaginateModel::rowsByPageSize(int size) const +{ + return m_hasStaticRowCount ? size + : !m_sourceModel ? 0 + : qMin(m_sourceModel->rowCount()-m_firstItem, size); +} + +int PaginateModel::rowCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : rowsByPageSize(m_pageSize); +} + +QModelIndex PaginateModel::mapToSource(const QModelIndex& idx) const +{ + if(!m_sourceModel) + return QModelIndex(); + return m_sourceModel->index(idx.row()+m_firstItem, idx.column()); +} + +QModelIndex PaginateModel::mapFromSource(const QModelIndex& idx) const +{ + Q_ASSERT(idx.model() == m_sourceModel); + if(!m_sourceModel) + return QModelIndex(); + return index(idx.row()-m_firstItem, idx.column()); +} + +QVariant PaginateModel::data(const QModelIndex& index, int role) const +{ + if(!m_sourceModel) + return QVariant(); + QModelIndex idx = mapToSource(index); + return idx.data(role); +} + +void PaginateModel::firstPage() +{ + setFirstItem(0); +} + +void PaginateModel::lastPage() +{ + setFirstItem((pageCount() - 1)*m_pageSize); +} + +void PaginateModel::nextPage() +{ + setFirstItem(m_firstItem + m_pageSize); +} + +void PaginateModel::previousPage() +{ + setFirstItem(m_firstItem - m_pageSize); +} + +int PaginateModel::currentPage() const +{ + return m_firstItem/m_pageSize; +} + +int PaginateModel::pageCount() const +{ + if(!m_sourceModel) + return 0; + const int r = (m_sourceModel->rowCount()%m_pageSize == 0) ? 1 : 0; + return qCeil(float(m_sourceModel->rowCount())/m_pageSize) - r; +} + +bool PaginateModel::hasStaticRowCount() const +{ + return m_hasStaticRowCount; +} + +void PaginateModel::setStaticRowCount(bool src) +{ + if (src == m_hasStaticRowCount) { + return; + } + + m_hasStaticRowCount = src; + beginResetModel(); + endResetModel(); +} + +////////////////////////////// + +void PaginateModel::_k_sourceColumnsAboutToBeInserted(const QModelIndex& parent, int start, int end) +{ + Q_UNUSED(end) + if(parent.isValid() || start!=0) { + return; + } + beginResetModel(); +} + +void PaginateModel::_k_sourceColumnsAboutToBeMoved(const QModelIndex& sourceParent, int sourceStart, int sourceEnd, const QModelIndex& destParent, int dest) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + beginResetModel(); +} + +void PaginateModel::_k_sourceColumnsAboutToBeRemoved(const QModelIndex& parent, int start, int end) +{ + Q_UNUSED(end) + if(parent.isValid() || start!=0) { + return; + } + beginResetModel(); +} + +void PaginateModel::_k_sourceColumnsInserted(const QModelIndex& parent, int start, int end) +{ + Q_UNUSED(end) + if(parent.isValid() || start!=0) { + return; + } + endResetModel(); +} + +void PaginateModel::_k_sourceColumnsMoved(const QModelIndex& sourceParent, int sourceStart, int sourceEnd, const QModelIndex& destParent, int dest) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + endResetModel(); +} + +void PaginateModel::_k_sourceColumnsRemoved(const QModelIndex& parent, int start, int end) +{ + Q_UNUSED(end) + if(parent.isValid() || start!=0) { + return; + } + endResetModel(); +} + +void PaginateModel::_k_sourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector &roles) +{ + if(topLeft.parent().isValid() || bottomRight.row()lastItem()) { + return; + } + + QModelIndex idxTop = mapFromSource(topLeft); + QModelIndex idxBottom = mapFromSource(bottomRight); + if(!idxTop.isValid()) + idxTop = index(0); + if(!idxBottom.isValid()) + idxBottom = index(rowCount()-1); + + emit dataChanged(idxTop, idxBottom, roles); +} + +void PaginateModel::_k_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last) +{ + Q_UNUSED(last) + if(first==0) + emit headerDataChanged(orientation, 0, 0); +} + +void PaginateModel::_k_sourceModelAboutToBeReset() +{ + beginResetModel(); +} + +void PaginateModel::_k_sourceModelReset() +{ + endResetModel(); +} + +bool PaginateModel::isIntervalValid(const QModelIndex& parent, int start, int /*end*/) const +{ + return !parent.isValid() && start<=lastItem(); +} + +bool PaginateModel::canSizeChange() const +{ + return !m_hasStaticRowCount && currentPage() == pageCount()-1; +} + +void PaginateModel::_k_sourceRowsAboutToBeInserted(const QModelIndex& parent, int start, int end) +{ + if(!isIntervalValid(parent, start, end)) { + return; + } + + if(canSizeChange()) { + const int insertedCount = end-start; + const int newStart = qMax(start-m_firstItem, 0); + beginInsertRows(QModelIndex(), newStart, newStart+insertedCount); + } else { + beginResetModel(); + } +} + +void PaginateModel::_k_sourceRowsInserted(const QModelIndex& parent, int start, int end) +{ + if(!isIntervalValid(parent, start, end)) { + return; + } + + if(canSizeChange()) { + endInsertRows(); + } else { + endResetModel(); + } +} + +void PaginateModel::_k_sourceRowsAboutToBeMoved(const QModelIndex& sourceParent, int sourceStart, int sourceEnd, const QModelIndex& destParent, int dest) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + //NOTE could optimize, unsure if it makes sense + beginResetModel(); +} + +void PaginateModel::_k_sourceRowsMoved(const QModelIndex& sourceParent, int sourceStart, int sourceEnd, const QModelIndex& destParent, int dest) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + endResetModel(); +} + +void PaginateModel::_k_sourceRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) +{ + if(!isIntervalValid(parent, start, end)) { + return; + } + + if(canSizeChange()) { + const int removedCount = end-start; + const int newStart = qMax(start-m_firstItem, 0); + beginRemoveRows(QModelIndex(), newStart, newStart+removedCount); + } else { + beginResetModel(); + } +} + +void PaginateModel::_k_sourceRowsRemoved(const QModelIndex& parent, int start, int end) +{ + if(!isIntervalValid(parent, start, end)) { + return; + } + + if(canSizeChange()) { + endRemoveRows(); + } else { + beginResetModel(); + } +} + +int PaginateModel::lastItem() const +{ + return m_firstItem + rowCount(); +} diff --git a/discover/PaginateModel.h b/discover/PaginateModel.h new file mode 100644 index 0000000..a1b5643 --- /dev/null +++ b/discover/PaginateModel.h @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2014 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PAGINATEMODEL_H +#define PAGINATEMODEL_H + +#include + +/** + * @class PaginateModel + * + * This class can be used to create representations of only a chunk of a model. + * + * With this component it will be possible to create views that only show a page + * of a model, instead of drawing all the elements in the model. + */ +class PaginateModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize NOTIFY pageSizeChanged) + Q_PROPERTY(int firstItem READ firstItem WRITE setFirstItem NOTIFY firstItemChanged) + Q_PROPERTY(QAbstractItemModel* sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged) + Q_PROPERTY(int currentPage READ currentPage NOTIFY firstItemChanged) + Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged) + + /** If enabled, ensures that pageCount and pageSize are the same. */ + Q_PROPERTY(bool staticRowCount READ hasStaticRowCount WRITE setStaticRowCount) + + public: + explicit PaginateModel(QObject* object = nullptr); + ~PaginateModel() override; + + int pageSize() const; + void setPageSize(int count); + + int firstItem() const; + void setFirstItem(int row); + + /** + * @returns Last visible item. + * + * Convenience function + */ + int lastItem() const; + + QAbstractItemModel* sourceModel() const; + void setSourceModel(QAbstractItemModel* model); + + QModelIndex mapToSource(const QModelIndex& idx) const; + QModelIndex mapFromSource(const QModelIndex& idx) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + + int currentPage() const; + int pageCount() const; + QHash roleNames() const override; + + void setStaticRowCount(bool src); + bool hasStaticRowCount() const; + + Q_SCRIPTABLE void firstPage(); + Q_SCRIPTABLE void nextPage(); + Q_SCRIPTABLE void previousPage(); + Q_SCRIPTABLE void lastPage(); + + private Q_SLOTS: + void _k_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void _k_sourceRowsInserted(const QModelIndex &parent, int start, int end); + void _k_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _k_sourceRowsRemoved(const QModelIndex &parent, int start, int end); + void _k_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + void _k_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + + void _k_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void _k_sourceColumnsInserted(const QModelIndex &parent, int start, int end); + void _k_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _k_sourceColumnsRemoved(const QModelIndex &parent, int start, int end); + void _k_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + void _k_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + + void _k_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); + void _k_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last); + + void _k_sourceModelAboutToBeReset(); + void _k_sourceModelReset(); + + Q_SIGNALS: + void pageSizeChanged(); + void firstItemChanged(); + void sourceModelChanged(); + void pageCountChanged(); + + private: + bool canSizeChange() const; + bool isIntervalValid(const QModelIndex& parent, int start, int end) const; + + int rowsByPageSize(int size) const; + int m_firstItem; + int m_pageSize; + QAbstractItemModel* m_sourceModel; + bool m_hasStaticRowCount; +}; + +#endif diff --git a/discover/SystemFonts.cpp b/discover/SystemFonts.cpp new file mode 100644 index 0000000..ecdf9ff --- /dev/null +++ b/discover/SystemFonts.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "SystemFonts.h" +#include +#include + +SystemFonts::SystemFonts(QObject* parent) + : QObject(parent) +{ + QGuiApplication::instance()->installEventFilter(this); +} + +QFont SystemFonts::fixedFont() const +{ + return QFontDatabase::systemFont(QFontDatabase::FixedFont); +} + +QFont SystemFonts::generalFont() const +{ + return QFontDatabase::systemFont(QFontDatabase::GeneralFont); +} + +QFont SystemFonts::smallestReadableFont() const +{ + return QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont); +} + +QFont SystemFonts::titleFont() const +{ + return QFontDatabase::systemFont(QFontDatabase::TitleFont); +} + +bool SystemFonts::eventFilter(QObject* obj, QEvent* ev) +{ + if(ev->type() == QEvent::ApplicationFontChange) { + emit fontsChanged(); + } + return QObject::eventFilter(obj, ev); +} diff --git a/discover/SystemFonts.h b/discover/SystemFonts.h new file mode 100644 index 0000000..060658f --- /dev/null +++ b/discover/SystemFonts.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SYSTEMFONTS_H +#define SYSTEMFONTS_H + +#include +#include + +class SystemFonts : public QObject +{ + Q_OBJECT + Q_PROPERTY(QFont generalFont READ generalFont NOTIFY fontsChanged) + Q_PROPERTY(QFont fixedFont READ fixedFont NOTIFY fontsChanged) + Q_PROPERTY(QFont titleFont READ titleFont NOTIFY fontsChanged) + Q_PROPERTY(QFont smallestReadableFont READ smallestReadableFont NOTIFY fontsChanged) + public: + explicit SystemFonts(QObject* parent = nullptr); + + QFont generalFont() const; + QFont fixedFont() const; + QFont titleFont() const; + QFont smallestReadableFont() const; + + bool eventFilter(QObject* obj, QEvent* ev) override; + + Q_SIGNALS: + void fontsChanged(); +}; + +#endif // SYSTEMFONTS_H diff --git a/discover/UnityLauncher.cpp b/discover/UnityLauncher.cpp new file mode 100644 index 0000000..8b6000b --- /dev/null +++ b/discover/UnityLauncher.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2016 Kai Uwe Broulik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#include "UnityLauncher.h" + +#include +#include +#include + +UnityLauncher::UnityLauncher(QObject *parent) : QObject(parent) +{ + +} + +UnityLauncher::~UnityLauncher() = default; + +QString UnityLauncher::launcherId() const +{ + return m_launcherId; +} + +void UnityLauncher::setLauncherId(const QString &launcherId) +{ + m_launcherId = launcherId; +} + +bool UnityLauncher::progressVisible() const +{ + return m_progressVisible; +} + +void UnityLauncher::setProgressVisible(bool progressVisible) +{ + if (m_progressVisible != progressVisible) { + m_progressVisible = progressVisible; + + update({ {QStringLiteral("progress-visible"), progressVisible} }); + } +} + +int UnityLauncher::progress() const +{ + return m_progress; +} + +void UnityLauncher::setProgress(int progress) +{ + if (m_progress != progress) { + m_progress = progress; + + update({ {QStringLiteral("progress"), progress / 100.0} }); + } +} + +void UnityLauncher::update(const QVariantMap &properties) +{ + if (m_launcherId.isEmpty()) { + return; + } + + QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/org/kdevelop/UnityLauncher"), + QStringLiteral("com.canonical.Unity.LauncherEntry"), + QStringLiteral("Update")); + message.setArguments({m_launcherId, properties}); + QDBusConnection::sessionBus().send(message); +} diff --git a/discover/UnityLauncher.h b/discover/UnityLauncher.h new file mode 100644 index 0000000..9f940c6 --- /dev/null +++ b/discover/UnityLauncher.h @@ -0,0 +1,56 @@ +/* + * Copyright 2016 Kai Uwe Broulik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#ifndef KDEVPLATFORM_UNITYLAUNCHER_H +#define KDEVPLATFORM_UNITYLAUNCHER_H + +#include + +class UnityLauncher : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString launcherId READ launcherId WRITE setLauncherId) + Q_PROPERTY(bool progressVisible READ progressVisible WRITE setProgressVisible) + Q_PROPERTY(int progress READ progress WRITE setProgress) + +public: + explicit UnityLauncher(QObject *parent = nullptr); + ~UnityLauncher() override; + + QString launcherId() const; + void setLauncherId(const QString &launcherId); + + bool progressVisible() const; + void setProgressVisible(bool progressVisible); + + int progress() const; + void setProgress(int progress); + +private: + void update(const QVariantMap &properties); + + QString m_launcherId; + bool m_progressVisible = false; + int m_progress = 0; + +}; + +#endif // KDEVPLATFORM_UNITYLAUNCHER_H diff --git a/discover/autotests/CMakeLists.txt b/discover/autotests/CMakeLists.txt new file mode 100644 index 0000000..6f44168 --- /dev/null +++ b/discover/autotests/CMakeLists.txt @@ -0,0 +1,14 @@ +ecm_add_test(IconColorsTest.cpp ../IconColors.cpp TEST_NAME IconColorsTest LINK_LIBRARIES Qt5::Test Qt5::Gui) +ecm_add_test(PaginateModelTest.cpp ../PaginateModel.cpp ${CMAKE_SOURCE_DIR}/libdiscover/tests/modeltest.cpp TEST_NAME PaginateModelTest LINK_LIBRARIES Qt5::Test Qt5::Gui) +target_include_directories(PaginateModelTest PUBLIC ${CMAKE_SOURCE_DIR}/libdiscover/) + +if(BUILD_DummyBackend) + add_test(NAME toplevels COMMAND Plasma::Discover --test "${CMAKE_CURRENT_SOURCE_DIR}/toplevels.qml") + add_test(NAME install COMMAND Plasma::Discover --test "${CMAKE_CURRENT_SOURCE_DIR}/install.qml") + + add_test(NAME appstreamUrl COMMAND Plasma::Discover --test "${CMAKE_CURRENT_SOURCE_DIR}/appstreamUrl.qml" "appstream://techie1") + add_test(NAME missingResource COMMAND Plasma::Discover --test "${CMAKE_CURRENT_SOURCE_DIR}/missingResource.qml" "appstream://caca") + add_test(NAME apparg COMMAND Plasma::Discover --test "${CMAKE_CURRENT_SOURCE_DIR}/appstreamUrl.qml" --application techie1) + add_test(NAME categoryarg COMMAND Plasma::Discover --test "${CMAKE_CURRENT_SOURCE_DIR}/categoryArg.qml" --category "dummy 2.1") + add_test(NAME wrongInput COMMAND Plasma::Discover --test "${CMAKE_CURRENT_SOURCE_DIR}/wrongInput.qml" "CMakeLists.txt") +endif() diff --git a/discover/autotests/DiscoverTest.qml b/discover/autotests/DiscoverTest.qml new file mode 100644 index 0000000..2e763a4 --- /dev/null +++ b/discover/autotests/DiscoverTest.qml @@ -0,0 +1,106 @@ +import QtQuick 2.1 +import QtQuick.Controls 1.4 +import QtTest 1.1 +import org.kde.discover.app 1.0 + +Item +{ + id: testRoot + + signal reset() + property QtObject appRoot + + StackViewDelegate { + id: noTransitionsDelegate + popTransition: StackViewTransition { immediate: true } + pushTransition: StackViewTransition { immediate: true } + replaceTransition: StackViewTransition { immediate: true } + } + + function verify(condition, msg) { + if (!condition) { + console.trace(); + var e = new Error(condition + (msg ? (": " + msg) : "")) + e.object = testRoot; + throw e; + } + } + + function compare(valA, valB, msg) { + if (valA !== valB) { + console.trace(); + var e = new Error(valA + " !== " + valB + (msg ? (": " + msg) : "")) + e.object = testRoot; + throw e; + } + } + + function typeName(obj) { + var name = obj.toString(); + var idx = name.indexOf("_QMLTYPE_"); + return name.substring(0, idx); + } + + function isType(obj, typename) { + return obj && obj.toString().indexOf(typename+"_QMLTYPE_") == 0 + } + + function findChild(obj, typename) { + if (isType(obj, typename)) + return obj; + for(var v in obj.data) { + var v = findChild(obj.data[v], typename) + if (v) + return v + } + return null + } + + SignalSpy { + id: spy + } + + function waitForSignal(object, name, timeout) { + if (!timeout) timeout = 5000; + + spy.signalName = "" + spy.target = object; + spy.signalName = name; + verify(spy); + verify(spy.valid); + + try { + spy.wait(timeout); + } catch (e) { + console.warn("wait for signal '"+name+"' unsuccessful") + return false; + } + return spy.count>0; + } + + function waitForRendering() { + return waitForSignal(Helpers.mainWindow, "frameSwapped") + } + + property string currentTest: "" + onCurrentTestChanged: console.log("changed to test", currentTest) + + Connections { + target: ResourcesModel + property bool done: false + onIsFetchingChanged: { + if (ResourcesModel.isFetching) + return; + + done = true; + for(var v in testRoot) { + if (v.indexOf("test_") == 0) { + testRoot.currentTest = v; + testRoot.reset(); + testRoot[v](); + } + } + Qt.quit(); + } + } +} diff --git a/discover/autotests/IconColorsTest.cpp b/discover/autotests/IconColorsTest.cpp new file mode 100644 index 0000000..46a3dd1 --- /dev/null +++ b/discover/autotests/IconColorsTest.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "../IconColors.h" + +class IconColorsTest : public QObject +{ + Q_OBJECT +public: + IconColorsTest() {} + +private Q_SLOTS: + void testIcon_data() { + QTest::addColumn("iconName"); + QTest::addColumn("hue"); + + QTest::newRow("empty") << "" << 15; + +// Commented out because it's very hard to figure out why it doesn't pass on the CI +// maybe using another theme? +// QTest::newRow("akregator") << "akregator" << 15; +// QTest::newRow("korganizer") << "korganizer" << 105; + } + + void testIcon() { + QFETCH(QString, iconName); + QFETCH(int, hue); + if (QIcon::fromTheme(iconName).isNull()) { + QSKIP("Icon not found"); + } + + IconColors colors; + colors.setIconName(iconName); + + QCOMPARE(colors.dominantColor().hue(), hue); + } + + void testFlatIcon() { + const QColor color = QColor::fromHsvF(0, 1, 1, 1); + QPixmap px(32, 32); + px.fill(color); + const QIcon icon(px); + + IconColors colors; + colors.setIcon(icon); + + QCOMPARE(colors.dominantColor().hue(), 5); + } +}; + +QTEST_MAIN( IconColorsTest ) + +#include "IconColorsTest.moc" diff --git a/discover/autotests/PaginateModelTest.cpp b/discover/autotests/PaginateModelTest.cpp new file mode 100644 index 0000000..a564269 --- /dev/null +++ b/discover/autotests/PaginateModelTest.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "../PaginateModel.h" +#include +#include + +class PaginateModelTest : public QObject +{ + Q_OBJECT +public: + PaginateModelTest() + : m_testModel(new QStandardItemModel) + { + for(int i=0; i<13; ++i) { + m_testModel->appendRow(new QStandardItem(QStringLiteral("figui%1").arg(i))); + } + } + +private Q_SLOTS: + void testPages() { + PaginateModel pm; + new ModelTest(&pm, &pm); + pm.setSourceModel(m_testModel); + pm.setPageSize(5); + QCOMPARE(pm.pageCount(), 3); + QCOMPARE(pm.rowCount(), 5); + QCOMPARE(pm.firstItem(), 0); + QCOMPARE(pm.currentPage(), 0); + pm.nextPage(); + QCOMPARE(pm.rowCount(), 5); + QCOMPARE(pm.currentPage(), 1); + pm.nextPage(); + QCOMPARE(pm.rowCount(), 3); + QCOMPARE(pm.currentPage(), 2); + + pm.firstPage(); + QCOMPARE(pm.firstItem(), 0); + pm.setFirstItem(0); + QCOMPARE(pm.firstItem(), 0); + QCOMPARE(pm.currentPage(), 0); + pm.lastPage(); + QCOMPARE(pm.firstItem(), 10); + QCOMPARE(pm.currentPage(), 2); + } + + void testPageSize() { + PaginateModel pm; + new ModelTest(&pm, &pm); + pm.setSourceModel(m_testModel); + pm.setPageSize(5); + QCOMPARE(pm.pageCount(), 3); + pm.setPageSize(10); + QCOMPARE(pm.pageCount(), 2); + pm.setPageSize(5); + QCOMPARE(pm.pageCount(), 3); + } + + void testItemAdded() { + PaginateModel pm; + new ModelTest(&pm, &pm); + pm.setSourceModel(m_testModel); + pm.setPageSize(5); + QCOMPARE(pm.pageCount(), 3); + QSignalSpy spy(&pm, &QAbstractItemModel::rowsAboutToBeInserted); + m_testModel->insertRow(3, new QStandardItem(QStringLiteral("mwahahaha"))); + m_testModel->insertRow(3, new QStandardItem(QStringLiteral("mwahahaha"))); + QCOMPARE(spy.count(), 0); + m_testModel->appendRow(new QStandardItem(QStringLiteral("mwahahaha"))); + + pm.lastPage(); + for (int i=0; i<7; ++i) + m_testModel->appendRow(new QStandardItem(QStringLiteral("mwahahaha%1").arg(i))); + QCOMPARE(spy.count(), 4); + pm.firstPage(); + + for (int i=0; i<7; ++i) + m_testModel->appendRow(new QStandardItem(QStringLiteral("faraway%1").arg(i))); + QCOMPARE(spy.count(), 4); + } + + void testItemRemoved() { + PaginateModel pm; + new ModelTest(&pm, &pm); + pm.setSourceModel(m_testModel); + pm.setPageSize(5); + QCOMPARE(pm.pageCount(), 5); + QSignalSpy spy(&pm, &QAbstractItemModel::rowsAboutToBeRemoved); + m_testModel->removeRow(3); + QCOMPARE(spy.count(), 0); + spy.clear(); + + pm.lastPage(); + m_testModel->removeRow(m_testModel->rowCount()-1); + QCOMPARE(spy.count(), 1); + } + + void testMove() { + PaginateModel pm; + new ModelTest(&pm, &pm); + pm.setSourceModel(m_testModel); + pm.setPageSize(5); + m_testModel->moveRow({}, 0, {}, 3); + } + +private: + QStandardItemModel* const m_testModel; +}; + +QTEST_MAIN( PaginateModelTest ) + +#include "PaginateModelTest.moc" diff --git a/discover/autotests/appstreamUrl.qml b/discover/autotests/appstreamUrl.qml new file mode 100644 index 0000000..e6ef804 --- /dev/null +++ b/discover/autotests/appstreamUrl.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +import QtTest 1.1 + +DiscoverTest +{ + function test_open() { + verify(appRoot.stack.currentItem, "has a page"); + while (appRoot.stack.currentItem.title === "") + verify(waitForRendering()); + compare(appRoot.stack.currentItem.title, "techie1", "same title"); + } +} diff --git a/discover/autotests/categoryArg.qml b/discover/autotests/categoryArg.qml new file mode 100644 index 0000000..7a4a5a9 --- /dev/null +++ b/discover/autotests/categoryArg.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +import QtTest 1.1 + +DiscoverTest +{ + function test_openCategory() { + verify(appRoot.stack.currentItem, "has a page"); + while (appRoot.stack.currentItem.title === "") + verify(waitForRendering()); + compare(appRoot.stack.currentItem.title, "dummy 2.1", "same title"); + } +} diff --git a/discover/autotests/install.qml b/discover/autotests/install.qml new file mode 100644 index 0000000..d09b626 --- /dev/null +++ b/discover/autotests/install.qml @@ -0,0 +1,45 @@ +import QtQuick 2.0 +import org.kde.discover.app 1.0 +import QtTest 1.1 + +DiscoverTest +{ + function test_openResource() { + var resourceName = "Dummy 1"; + app.openApplication(resourceName); + verify(appRoot.stack.currentItem, "has a page"); + compare(appRoot.stack.currentItem.title, resourceName, "same title"); + + var button = findChild(appRoot.stack.currentItem, "InstallApplicationButton") + verify(!button.isActive) + button.click() + verify(button.isActive) + verify(waitForSignal(button, "isActiveChanged")) + verify(!button.isActive) + } + + SignalSpy { + id: cancelSpy + target: TransactionModel + signalName: "transactionCancelled" + } + function test_cancel() { + var resourceName = "Dummy 2"; + app.openApplication(resourceName); + verify(appRoot.stack.currentItem, "has a page"); + compare(appRoot.stack.currentItem.title, resourceName, "same title"); + + var button = findChild(appRoot.stack.currentItem, "InstallApplicationButton") + verify(!button.isActive) + + cancelSpy.clear() + var state = button.application.state; + + button.click() + verify(button.isActive) + button.listener.cancel() + verify(!button.isActive) + compare(cancelSpy.count, 1) + verify(state == button.application.state) + } +} diff --git a/discover/autotests/missingResource.qml b/discover/autotests/missingResource.qml new file mode 100644 index 0000000..af6bc82 --- /dev/null +++ b/discover/autotests/missingResource.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 +import QtTest 1.1 + +DiscoverTest +{ + function test_open() { + verify(!appRoot.defaultStartup) + compare(appRoot.stack.currentItem.title, "Home") + } +} diff --git a/discover/autotests/packageArgument.qml b/discover/autotests/packageArgument.qml new file mode 100644 index 0000000..859126b --- /dev/null +++ b/discover/autotests/packageArgument.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +import QtTest 1.1 + +DiscoverTest +{ + function test_open() { + verify(appRoot.stack.currentItem, "has a page"); + while (appRoot.stack.currentItem.title === "Loading...") + waitForRendering(); + compare(appRoot.stack.currentItem.title, "something", "same title"); + } +} diff --git a/discover/autotests/toplevels.qml b/discover/autotests/toplevels.qml new file mode 100644 index 0000000..ac63f2b --- /dev/null +++ b/discover/autotests/toplevels.qml @@ -0,0 +1,83 @@ +import QtQuick 2.0 +import org.kde.discover.app 1.0 +import QtTest 1.1 + +DiscoverTest +{ + onReset: { + appRoot.currentTopLevel = appRoot.topBrowsingComp + } + + function test_openCategory() { + var categoryName = "dummy 3"; + app.openCategory(categoryName); + verify(appRoot.stack.currentItem, "has a page"); + compare(appRoot.stack.currentItem.title, categoryName, "same title"); + verify(waitForRendering()) + + categoryName = "dummy 4"; + app.openCategory(categoryName); + verify(appRoot.stack.currentItem, "has a page"); + compare(appRoot.stack.currentItem.title, categoryName, "same title"); + verify(waitForRendering()) + } + + function test_update() { + app.openMode("Update"); + + var updatePage = appRoot.stack.currentItem; + compare(typeName(updatePage), "UpdatesPage") + compare(updatePage.state, "has-updates", "to update") + var button = findChild(updatePage, "Button") + verify(button); + button.clicked(); + compare(updatePage.state, "has-updates", "updating") + + //make sure the window doesn't close while updating + verify(appRoot.visible); + verify(waitForRendering()) + appRoot.close() + verify(appRoot.visible); + + while(ResourcesModel.updatesCount>0) + verify(waitForSignal(ResourcesModel, "updatesCountChanged")) + compare(updatePage.state, "now-uptodate", "update finished") + compare(ResourcesModel.updatesCount, 0, "should be up to date") + } + + function test_search() { + app.openMode("Browsing"); + var searchField = findChild(appRoot.globalDrawer, "TextField"); + verify(searchField); + searchField.text = "cocacola" + verify(waitForSignal(appRoot.stack, "currentItemChanged")) + while(!isType(appRoot.stack.currentItem, "ApplicationsListPage")) + verify(waitForSignal(appRoot.stack, "currentItemChanged")) + var listPage = appRoot.stack.currentItem + compare(listPage.count, 0) + verify(waitForSignal(listPage, "searchChanged")) + compare(listPage.search, "cocacola") + searchField.text = "dummy" + verify(waitForSignal(listPage, "searchChanged")) + compare(listPage.search, searchField.text) + compare(listPage.count, ResourcesModel.rowCount()/2) + } + + function test_modes() { + app.openMode("Browsing"); + compare(appRoot.currentTopLevel, appRoot.topBrowsingComp, "correct component, browsing"); + verify(waitForRendering()) + + app.openMode("Installed"); + compare(appRoot.currentTopLevel, appRoot.topInstalledComp, "correct component, installed"); + verify(waitForRendering()) + + app.openMode("Update"); + compare(appRoot.currentTopLevel, appRoot.topUpdateComp, "correct component, updates"); + verify(waitForRendering()) + + app.openMode("Sources"); + compare(appRoot.currentTopLevel, appRoot.topSourcesComp, "correct component, sources"); + verify(waitForRendering()) + } +} diff --git a/discover/autotests/wrongInput.qml b/discover/autotests/wrongInput.qml new file mode 100644 index 0000000..2b5c55a --- /dev/null +++ b/discover/autotests/wrongInput.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 +import QtTest 1.1 + +DiscoverTest +{ + function test_open() { + } +} diff --git a/discover/featured.json b/discover/featured.json new file mode 100644 index 0000000..e2358a7 --- /dev/null +++ b/discover/featured.json @@ -0,0 +1,17 @@ +[ + { + "icon": "kde", + "image": "qrc:/qml/DefaultBanner.qml", + "text": "KDE", + "comment": "Awesomeness!", + "url": "http://kde.org", + "color": "blue" + }, + { + "icon": "kde", + "image": "http://kde.org/images/teaser/jointhegame.gif", + "text": "Support KDE", + "comment": "Join the Game!", + "url": "https://relate.kde.org/civicrm/contribute/transact?reset=1&id=5" + } +] diff --git a/discover/icons/128-apps-plasmadiscover.png b/discover/icons/128-apps-plasmadiscover.png new file mode 100644 index 0000000000000000000000000000000000000000..a20f4749b9b4ea18eb08aa39bd976b5a565ec7ba GIT binary patch literal 18930 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 b;j{k*7r8(kh58j*00000NkvXXu0mjf#p<<$ literal 0 HcmV?d00001 diff --git a/discover/icons/48-apps-plasmadiscover.png b/discover/icons/48-apps-plasmadiscover.png new file mode 100644 index 0000000000000000000000000000000000000000..81d05b1aa71421a9c14137333219b4bf370bd531 GIT binary patch literal 3466 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 literal 0 HcmV?d00001 diff --git a/discover/icons/CMakeLists.txt b/discover/icons/CMakeLists.txt new file mode 100644 index 0000000..aca7055 --- /dev/null +++ b/discover/icons/CMakeLists.txt @@ -0,0 +1,11 @@ +ecm_install_icons( + ICONS + 128-apps-plasmadiscover.png + 16-apps-plasmadiscover.png + 22-apps-plasmadiscover.png + 32-apps-plasmadiscover.png + 48-apps-plasmadiscover.png + sc-apps-plasmadiscover.svgz + DESTINATION ${ICON_INSTALL_DIR} + THEME hicolor +) diff --git a/discover/icons/banner.svg b/discover/icons/banner.svg new file mode 100644 index 0000000..e8da332 --- /dev/null +++ b/discover/icons/banner.svg @@ -0,0 +1,194 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/discover/icons/installedcrop.jpg b/discover/icons/installedcrop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c1933504cc32ee45ada0ffc38c7a58faafd8a416 GIT binary patch literal 448647 zcmeFZcUV)|+CID!6D9<7LJWwAo&-T@p?8G|F+m7rLY0IfEws=BA}CJ4pa_VF^kzhw zl+Y0nu~DQe2-uk!q+5;@9retaZv}MDocBHN@4DW2+HGEVECoIU5I7b@=xf>?q~($}+hYr; z+y1X-j2>{w`zlSx8Wp=+`s`q|smVG=e-AL1Dt@YHC7I#$VD9|7(3TH8f!S&2s+u13Z_% z+4e_42XFbBP6GvOE7`112PpIVuj#uWjVbxp`@%~%)8KK?mcOJ${*o466LxDH*oE~H zra@on7-{GmX@S1dFwzEnrS(6am8JzkB=Yxv-U~8rl)(^zpaszAd%qrQd_RDIxS+ki ze*f`Li1=ezWI%90EXxP)6@#bIsfU9DLIUvGYMR<=+G<)3WW2_4mZqkjj*q7IAHRsb z@{f!RGg4O%;i!4~gnF?y5OCZxOkGn=LmfK!!|^arZ#F9u@5S;92r=IO?#8YC_y8Z{ z{YP}IHLSx9vHSzfV5H9}f-+;TRn^-oH_} z5l9P9tM3PyB7A&}>?memvw$Px{a@=69UZL}t*sUs;is-?XlSUep{1^+MFcsBoS2YE z&*Q`p&R$Rg8oyBng~joX2mmh)@ci|0!C`-v^&j60+>FN`1a&mB4)qD}jiG>nVgmX{ zm#Cpj)G~0;)Hc!u<4ThVx=Tajp!$Ew`R(RI5iD@yx0`i9?v0zjcJAhFf64Q2w}nPH zgoXy0m`0kW|O@eMW6G*H*XYwLm!4RsCSzIoH1*Z+D0$V}AM4G#WSmOtyT zk)L9ssjdI7ix!lByZrCf)cCgjEC0V``1V|jU{62Rw|Cpj``1(7vYCd3MT8y?2nNtF z3-ylTPy#rSo*~{W6HR@6b-+WLcm9vLz7=C88xY5T9;JU?-WaNz!}QN{Mpi68 zPwyBDy2Bw#fFFw!X`*dtrejFeHq$iF)TU~fX;AbHs9JhDWL-m3GaWr`>OuAY!_7i; z{p&IXAU~KD5@`y6&xs6;;0VXxCSQ|1{WcCZkAebB0K2OB1o#+f8EWcz>uPxteROp+ zi8|hT21G9%14E*wj-igPwyv(8o}R&GHy{b<<@_d_pkcl zg~nW{=%XUMS;qT?r3=T>*V4)VQ|bHh>cam2TD||TytX+orJ)fq8_3`DL|eaWBHgxga&W4TbO4Ahvg6x1{%)pYZGpgq)_pJw*O0h@XY@W^nASk z#9dfaM9_wo_3>6`1+j#z$N_w;`4xCR-bTKm5kM`N0LkFTQV$Gc`5jdM*V+I4+|9ZG z`3!`#`k!(e9Q-NRSs_5BM+oKkAJ3pe&=xpc_y;xw_(P(QNCX0j{_Z;wlsH;kTnsHH zwsjj8vvr%qHZd`b6h>k@PEt}*{QDi!QaEWWP7)_91hxg-gFuQRk)pV*Vq0+O%b zkOT^m_WjW&gN3dQ90GL|`3?oH?i5}D8#w)KgTcYo zKb}J3TVN0zvjsSVuz#$T5>WRLjcV#TJMLv~lQ2hDR(cLvS{_#A+Ibmf_2yi>7O}qa zy3f%_sU+7UGdE4QE9!Xbp*nT`V9S1+-5lTf2TQ?COs1_XbJaRLBconihM*&!N!+q) zm^DwnA=+NJvN|H$6?Z(q`3eCdV|bz{vN#!oK+W~6HGV#GB3iFJkSl8CC)n#MIWL)| zwiAQElgQ%7h-2Xy%Yn&ugCRuewYC)bWBjgE_to>1p=78hh*xpLGF$i6G@b8B3&?_Zmr z|KexXu+UOGu%<9kWc7^I!qzU^p_|4mwQH-T!;=+D;Ep&)_{xTv&3F__3RQ#9SM@S6NOA)BDN# zzOUJK0gpNg1@!%o|D6Pj#XBVlS%6kYrHDZE;k6~7yyLEP* zw^~P(O+tWdz1JmJ?@_~0sr$zi)(nqby-LWzwMDwwBo^TwIE6Q_ZVex6tlvrr%T9B0 z*nW~-opx@j{b^p=T%qB~rT2CX=E91@Ntk%(9>l{RR(F5ZRps}9(K_@&5q+N?J~g77 zG#V11eW+GcBom%0rc-nyMv7W0uw>KL-gg~qXo#~K^*x%sM0gi7T{C~gqTB_(y|8PS z^QTcpf6c{)T9tve7wRGGB0t^YL6<>!ud33TJFaW5`)@pT6t zG3t0XnIJ+yqRd3Sp1Me7o6n>Z@FIzYiM}vpg@sZ^R66s#80w)!bX%C`-F>W13;J z`?jZq7P;%DzaCtOcw_M(q4V|2Q%}~G_S@>o9l>@Ex|UX&9-@S&oW;=#_FB6}ZtE$y zq{>Odb%h^4=PV=&A(rtdxI_{O5pgf#bIncNQTLuIJ19Y2WA%K5xCqNG55rQHcfrq> zx~rv^TBx;uE)CB|fbLCLJgIoAVqTfZcpM9L5UJ==_aMgI9ElyrO(~{)r~2Nv&N(ZCA&?~ZA(JIXh)QN zQXE+B4xJt4=c;V(hE^jRuZj-jDAg}qV$|8zRF)1Ad~P0GrWhL!I!HMTBc$6*(dco# z+}GEncw_|5Oxi!HoT+f1Rpse`rzfNfdLRJMjTQwX4Lk1HqLb>-o;vH549>#D#KbJi zT2&8A69_myK^c>UqCk%E=mtpYzoEenVU3r=mTrIG9oyjn*`Yx|ZHHOHxK)4}j#kwm z-GiS^JX1O8hT+do?TnFfz3JLvF;=@6R654Y%B@c8ia9>Hy-EGb;Pw4xqVX}u<{m8- zIZU2&rLO9&j5R={hq4iOG2Rwc>b3LC;hJ%^Eu({TQ)jZ0H^6`qk_2Ek0$js-|JD5U zCgTJ8kF%A&!wjnDUgu5`v~jm_30#GxYn0w1@F6}t=LY9hOcX4|FQhk;`Mt0 zk7;0j1Ykije6={QtoD4ky0OYs{{6z%*ue*9`3}{D>$@YKEL*;5fA?_y`1)u8=lOh` ziBXU{bu?#j^x~9ERB=y{Su^#CTTwvHA-k$e3L_`>)FH@lf~1G!05TDn3=)}ZYpMw6 zqT`+TaOUv3B-&fG3JC@x2E(%HN?FFfW#7txi=w9VWZTog#+$Sd zmIK|#ftV(UD%n$0{}`F2?J1&$s~pK~(He8+6Hr)0_|IxF9D%l>tD=-#iiH;%4t+(! zS7WiAzF{n2Bsc~k8qR;XgSK!F!-Hq?6vz$)EMSA%iOyUxh%Aps!5k?n61GyA5FVm& zlW6I30iuX^-f8!VYlXjWSBO|19ga}lA9(aoPKeD#&xZEXV~|~F=B)12)X!%%-iQ*1Sj6Tnn|OGxpf|>D_*{w`0S7?J0-1q zGIF+Qf?XzGHCvvl%M#cdTg25Fe-?iy)iB()Cfl;4eKTdCZPhqt<@3C6)1*y&iGNS~ zWakUL{yeQZ$zKw^-P`pn5 zj75-!IZ08DlyOBh1uGB3p;b%ZJOn%ea}FY*s|d~sVl-e16-X2Xb3~>2{-1WO?YfQa zk#sOcKxGZ#LGEld9PW(0f)gI4S*4fH&ys!m>tNrb_Sp7N>#V9fIKgSF?Yf-h)9U+r z4`_W>y>af5HBu#4AkdL2+rO>zMQ39J?GBxws)`b`K67{dW#p5W37UH%SBAsvN+2#! zlNbO5G9*uc8+40`IrVhDIeabe-IE861*qHFbr~JMD(61xM7@=Yl?7@jZvDCj&j{Z1tcUSlq!i-pk; z$;$XFQ{~$bijN>*p@d2txdE|B4(TYGgq*`Q#JibO)yE;6Eft#~l`Y#S+xCD-hBswO zW~I;$IRvHLrE_fLR&>>Js&`#-3!q##jHwbW90xM|~$+Ffq*Lz8ho5Mzhdo<;}`PM>m) z^*h!yamjA^yzWEcqvkprsV z;FB5mh!K@Qd2tmm!2dBPJqDey*V#-a*C#Oij5Gl{6M5f5o5o5s^ES@7fSd(t2Nki%@_U`57nM`4|qCspXUv z9o=fyTYpaZRku{*6Dop)<-*B_5Y&D(g(QUzPj@x5C3 zd|O&K${c@MW-2f+#f*SNz_I6)B_LA90}?sGkqd{!AQC1C2ic;#F-$tdD?2CDj`FlD ze9`OBC!rXG6cPqH^U8gr=h+B(Wfg3uDati4g{o+n(jzd=9-KJeFKCu?6bleYmkhD* zy3;hLavmIxu;~br_B_jX@-#4t>20q}$Vxgw(`;)am+ZEWJQ}iERfNd%Z5r8Q^KNu# z5(Y_}Q8*aD9J-&7{?*2Lm}4^w)_@?C6 z>8M_m3~?G8xL$8y5s z1Ta7dD#=TYl{Ga22bI<~2UAL>G9Cj@zJf!DmJ$8OvW8}viSeY15KRn~&Xwy{!D0wo zF;@|R;WeITWcP}bA@Wr@&US4x$7JzVU*vgD<;F|yp`NuXFA$hOc!o-LMo9xz!4k({ zC(kkhQwN7~vKZGa$6IzEP$MZQ%gA42>G?I#wrl;WN(4}F`~F97XN4+xa#jB|Cfot^ zxCm;;K_6GK%o+v>W0&=q3jq*tH;^ETA|ZHqGBa3D;TJ$IIHZ@V8IkHwpiDYvSGv9Z{FkC%L8*`;9>Ep$ zxGgOQ!MV)Di($X+wDEeca)DL-XfQBX*SSpZF+0KDSDQPfAUc_IYxn8eeK+=~5mgCp zoY5ab3$GV)O{v&)?|=xWX2jC28S2gLl|`a^wDw=FlbbGTFNb)jJEEQ~k(Rl4IP}u5 zXqLFE;gDt+@xl9X|DxInW?_oq*~@HRXJTc!GFN~aj^M%oe|VRL%+6}fkAFH^!I`$# zCpvoD_lqdlb0ljwQYx}c|y0Nsku-f2%As%f!G{W zC`;?!=1%2Asu#DW*4$1~5-}O7TNY1{jG$vOgHkZ6zDgt{SCXQ71-y(R0hkqd5`p2Y zL?U5%XdoMfmI3q5+kH7k9!*v?uTO`YqA(~8D&8D}huQI#-9l5`n%LtTp>C_M*0wO^SoHVz zc?W;*vZy=Y8vvp;X3`IC=2Z`wu{HKZ0;30b4KgS3;_+nX(4&lkrI5I|0mi(_nXZ5s z%S-{Nv+7QtDa~900^if;wVXY8nL2x_cChXcT36(%IPSC~`&IQT{=lT1SaX%41KYzzusr%u;bhcXVbj=6vhnABC z&xiww67hzjmCI`Vp%n`F1~;e7EL>I()eDVJPA^GP#F4plh>l6@kE(~4dnzy`kOT;L z5Uu9QluC*`o-9KEra{OE2rqP1X5RMV+^38{ZRw!l9f3z#Nl;MEl_K^?tvrprRms(n zsL5dRn356!UhV8*23uQQ%iWPxrf$<6IT$2RR&9Jih8Q+wQt*V+($zpHRR1!lN|wwE zDjB#2X^}zG?o?C66{wbtrwh># z0?>e}(t@Y!s-~dg$-d!!nAVy|LXMu?p$vI~~Y&-UGrj##A-G8*bGySw$fH{WbqDF1?<)7iC`A80A= zhn^;eAV??;B@$bWHkq({Z|t(sen!!Q_gM$myDS7~7A+BPhM%{t;|zC=>PPoC75N!v zLS$1C9Fhl48c!a7FQ@KG&NJ<0wG+DYL8~lW10&F1U+wncoSZu@WgV%aELoJWHT z&tpI9b*|6$K3absz3gZ0r{emLk0H*n-ch40W1Xp^2OeKn-Z@iT$otOgdhHC?7M)B( z+hvqAHc)X4Qb`ILt|*0X#?v8k_8DGFnFk%LkP!tY7Xib<$H*8(|Mb1$S`yc;oY`qk zB9K{z*NOs}R%Z{Ej&lS8lKJF~)mp=e2c~9s6%%c(T2NJDz<_5Bx(Cuya_1}uYMRUX zm^SG>igN|TN4C_)^R%Eu5&J^->wT6+U9x)Q8(I?(m2{L|X@@pt+{%-Fs<%23fO$_I^57 zIt%5mMr9^NT9>yh6gfP-knONK`CD)27hM#D@W|fn+jVw$p|m^ZJbP%dzg`}IEq9(_ z=LBK!fHA}|h`my~bw8}cRvTj(oP-{_#$8_9*~>>S55M1$n*~jT^w^7OEDb&%Ts~+N zUFNb|njl@XYIL$9=I-?jOA~pzGELj*-G1|`!s$svaAfJs3bPOWiUkWde zprg~l+B+V~f~HDCfT2ZEs0U$4v`|D+gi#&@L7ITNjp29uDk*ELZGo<}4o}4DY+=6X zUAOeXen;n$+XIx7Cm^+wixO-eU=R;i3Ta9v5kJ#l1x&Bl-!a?e~Bpo1PHYw+%#otZ+9m;0gXX9LCFpd z+bwSDWb;x8rcnGfPdp02mE)lmNThEdfD{1;Qb^EdXhA}bj*xjXf0Q(dBA3dOOEt`u z<*wP97N=JZp~L%RWFsDyG!Z=v+5HW}7n`55%MZKwwABoGx?_K7XT7$3mX;8tEC?&V z)TGYPQ}|A*vuH|>762Ler;jmB59{yRs`4PMDF4;*f#TR{>8WDh1~BEIG4ED)Wi>WH zO8ZFOWaqxeZ(a9S_TEH{=1;ce7cS;gfi1)E@a9;A=lT6L>@nXH#xu8k9Z)~35IpV{ zwtQN3C&V;Pvad&68)ey)PWfps6-F;Agk{Ui%I%3h^6EyP^76$RH$V-$NB7JKrko?F zEM42|_H&b$7M^!}4(QrCe`nJ8Z^YP|wHJPR^Jk~itmlJAJ=S7w#@wt9yk_NPV|!+( zKd3_l4#q-*Bv{jj#iT%RbBGG0l&Ke#P30;iFz8$yFNy4cF9kD0a0}q#K_sBV;DE0& zHI-FOd8y%}t~?`sW0|oFm~pk|?`(qO35t)YDk@B`b8MUxQL%*VTT|ISl_y)Ph0<)$ zxyNW;WR%>IOtECizq;&u_br$TS^O~Rj^_$TwDy+O`s;3w;LCvP+D ze&>XAE?_zoDa|=*>e=kl#|uYT3s}3Jy>M>1;mOlSHF7QxC)bD~i0`N;@-92fjF0); z+r|y!u0Fjbw>TPqWAu{i&DZbtG#EJyq8r@?ohZG8)$PkvV|z6f=%?B0n9(G|pz6ZUYOVC@39F`;pS+QI=cJ2pIw5Vr)r35nAtiHRh}- zMNWWiF}q)ueg%FT135||Kt$mjRL{jjAZjAPrt(2_3HXxA^mE&(10pvVQxBq&FxSYE z@+fmr?4#t=Ii}#6ma;sG3`_BPh)%YNU3uLQE7AEp|1~<%LpyiK&!BAg3G9c)r3&hv zrrNzi1zFNmsIbBwZM-72Hx=!5x7(}droK$}s@GcHBdey0%XKo-MZWbAOxo*S{q%!R zqtx_oO&h<8)Qvs7D>0A_9V)$_7(ZIfz z$>{9IsGGi?d)gAUikT5s<}BdS{1&y5D}ItagiGq{As`Ysn8?Xz?_>! zbL~IB+xB3#6R7Pt)`V%e-1THHFh@&xvti}61zHD^JX&k{Q^hO zJUJ=Alxyuba&7f#GW^aQ$pum%9+DPADWQbp9(9ofMiU;H&V_d;!-Uf}WI7%oX5$YM z^?-@OOp(}uBbvP19B-K`o)hg$P7i;%WHs5j^vNBM+^Tyf-pZDUeT0`#Lh|w%o(^p` zEKapz=2fW*>jME@eE)*dG7`H&DnN$qx3-sz6uADkI>i*WNC!98F zSiO2G|3mJm%|SuS{JOy^E?Ef#{No95!+?b!IeyLU)0{|q2RW1?>E!mADJ0%7nitgq_It5YCwN<_{D0=dB2~GwVubk@xE1b%yTKDgFnbn$@6_;{86pA z!r1W0nk$+g{kY7$_P((Z0y2 z4LYkcSYgy*FQ%MzW-v+>W=m(ph%!L90K!Jca2ccWp$7~&W zM+{vqsRa!~V7wVOb)^u=1WzaI-Cc6G@p!Bvn5B+K*8`;s@!(t#O6zu@@Bxg4tN_O= zQnnuB)LmIdr2F%d%{5W*2D!$vG6*dh1cztZ9!{YuYZtE1GRoaMqtY%NIODpW-s@c> zvK>Y?S}R-Zvo>-p(b=&tY04?pr_R_ts>XtjP{3c6IgAmxR9|2@Wie*0sO@hfd3^F8 z%eq_$b%%I>^AqLOnm=vCq+;m0z@)w*?w0BNExt|kog=W}x{S!_wvo7Oj#ZaEbA{Oz zI0F~HH+Wl(dj+E$_a~PRg`XLKV5dbI)h`sRuDXY7(zr%?pHFtR^i>?g-@)JSHkdj} zoc=*KHlk(Jbb-@38FQ2KcHZrNEWd`?@A`DEslz03u%fES;PZTM+uPZt3hR#CsKLB( z+>;ig!{4yrEnhf8^ls#NCV&V64$MNraAH^}83;yz1`?hiN`^rt{n%1KwLCn41sHE| zIv0Xa$~57Tgi=j~aZKOAkvggTOILlnZ#r|VI<%`5uoIF!0j&JU#w(1=`UhJiEuDEz zW?Pk#-E}&b__hHSNA@!gNCnp4?V%;X1onhcK`_ULk+(Az`%b@nW!1Dy*X-9{hN61v4z?jM zwlpO(eT78j#Q6Xt>T>16zDx$Ezxyv1;zsdh>Z>&=O}p^rIb-#`&UUjO|M77xX4Dg} zEc^7+->ko!91TyU&Pz}AhWr+1!%-wdcmkX(E|D^7ccS}){!Z1qsm2;J(o-XYvkI?d z%La8LV*S6U@45NJVhgrNI%VMcoXq^3x{XbHS@c}flY4D%{M`6Sux-b3RWAE}GCA8< zQ3IebJJ9xS?sK#?b5#3ed&j_&Yes&5LP3t>P4sTkVj4Js89XFtcwigAG7yZ=X%ISJ zrsi;f3ebQ6-6S-)2*7{=;tNFYa{K%==G1f}CuF7=g1KMrZ+EzEZDN75bR~a&c#TEQ zEOKvmR?XB&HEJCRZ;9UbaL{sa+_gjg zfxYX%>L9NM%wJTCwzVj`&Yf;8l3RZq(nParIxN-6ITf6LUlFd+Q}L6r$=QKe*izH! zqgo5Iu4S$#MoxTonD1;m6BDDmvaR5wVeuCOtyxU@Xxh7q?9OE{3IPw2NvY1qzCTg0 zwsm!ybG!a(HFd)OjNDb(TiQ7;r{;@qUN(M{EsoN$gmZSxxy;YLb2n?}d@O$b!ilr* zM9h>=vs|7HzyY$r=kxwOAP9Lj=I2Rc*{-y=U((b*c|O|LyioLy)k7 z*1WJQ$2KaJYkD60LWOqG!F2LzJzgob*LC^el|8i;W_)M|&kq!4eHvQTUY3Or89rXx3Y+ z_3=1Y7}{#T+Do}lOSjWs-k6C9t|X01>YNKlWfpHm<*liD zR<%bYT~=J2y6+y9RR)342!d&Fjk&8&E5>%N?>I>G&1xVL)pT~@>IV1K<$sjDULn)r zOh$N~1zN*;b>(`+4%hd~#-AQA?s?xV`Z#k))vk?wu^fHJ_le2b!3x1BpbOU257eUA zUDfLse&{;+MOC**=N<4LZl?H`X=WRqOKV^hsi{c=HXy@100M;FjR6Dz)&PJHVaJmo z;64I;fVo}>;6hkQArx%l3Qrea+clE^_PizQK6W4}z-2bZ2fCM9Z|ikQwOy_~s5+<> z%*AIZ49l*+8az{l<-(5iPujGWmnM)==+SHaU~&{`$F+sXQkJxpvR9J~x}&p{Vzweg zMj(W}5Bw@%=TUGlKt$nWM7(Uo*e8Gkj~RpuHk+GNlGK7r)X7gRnAPpL$4uZWy`KGJo%2E&UN$J)x>p>=bi z9H~@IOpSR10rJzR(`rlUs||mV)2=<$#CMgT4f$yvKlUkqUfxJ+eQ!y@LZ%~?qHcs) zq{htNwsRsc$)!JHX4WcH1Q_|YJP2*?LfD00keSX0u0uSk=j@e&&+1AGhh66{*X6Er zLL4~lMZcdYj@vqLUcB?_%n{d;@kQLVYVtB#@PmyXOim3Cc9TbLJ|iLN1_4p$g1uLiHK?5Nn~y7*`D`79$S&mSg8v zmZ~uf$1Lc<^})bS%snif;A+=Cu2bJyTc1#!Tqe*S9Lb-}t!gkeC$GKUZ*Nac0L$hc zRgG8|oL6Dm`rsTK!)NE}2r=azG(J5kg$@a&fe;S=3M?T295i|o$6orU{CbC9%|IzA zBxIUWfQcYsC9`;sL6EW37GjX8ijn8A4z@5a5`?ZV8Ngy7XSf6&#kZxXU}`p^3LvDw zmvgv+ILndwylsWdBP3xSiPxJdw?R&7mS)lf06V$7A(a7v+XKGYd&#%4*Byn<;v84S_byfeeqhKz$r_sq{Jg3}S^1}Yk`CCVd zb3-)+r#jfTg7f?Grw;0R)*5NPELa*2a^WRgy&u)u7wgbbCx=Xegg+n^$^|fxc)*X? zz=XUr91Ru)K@xHaXn+Qw95yKgL4fR7O~r-zbHl0~WzTk_CK;veRRa{A9o8EsHY!ym4G?Zd)Ahjpg)UYmtk( zinhR>sN?SF%Un$v)|Nz!J0Z^SB3h91w)*)~)*-$>`;PC&cAhvDklzCqtype*J^euQ zz=~_Rf#k|RuNOp|KI|L%TK4_4x@x`Uu*v>s747pTDXC8(bm7F@RQDH?tWme2(eG}Y zw%IP*TnXXfB!s-GPOyLfV#MdGe^~IW@idazVYd$9!ew(?4C7{3=4+{Aa#* z&YAl%|MPm6UPA$6O*`yY*T}h!u}*(EU%|1wAw9-^up)NK@8q+QTF&~a+fow)EOW{( zd|ZTjI~?Wvf!M&H_-fW#O;Eb(%t7-*{0%&S4x=mLzOnu=0JxAfRe;jB5cb9ptH zw1FMQ*%h%i#bpyPg{<;H6{UOaFVuQ!wa4VK?w&pF!OcV}Rtey7Lo)ymVv{g1u#LGX zY0p8Y-yX`yJ-jD!4keK!rlMTRS4==Fa-lMor&~bVxD-V$0fzT~2*M@+y)Y?9DM$(< ziW7!O6iXzNT1p;(`eRE`SukuFig4iZ)UB81<~kXvGV$UKlI*IVF{~D%tOqY1Z%!zj zFT9!()!QWGiVC;lcp)leTYi2vx8rg|-!b;XxoG>Ud{Il>go>^0nUT1d^=?09q`$0Z ziW#X@VQ$82L2uXVny*IzLBO80* z?1MRz(&B^{0j;i+Ckr@MQ*HA>h96>FJFlyORgz!abUJdoZ|P6}kQ2#y8*IEQBup)O zaN7l%Sg!r++@0uAAK;3^Cl8Yv7?DZ9RcVED!= zV75cIyrbiMRv^o2w!CoJ>N;3k0KY4F_nhP7dS$fol%($zQ7pkd*w4Z&eZYJ7WlB^{ zSBZ;n!smVVypgh(m3|b>LdRF?27-i1M?4JB1Aqb$myr2}6#)}e02yFLG4gu8H^o_p zR8yZ$kPcLAu`qRmP>Lm7U?5b`%hnC$s&cn6utO9*k^~tJW#WOm2^P0dxI!}`2}A|C z!5^*w0a1bBp0nd&ik`C0l%n%jxS&#ogYQ9+M12?26d1DzeK^KwnNEXj!;p0roDikE-w z#oA!KBNj!7;Sz(EnWw8(kCfmVYnFQ-4FA4Aa}CoQ{G&qc$r;YpB+aM2|7;jM@Mdv8 z?RNOouf|bt>p!0f_i0H};@v;FtL5|G^t-y-Bwy*CvYhZNvGL-JEp@n}_%OIjc@;T# z!fpG+%->u%A3xSP^!fFFG}8J~92+_0(KIwW6SLN|Ywi58^A_h%MRlIMB+%TATtB|t z*lE)q=EOB zhxP7J@~hr#wXb<))$g@D(qb95k^z%+!oVGm$rDX!6LK|AXRm|}4mTO-$n6wYVvUxi zwfH}}saBmrYWMl&`Qy+4@jeBElo8jgdl>Mlb>#B6xU9Ys)&K!h>JL z>v{FOz4lkP(gl^NvkrV59j%xE7RMj4ZPn@b$`nIES4u2VqGY7GB!-5}0?X|XAY2JU zQP3qxPEPn{7?ums(orNzCB%C>bCmSboPGvnLD7_QRuEKkO(!2Uhow@K&B-WV!+GVl z^AV~~c0YbwbSydtf%MhR24bVf^YDRH_eS4@{?!v+GdWVvWJ?S`KX>OxqA8)fs4Pw%b?UEUMp z6m?*}Yhc@*4`zdW~e7G(~>Xa;Kw zj}Cdl7)2Z$7oH45_dtnWh$*#kt867aSRmJ{fCK&%oX%CPQbj@pRJ;dp{sGwt=QaSw z!Lr$Fa0NJG|A}26zuZA%?uaU$ksCxD3HC|a;F0unFC|iCUe0CLt4W=K&vq}K=%37+ zK7v4+X=iqdot*Fl5@M=s=xqga*!#RlsiSk6b(ibxWJHHKKah^-Y=ED(cw}8x9n&$K z!N{-J)5&%Z$fw{4s-m6?6+f1Q6~r7puy8cOey&JOMa9zlR@yC>RiE&wb00^FM%zY? zPaVZC)&-v(YdXL3L~5H?s?$GDz5c9!U`^G}!Yju5NYjJ4_ebV#x*sKnUL5MlSY`YQ z7M+XK;_l|NeTqLveBRT1W9p~vFIHci%fHrMd+_(-Z3i!yOnJLkU$$xP(ifNgTdnh}B3RgU@wLHDx-L(8tMN=b0EJnWiXRS6DPLbP=c<~UgL z=5fve-HO`JUr(O+5T!zMZQVw0=g1yNGd|eKnyrm;PRJy|HWx#HmD2#dz~BI<7ElbB z^pJggv#|M4DpoSdG^J{AYdS#=Su?_7f^ZbBvW5=T)OfqzxJq*_<-*{*L{&kgR)Ta^0WGDd$RbiZy!Uv)RE}Rr4RDtQDh20t+SHv+HNgkE_tbt59@z%0?2p_4s<*JKv9&YDQLm=2rGbyyl^-t&Zw0w>rbc}IxIJ>+F7lg zaaA|XEyl1;&8NMTEN)==qeby$(rn)OuoE<0o&KM% zM>uCV$96`2?z?R8+j8HRriU-%-WiT|{C3v*#6LqT=h61M56GU$J67LCj~TKT3`bH_ zFZG73+21%1?a!O|^y3k`9~<9KB|Z9k0Y_KuV3V>8c?X?qZ2r6${0eI=ZcB08h>@Fv zT#BFEe7E~4*m&Mx%j0PmnN^p*(T>%Ar{b%-)s7kqVyF1dk*l$`;!@t%FI~%@S$uBv zrS+5kWo_3lO>P}cjMa{Ls$u0q|FeAH+XQ6S3_ZLUVEuWN5jn8t4_E^tfk-FNEW!kiDu?h&6lO{1)49qV(Gl%OI~BxqU87oxvjWv*qY`Sv^9-U*++Ut-n=;xh zoLoREz!%xHMMB(wHC~#YjqXE%M6`rcW##FdKw}DTCtj+_@M0i@#F0zVF-Vs8E`=8| zmT(djkG4jWAg(hd3970FtILH8i2+%H#g{2eMMYBOH^AT@rhSNB+x;sN<#C4JompDO z>_$jrKWg?!#VOOTkqEi->igQ*eYNkW)80?|g@=)xybam6uMaulIM>xn)7FYk=!zRW zL}*RzK3Udjsf=NgdLrZXr803+Ma>I4m~)v=c4^hm6?@ica9$52L1~%+i>u=cva8*b zpE?HjJvq4T?E(0~uEE_Vb)$QnLWiP@s!h(1%2wB%Tbp{&))ha`Ibpn~Au;rCs%Pg% zJ}$bpybITV-f_J4WoE2+QcCWpAN-6jw}wAdJScfQZ9Kcs5~)gvGPNAo%Zj#t8Tx~J z_lMsWRhtnSuAht}J_(AWch}EU;8#Cz#yT#>1XsJMzT{T?s2@bkt5zBqtG-YZw*2S2N#L1H%+9#}n^edu`mi%Jh92Y324w55vi>nq|_`+TXSSaDrA-fIx10iri zJOIp)0I6(jNIYn65(JsTA8;Xv??3}9M7!s$t(Gk1x+j>5fLBzz4+iH?5XbIw%W#-} z-zr>xI+ZEPoRXZI(xrI1$K-B#5>>FCR$e}+lbxpFh_-rPIQ#sQWz2R)U}Y;8as)vc zd7&Lbe4R}KXb}a!?b$1C=;MB4+m$jf4PVYI+2&F?sU)&{11JFyq{Of_hm%Vh&S$(m zuMm%i$jGfU@S_b?h>=_}P%;2qCooM<60XMsKO;p$VCBumif!n$*@5=y2iMPu+?6I& z>QLpWtqm{)aCf9VczfmTF0!qvM+K&L-K`_HeF%*)8hWROLJ#>7PyXKJRsVST`S4m^ z(W|8=0-00|lAnP5DekBm!dA&^z?Q0;EyT*DxSSlB;fCuf-dXORb=tDOTbXlFGug$} z#wIzVTGQIqBemmyGnweGOd9(V6!m%X_+p)A^n6QQ+013R>7=!(hsTdzIbOVFD)K{L z*ND!bQ^>BLj6cMwXW#s=uW|YE&aw5?12GzBsGq*`wY=OGHc{qbAh~MNlvtrQWMRdg z2;a`{{A83hZLHVu;oy(9qZJp!J{Y}uK-79N-!eK^FhAoLVxxaAC)w9ENlc_=q-OGy zVy)Iv;pEfC-4iropFy|eaf%-+AFKb@*_?z>~nX1#AiPl-K zO*(hMb zoLB2VW*JltiJIc?jj6?G5xvHe9J3;(bgkM_k$V|c^Vd2fRjhNQR0!}Zh4*BA7Ip@$ zd{~*QpRkRiQji)GNFEG82LC6w#Nz>MJkJudS1E2%A}>DbUm&F?YE3|mwGA~e)NO)o zUIY*@TyjQ+IK1)7luxkkAzr#7CcZwSgbbo36s}{Ul%o(afUW?&Fs}f50c@#AQ9xaU zk+({}o&SmaQvOV?<`#;4W+}1-WghR6@$d|&Ln47WYq);j!1BHzetNJosyuq)4vdjL zt9}{Ki;DDH-_Nc$`X{X&?j&iTRkA|!jw;czlHm{NDmp^Q?Dmezkx7dmJI`<~Ok5$x zpofOxT!qZp!KH><*Epj={9o$6v!6TRJ!$Jx^pEuqjVD?UC^=l;pMT@GoWo)_PC#ME?47l?+N7PuwO#(+hXVHvet@! zvZ~M;j2w5`m*;QY=QV1|`QZBFp|r~d`_=ibaYpNJ+?>PTn#6SdU>rF!U%sz?@Z9lB z1|l+3HmQ>jx7r@Jgd&>ft-idB{n)morV)DCjNN`MZuD=ilQp`#woQgILz&I;cJ{b} z_2SyrYViAQAZBrJE<7EAN@0)^kS7=b4q*^wL)=0zfE*!4>;MCSvv`E0a?Q0tzXBa? z@RKZimVYyYTKJ{VG{<#vsMa2WmGA-;e2@3GoFkEIs`CZRtAyn2;g7rBtXtyJv>K4g znuYBKmTAVuS&X^hxt65TcJswOA>vVFjeBYSIi@9QXHimHT|$Co zZu6bXnS3e7N!>)byBMUIx7?T_AI7k?6%o$U_8;rLa-WinB3-#^E5{Rq5GfFtmZ=1G z4M-XYEIS&QkT4}9Nl>O7_?3AkOe8hB=@$Q;1iG0QUs4(`pHSt1kW}aoGXtw={vV>= z11!n?e*=EtKnJlpXliQKL6dT!Ia5kQj+#3(2e`MnGR2Xm9W*s_Wu}lD_uiv4v*k!p z$w_AADN|G`%TZ}{{_ofGd*AD&t3_PF#dANOb>E-+nf=l_^*2T zOJdmdOz@q0JJr`?50rhQ2t(EWCyY&5OGg6i*+4%{?_`;>Q%y~;6O7t>I}49C982R` zDr^fjN#))`LjCRib$r!_RW#0JPo2ep_s-%Mt=y+MmLCh}bnR&T^4`;h^Zf+9{NWwt z;JnBO>7G;WAHL|U{=v}=e!k6LJ-t+iKUWyWZ5ku2w^(K9Nxbep*YTyB^jpCLjiu43 z#dSiFS!2`>Cb{YeLE!n+n(9|Q+H>Eg_ctE7JTxrm?Fz2oQi@K+=(*PMTIM9DHSa8{ zNEDD~S_1=0FzxM~D%K$%7S;JJP2rqIc7fyKbC<2W`uF^TI*Vg%ZTVCAFB|Znv&pgl zi@J)h?E@7ph%0it0R_98dO#e(f@i>p1!fFK1Db|T2TuZ2fuG>37m5FWql?$n7=xO# za@VXuz^IDA!+6gY2Bg}NhWE65(0Ht z)}=?YVuFA#h7WfSG~bdIfhjn#v&;1jp+s+e!0Qe;-)hy|PZB1YxdlqMg6S+BhJv{p z=Iqi?Akpn+CcElXB7}v3fjv3d6!V+K;aB|SQ$r+i+4d5O>Tfc06nb)n@@{65mXLXT zKxTuVdCC5^ui=&LNXyn>vv_!$1RJ1+S#PHUP@@G<)9EjDAr5IxvmaeqGGFxeHjKkb zhq$E*AL5%j1QG@vET|RQIqx05EE(t%RfB{V*LW^J{;)r`T)sZNuAFvK&Tzi)TSo7f zDMBb1-Z=aWh+HjLd){_aF??ezZ)cDCN1qc%q8{GZj8*)@bu5BgTCC2GZKS<;HZ7Fp z8Xp-g<=V7yU&7roYF0;`T5%V^iwZrc3A_yX=AsAzxr-w=km8$UaZDv6?ipDOsrTH~Pb(c=xa%xd(9rl-20NC-b z?Jqx|sZNB^?nb?~pN=!M6)7L49Y~b&>oKz`(am8~m-q*$<`pRj(_!i5WLt2BjUc2r z1hziX0B&@`x-G0?wEIvt#v*9=`I-Cq3J7`%t`X+#>`5U5ia$r$d)P*r!h%r}uod2( z%FpH`t!AJEV?((Mv%AA13Q?w(^#9g0aIkUm-~0v6!v2RGBKaCX&f4;+$0QTuK%f}Q zv~F=zlE5nijkJ*fD%r~=HiVlHTE~i9|8(5>BqI&rX4nPU>(ELWj3jK%7H+Q2R$ul& zi0Y4>UhMU+Ruo~y?IS&YB0Op6#E{JBnof^WyTl*TTs-)jW(q77t{I%SsqNjfP zWt?jE&y87r6rUgSDIZS?<@Xl!tSME9^(xNm`GyXEP}%QW;e7v8-rx(J`#s(N2IX#7 zkt8Q)O*ZFr&zKC%#6(2)<=0v%4umfpmzHb%dU8dT+o0({(<}-a^T=BY77yHtS?l3V zmiSn#^N&~FEgiKJac6TqK8}tDri@Hjx94jX<#hi}fzT-+$jHHfat%Co+hzoq*@9>j z&w`+4@Dxx}5Q%^X0_h4y0u?bB+vzK0KP#9lR2qoyblB&>c&_eG`xH97zREOrR7l$5TFP)!)T1Z z8T<9`XL5q{HA6R&zJW0GI{=FZ!YxxCq1Hs`68;>J<4bb+8F{`wpKSys9lae~?5aW) z;y);i4jfwzub@xE?) z>1yojo$IGQY43TRTFi*({c&Kz}uC)d^lG+>S~Y>CjcUGC3ZUwoz$}YuyvjQ{NR8Lff>xX;knj zUuTD-Fv2)=Bv*I8O2?qZyUm4Vug%F=GYJ`?S}|rr3)+0fm#IsoO*q^7L3X}vN-`8@0};A{n$MC$RyWZAZ;|KMfMlE~P4+!erKWAYp4ZnkoRU~~drH0aUPqqO zv_7l6{=D2HVbD&)wUIE?iN%VFq};GPkL6G$pe-|y1|b3-pV#rKS)ors=0-rWuCsfq z5HLKcA653qtFI?vtUyxo*dM?Q^pm)KTa-feQ;v$%&m-yvwZ_ zi`?JhTy&b0awvzMmd&I=2_qAuaB_#MZ)@-`)1>m!=} zG*hi86s+`LY38b{lFi{3RAfiR4G&&qC(We-FG zB{LOn09k>u6)7UJ(q#R7%D7I1?F3up4hMEq(H&dUp+lEf#`jc43(hm|ai|1ji8M9&{Tz=8TrQMO&4MxS+HqUW{c8Dp zNh!P|(etNl(DHX`Gsz6GG|~nukImRxK5n7$zU6V#!SKag#gOb0nA_P?>Ml)MwH*6b zZ|@G7vlRL_opyfZ7ir(WoWXoWV;>2&=Q(mJ8Pi+0)@VgNMMoVMz}tL3!kg;iFT0*` z)%5QykPz|i_0Y9CgLMyys1l4EMV!E;(gnM~&U%a-}P(H6g&_v(RCe>Zz@P_*k z3`VZ6@iXtgrhvngOYaf)z+98`9QRq4+U>Iu8c#9xwN}6h14V|Sx%Dp(p+rMVK%jA? zDagt^!8(jgEXkEC0OCTQC{HOowqSXvQ^hII`)({CpdBXa%E5AXoSMtk(-CF_H&LzR(vV^^Za7b zX0h(fzgCk+G9391<-N7%eAB*sYOi{%wR00BCOxy|`EyY=J6xr=i@k&9Z!YmSZu)Je z={+2NTI?v(@zGE)&)Ozy1jyMqx55W&*=s$~pUkVo?rB9FeZ_tj@V4;s&mZ2{{-Krk zJE=FhpB`9tZ^}%F7W_CJaPtZ0VA0R}_5CKR-djQ6blzM)X%b5HwbW}oefJgEU41(ncm86f=NFLZMiqAZb<8AyFcT zIj}&`htsWy2(p~9sa5LCs~HCAkz|FvHz7BR#V&P@@^h^1i;g$+_Es!l=QA8?=L+-k z1E=j0;ze^Og$8fO_YBns*^t|DVzzEjKkxFJP`Z#|?eI(jD<6cwmmQ@a~@k?Yth!Ti&zVdOO_%BR8A~_K#;V6&ecN!MgMP<2kr{QK8;9PQ*h62b^(v!PPDUlO&$)f%!{*Oq>72#jfpn-rCSB&@CyWOw#}taJtuJWZElo=|9*ERbNVw zt=%8G{c>ZA$Wj-TSY;iWSg$B={#ZqsxSKcW{e3n76J`G3n*06P$p1(BW;@uk2Rj6xSF7fEQ| zd%ZwsOt zLwOG7i=w8u6w+Ro$c(sQNa0qWqN17@!n*o5#zD!266G#GdbPb5q4Ppj7P|eBa%J;4 ziG*%nnnag^K@r+CjOz_}D4ASxVop%HmoZVv&_DP9?y{W|7AJqSNrN6hN> z#pKt0kUD;nx4F&bF1&1;`LeQozxV3x(Jhr??vhLW)+x_rafi;c(pnZ_VlAeN+rj2B zsg1Eke?~8IOGhib0}R4~Dy~XQ-W>i)B%_|rKF}@TZRQTHL{_o57J{|~*&B>Y3ptVO zyoCX!*B{q-VH@2Ql4A|)Tid-1ewpVuw$wOhkF~U^FB82{ztlFQZc(d*NZo@bJkCsD zWZ7iK-@syE?FQsqfJ*@Ft%3Ef{(%H%wSex!+By>?vlcr+A$ST|7M?)1!S1Phw+(dc z#v1Yp4ZgbBNm^#D&bSg3B4y@YY0Gi76E#!wHNB(q7go__(!&{2JxeVONJWxwYrY6V zdXMs{felm#_0DrU?B1h^9!fg31l8xxCk%29sunb+gnyXy#F$)2cC1l~tHaW5tF-P= zi73F8!aht|W+lk5GEr2!R~^Dwvc3UW6s1ku+1P;=Tmh3wY8h?)nEqQ9Rt|%Zd`d>Z zcf}8K&CRtC94Pg`5|kA}h-~nmnjBya!d@s$3+4vrBc!F_`bme4v5dW)xW%crs6HUB zs~@Ii81^6+Uv2u_Z;jl4{}lVIv{k};mBPCtRKwFC9BCBJf|1{)G>jcBFN%LzlbGm3 z7PLhNnWcOzbv$sdkY=$PkC;nbDfE|*A)fC0ad+yi29$LpqGQi7X#PJzJbG@vcKdy- zvY8N`InJwk+2z?_H+{>nSY`fPLGYip1HH_mFqPDqo{YxtJ9|`z1OEBtdw1Xg!c=)h%(hsDt$pO#`z;{Uz;vA8lc)^+jg_Wwamr`IBtd8a-!ud$1CjBFK~G&DE% z7ySFz+!5X%Jzw~}OA{iwK6eF!pAtg0jfU~WO!utS&9)=++B+6S#nIEo?&ey&JYL6> z45d>45&yAhEv9lY*xznmTt+cZ_OO*UBcu3niiCz^>8_ z>^>3Y*efk=; zJiUseMk^7@$;}B+X4Z^vy*yj(z{8yNwC{XMg>w>@KW zNv1vZ)q5zN^{EzC<4h+9Rb&p*$tSdKU-*ZqG<{qpETWW>H`Um<#)ERZvbt16J%ST`}NKM?d zQ-|2$K7OA6O89K6SzEyAw+of`sto?R=HulMl6uoQqu7R5Xt&Py2)TK4(`(A0 zIUQcBtA#}Uw#!b;x63;NnwzgS+9{8NQ(yn%m*-mG^h>a)d9%03ce%jz&yQErPax4}?RzM8*%I8nH2ZwosM@F!To~Mb$;7NUB_Sv)4Q>-hPC>n-j1gzoFXO``KZqD}|xQnxDR6k(8^Om`5|>w4?uhX`2#3qF*HEIG~tC{mHeu(HES z{QHx#Za~CLqFlhoJ6uS$o9b=?BS0Ya-7TU4aF{u?=XsxoUi~N4!yP-2*&8vh?ybSQ zLfBl7EMJ|i1*R*a1xrmujW}NgIkl_;NMqJZuFieVvZlKGwK+eP=6_SISB9U=v9{Ol z^lUjResAmh%9b9j!!!GcQLp}V*5dD{zOQ^8i~1y%PUYNQyDE5jXHYj*nKlm9Z#P*S z-q^5+S=GD7iQ3Uc_Kz<({`fzrD2SEIk*NDz)V0IZjSXOQ*~R=Qn=%=h`g-}n2nbSN zxa{Sg4%~R*PiCW@?OgHrcEBg6Zq}v}xZRJKcoHKJi zrDWRLP>a^Eu4xQDbz8kKxW4DtQuvC)vcEP_-YM1ebZK2y%GkZKJem?u!lxX1goOh= z3rxXAACrtC3YR{S^D=|X;K>N20sV$jGe!`)VqWcE&Z(NX9GNcvWY_8$g9Mp4v4WRwaLVo|`&woK z7NfL}VLNkZwnz)I=^Ob&%>GlMVk(Xs7 zD#_h%Uu~&}6$I#fm0LJ?r0uXCGwqxI_v&@qFaOrh*rgvHn&iK#s`j;2dtNL(e@?U~ z*0HEJr{IEsbFnb_Ko`$1_*By8 znij@+9{TMvmsj-jlWWbT$s2_+b&Xe@xqqHrZ0e%Dxetd`ER6=Y8OGecygl%uL$&g} z936YMZf0vLTHvN-Z_1m(e08S7u!fc+UhRwO>Gf~9JI7S&f-5{R@z%!KWlBPF>W$({ zDul5>Zz^;PZj8W@Fd7OFJxdlVKu!^prPH&qWCW67oP!e(u!f1qB7ycrgpP%gtpT|S z18{+f606%w9NCPKG`X`#{P`NgQH}9N=d5M%6AGgJ$2?^`YJ=))hx^sVy?J-gq6m3~ z79xBXEBdJ!A9%B+(hr5T|u)^}##L!8J297t*4O@x^ZB)knqae6|{V^e!fh-tylTm;v z+0`=dGE?A_>)R3`Sx~z{2oO$e(!1vEE2*f*pba}HS*GtERjcf17I@DsAr3`C84UNV zE=V2gV(JQ9xixE98>}paGZKAoU*xJ|Q&u?JWWkIr>h_m%zeZ&7nhG0nJ_>TG)ve=6 zXREGPrH4;s#IGo8QcIPF?`#CTQ@)qBS@AqniAO0*qeS~nPA-l^JnTd=7D(c#1s2LLNGeCZrJJ9siI#q$A?Zi2EMPV=2h~G zt*&?S^kT!mG~U@X+scT1^KOMIuILc4_>(^=^}3h+)EK$_r}@vd%Gk!>m-p7HnHi4a zl5hN)3i(G4+3N;7)$o)yzIwJm!cTr&RGMtaT~XIXJ{XFQ)Dpcg6Yf(oa+|#rcHq?p zw=ST}oG55(%z)+L{7iCzNLPmuIx=x5P8LcMi_cEjXDR@-5;GCiBy_m|C|5|tYQwn1 zX3UBI>?}Z3hs62-Lj@p10+9vKNRE_lWyZ71zwOf(ei_KApAhFNPd``7Mat{n8MtE_ zgsBj{GvL-3mF};IY1qA|K?f|o2YpWK- z97Wkqq+dp@Ft9)7(B@B90+$|w?+2^K(n`3Tp!g?%&$dxa@zm`C1xx}I4|pbdj}Pg$ zSZ){yTztTxf!7nkpCQmpfyoWfuOcDi67VGW2oTXmYa#YxuGdinT^jD>pMI2?=P})Z zSFQvsSVBU|q{0TU(bimgwTb&MNF@xsZ@-iyZl84tzcFK@^D1w%t0<1JQs3;BPG<3r zM7+WIm~wTJ9qvgR)yWKZY99Wp)Q_<`>HYb;bre6wi@Q(j;PE3Zl(K~OOoRzA{C*hIazhl*Cys{<<&y=)eZH< z!%dFrPyP5`BDXjmyphq+^)Jj*-04E&uRpgwej$bLPw0&#EWDa`3R_kg>Rwp7QnYsR z(;Js=D}uLh4NWEDwe9=*FA+A;ueQ2->W&^4Thy|GGbVwNtO|CsP^Tt6L541a z4>9+-tC^?vcp#yB}W+CDKc5nZC7CenXoaDu3+&Kyi zsNw|tDmC^xU0_V~bvA$nwY|hgm=RiC#-%)-(;Bk@SX$&KDM=`*swlm6eB4?~>&RaT zU8{1}+OPf8Mowq2;BGo~d~aQ{Y3N>xQv%KE1;HpcSY!5bXf1HcBLyTg#iUYIDSM=7 z1SV_+;I1O{qoFztW|!Py8R`~@U$41umfkO;{^a9L2|KyfxUWQQEVlEt3h zBZE?;S`PI?&E8$8h&z;Xs0Re}9cFx0#rKM4yjqkI#O&VFpv@&=t{psl`_hcFjZxH< z@q4YdNmb3`be~acqAi9b&Q-Nlo$8wO%xrXcXWJ<#4acB6e5TO?Zr~!r#WE8hxT!qg zxTz2;S>%66!DoZPwjJ=uqvN&Mtt#ROIz+~TSO52*@76WIBNme>3j}Vdr&=QpxVtUfB$qF73tSAXb8?yDjD!Z$z`FMh`sJUF+e|9oHe~M05qjJt zfAXm)l6GE~eu;S`DQxTV9XzMTWUNWAuR_w9I^Q_Je`DEJ|Lp~5H2fj1KHPh?DdywZ zhrFyF^wR4X`^u}iY}d1W-+4h-PM<5>jQu|-;XCunOFa^Tr<0w<*KYi_BF z7gxUNOiz?v?)s?$=l(3T&?e11z-2x9lrD9pCDOn`;Ni&z<#(UQa|{$(kdk&HCBPMp z(NkCCWF=2A#tLA;o|rJ1g~$XPA`a-cWgaOR!bxT*B~uE+5W;qdAYl-K4&f1C2?Q<# z854m#!pbi&rN522zE+oXa0&gzp zmYc8=9FD*ZdcD%k3v6`o{%}Zok)o*-poC~=JE73=DZj}qDM)rl68xTqOU!r4@j%q!wV1lVWO z_)FJa=lZ_Jps|(6{M)e?ncf(7^n<^&4RqL5^suRW3 zgbLW?(3f%jW>z8dmX8~qMJw=oY|f&4+UKDPoOhdy{&l>rUGy)-qLWhm%bnXnJr(^C zvV={b5B?dxdXnA0<`krNE8}lf?m2vYII~Q}Lc{LH)qb|(kwaI$KQ#ZPUesGPOxuc? zj+yNE_1hBX>5o?bE4`76_Y1D*)r{@D;=ex({5acsBM&?}GUk6@&Ewaf8QVM#!E@=C z`lgcJ!>3Kp?$ZYEMxSd5nLh8V$qiOfQ3PHcUjyd6#nM)<<+}vf_iggtcN1-$*qG;P zu0g4-mcNR+bT0<~b-Zi#xGQ1RtdU(2Diom5+Pt?x&{ksPccu4L$K)7F$@+1KgngL( z@(Pq%FA?k%Og0BA{GtVf9ykn3jw6987pee%198U81~RmTSTdjv0nKgci}tdHmP(C= z_Rm&m|EzRVtBP^_Lb7k0d_i@Ee+m;%t6!Wktgf!txAJy-1VR-(6~f3uXO#(Gx*OXJ zbJ$jsOfRa!Q_9OUVKWMcfgV$+)gkaG@5(LXiV2Bgg z+SvR8tiGb`@!mp3ZMHI*NN*&t8x_mP%^pnOl>+Vl09!W@2r~dQBGMqdflz}Ku|n92 zLbX6U0f7@i9-i8~@^msSeea2sOU(-QP2jBQ?CSkH-EGFJbDRm3inxuLD}}Cb95ZV7H<* z#h!8bAN$+EqqAlNyM$r=LAS3CvY>xbsV-fYxZDHcW{0-1gUA(t*=G50WS2(_h%s>24 z3XpxE)xlL!!KdDmnqfZd}C48gCiS~EGyiJE( zE@D0D)&1`CBN2F<4V(^%v38p(pyA9+!=!;t1_2O^z*z`DlSsx=fE_t1X}kAp^OoDf z(S3^hRoz4U_FNabfK2g{7m%aFQrQOT68lLTfpaRvm-(q9(}GEAmFJ6k92z7E7GY(j zg|O>&!u_*{-W`+Nz`JX{cp_oGWkN|>?KVBA6E$x+)a@)<$(E^a9fbE>afw(eoi?bx zmf_UfrmI)T)-Ct1-%wmvu9qA&p7L_R_7^ zjKovWId({?v;Rx?;GH)Pt8>~{((R91j=h~>+u_Dv-R_yUb{3;B_Q^X;o|frr4%a}B zRB4TwhI(q$DP*dm%Ht$Z#-?-}_`+pPh2$Pd3y?v1KqNveV^%f`nE)l5(t(s%KM4M0 zidX_eiKL)XSR&PUo9J=nJI_0lh}Ai^hIaNOS(bH5b$z88JM9@>vb5RmFIDmlQ7bH1 z<^_{G=~CfmlgdBer1{nV=%4!P&D4nC22z!-w`|G@;8mUK6jJ16>~O4lfqOl&F!`)s zM%DBLDAg$FQY#$;&qRn^+QsvsBMr@zPPkH%fWxFj+M*_<97Zjuwnodl*E(B;AR!zX zf=?k#fp~|QAZH{F3f=@DC^bNkA+$Ut1*~mD5EcgF&c2P<^tXdj?n&SPtfctyq$5JK z3EVN!(kGY{lBB0GT8X0~9W`^2S#kKc*gR8%s$?(o@UehYZ}*J6kLfj?byA&o=9!eR z@{J(R)_-yUddRgk^&RpKf*I@Kqe~T&o+bufqyNmk|F}^O5@A-ChsQmUEaCO;p`k3tQ$Ud7o8in^G`o5 zbXck79Op6**#?A0FrCg9%pZQSsrFTJ=GGlmQMF;4&LLKBgCjmEy04)8y^)`t!&6Kg z8IvX~y$c)=93VQ12*_h3;EiR)fN~qMX$Gcca2rFYoD8#8n1X{$0PbRIR(X|$Vr75< z#Tb=nOSQdW`=l1|;K#y;-P4RbR_~hfg}t3BWDqv`GN93xOOO_KFY|g3_$IBpzpc2( z(d({;5A$ANDlT(3ytI~g5EE@-kf#GWImqk@5nc$UzeEgO%mLRZf)N9k8!0X;1DC@F zMt2Um0a%FUGUfHbSw@Mw>B`DT!z_k^k=t#uR3hMF)(4F_;{{VID|u8cjUj z0}Uh6>0muUS}`JW@(nP?0Gjsx@$%=Y?t#_bwUat=wDGejNVV441RXfib0g|&7;Y69 z!tG%R7}P&;YjpS`Bwto}|EPC9nxt)c>qYAL{(bi#xuo-|lpuo%!c@+|!ghW>*Q$2l zwuT2Y(Z#9}h(FOQ+_`{<(Kf zvF8u%FjPZpLpj$Y=8e}D&fs3{oYQTf-PO%FKK!kz=X1C+A*yTf=gMnd$IUw0JXgmt zAlEze`vby6?3IJ>+0WZr3S<5r9}W9l^T>?ya73u+#Wm|S~BglbLL(wk1Yu(Xwht#MAy6TG)z_K>)_Amf(i^t7TH z85~4Kic=KcjWrrZlH$$dD(6nNNU}}Cb@E2rJAD~9t{AmlLKnTS&6s;P~&7{bJlamU&KWFNYSTP8vV2}dy`LahQa5-84p=P3s z*GkE0Dr~y7MGH?EaNeHhYV%*ciHz^M@%i8T?*V9v&sFtNnk-CB>CJJ%T6t6r(A=kkN`P&cyRP;o=({PE!Ojp(0k7GdeX`=9$W-FIqQC2^&= zV2hK}s5zFh)-gj!>&ggt6~Y~FX~IyV%!L z`^7mb>Ii*OYGllBf?4D1PiW~1>u+u;8u_q#^6u10h7(v*(9F@PUmt#%nZ*@-66d8V zpR9_p!TyFxV4VQpX&l`^P|ie5W)2J1TIH~iAUHLs#RR4=q)!A*Y$paHk-&Lr)+sof zglXm6I<^eT-nIg%NwvvoFci!la8FZYRO9kTMP{t++9lH7p=@qIvRKlI#kw$8N!;Y2 zvAB?+-1bGM4v`8wm-c`p>L1lJ!om*TO*k^l_%HO7-CrI~!jPD1M0qJ#vD_sn%d^2b zh!{wGS9K*_r@)td1__a*O>#oAQ?TV&aKZr)n4wm`xO;W(7m81-*iAg3kCGSLMK_2( zL}<6NE={(p2I^K6sy34@E#Roy`_Nn{9t^j|+h-+H1ydK#Yv$Npc+~!4-23#2g*m*TkWY5v>*Mr{^n)_?ed#DUBFe+Rb)lG zGnSU|v&q*lKXm6L{sL%#E^6PK2~bluUF7!Nr+vA?>E=BQQ4UaB^)w&sUVO;%y>ejq z)n)(j{F$*fesN^6DO%}6p@l}Sa)9Ml&(owqt0oJ44ySwl(BK$hp*SM-S>Hda7nxBL zx9bb3(R;QVFb4>JmN{IT<%37b>bd*y-5YbxEhl^DC49ONZ0_Ypak3@VY0ic zLvXsRSaNoa2nJ$h#bGHBiY`L0fFMcW&k=|9m!^6o+j_feuuB7opTVfDo>f_!ws_3@ znWw76L7h9b^_I74i-w1X?RDXAAroU!pLJii&f#wh9ec;3!FpYsj*nI||wVH*H z@F&?4=HX;OZ2$)%aB>ntz+*XGHOlR+xU}RxOeS!TkltP81P6-(*BKaiJsljZkBF@kF3mggf}B;}XZCYl>>yPP;o;KY8+G;>oiKCwuC7_?Lr)Kz?2y zmQflgeiRS}OZLb{8Jy$c*~YKFegwY@cESx3@+bV3m<9H>{YIDe85~U{mT2US4ox<; zX^DFxLb#)v13s-7m{jP_R?p6_qY@wf!r6Vk{r*9)BBefjmG`&zyDj^J)`Q1-4|1#Y z7FJJhZJG0k|DfH@F*oPg9eTGou9SD3UBC0@&3AZ*Hja#?{^|Pu=dT&sxw`fF6uzz! zt#0*nFlT3B(*4`T!!hPwQ!As=+24b&x*VYKdkC>f&ZsBi6;B@A;X2uTNi7 z&Cgv7(CvA{C@gduDVcXMdCJur;np}ZaYg6OFX@I1&rH2rTVUryE z8Qh?P2uGttkPyrOf&Gmf)|%2sYVEEaE*TYG&g&I-s8wh!%_~)x*qfv<&?S>tURrHf zHOdz=MiwPR1v?|X{$c#?3<=&N^x*3wS{hamK{E%iB|QJ z&KL{tNqqN0cs6!#Z>sW~uJzj|C#EX>-`g`>LV(!_nV10nsNU5D~IL<`zO)hJdCL*{_5;N zq8n1RYIrAjiBN2`_^=_AVXyPIUNmjTjHB)NP-SlZUCi-H|4F{o-Pfa^b&o5aUwze- zv~u&W^IG3ttcZXn;9RXgUbddK`2Zp6l3)Rr`* zOh{r&RoBtlY;5s+DX3v{Hk6>(pKI8JecFRgu$|*|CoPXIl|v z6e6-pt3JL4B1)KwHA_ycW32aizfAXnq4e$QYrsitnV|cVBM~t-#AHh)=?FMl-qyRm zQyP*(V#@W2ax85B(srZ?t65e6g#@pG0mDoP6mq*&G?@JSR{$yQcItpp0fA`W6&a$8S+5HP zcDov?l(XA8z2%%dK*sE*{;Yd=rhR)S zT;0w!@!R6t9bf)WLhN;|ANc}!Uxi@5#<6|H8gF8jcn-Qn!G9NZlktlt85U^aiWSF! zH|no;0t2{qInSc@aq`1?oSEkf-aJj2=KjRQr4>SG*jUL7LFa+^yidop;4gs;igpddU@Q@({iwIq_ zOVzNY*N(J$t5487HNX;bW{tc;ZQ!uGOPITpW|1P;RAG@8D)ap(5*qx}8$(M=6NEZl zdQXDWe;GPc1o;vrC~HdJdguOm&4N*5`8;*AT>w>2N0d}2fSQMl1ErQ)Hr@?nGi zJPhf^a5*%f!%O}nHbI9@1gxxFqJKODQW?Nif^=u_GJyv-1l@st>K^Ie8EyES85;b# zngd10i*f-N2ACz-?PcSN(SP04!@;u$Mkk%7cj)2ZeO$K-JCYON=yLg4R*3X-D`Smu0 zoxQvG3Bnt?$oxFi*!Jp|*)D!c?JJVnB-VrYyhE`^i+XDYs7|;4DY~(9HvWgaHh=qW zFTSZUlsmZ{V3E)l?#YOjnlE12xH$VQrXzVvd%pil=;sIOUzHDEy_p}&Ax_KboOiSk zi^BUZ#L}|vtCkR~R-^b2G#}V3n$t)R4vegc6%`-a8kjuXYag}!(B*PRU0Hr^pPHjx zHOkCvG-TYjx^SbR@M3yP{e+{jZ`N?oZw)Jg; z(;Al8=`@jKV|YB>EF&wZ&J>-()G@HJu~wb#|G=|1o-eLOt zwlS*{K$nQr@>XA!BLYJ`5flj`BRut=pUjhvCkey*QlU&3Sg3%?fEr)a4K$Px z7UaAXI~i6y9U>CtjNzE14{OVFJUB_nO~&S$rI0?-Po3&arg61FDYRdwR7GTzvXIsD zL(8n^Wq#Ib1*ILd=EE+g_zO4x(ww_pnLkoj#5S`~tu|A&&v$XB+S>S1a#H>Z@hc3a zuS#Aws|)ovEmPYlOAMAVgiykd)6G7qPA*^On2MKgy@R)x{5!bV1|;nk6Xm>Xv?p*wla=uN5`o2{E~j+S8ECXm$sG~1Z+L=u_tq; z0Dwk?xAu#L=k@%G2^i-*r*U(-zBsD__;9Hk&Z@7Uw&Z_OZJ=ElwTqhCwl^VN5vV(G zt;hY8@J>CyMl;1X*L(fz%ZK&+*zuT5a1Gi7tdleOj;nExB z&o5Z!MJ(LSA5Rwu^=HhHtf&`5`NHjo7QE*0A-9#UQdGMi37=QOl93+bnt*~r$RbiO z{?8n75S$E$mx6B}Y+e%;AcZ)nTvxXbp3SEaQ*jXxA z32h9$WdcDg()*P|wNK((D_E6^3JOXYW5EFgzbK!5hY3UD8ZTy0jSe(&^+W4l=3i+Y zFmh(=W?O@*ho*D&%n2A?jVp*|Az--|Fap&8NWXc{9F`$wrj#1R00U3Dv;tAY1JEQu zJqiK|R;ijz{osJbSfNdk(vUn#wS4)|ZQ?4?I8#hW8vM@+a2CqgAs1!?3Lp&d*Z|2c z9@PPsR}p|2{SQYghn7gj*~ZNYs6IsqS0Q)6)LeL}Gy@zsw_z?{)Or?oiQ4Ou7Hpa5 zrzq`~q`ohdnMv>2wElWDJa5cnsrAXzu;8a35A}*k1JP=Ku2=fAY*Z zVAq#+p)y*9FU>V^c{}mV(f)g*3KQNmd zv?Zo}Wxt;-EA}O9yyT?K=sg|mbmknKJd9jY|9V7M_qy(yMGnLDfRu&j>(TIl>$D}! zqW!GK4>Na$d_K$@78USsY7hKe<2F`CZ7p@5J3e{Rk+0fVshp}FaQf6u!ljps{?kE2 ztmk0|st(@(TRt%$OdqR|%zjnDI5fIGr%}gL((xFm$sw6~#{o5<2Lg*ip%QQq8E$4P z0?w->(-C0AOovY;LSU%|;0TQ=F|ngovTH>p0+)s|E>J_4l^H|&GH9D>ubE5sr~B@4 zPm@9GjF52&8|}{_Cz=`9$lA15w0>RaC=`e?LSG@&OlUeiuoneKV56ODd@8T#>}1$k z;jK4Y!o>an#g98yEbZk#q}oiZx(MD&6IYIf%#`aiWxzIa^DTo~lpxSXBcMzKD1snx zxWJxVm`PTvKb8pe>o^%eh$cu)gzXz*xmC*=BPf|U3Pg~NZ$JtoKz&TY0wxRu*Z&_% zU;vG}IQH+Y-b>Qg$SKCeG#AkXe82k@Pv(K3|hh0B1A;(_)ARffFLMSoc?IgX zLAX4c5qNiY1GvMUtawu7GoQJc+mScmk`exO|2cbFiR8Vy&z5bo5JK6z`{qNMLHTz>J z(dJ=;w85^A3oh@1%T(j}>@ZH|O1jvO9$n?|-puz^m<_I;Pgl2&e0)5kr>#1uTToAcN+JMahJK zafKBb&=+Jh%s45J{h_tg+S4+cms7i;AK2>f*0|bE+Njb@^$u4$=R!&!7~&l;nL3GQ z*xA{TJ4pQj1`ZJmZ2(5cB)$0535{1Bvgh$pE!01)I@GDxtcJ}ec+7^>^04UpR<*LS z?Q9!xurb!WU(f+L#mJ1OYX&hWK$v6Q6+nlCsczN~DPfmfL0sEso&X#OMAL?<%c1xj zk?dp=WR0Ndk84#dBnZk7A%Edgq8t{G7q&Ohpw|RD#t`;@Ln1jAIP?PS2PR10*VVhx zYaoraNr(ejY!Pc^y+8wH3K=U{I#GuA%rJf1R;J=YsF}7{Ob{^PG+Ok=US=o-=VOjRi6NwU@-d&pThnb4u2^ zGf{h^g61>6ah8iu&)XbPp1&48z`xqXb_GY18L2lJYMD)Gcg>s^vhW`JS9JO90>Sg6 z6ycW#Is1-?Ps@aJgw+uv*E983ZZw^B!wl0#v_iw)1!xq?H>rm7Pj69Ue?RnL;84t( z`S%AKtq=ZnX_MqTx@Rv*$*xxwzlqARa0oDCe3zGbsvpz6U{^6CnD@cc!QauR#K3)^ zb*b`#^$D9qEGj)P3EL+Pm@1sUKe5D=9{>MP_3iOY_y6DHvaVU_8X=Uf5oL4AVMKI| z%wf)Q*ydC;VkGBt*J#SQh%IxTGc)I7=pd9~IVY9M`Opy+)%U*N`rg0$ao_seBcJX0 zc^#jx=d+Xm))^2{7B#CLiUn$b%HV34H3rIDc4JogQ2FU%LVJsa>}V#unqQt|OFn@a z^l}*`K(GQnnEXQy<%33O4K6|KxE?9|ctgHYkcC!fsNd=dCPf5A?|NS6IfKz4rT}}f zpk+o~N@+diZ(G0Y5J_KpB>@gYv>QNd|1oDSX7DQA45Iv|=82@kYCJ0D?d(*|=z=4Z^ z1L7l1Z#38~Pl|sU1n|kD0^!*`N6N@%85D%ddV>dLxEE_m`FP0B9UWFr3R1?vmEY z+tW8*?y4%sx~F;$eE7*|{w4j$)uG_9)7#j<#<}{y>9L*JjMVi}OY_NetPr5p6 zZG6=*{1mSDdb56apEsxfhgdP%C1X%;xW{YxdPgR^iRed=yGW;nbcahHcNm^>Cf_I> zSJX@p9vL3amCwv^xtNHRW2xVj0hgduC}3-%uvAzv0W`p}@kk^T+@V9Np=Eo9<=G<1 z?qs^Tuf>vS@rAecsMN*@*zv#Y9y&-`)ZAs+%VAU1Vgj_zJ2;YoH6w{7s4VOk?o`Wc z;JRq(OjxBcQ5%MNFE%}9F4p^cHJvDt9LgM*cA=Qg6TM0s`sG^8t+3$0B?s>a8ui)lMuSwvE@fBRVj+k<#5AZ%C<4oa$JuBw zIRb)i!1?jPo>C+d{6c&(G9C>!rl9r_v=Igg>lecUTOxpd08|N16=lcsjZ#Gph=`P) zIb6hq^u2rDP#b$NAhe*PTShD+<&n2eXC!&R0Y?rs zH57R?nV4YCFN$7je#w+MlpVS}e>WLOO{bEg^#bml{44xE+u`U;jJ^}lCk!5+3+@_e znskd?>XeLOgrE86-0)P-oW{fwQD7*>ob&T+!`8v*-H(#~5%1@+z8038HX)5aaQ>|F ze8qXYM|U^i%+>R1qpseh(>YU~g7^jZ>)+-VqP#ai+wQ6LgK^!#+a>iCeZAo?iTh_) zM_z15|6ISPYHU6pXgMu*!>w=i-N%3aV6V7M_C5PczwK|Q2JdI5zDi7cw6Ih>^N+=R z$zE>DdvUpmSgtJkG-pIXrs##A*19gcYl_h#U#33rkM6M2jqIg@qjGS_`QxbUM3AMZ zaM@=_lpVYnbSNO-JO&y8VxsX1WqTjGK&he;i{VR3uOf~s*;FTg6xwn$FI?06Armf~9Gem15CUP`C?T61yM^p&}=q^!0+dAY^Y0 zhz2wfJ2JbO29%a?hA@Rv2>)KuEb=xUcN-~?tpKXzGLV_#A5e=Rd?3w%m6rkwCR@bX z>%Abf;=SH$JmfJj(FQ7m5m)y~60VoUl^hU$BqFenqUNOThJM@Rv0YMg(thdBAFem-G4_LyEX;8G+{vPV{fAuMoQ2>dr@g&6yvLDVRK)z{JGL_YqdN4n~BQ zTi*(uOPm7Ik^fpPN_CCYaXWdVd7hHDaw+bAuk*s+q?MAORYsGpP;XJHF2FI_a!|MZa&f6ek)U9}$H6`}^wAl-$IR3u%Q zm|}7l9Y*dBNluwr5S4S-9D__g!9U?0qPH`^=d8(h!2t_}f$9z>Zj;ClRId4OAl%@e zq2cl}u8B7|jSJC6-c6d#INyX54v)z)ewP`BzBNi(3Yn!&Xe>bv1yJgWR+Q$co)<$V zh)l_~EUX)gQi+Q;^c&8VBtG=eE^?>_S|+}w4OXq_Fa?FG)YTWKrq|MJdS zJ1x7OTv5@8H26|Gm$lXZ<5~^Z-EJ{J60N(hq&aYtEu27cp?tdXGv=nnueO`km5cuL z+dw+a(g!nR)C1?qj~{CdAYYwXc-iG^`SsgLd``$#&ihAQT{vE4?yf-h@w*W!c|ZSh z*{F-YS>JyzyW_66i{hhOYA*UfKiAjayGhkr_hqYTyu{-2%wWgTWYTDpuWwB`y|Mpz zVJ@AhoN=jE@t~ocnXyD*R#lZ80Z{mGt+L=dgJ2cB_@9{yAfXU}JzoPficrn66Z9bT zeRVkvKcqe`ri|Nv`?0rRj4uQ4Qv(>LN+V21TAZ?1q_1j|KSdeM@y|=M2q`1mO*kp5 z8N`G$YM2c}r^fS7uMjJ2*>>y~VE@1Wu*L3(t1%jtE&nRz>RYK^Ls0<%D3uSX5>;-G zt3`n;7$|~2$qouMRNz@2j~;UEo{bA5;fppxR%y2KU`oh`KM=H7{X`)Fha-CckiJYZ!zz&=9{nbZ(X_n*|6NW{;kKO-ay=y7 zAYL}>_;{+?1w%xV=Sg6C+#Z+jz^rf;rtI z$9kncOdIyf+r8l&?eQ8>S#+o&zRYL822!P0Zph?Ee$$ICkjQ@4M7pfp;;D1P;t)|3 zza!~Nl8`gKeLNMzE=?puVb_ASlO22BPwUKs z3eriAjjV(x9@Vmk`>R4vWWF+2nw0XYWkw1pHFGRpmbIPHoV3UpaSd!y8%u2I!`Y45 z9v+B{nyEQDE~GP-p1^F8>O&9LXrd}pItrFglw?aT)@hgIUVR8=;0O>^9L;=4G@N27 zFy_I^W;n=lk|SLn*ZLgJJJeKtOiPd%9grsNOnvbN3#6Grcy+3uKl zxqaZezcO^+vPEW@r?jRZJr7j=3(ayGiqlo8yE(w5q2m4i3$*8B}z;{Oq6Zl04>86doo4V$o8dN5RJ%+^ajZ{ z%;WYxX}Zqjq~>W%NGrcMYNWx^Gh;hH%BMajT|Y0@qV*xZthAa0m;L@x)fq!xl3)k# z?I;N^Kvr|}t&+cPm*y>AlAS|#d9~A;4wQgQK?qF1`8L*5frpGy^&s4j@7U4yvCFFF z<|Yysz)H+#BO4ZHhsu`yi=3?lF(zOkcGr(~2vjON0SPG4I1f;V)1}f@>)U1ISp1LU zs%&NBAyiX{5-=jBf=UYHHYx-PZqPw&5=a(7m;M(?MXMu-I3(Ddd927Lq8uvuGHw7{ zQvtioJHm;@%55P5T8GmOMI};i>am{aRJ*RXXwvE9w1{S-VS;>ikWx#QpnaKd%cwct zNmFN1sY$L`%Bng{_W9=I!gOjPKbZXxqBa7m$YNtnBA@>HCx|7Y<$aBJX1FWrSJ30> z!rafPnEUwQ?Tq!!+_F#1>6@=J)Ebs3t9os;*=zDghPc@|Z^AX5X4*eK+%9Nb z&Of3N9U1-8JupA!=W@Pem}T(hwLezhF0~c5etN&P!L6Qvs=s0OxH>{VqZYSsm0?zL z2*m2*mFd5%)!56-shA%XdO^S#Wcv`NLN)wpNM83y)rV8t->1Vy(g<01z1l~YF$G$S zp%v#Zh0fQeJabjMfIlph*BU9WwWe9trj=fK$%@Ejvd%Ld$}Y)-jMF*mIr z7P(V*FymTEZqKWM#{Ljy>D#)2PRh_rpjyy9LgHnA821j0J+@;Pkvb>l^tadI{le{n z7t81Lh@8b<^0!<6{7b(Q!{uB{>8)V(cQpPyKH3}C^{en^K>1=hm)}X^M2k7=Nsqi9 z9sF-+wixOnzAYi0Be6ZXs<& z#SGli_x`(_QtRleI~Jvh^|z<{)T+NyrWw&wUlONG{VhquTNV|Pr+3L?uoj%5xtUSx)0gSZV*~0gqUWnr zt%h~EM0D4SMIyFnDtOIv%I$WImU);D)xZafrGfFK>YPBGC0`v9d)kApt9AB19M6?|zr-E5xaMcdO+&?qdq)cw63g;9$e+?2BC=Th{yj#(DjCZ%7z%(JNxN`G>Vi zlA9B8dD`(1aXa|$@Xc>Kj)ltaZ z{p;p#HDGNWgfw@lbzJjo<59AkVr#}9w(pn&s(xK_10(*v{yO*ZR{nX=t!=Eg=K9Io z#&L|UVov`U4lN({83&t~d)oNtsSXk~{1-_3>06UtofGO)ckiU<2?j0ORsrJq@q-Db zk7dBEmLv@VURv;-nTm=+>>&`Sm_2ZJu@w^*K-gZkZ`kPSmWm@i%i@Z8H0gV=8zMVh z$JUe*sx$8?y9!4=H;_$z898-Yi}E@^h_cZ)(*wJWJ2r)4I12vH800oX@@hR1?yXpxS_lD)7;4d?% z=0f9$$jnjn1Lek7h9ETo-{#9|=JaYLP*_2uA%=VqgJBcwb9#aWN|w*^w$@%EgF%56 zAvg`Y05X>V9~Ak2Q3T=>==ryH5ANK~kj;uChzNkef!&1t5g?z5r-~Awp?Oa(=sW^! z*U<^9jQWI7gVd$Gdy#@TYL8o2cf^{s@B;$_Pl=5sN7$<+~h%rc{Xz$ zmFcL9nn;^L=wShp8?rVVw!CCRf8I8K<->og#OKk%_%Zd-y z1>KED*li94_jSJLzMf6L;XRzYseN|+h-LRWtG-PIG?yOD;;AQwh!O&v}Neij!XU3omzOB6FTGFUugG z44S~6c<{4mG@BtLsFZ9n<*|4X^fS;r^Cv?AZ338jGy`P$WydntiC0_gyfpCFEm5`w zBT;0GD&BQ$MdF;U%^{=C{l0>tOYcS+7W^hVSiM9m!@zH9m1QV;l}$BizubEhH(&Fi zQvz!yRxK{M{7z_mav9D6H*zf}q;gc%MC;0gOsL6dTjcrmeTB||I>^(Q8GIO(z@ zzZ}0vl7ie`kp$%4VQ>HUz*1hpx5Vr1^rbv?~cFwX}ZFvP`Y-Sy=yVQTpKy7|55+a>w6m> zchWmCoL*^_@Z~c+NMlb8ucBbRpvSwqzw7Ib<@-0sch>J{FJf+4r^S@Csxm)C4eTfG zek&ZEKNEC6NO}2uF5ne?RBb$VP|w8eU$X&suk<_e68EiqBi{%21az*x`KT(x{so}r zO90U7j*K|g)Ck;i+%Ypvc81rFcI8Ac^YWK!G^c2* z$8|r^p}f+~pr8|v%k2;)0-+aZ>PFO7ND}z)1w?5we8NU}8v@vODnV^8!{bGr?FmMl zEUW`PpefYH8K(g@W`mhs)y+BVWtaKdjB!Rt8%j|_(xz{{v{`l!T#aO<$&PXWE<6C& z3zjI?zVf{C9|OK;M4m>LL-I{mnV38K9g@&lIjLWrs7ii^_} zsuQjrm?|d3QyYh;T*u72t*SnLW-qvi-f+r3O&I_R& z{Q{4!_q2dz!Cl7L0`KzJVV?Tw_tC}?sI|yBS606g%$Y|%PpI3dF?L>$(vu-r~i&zb~Fwjm~7vA;Y#-A`G2}M&25COo1OO zBETwzg9~~Ed48%riC_b-<`d~O@I5>;Iq|adPtl_OyUB}@rKA#Np7wdTzgw!mbD6x? zd37assT6;O8mlXM>&J|Tota9Qy9?8QpO$PwJQ9HreTMf! z&?NZ=3oFJoszJ2b&BBy~LCQ-Y9hX`_74g9zg9RN#6noHDoB8fprVON>j03E?PWxwarw<- zd1F^pa2n{`OE2^yx4*o7hY5jTSL=CMQ82B8S;>#FYLArmUeoLRk(9*!Rp?mwot225MoK-CZCCkZ z`qaCMlaVz+^Y{?YvNV5&!3F%#4S@$8lkXNMgGZZ+ofI@Gl=VIj3==Qa$_SN`FQjJ3 ziP(bxAbNqFTy9P*>JouleSu1k5KvzyA$YQ*6t zG2isejg+ixuvO##KGtR{TA_U`^bX3ac36rw6jXD|OBziYT&%_~R{0zVZHg9Y?pjw9 zKj{#KSS8xx>~$hq$*76CNZ-mCX~XZbUM<9nLU9+}02@06oebMYs;sm@baqP7OH#xJ z{j}sozCehVhiyQEx(#3jh1y!|!HSEtu@}JFWWx_1C07H!kyzqh>{8f=QCY?GJ(PWf zpw$DJe6Y_oqKO#^+Ec-nWiK}ZS!=MJ1H3mX7;y5z{CU>JAAvH6aCXXmlZ+$>b5|v( z$B*AmO9(1DHGBB<`omKd4xGpNnyXR*M?J1XgKlXDX!TjzeG87R@Yk)1niZcMbG8`_ zQXHAm9YNj*t+c;xt8}AA2Bj6@GdW5ulOQ-$&N1M9# z&ymXRf3(qF2g-l_)s+70e?heKCq73Ny7Y}i>W?gh>uh~GGH_mZr_N6@#-FEg{&mp% zr5{1tiX!bXX9ouAY`S$?V*;*-S6mEx`DESey^>Ye>`~j-jR`%K)o6uFX44{g&neT!y~ZH^asJIl9^29Nz0 zUKqWfK^nGJMl#I_gbSs&Y1B$^nXz|Q3eNE%FmxiM2n~g?#(=;t5Y4qq!i!G2Ccko0 zgpAxBmvcZd4eto$an+{US5%&NnAzSP22;=M&crfe`zAZ%kktznOD{KvJc`;ZA%S9% zU8`naCrwyiHhM@HCr)Y63|WoM7}gWJOHIcXsx1S@G|xT4`^B1`#)?k3qO|3ZGXkd?m0{_8%qM|m!Hc#h~Ig9F^WTG61jMksXpq{r~PEO^_AM78DVA{?7Y#2z|M(;q%=6-cmg;U5B!$&rg{BdDq|m`W(}9 zj<__lWu@Pquj5{#eDThQf@|Fh<6h?$r6SXoyXL&qUe24R9o8k27iLIXB;ZuU&L}!8)aCo&FjAM+oSW+xmGRAl}D_^$|U1BBXZNRcataDUs8@8!fY^8$X_0a zd5xpv#q4cF)F<&Qm{Dh&?-5OG@*+j)S*a;jIcSne1%O%Of+0VN#h#S8QZfUhWg~5D zWmO^rRh&_xwxHVp2Ple=KQY`+Oj)%lVR2T_s5HrRDV&?xFtrQ?sD)PVm z;dZ{xgWEDns%iV;zf8#c#>Y#v*23PxdJ(7aLpRmiYaXaMIlATL`ptSuWDj4h%4|3m z%kdwi*BQGpLo5ShUHsCUy9LIwoKAFoPOqdXvTO2+u(|A3MYQY5P~Ajds<=4zwB1f5 zNBW6U^}EJ{BE93w(QC6uJ5+BK%vug32CVh<(?f5SM`=ZkM1E$t9U^3Jb%A>`&-;w# zN9MGj>(efj!rHkZE@>6 zYIFTN2zIn5my#FNr)+{Z7S=p416Hmz5%|=8qG+cx_l6jSaRNg(bDDgSc#-3f_sU|6 zl`XbkQ2FM0?FN-m&s^2B!}O3E!&6Wi!ubRh5MRQfSIL#fi% zNYoZi1ttb|z&Im>qI>|)CnI>V5>g}^53Wm)4sqa#upn=O2jx#hkt+A*RX7*~CkVT@ z+4H|3R#!3n63t^2jB)0IM~7V&AtCz$AW8utJlG|jmOeMWKH{nnTaOdN?;bw`BqJ=RfjZMo;Gw3A1Ul_&W#hSv4A zwmascmX4<{eCDTHSC(fziUBm2w>x2i}szp9Yw3 ztjs)9X%?-}IUN+_MQbo6U$>2y6r$}N6oRo3cy0M15Ku}v>|NJ37m4x%*Njq88*oB9 z+2-$3x(6j%7MGZ}Onfr&z&}0f9{qE2YQK-7GJVHiV!umAQ?MC&jXab$s}r4rL9>tv z9*@k6HWr_|;?y^TBc~`$WmQEe2+Bns4n1*xA8QiTs!NG6b5v>^HoXl$urqm81_zG% zy^<$UP`In}wz9FfVm7Yl%34K`MOcI|X_+CMS@Sz4 z6&u6KJZ{%d-3ywcS0!O-f=U?J?PLg67|Dl@=cfYk-@O(WEMvfM0RmzYA`b0y3+I7SI=Hbu~)ZIW#MUt zZuAi4*!IfNpPy$(dWwfRr~h2;*oh#hn|2~@?{tqpb{dHGe0g0%8 z^n1cravDx|MyBVmzi!0-#c)4&SZpdNNs;83=3Uqo)FKvIVXl%j^>TLVv8>8D_(im{ zyyrQ6Wvc|YqGFxZzB}3ZIJg&#}Y z!F>|~39SCa_vX)C)z7P{>MqaJ5mz0PQ81K?JsfI$?tkzk=%_Ri4Ton|S%uoe9QczF zlJ9D4u)@lm1p4zwTo=r(N>gflZO}Bc6!LoZ5caJFSc9cy>AdQRGrR zp(>_ZGD`4S4HY+Y(r?{(g6DE3X3`7H;z@tv6m71USC{CusseY8%Pb_Hz+3Yr(wjzz zqk>6!iZvy@;Qpx>@R6vPxzg%Exs#sK*UCn|h2GMrd46~2!}k0Ysh$cTKFw2)oULPQ z-Q(!8W2!@{txLS4rsFyuc)uXeGSaFxB762vDYq5|ZLU8I%TGC*ySTpTmI+)CO1SRl zMtV#t20QocOT#1A72N@{c3u=xHp6%2nCxczYLX}e@yTH^DrnbBH_8XR-HtCk>r~mF zI9l3eb-5IJ(zUeoo<|ps`s@Ae=8~^J`?t~Z^r&&JqD#3BitcPxp&Btyps!icfxdFg z6s=x9Y%$d=wakq`;8_iC$JPUMJ<;i45z1i~N@3?LKmoOv5cbri_sB!V5QHEW$k+j8 zvNBOn=3;7fLpdBf6#mlh3Q8kyT}S*vt@_sSkWLdLm+fpso7UiT51?MV8G z3JtsbbJj+N?O3VfZPE#&qF$Tw%jGq?BzI4Q7Ru58LXq92Q@-+9oK;=B7Z#Js6BJpz zNPONZ(y*FpLmhH-tmYS=>E!au$gp*(nxzJ4deFiC^N)5L~;vfbW59_t3 zW)oP+3T0%hglu-Q!En%rG+Z$VQ%IXt7Fa*`R8t>qw!A*QIBSV`j46uI-fQ%GgcV5oq*Mzs9$4`QY~aXca*M#Ppr{ z(qU?{0TkAkFz`%gYgZ+>(NRIKwNQRtgJ_f*7C60rw61kdUgzoO|Kxr-d?40I|7=A; zcwXQ4Tb5p$#Kp|gT@~$@sjg~o8Pnvc;oOm)@OSwhhiAWCIsEhr7!}Mdt$s-x`ql9( zn%@1NfV+$lhn)M$?}wLuitoH_T8-(99_q9mqjRNvpCt57-_Q%U`qy}Qd}8JjUy7p6 zQtjsMVo%7#9Je!a%Dp=12Ko!YcrKBho>hr%Zi$vRAas~v!}9F z7AN|5)z_4Se9Y^OjGobU1opff8OJK zF;cES+#kmus1{Wi~mG_sQE|9ls@I`MJIY(HkJ~#+=?c z`aC@|Km`$pKcE}L7~$*}otA$2`r(A-ljJyzs(~gky?uLW=v}t5Jg$V`C}sBs)@tH5 zQtS({7chOxU3~GTaUTkC{NUxYalDGrU~PPV$d}HTT=sBqf#A%5dvWk|{q)%yojdd0 z+VdZz=4w3uwdLtUPd?TSDK4~T47Q=}fPG8QNsI3i+c_a8+H-j&ecyQ&#j*FJ=VR$A zSLd%;xl6AsZ{;ybR`e@f>+ke;`aY8e&hpFy{J1JBJ^ChRwhmlbiE93QGI8}5F+Y5N zS%a=xpg(w$fZXL+%JkB`%?sA-pslDWk@m3fSGrCe4i^}kp7Ts=lC%9TUBTf z-pt@G>t;;!cLuE=yK6dl$zt8`pk? z{q4-rT%)tVV9Nib`f0QNN!CNhQBgKw-`x);E~6?DOUneyaD5>aW1-C36&OLhgNjja zhl8!u;tDxL%467!oGl3N_-s#b;J*PYw-rO-kgN64g8cgQRS_iQ@LAtMP*+3vX?qnB zFo#c&mjJi;x7CyqhN+0 zMA?I@Z$KUgZw*yz`C4H)%oG7kW{#Vcc1Sp|D~HH{3?XJDbJWvzG_CAOxzs%7ky-`G ztvTdQq>n3KiT+*1yIo?v7cc`w!|VBuVSwfn>NBcYP69Hb3WzFSMWthTm!6$|1Gu9R z3uYAAhv}j{M9zLKhZ}^->wl3BujsXHSqwKaM+!(i)>D@nlO#4g>ni%BHKv-L&;N~{ zvpyNg{CfUhLVv7MR-wfDco{GTvZjVi8DG1Z_H}W=H!?+^9xxGUeX^ssE@Lb4vU_*n zRLS$jlq2IR-HV6j^@AC~_XmF+Vp!h|;pLC_1swfx=IeHew4Zay=-X{8eU%i{`6W^T zCAiDc6K`!sAMen%>=FvDrm$A$F$4Uu|1bg^g7fv3KHi;E)$e#u1i^8YJVhOBAJ;4P znOLF}!YgY};&t1nja?JsM4xyyR{0Xp-j>FTX45-jY;%X1k0?Ndoba&NL(FTM&%Scl zOL{QbGH6S^73TZixS<*-;mFq^p*BVm=hdg=`LG0v$vKAeLkKvt{tu#9$>2|i#KR2Ig5Ib3cw}Pb`JpFhV8)bTAcAl})We{^TRaehe*=mS z@*7aehr+_wqdd$MGEDoDVmgJOPu^9F1$Th7c# z_;`vcgF@wwiQz87`me7X-HrWA=VfUT2vCKkT(bJ1hV-67?SCx7LkpcoVg_9G@|O;d zv}{T0cJx$x&*!dujXgs@D>P1&+})==L-PCN7`@?M;h|Khv3kv6T*2Kv`tALkFdnCO zZs$ittoOeb(Ff*oKSajz0tbH`VOVeT*SrjLuiySY*Z)hY^L7ro zk1SH#Jj0tl3(a;eT{W@RU0GUJmS7Kg;U`5|jv+Hg{JVT>)g_yJ=ro@4g+xH{Ku~Fw zppNB(2*43a{AemL49eVZWN?`u3KIpjik!2(0aWx4Vr=eV(>G`o?L0r)rD~`tgXp_i zqOuxtPzIO7zL6A=;)wH#SxcnkhBQ{|jC~rvQx?)H#xM3jbX@xG#^FAZ&0w}M?UmEZ zmLu|V4$6_$Es5R}z3fT*T#YDUzXmDJM3j~(yrEF59bN>HdEiY-C=*Rcstm!vh-4-W z3|-4foAv-55Ctp_2E)?Vh!@R_!D|5PSlpX%irRoX9I$So0Ri{tQv`$&xL(l0CjvgF zX%TI&q>=&g3ZM-P5di0?qkGza`HliRvRCAw~F_jFzW9j4+IGXeIu`y|4=#QOoG<0_wR@dh3$-Gz>}vM zA8w$Z^d%Hyq(xU0;hFhHnWr0frrJ%jjj~||k4VuIH#&AO6$n9u(THggCBa5M&@UWPsD&G zF3~mMbp&NGziHz{?6*7jhogq|JEBtEO?VZV6SE9gFWO;@DUgEr_SMq_+ zOmu>fp}=tjtr85*kx*GEXt$wpKvP}7#uU~{l?C6E0#wY#7Fv|*P8$A$YFLRo1z&uU zSEHkQNmE)d+`K68z-q1??#qg^nV@7-wM>i31i;j2uTGSc`2|rN2id?nW8%_73R)Vz zsH#n54b-n0$mURn9cpbAn*OpFv+*BZ@p>VO2`d>jPqO>kOp5Ayi08fs3(SvMuQ3Y_Y)e@j7#HRw~8A9!xVw z&1?i9BEkkRn2jMDj7b2XK%veLPF{WkN|Xi+aQsJpxmy^5TC(p(;>2ZTL8v0Vo&d)o zFCTD~vizgWb#=h&F!`qMI~y3Pxpd&!rI z@(A6YWrLfH9r-*~C_-ph`Kx0^zJ znzP?HQab^};(g6 zWC~JVeZBZzrw3vaxGra*VG58q!#yG^%_g_$zR9$R41`}G*p`DieDD-B`;UtV8q$#9 zMv~N+)&)2^F1?2%E#iT-zB1!;GX3g=@(#{M$e~c?0sO^v`%s}16rJp4dNb7AmhcF1 zVpc`8Tr%1*H1oj$qOa-kG}Rn8emj1c@QtIZb;Kw~k*)qnv10ViGm-1yI^3EQB3g)^ zwifKMn=A3W*695dQ1*JqTX~#?@80J21wYR0-a@^N>Y)G{%HiwXe(e>i`M#*~x%;1b zaphw* zu6^wX%63876wooH+YCrS&Wk~~)ode21**rtXF^GZ+32_SP{1dHF zZYv~QJ$qe@Td1v9rt;c<4@u{8%*w*}@QYYOPU3sB=l_GGR>sSo5?^6>Fl8i@L~GK& z8_ujQ3A?f}Yl@*0LM1Q)!zCCf9l|GJm_#WPwG%&4yg`#8r&S>Y(D20?3>IKP6b|&7 z3AB55TsT%Fj!)R;HG3&ttfFcE7TkuRWz*3zcLIuzQ&qw_~ zP=cBkBO%~A1}Av$%!lpANSvJEL0>KAyDtx)!mBZ<{D=#;gGS$gL9UZHCH@j8t6Nf6 z{E7+b#?hi)!aQTl< z^87b9TRjP8miPa8jp1&oM18e0kC=^c4PILPQ1=h0pGtu~mxhYwuo5X$=f%LE=h6Od zS-*M0tkFtiGV8GbE-6Pd*Y}5uUDj~6qLGaQBpZeR4pv~KDZmGb!^PXAU_lOmfN=p7 zNT`WIs`+eXe2nA|8Pq>hk8dujCh}3#%?2kHrtE;{Ca9Ghy)5FTj@!K!0cE(Yg88=c zOZM^rVrgtL3XQU_gb@R*Cc>0QMF-C4K0JJ+`UhizA|zwwA2}H`fiN`M+xLiQiB`D%!WR&KO6ErJG(GmB(^O}ZdC&I6jr?^;Dp zfWR7ArtvDFPbCj*+dxEM_P9j+V1nSqM%RYYdKwjLBcX*)fw@fA%IRd;q)Q3J@+#**OeHR8Iqpt z0>6-B@h7@#Cp~LMwK#nubUdOjp{(laP4%ws>6~)Q#4_`|i}=J4rFQlJTDnGewe-5U zfbb*6kg6c!A`Z|Dj#Zr5vg@$95v^yubg9}zcV~S|Pv3vQ!(#b~_I*jtB`|4>wF`bO zL;7-};cw`BwD&8|e=jZSID9%dz7}yG*UJR%osZTrO#j`F(owYSh@JpxUDV|30C)P< zfJ*nifbhc=`Jb5I50~(m%kK;RHOYH@+O>(j8z8hBX0T!~y=DI1G-=|6*_D~kuWr3>Xy zh~wOf{1Evm(y5jLlCTjBousN&yG=$J+KO_G>>Pn6@_*+}Ff6he36jJflK8;a2L9n7 z%CLG?3SL2hQQq=QEXmf)qLGiZVC9-u-R~|9omIK((K&RJ4-AXq9BbCx(N6Lesn{~|3C?6V+zj8Wa@$5Ge}|B-!TciF8m_$VBVC7E{bPWnu6^T61EqU zHnxF?G}2J5TuW-+P`5(>RE-U$slwSekDjo9=u-Ah<$QyxhgH?6rGdmg&82CnIjwf~ zdA}&L=+84&nIxSH579afiyyjX$jmXxAujweUnh6aB6BQEkhx4xcsL+!Vgh`84EA7FCRIatbmjfvdd`A~6o zd19VZQ^yEM`0^{5;qErn##@V7u25BO>&n?Zs2lZ%ol-}QTsHcZZ7^@@beLD|pXarU zb4MA(tCuBHKQ-6;N{$;e1SnN{Ta4Pbh=CSP5QYV{5;)=KyR-)*FxBQ^BK&hnA4&p4U;+E@JJ zgy@sZr9jwd5Aoy zKMs|Xeb(WLVpb_4A0pUrJF#rINbjY4o~Cc95dI?LM&Mi!cTq$b3#GCkz)%8!$nd|I zLfYI0K^TijK6E8~ZXKxWBGL|A#xOl5LNAEnLIoNV*m1z0grw(f;V|N+*|FZF>U-wE z)*YL-i2k6hx2jARzmzbOQpOnhMH7p0@RX@du;R$sajBxV-m*28*HBoTfaz_0qfZLbgu4+I&5t_i+TX z6gpJ!G)ny2cmu=Bt@UJK+Z$>7ruFiBTYu%91Y}OeSjeSK!DTL9bU9J41IoXwauD)Q-%URbUEJCT+1_Y2 zd`n4>0DcVmsaunwUxs(K2Bss!zaB{5+>M#9Q^i!Y=;VISC3Z#G%<5h zri-PO+_LV8Ph5~pedKUa(1Iy6_1f9gCWn<{!zMt43`IP+FYfvVojo7?&l%X_6Fa+zCCLs$`q* zopqR^?d#<7{as#X9gaoikP>LB=|f?M&Fq6W*&;7;DY&$t5G|COKXEVF*%OCeUnMMC zYll%%&6O&q$Rc>S1|?2O21bxEAV3{t)%GR>7|fGOVX9p764?JhY#r>3fKiGEI4`9( z8WC;f48#+-k`|K&w)-TY7r;5x|H*YhSkSC_5H5p?8y07ZP)GompFsZtAs~kbr^t>C zP;Bx4rs~bZq2Ax{@%KzaW6&8ILUd--Xe>jPA;KB^uCW_iAxp-RwJ0@2$(9%+`@Zjn zLegnL*0D>JPs!L?j;+%2`TkyWKELlD-{}(9bvoCDdEU=*KlgLrpoxO$IE>8Vm+9T- z;N1Mw^CL(4R^qUgHdaL23$iun4A0^BlL;?7$Mh$od_E7pvd+6GiT72_uI9Nm`M%38 zqBlot_s)WKvdgKbFgseEiU!0E=}WeS#b*-uj|^={J}m+Ee+NfoapbibLF>r zQHLM)5wdMlcFU`ez35cpXF2cJfrSvJ`Uk*%@07HkNzRj^Vyjh6*XUT%3j3^l59#X27tfLI z&8~Ni>Tbnad3JMFLD`YTGDWLJJxeC;#e{-*3HG?8#+$pOkm9>F9L{WX_N%e>R8Q^g z?aJ@$@;s+SfrTm9+r0voS_*WAbfd}#Rq=p$y34i; znrjt`)aTYZ@_)dh2y1qs1cKtQruWD&xfcLu;x4oK1=%wj$>Bwl)8CYwqVo3SO z=aa_62L&V&c~Q#?FIyqU3#W(&gv>QPJ%#_E$&mWwi{gq#JPPnTf}xqOXT&UD9uynD z`ZiWKQMt=SzFFZ3;bZ?OVe1Y1TuT_+cg$t~vG$=w{#(se-Z##UX>J2wh^spbdGntZ zudQ_7^-24En|VEG>fGtKx=+Tww(SpCypJqc7o7RQ&u;ql@R)dWH2$ly;Z&&#@no?s z|5CPS?A_bdtL|539^8Dp^@QC2+5XPX*<&E$(RMg?|ip>#pn;2mWQVY87p2!`B)W;v+_qes&r<)JPCFJaY-eHV z0Pf|45@gX7xj4ybs;6^?*Bd<>9Hh{0o&iGL!BB_*$HNib!~XN!XuwptRe6*A2Pv%3yeM1)4bqj1H;$Urc@h7SC(u%EzkM%@}+y` z56dO9lNYtrL6yT5Ja?l-i^9xDs(30O6r(*fUc!Iqg6kjpY!9o0JlBS{gcl+QbW}4u zQ|`JJ{)iaAn0D|`Z%|jRTnh1%_YJSrGha`f@A^JxwZ9o3t90f^QRu}?55QG;IQ;pa z`ywA(pR{hXvu3_8xy6PQJudPS?)_uZuO=9nC@o!A(v6JVEf^KmOm@PQ7_b-q30`E) ze?6r0t7!k-bPEvN{iNDxF3qDG+Y?P>*MJZbYr{Ca=tKb$$UkGR|?X5{$j^n-Hy)ZsMEDzUE1 zRgctXpY351WiwU&t`g9Pd4W@G?h^~uD455;!ax9F0x$3;!MUL%iXg~dG{W3uCNMG} zaYwmR1>Jo<>rFJv2QSQra)`Nd2@f?49}c}AE~1@qWX|jg9F!Z2s?J}hsfP|T+ZWgLKh9!zzU?Oac>E|Jc1nb|3(h_P2q2)Yp(zrfKKp2H&SeC>f)$*br8@n=($oc>}+j58Rh+0 z3Z$TWN%sGypfN?)j7L7Z(Y@)`ZwfK(o;QVA_vP<~$n?Q%?yolTkdb|*lE)K=Dx@IOt&Ii%~Fv$5fYd*6$~djFhtATNb1Y5(}rU$M{W*iDt_R~;I( zT{Qw)&&MBXWqthB{UdP7LLxrU0g>4o+7s>0E(_b-kO?-G-VXfW`fPdtNK&3X*y~Ph zE?d5STXWdsa>ail#_YeQUIm*JOt+1b_#IWENEY?oreuAjYljvUB%IXl%2tU|!_KUN z^J%0>u%UI)O14cH7B4li&5Xmk3L8EU*0aSz<`9+-e1MS|PX9M#0GkQ0hq!zu8?xs4 zX&fYME}g|U%#!j~A1)&@L@Gr&mfhKSmW$65=?>0HjzBy9hX-yfC%@tSbiGXgs20Ks zK$>zoubbe;djjaJ@hik9m4wo9fX5I$;Hf1xn{)-j!%-066P-Ys4;eXNAflBI^Aw(8 zQ*#dwC%brZ!5{O#OJSm5%kl4x4H}MNP>Wa$n7aZN_-Vz1`7H2}^i~<1kpZLN+Q5p0 zn_ysaf5RYQAl)r(kA<+{Q03o51Db3=Hko=Dk1j_vIu6ym2&=yt$(bS=MD*U(m@r#ll`#(q(JAMfNIms98|wYPyGF`t ztnl&ZTiF*%{jE%5wI*UN<&2X0Se7B_KH=jCuc>j;w4QxaRmj=nk@4nb3s<|=_j;+H z=c#eJW>eQg+(u&m1S(HOmy_MaoCX)RuD9AvS;dw!uN8G{TW4+j`qDhIxXv3_3eii$0Q*3T?srU7CbL)ea`)_kcik{xRk@iDjlTt+s zQ_T%q$fCY~do5-rcx`RK+T#|fHpm2~zib^HPja$+O`F_}v_TzK^FyfQgJA{BCmbhj z5Al&9Y^?|xeu4r9egH()Vt{28a5IK5m=ZKa;Pmc^Mtu>L2H-5u^kSKR%CU4VGbB9J z$qlSka;H9&O%4zBbK5R=EN4g#MtA4dl0;wX8AA82J#Oe0U(69t9my#?s*Z0blX;Y2b9x1AL!5+_8xx!k*YdWS9V&g-S%R)F+~gd;3?- zu7}rd`u6^@kiq(-eFl7!IgzWJ$l?cKpQf{H5U`!m)q#zeo-g$>-}?)BJCA76czjug zZ`7|eZhu-mX9UKx$5fqF8}f0>FK}hw3%*$r;a#m{pfy8e zYMYlS-xuI(*l?VWq{gb$B=Y5{W=f>$!v}3H#OWbTp&IaTq6rX~#K4QrO*s_l2B26> zfB`xsw)~I|ybFdIYBfvZP?JaH+uT*UPUzQ-QiB836nhq!7S_(;O;-;4_O}ik)0}b4 zeg)i@$moe2nnrM>WvA2W+Lm?NnSg0P>3~tpUlzo!k|J4A&kcoW!txc#b)ASxEYKu_ zx1$I=xUfJ)F|g{>2MG``)({Rg4fYk;OA;YU@U)Oz1-)mTmVc|7nIpCmnz&FWz6x1!6lq9evJYdA)BY@Nc zW$?ow2nTW&Q0(B&WdZSV+z14%vH@`46MQdVfjkemSOh*~%K=f~=S5CPz~0GNbsfk_ zq*{+$KHgq<+!lcK2_M#<(#9N+g4;j-mxJ&(5$AJ(KaO{9O&La9fM3tXxvF)@oc~Z< zsI#Dnl~!ojrJSK=SwWW?p9}%bl5gLa#$|}ve16%py{=tmhRkDkb*^`@k9l96I9V}v z-C)Wi+--1IVE2dG06p?Y!}2JN-9#(S2uAG^V{fMJS6f~ASzN#Dk)xC!aYgDp;?21m zJG51)V-Gd*|1=r>9&#<#iMeC)EM|FK``d2PzVFT_R`cyW&TMS{?cmgFXCG=!eO&w* zqc9d{TA_P+N*CDFb}rQo2LV&85tc}SyNgZUZT97X3C{1oq+-(;1w`+s5d-3}X#Ms;Z5(q>?oKn8l+B28CDoXp`k zN(Mh5e*hZx9X@j>AG|#si5fD*8p=Z!f|(mB{Xn-21^Q*s3Ujw+|NmE@eU4AYxs;Tc zg3=5E3B6GG+u%x^UFkaB8*%C;VB2?0m=&AKuUN5BXhH&(7EHZ#fnpA z<^s5OK!of6J}B{R2kwENbMa$?8}J-08~p7u_PNI8;#+UOnY8y`H+Z~XxP9`;*zaj} zYUGcK<@ZX~0TJT+f0$O6(l)h=wcl+0V9#{Dnf(4+o41w7*TU_BZV=XW-je!R8)8r7 zcf)^}94iX^&i1%rzdE(RxwccWOP%YB32*D2c;0mXdvoyBhM#{Od(5ZB?_5@_y{_%i z`X#j4QzG?Vbiupzl_+7iMcu2tI)m5C+08X90rvgH?Z?V@Vy_~px=_peLA%jLP_qf4YZ$(BU^+*2~ggCgZGbj!U*fiQZXbkpTR0^S?}69%^#5J2th z!2%srH693q0Dt1?+)(0Po{)KnwmkMw96?rDa#-a^zUY1+J=reUPGpp~HmdPma`>fH z=UY}+4KShBK@K$!P;{(9hLc-l~*!kj;m-3Fssf#Bf+3wgV;lnq8WK)8jx=LV%2-k5DI59qb8k zS*mFQI9N((nNzIk@uxe$d6=MS!f_jEkh4G&4ZgzRkc3JvIcYjbY25!Pn013P%g1*C zIc|KDLYEghZ=4eFG#==pU{O=J(I&My6iX`U^MH?*%sqOx*k-nyXwMr4dP%8#bl2>) zUkRF^U?LAr;~w6<05lfPyS%{i_oK=ADTbKN^^>-00K=|#t8$OZF8FXjz+dOH#;$mJ z%=e&(z34uPV#POQBlAq9686~!zhZVrZ|YU;v*{5%h2bY3js5N^@(5XPI;T8mW%FS5 z!Ig zPkG%kH2m({aI@0*))Ok`WZv6r1D31jyjH)2f>cyj=AlUySgIijwteSOpb<^BJgL%Fb<<^umwq5&A~ zOrj(ve$_$0Kp7?R`3vaVBax;Ua5m?s(&QD#1C}wM+voPmQ^zxhHd@L0BH4g3i!CL( z+f;#)CPIc_;DEAS2m}xy7;)1Q7N{`C0aYENMhJ5P29H z$#6Ay>r?vr2rqQ4isZtT;peI#k^u6(g&&&;HojXw@~D-0m1DTF}v%4Sz{{qxmZ(_Dpne*Z#5X+mX$U zJ4HvGUTnnP&1VPyb9i7L8KnDdb!qVG+4`*|_QShv+jIO=D|?cUzOO$iyu1@TkQ3NN ztzS{Sj$aTh_J23ma_wfd?jZ1S@7Cfsjc;amd%vXpWw|;xZ`tN;9q|6)SU|Lud`n%C z?Q*Nq!zuYleT0JjKgC{%~Mn zbfabmXB-X~xe61GR9Wey8Xule!%q2}hAH>*=m2`=x>%h7GT9Q2v9DH4N1 zj(q3_EYdsyuxEuunQ|(MVbkY9P86Y`!NnAuj=%;65VD<1fbtiBt0)2<-Q|`pYLHwq zXviTXB7u4VwATNd&f>88pz}h_pkeyl78}G-$MOxzTez$o;?!~)ZwW%klb5IV0;?MDB1c%VtU=PkqPn#BV} z-KpozRoXgZ5nri~1RL!gWp_U3ZgsOCuTIUF1$Z|Zu@71kdy;vRYjzZ3%$iGj*)IFZCND1BZ_=cBR=hdNYMk$$ou;|SHnjOz?$s?s0HHzF$JRhC2&e>hLiBGirqMAF7Wf*$ObHd>dU|Lgz(5{>i?7Gr zpW^XtTbUw`{|8|gY}i*@FqPjCaw{1>Q0SdVqPUqH8;i=_lj}0)D!?tB^rBh&C-;%h z)t2-YJ$K0Vp^BKdm0p@tqBeDNmJQA9BZ9>FV8l@SdZ5f>#79YdofjCOjM_%&n{%z7 z2=RbpU?@*;8Md9|WdPYI8^D1Q0X0{_Mxm}AgMcc%lEMELTIU`b?Fq<@LujtjJVX{w zfKx$rPQa4&(Q!yqG7?PsfQ!f7;@5%;62BYPZ$(5I_jnZ)6vXKEhR%8^7JyqR%?Mq~ zzCV@M6Y#Dnyj806qs;Izihf)DDJPz0O&_FFU~jq(=5bY|j02~M=WUd4FiR>l=-o8g zPeoA$kpMjxIQ@J&-Z|JhHUE&@e&vT8De-V8scapZ>MrO1G*;fZ+ALN3 z)jIHJvC28^TX8)rR#1oTZ&qnqY0`@KPB4nCrG-~<EX8#zZI>e^jX~}qjS1v zJUpIK){0}_H7TyT9^qUq4qBNKRs3zCU;)P!07w!TxfTb!o14JmE;2Rh8fD#|XfOSB zq;?}brti+-uA-)1gKNL4m=c`IEBWk6&hO*JXYJhP{yILTdn2lDFZJpoZG!Vr(twmZ z;>hXZEN%yd?Jg+(+Pv2N{`DmW10TW9PnNYYx7SN?d_PhkuW(Ndivv-Ez(R3)K*h3z zTq^xH7|*~94ujW%Px{~ul&u3-$9)n`3Qm%Vp+=M><-p4GICIPFG(w~JBmB5nm0Q;= zfj3`|zC1rRrCaGFU38y-M`#JX8l8d5$?@a~8tuNm^@3T6e&E23APLSF(wwITu@x`m zTRu;C>0r(Z$o2t(JG=xQf8czpuh20x7?fEGI_^el2?Pk@N!a)!GqXpLFu6N&e?v%F z2twO-SFn9VfPx(8*C6N+&3%%VVhn6aVfMf-8914OnwJb73!Eqx^hk&}ECOR>2#OgT z5|O4L4D6StNMmjB`LrY#f3+NDDnid5?KSZ?&a#7F{z&ClS8{*B>t)glRjDhV2Fys# z^|lS}=Pk3J)5fU!ha=|7?ixtl3f7$cXRc7`$`{pARVU%McohT9>`(EOSPtpatF4?XB%SBl4NG~!E9SP(Czq>dcGx3tmkh$T zUafCmXBA%>{KT5t=&9^m7`VB)@W%U3HC=Fi7P;{Af$Fx-=Gfxz+nINoVSe}C8kw#; zz5RZ%Vd#m{^v`Ny_gg=6c?->;5A(z4lK1+-!sF^C5_>El5Xe}pw>BlesHj>h{Bq2R z`a@J>Ls~{{{7uU89{WY$&Gy4XZ)0nlZ=}WS2e1-*_T5JY8alsSnX4FkfR7j7Q@uaJ z4BIPGbN0xWSmW%kOm{>XroHhTP<`O#wkdC_~|{GhYoNc}&d=;r8SbIvMnE zEX}+jxwaM*3`GYwklta5Z)J zN52Ywt|9tup;m73U%DYZvadou^=xhHe7PO|Ro9YrPUYZ+jM;$ zbDi_ey%rShkvm>AC$XiYJlp@@zosO((G)GXJRBTy?&8>wU$lDkm^~MR1Y+`^V;|Gh zP7I`#-bXRIhdwF{CY7cGF&()@{?y$}URq9CBayfCZ zHAZFEw?kAwzg&xAXD-}cBmC<0at^UFV^@zi-Y5b5#<5rcR%5}hAHwpOme@kz4-6hh zCZpg$v;;i7P8E>DN=;8+pOgxrK+Brlh~7uX5l1B zX+D(Ens1a$J30A94aiB;uj4c2nC&jySWqz(x1LAWDImST+6+iegQ3nI!hj!!0Ah>#pnygkoZg8@+rEGi&`^?r+tTnEwO%26${*X=qCJALt1POi84>rIArUCUduDa_A?eFvQYmV ziKo!LHF>Mk4t9_I{;;}2nrmZU)UJ4Y2wq))TVRa zVRu1qp1IT8j=$!d4H_fAHaYL#+FOnIsdO~(ns@sLtVFl^?}5bGu+5eHq9+oAQ#zIt zN`GAm_~sS~+?4Cneq~jWPR>O~a@?ZdSmaEudgMraexaJ}M1QNDUOm1wHGMz#9d-DW z({XDtPQH!yj&9kx8|g)DE{9H9M#nDa#V~c=My`iP-L(K|iGi8FwOYWGm#}L4lw&@B zK_p!Ku(Y2LpQ#t8LoxnozoUs*oHQBDk3^)P!O+i5N>~aE#!sP~pn%i_svI4v0K9%1 z)J7`~;qpFV#6Gi;F(E~)m!9!L$x_YzD(ts5{Lalj_H&_{JUvtM{*g8n%{q!o09+9S zCeslewxX^IG<=2^Bs`PvCKr!FpvsbAaz7QSO!fKX$P#(aAb@4_$f;VSv$92!38B+v*z(c>rp7NFn+_m{etwCfZ8?z*Ke zCAL;ItR|XZYJ?DL=aEqr=-Dd`(YiQkb;mOgM3Voz1;$5{01bS1#@LkctdIBUlvO94 zL9kpS>?+S1TRZeH>zei1!DLVEnK|TmAwMoH6vfDvJIY&koKS5#ol2ffdPU2U*skiL z<&DMIX45@KMLumkxuN`Y_IKd0Qu|HN<+UlxXT8&uf@80#g>CMn z|Jp6KUb(g>{j0f3{p5Uf@`d%(q>i2ey?SD>ZhNRrJON$=s`m(ZHbcRDC`sr&Nb6iT^?a$Yp z8)&Z1p!4G2cJzlU@91`Jzb?9~(NuV+T8)#v1r|S(Qy0crgNv7azP(ysli0~y=6tn~ z+_MCVO_NqZWGCON1U?@C@82WzrG(A-UU=EF`)pLEE2^=A??N|oJ+LepE&wjDu@IS_ zfZ+<-@bQx&(=r|i2LJnifkOtV2)uoj=doULeKO(FKC*HyhAs1v{%S`o&i}`Zj2?o? z^@SSxF%ETDg|95n-!+;&XY)}yn?ZIC0se<~E{?M0ZjH)zk4mJ0DXpf~cBrym{U$!V zBX6uKxb#0$q8mpA=?+4UYVkvmEYcZdA&WgpAvgV@tAgO$X`9N+5FzUsL1oFrbKbA` z;d*%I1NJSp2^Zq%DBIew`#GAX@jwLvFXm~apq@WvcK(HQ5=4h1V4$7>JDmgsNJk2Q z5JCq}1Bf0y98^HYI@R52xl+sXk4jMu*2-BWVr%h^~fBicDH`J==40r?;Z#lOOL+XaKiibV|F zsYqmie#Mh)CBb~PCtbrc3(6V&b_PBEEJBTlQS}3#4w4;Ef-EC{V#Mt z=AmP3kjfDJ`NhX->F5k}JFd(xqWt>dI!-_J^vj`hj$*uJrb(^2pJd zpc4;{DjbvpHB8{^;cH+_)02vbSru1o0)BCbhC#Oujx!RM@plLQyhyNVsl1b#Xo)mq z!e!aT%T1M9Syi8v=8J%V_B!>;+F^kn-XBwv0sFT;(+KzO8WsMWFADCM$ZBEtUv3ac z+S_pt5BqUP_u}KrRi}y${r%YZ@y8;+AoNj6S^xy6}<-G1H}=mjkTf1 zkwJsPtqXwof2KFadu{Q@ck7;R{+7*^&Hc?uKU2TDvxR#DxvX``?wEJ!hHRCE*IPda zQm1WOobdVe4+|sC2T*G(6`CECKdUwykZSSLc)I6+bZPpC%mIa#mtzNr$%Xh&qmjNH zjq#Q0HUbaLKeV9$)X&Z1`Y#=Tb!f=e9gXa<5VC0IJXrWmxpE=GFhhLJajo_?;ty#uw zp*$&s=vgV7Y$(sn^;a!;Gn7@EUng#r3T)gZlJI8!qk29N7VhkayIwh~jCwB`pdyg~ z@r+hE01Ish!r15qr{o8EVJRnSWldUM5zuj9L7eO)y{wuI6q9AoLnmPTg8kFur(ZbJ zfio9&h7Vwg0AU2&7K)G_WC)TgL?G8;Fy8)+3*P7K#q_uCrZjr*f5!hDrJVqk}zHu(*-6_Uq@hrDny# z2PQX^yxAU2{^DhM|L7=x*ek9G+x#d{ecx|ngXjH5^l$k(ig-nDcety!L!pjewRd%t z-@MhgmC4M%!G#Rc_aQuN%+gC#mFbujJqZql(ooOvd<8r^mT43iz-_t9Nq`H1Nd?#u z*%IQ&30zQ`+chU)P{20`fWzpU&lM7xS=u&4(+-EORQ0fi6$b?K)g;YIq;A!nrbHCO z>Jc#fmcGhjsSoVT3GqZ_XZ(UxbjTQs^PX7`@agQly?he3!`{}>v7Iv|PRs40PLEC< z!UR0B>EMH8g2X%Gon?{2&*-ABmTfSyz9smCI7B_swgIfi0L1Aadd}y8icx&yr8Y*a zu^Ab{9^g0cFjf^F2ac2g7Dd8E^Q~&HEF*beUL?B@Mf!q%(H;Ge<3%aw%xP=(DfCgpR;cbM8v;H_p|2 zTa6+7a2@-l(wiP-XLG)|=jNQ{@hVjR?`ZlBx!JCcZ^z^mzF&4_XZ+!A@YyYR@S5mb zId;p=OdfMU_Z)2DC_9Ah@mH1Oxq|sx-NNDKqgT3J4;4hRVl5|)cu4>0_8y@9slUAN z$^^dpBBJQ3QA3n>O>&vJ*Xs?7*Xd(hOI@1_F6RIz< z0izekkEFrMh$CnV0)gx*U++xTOZpck;pQ3OTf!p@njHubbU>>BK0udA2Y+z`M~@-W zCzR%0IX3fCSQR?0Y*sK*+k9uTx;L=h1ze>AB^ishst>bYKh`Ce0o5b4+T-ZGZF-I z0sxZ?GRHTG0uTu78Zulae3)RS%4}#=nDzqB-Vj~X#gdj(($Ju%2V7Uli1tOA)qzxf z0v!nnqF;%gz+!M9KnTDVhszeCW1$kDMHA0w4u>Z|!U=k}bc`dLt1g)kFJZOh!Is_d zjc?L<5H@ird+&!iN|GxMw@o*tBHl7FlH7Dtsx|r5yVSRylBwE_&Ug8JdLp?YRn0kAYYr+N#Yed`*gO8Dh*0ch zr(Uae89o=fti15gf74@7{%dn@I^PV8MP5rQ%F(KB(wg{mWpDp%uJo2Ls7h?4-uwaCOGc3|BF~Bxs904;WBRUrYEe4RLWf(M4f&{42SU3n85kn-Z z0xVOpFboV5F#?TpCHJU_PakQlW7+-il!@{soR&rB8g)XwD(OU`(0N=7RSbk8Qer?i_s1~U82MpEBD$~<$}@;Ya$?4;G1 zJy3~owDol$U=mBw2aZ~as{EZ(HKXV3EY8hu-DS}1i^EqmXMb6g7i3mM z$iL<+xz)ToR;;$ijyX$P{j`&Qzh!s7Tj1b;*3R2l)?Mq@l<4k{qdr*;qk(0itF2kbMjJr{- z4XGF9+K4w%I2ZelzZt`povctyoy^TLTD{F3az#~LawRxh9G$kSW!^D0Zu?~1GJ!bJ zwPP>*3}_(Q%KBuSkS4j;1ajSFICa2`8x&4GvfPpnQv!={f{t%svO(huCD!>o>r4g% zx1I$GjzB1C(?Olv+p-@l&~wHZ!Wao$e&0Z(7ZAr=x^QgxMuyN{%B@K zxzp+8Iarfawm|;MuFALNwtRhOmvjSSIPG?bI1Du;uu&D(BGE4=3!5MvcX^&O*s69? zxk;^ER#Vg$P;`|;H#yx=VMi)`wwlfsZc;y%SsWi9{cU&pZM#`t_r8X)v5QXX((F!h z-eOYNh5gw4ct(#2Z9^+_~z)F3#Hquwqm2PPcB#u;FA< z*r%uG{#;K3MkYE}50i2mA9%z><|UdCuT$rW3udp*FZpRm6%-ByOzGs9m=z_m-L?Gu zKNd#5If8LIwt82J^x5i_eQuUW*m9cW(bJ!H@|c0vABvJbk4A)tNXjBr+Ng#$3XReW z#5gl^pjiN990Bwp1ai1^od`GAQ0R29?*cgnyugYH2B)I{m0dA_sNy}G*9i}(Z%kD8 zZdI5ePT8ssCJa({N2yt-%k#X$f*Y$UCLbQZRhMjBe;Zqtp@)= z5Ua%n!Sv_32UAD@WeL^ZkAFtNmZeyraD=B2|0ric={6t4=Lo?i)OnJ)&wwdhF3u6c zq9JEG9n0ek2xm#yb~*%_eg-xnd`4pTspMY2OOO`thXt3+H7}$>$xR-46<1&(G6oEl z>Izi@4l9p(Xg+s2+^poQH8^e+FbH!S`k(~666Kg4oHIVWcDyD3nWon%fxS_1_iPW7 zlT~d{$wmc9){NjL)Y5gBd0F-z1z)>V?fXOqEo+?tVS10{p0MohOiP)1wr<6ExwTgH z-}-`J)q&hc`#EO!vW`6q+05;C?B+Yl&nn1`)(di97#>YU2r^l;he`kHU7%GaIC zeHAe1)JmLa<_lcl1B57{f)A;T)Q2ExE_;=X2DmW~L0A{cS5}kP-r?zxtLPKR+%FZcc;VGBlW%#4QAy#MXjsh8@~mqYMM*pRE0jTy9u76z zSxZaqPdUhkV@!&O5B=YqlKqb(uAU^(Uxn=gqEs0e`uTKQ{b3}e*YJokkJRS}_6>3` zzHEC zc>Op}GcYBA?;XX(5zuybbaPYrJ(+Uq%W>@s!n@tvs3 zA7k}Jt*^8?CP~2mB=M$zf$Y<+{|pDd?R-%X@xdy*a%56u#zEdZh&4X)L-T6emlUIR z>`j{K%=z=S(&I$t%OE2o2OPSVj~gWV|1t}~yaY~s|Lu1xKnfv)MKz#?8DSd8WFS4J zV)B;;a`s|9F;V?OSHJ>s@=n-b>R@odsIR;VgDB0bkYX`v)-dlIw4 ziBOublPyLkcpCI;YW+{mX;7pr7tY@kR4;R$@eGukNKQydrCo)J+@76ZjqwKj-?E(8Z5D?=59&q580kjVi09TL|=wmHG=0huT)NaCwV+%n{KG50dKSPgLNrD}#0IRVf-( z8?$bwOktk>dKf*jkuru~q)%EQ!HvVOnP*U&ABe`)M+(N@zhopnX_zFEfD6?-*n);6 zhDkj11L+FwL%Ago4k7~$d}b;Tti$W1o#&w=u%>$Epd&HoDFw?6&;TQpwD{VZZ{aZf z`~+!u#_ad+h?gERw_+4_$w2> z&wcU^ieZICJmEm|_Mv#<#T3EW5UbYn*%_;nQJp>qUC!9dTHmP^OFXFCCHl{i6tCm? zRgV#u%iHq%O`%l3hRBhoOJyPqadXS}MB{tOsVl~lTLVg@s*09XC6$1-H3Pu{doI#D z7Wswx1}f`Wd2;H_Sndb^FIGPY<<r1W`PiAN0Wpij(+Cg|qOiXOm;b24^0T6!6BRWdbW*5YQrsNP#=s!ahQ<15PxV zm-=YoDUdNhb%5wR=ZQ!F&@#U2#Ni>(R`bZ_pxy)h-xiPqc(HJg5Ow^rkRHy6fmSCO z66DO0h6sEKf-ctprejgC1|WkV2O~aMBVoX1yOdFLYPGScj?xa7aQ!%$SGSdf=98n} z6fKbj&OWBzHr=DA3>*B^mYaqA0i2Rv7m=mkDxCZ*jQAfVi5Dj7qcO-Y1D@(QdEp8j zTR)ayCo-u6bDtTXfppPBB`PV3h3(D;m}sW-xhc=NhlR_>C+UqI?9Thfl2{Qb*opcz zY%X_4;4b2RZXBTN3o$O(an9#4s>;#_(udDoF zA!YEXAYfs;iFK>kY_*r^BFf_Ew2oCvg;(+62)tsQdtGy#16Ha^4UrE?v?H^b+fQE# z3kb!-S(^0aqG;{ip5dl~?v*CD=pe0$8MRr1v}%>rf(NsYv}`Z4u4eAe8745vQ_lrZ z7V;wEAvMll!^y5UoMKNQ=VA<}O5#7h3F-?sU~9KlW!zk%2LXNnmLnuTuD=Y?p1# zfGd@Ubi@NYKN+$yq=yBNM|5&i5hM(RHM5Ij?!r)m0ZwR$K*6|zhKMf(*sm*X&FR4a z4l6neO~ohxB$?_}A`lt#-Z?HC<0zrohAWpwV_G%S$w=sc1cFqbk`BNNh^#>l8kz_| zFGPew(6mOvbvCv%I+$2#kRUZa@O`ype%{ z0MndR7$6ofhyd6Ph=@3|n4ionCh&DvOPoD}9~avdg&DalL=@2+t!SO{A1@{FipNc6 zKXf|y>!F<~u%4kAMj2z~$v*N@_(|t>Pd>b)#BR+tGya6? zoy8o5V8J+VI2dec>MHaThww=y;8+-#dSXM8ON8i2F-&E|7nH^!kjy=b%S2!#K)r_y zfjv5DSo;$6Qzb)=T4Yj02vzw2;6hW}+pd+J zouiSvLkXR0CeO=0>RxmW=V{!3`p6)jcdg0xboox)gqh>vfZK7;0;MAoJWamXU!(mx zGG@$u_1%r-!Kr_%754CEqnV1~lkxfer5l$Ibf?UQ^B?f?!G)ntG>c~L?pZQNIDllM6mFD5jQZc0;(NA4j_qu^Y|Y*RPc%L3*jbzSy_IwoO5Q4+DY5R z!1xG__AFBS6T`94;W`r0Lqn}2xkIkJBX->2=JI7XsV)XlGCYE+@9dwVnKSa}K)JM4 zq%T<_9ax)IXfnxU9qD-7=-x&I#dujthfXnvlguR^sfU9|Wwz%*D;o;~Ta~R_*%&$n z;;p zrwVf!5QsVkq-MaGCUr1J%7#LUv1!LVy{TvUj~-Ip*--t&6C3Fz}fUwEtgp=awkIo##a{_03q4{`UZ@GD4N0V6e+QmSRGT)j~eX{B{&AUxO>!I$J#O(opW}! zMkn?k7`yH|KA|+brVv7s%JXe+9A_41l61o(atmUlyTIz4P;r1<*tq1HOOecSzrZSb z>>Y#M#{GD4IT!<$8b`5qBvYKr#+{Kvnjjf#Gn2VuYOoqNv0wj1XS@ zBMC1gL{d{#O8t^4t=4ee;0=ft{dBI5#FoMX6UqA?xq?`kh;rx&S9*|cMe*|EY9qsE zW7o?$ThMK>4#%l1w#oIEmYRrBe-G`>4eBN8N?=o*RlQ8>@3% z!CZrqGZntt6=6-Smeur@3~d*oqhK&BgkB_UM8XL3hd_$}mH;wP1!X6~B=XfIeqrD-j6ZEl zGFE60{XH__yTDZebNAM6td^15)XG3F@mxb!Y^l8mgx&eRYsOG#0n|f!Yt#(wRjXL*uG{ZrPjsUEnf67`VuO2b)x z+S}x8a>4jdH9<4$37St+5pr;Fi7IerXwTjzuS&PAAaC(l7^RchI_WZ5Yke{-YY%m{ zL`M`0LNb`JKFbyXgo8mv6EP47xr#%s0^$I~Lii7w(cUTHS4)VzgHS`5*s7N8ZsZOu2T-!xoZcnu6@`nyJ=7&=r~*&KE%|b(bU6&5KsLMsGTlE4~i|YZ{NcbMYZYWs|#OzvhP zSnEuAmef9+kJaRUlQbg4!a(I-*n;hjr0AjV7v??20!>PU=_qc6Pq6uMrH$znlZMy& z)0>B`RBXg+uC@fmX_y#6lv9?i>YfC6{BhC+D{WZqHj3U__l)XX-;6diC2kaMGz9nY zNdbo>-Rf>XIFtXlA#gOq`6}v#&!Jw>k6BUsfK+c`=o+o~ZmfBzciT{8L*ZlGb9;SD zV~N!h`eJoqdL`vyEFcZ*-r_Nd)Mofvr!Ze6b4Ba*U4nXb zB5oS3b=t;^+GQ8;v<%258Q~tHtF4z0 zLFd;7Qc?wwvcSio1$UdV2&6wqQ$mw)pt|9%mI;$+Y{dxW0fT{v!a&HtXJi7o1};Ke z%Is42Cdg7a;BLlvapk1c+mof-vdIo9RnXnWsR5!JwO>^rjVGGo&<{p816{$B} zNiwYYUk^r3-<-qEDoPV$gG`*)-gT#pbct6CHewQuN{UKH$Lo^rnOrsGDsA($#D+bV zD`sHAexR)<`t`%tuSnd9xXJ=`GL>@W!{rt4wA(%&KHhRkVch=x;omGiY>me2ubuZ- zcr%)4p4<3AFd1Q0dz#-T8g{@SBSq=mvM284M{dW0^2}slO>#0Z{dc<)+^05=ZAf)4 zYbp17YhMkC8%J%=bwOtoRa#7KUV~+RhP^ANRHCB|tEz(^3^QCdm*xc0dcWk`vl|A;L_6K}5}!*dS}xz8b&{zz((>2Y zfaY>UvzE` zVNV{sHW_O$p568iBk%<0c8s@nv~BKB=S`i9cu2i_@WR&w)uG?8o0kG^V41u}h<&uU zk*-jq3Z7iLYIT!ONp9RSoA|gwyJInK&mYb zyq<&ztTh{?dgMktMkL8tp$YbfaMV$vz;FDBA4Px^K<@%b4uk=`p%W4HS0T)``)+mm zHkSx#WUYcBPeOj11K-6-wBoyMQ%sENh1vFXunl0*#%S;O85^B>+`|Zmt|D~tfTC+r zqJs!ltZgjEV&>V2ep-o?OZ0##GVUkEWDy#qJ;k?xiLR$RS4Df}C*q2V%&B1*8gbl# z3Zb;&lC1CP&|#Sn8^Zk#dPG9GmXYf zh6^V5RFm}PNj`dWv8q@1F<-l%gM*!8{(rb~{8jf7-j6-Y?Kx=y?@#Se8hzn8re!nL z^}yd_04q(aweT-=KR2LdxR7RY@LlPRvH*6wW@NW3GWSNvqb)k#yH!OMEsmoopuKssckNn zHOGMkIDeeBP`RrPuJjb8&!nS)zyVc)Zf(7e}!tqc^76s$Z0K3met4bg+3`)ctSQ(IcpaHG} zglt{BODfN&dpr~vJsUf<8r!m;(BOJT7`m=Q3yM>hp9)L0e$X{mwwxXtaBZL4>$=3L z!FbT9^>V-3fQ8Zi^9ODz$1G-3#7e9Bz0Svt`1!kZKhPk8*>LXWbw_F5>n~?Mt3+(SU5&Y9Io*G_mOlAp=vZBx z;j)>`1F+7pi<&ApTHibHv|A8qp{dof{PPm0J;B*fSqy)O6_6ddX6BV1x0D}r51#mYKph`#; z1f~H+)EE1AkC*d;lhbH|y4L z2VrBN&i#e!&6%0j4KOmvnvJozVq<5q^E#CuBk7xGn+UcJNNT_^;HIi8sYq6?KO4bL z0)`3Hq;Oym>MFe-gMmPu9NWTylv1d*nXag1eW21{M3vQ3t)mU>iqj+k{_`VJ(J&;3`V1@eHIyT&N9(D}dAoa4?Fri4LQA7jbG<7? zlfnSKOH+_+H-rT89!0LqDK0*U3tdeQFzHHy^p_ors61~Gb8p_@mFKJ2(+ig@^X!JM z^?Z2OyOlF{?nsc**ZU5G8`oSXydoZ+d{yhrF!$SP?p-*r=gDj#zdW}mR#KJFd@|x8&J{l+cVuTaK|4RscVO}Z#Ec!o*S0cstoQ9>fL4N0rYFM_lE#vU%T zjP6bj(^O)y!EP0IH!N0!PWNq;Rj3t+-v7NHh81?yu`w8gIXau22<;11b-W3E1U5{H zi8^T$27}NHFldK{<_9=l(^6%F)VL^SCLGfs;!jP)B|{to8DtT#IRUsdu%Q5&WsRu< z`DH8#p)=H{~|*_j}U6qE0{Z4tYHA3t^Y=Ile=$8{Hm%=T;Fc{0{h`zrR*{@KCG6QydkJ0`u) zY-8@n(j9UAH;(PAZsEtsTvc=>mN+X#4tsfdx#_tFOcmD#23le-#D7rSAwC)Z5^(5x zJ`CK@NVv6jV_)_Co$V<5!1c+pt(Ft+u}Y&aw+=}U9Q=IvhUpt?&bYdZx_+&TV~|ms zR>rjbyHlY)$&0Bj4On-YO8Rvyg&6hJcmP8O`2%48$+QeK-hpHO11x~xFcHuVH~}bx zApsmgruy(GnNQ4~EJH~{Z-ute4FngZT;1&>Dz@~;SSPum&$VQaE?nDmk28UE5isABMnq~>nF1w9EUB7lRF3LkE zxjtQsMEEM?}2?LE-tRk20|(6(2{B zddCR5dq(%@@ClOH>n;AR`4?e+X>f2eyl!e`WIy&?EVUqsYM!cjb*v%8Iz>aH-U*vq zcXn~G&2@j=cr%fC)M~@EkSSL*=XK94)GXps<)yYeBA}OWJTRRkDu45orUHDmC*6Su z_G}w|h+1!H{K|Z@_E+1b0B82apY7eXvrc6_WXIcXc`=8aOgEqKiaa$^D=HuQ@Gm7@ z_BNa^-W^$K>*BE&1rDPngB@WHmS*OuH^s$KCDMke`IJu4rV!r&38^ma9=%eLDFU%uxSv270q;2 ze5DQsY#qR+Q4zlu?-LnH;Mfd8m`4^zc;FBj;0ZgYz(m10BY=b(EM(;5Wi<~Yrk97$`*9(TD=ZO^}@IJ_Df1+q==b~4|$JMd1 z=HR>fRCz*i8$A)zc~N0SZRG6Q%Vw@xjw8xIg%`(nlAC7))p$Paop76CHAhqLXeGBc zXz&vQA9=WuGXg&`q9#ap?BX1*zinxb#{-sknPdv&ueW&4R&S)H84iw|;_aBsCj_&! zX4l`vDMlNLyndH(B6dE-r2Ua>YU%abQp3xKOZS948|yHf(gxcyXbyR-S^+H6?Ru^b zMHi(Ge0x47gA7W#P~kiu;4-k3p#BFD0A_=?DhQvWm@UZia+1B5$?Q^?D$C!rfQNPv zCptu3_l#XPwEp9gm*hjlT#V)dt646p%Vdn^f_L$WQLQdN*T%fbRSvM-q2Qe87medE zRFMO;1Z>@BOBt4^++hpi+ceXZB8QaxB`}0ULb?-kG$o~`_I_ zblDLL}bb^K6S(!g<7_-y5wAzYY3~wj^tXJh1F?=F!f|EThz~R4@@+*Fx0Ko zmAl`xqedbiQCBi7D!Hmk)CEX)(R^KI#B-R58KS?gTzM08d_QmPi6qfd+fz)-B{?@ZtHyDo z?Ys>`uj}-i)zGMqLVll&op;W?;2;ohF(86#s$T}yvF+-neMnKr=9HwSX7r z_np`a>#1ER=ZlwwT~_+q{5VE)o~5%fIv01}XwDTLY^rcuev$%K-uvGWp>gFhodQKE za7ppVMIpyiqpDLi4Xy5s-(S55YxPH%qey&&L>0O9;%;{sv>wqAf)4KN4EBc-J)3>= zAtIoMt%yubBtXSMjbI>1$a0AkEYzgY$fjBz12V%n5Z|-GtvpdsP(|ZLMT>y8x2B_o z-0f@Z6`m5A$>=DS1)FRgy0b2+!!M!aH+g` z&J6R)BAPh(55EHh;g-#M$=i{)mBhlLap?{>YeY&qWZ@x7%~h%Wbh2BBU2R6H53RQ| zMPTv>iW+^aH?3q+q$W{N^bmn?N2?%wD@9 zr`7p-yc*E#$0(gK@(icy(bXW+^`s!(80F?$`rb#$G{jYF%9hGq0trv+jC^$UA_4=} zwxh5>rNR9k;RW1Q2M7#IehZU4K+8e5GvGGm7J^CoeT&e7ptq2`HVPVToL8}m8SW*m z?zw}8V;!b^~6=GOmFap6G~)b22@M{p|cE`&`dPlDc85x8|eNcozp%Q=vdScoVH z=*b`qA*k~UN(k^`IJsZ-QhN{Zy!Uka$raCzozT zR-8D~)0UN@baAfW{#A$=|B!>rNuMG|w*t;sj>fc^=V4x@Sb*ZBbXb0gy!z;B{wPhj zeyI%3<0jrQUM|Xn%vF-I?E6~ZUWq<1vhEH~4{9&Cs1=cSD!1~@AT}`oqRRDAu?)AC+rYG(M7Yv+1n3QtdZg=`ICjF zD;(_Pq0l)bXf;Y*h}RPVZ&8FFj0V&NfK3zv5s`QUAp0NwJQoDLk?8e_C9CaPg1`#& z=Jx77URyY0bD>EgaBb`Xse^S}(#TE9d2B9ju@mkJKdwxSj|!`IE-&**=>3poxc4WH zgzZQ3OAT^k_M;)qvPBOAQ)}hml9B+%ErzyF-UD-aFbOa+1%WVNswGF+Np7NUjP@=a zo5@rx01<#~*7@rBB}7L~BpR+RD&p>zB>t1(Sc}aN^e&hcHg9yZB6HxPL;&C`Lb0JxOCF+F1hL|iWC5gBt50&g5JQZ2NcJx z>O&>t=~V+!dqfihJU)GRqpV>>k@E5iMvr){_FKCY@m2?d)En=HCnN4S!8sAwOOTgW46-p$#4N|*ig`TCaG$x6+RW1krQyz0HxqFhdY5X6hB*W46(qpW za&cd5jGG)%{OYhxE;qFfigh%{e%N-OOZlj9<9@7dX~c)}LHy_L=hY+W95=zbg`_$d z0UEm^6P?!F@Ot56p?4fZr>H@8|9%pC8SNjDAM(s5~Pyfxhqm~>^>)8O{I>_oaKyvi9OieSU(=2^JO zIfMibt_j%RSWqdVDc_}71^P>1Soi#UQQT~olZIu5 z4m*SCV$mYt+-!aT>-Na`keQr0NQvAY+0v$p-mlE&`U!2lj zR3Ad`O-yKabJ3%a@uQGkVvVWV2G<FtvD&!4uqxxdpD+|qU*Dd}%g?p@+aIjlI&yYM6Hcdq6OrOjX^MkGJ`9*|VO$PMp>05~g$x(+UxY?%PcAhtc{=ZoOKeg1 z`e>u&(m9D`pcWs@ran017RHUak?hsJtsfUlD+6;N>ZLoYUfXZ$nox*4ri`8Cz-(vj zkhrZ0^$z#WHW(&_W@u%Hi+OXW)di#rRr1N=2)wwTpJ1un=1r?_J{t|@xzi!}Y>1eA zyQWegUJjZBlO_8lgH(;MT#Ko-a8h=(R)-MX-Qd8C=Qy4l5URFxYNn9SjC{5g8P%BX zV1rP{Kw*h)K(j$w#@dkvA(89JSSMKY%uv-#5{7~T3hgNBj_@Cd2d`Bfg6h!Cyjk$a zXwKTSf0&l00UY>ny@Bs+o)xx4SU{HLW-Ul-`%Q~AH1x;v1&xW4Q+*P$k~Zn6 zX-1fqeM~QHO?5^+^BxG%+(Qfc?P6rY%ihdH*fm|%PIkB{HI=%sP(;)y;nTcorOnxWE~cnIYHC$(C@!LuK7RT1$M~^?oX@ZBA^eL6 z{W@?F-1bh-^&5EydaIX$X2xSyozTw5_9%`!dso~tc8MxpzQ*+rYrIi>#l+;N!(&_Z zXLlzBixR1r&Hh}W$|PYh`NGj3Ff}OR3nmGKYk!1p+us;kP9#g8(PiGO z?cZ-Y8s-t91!?e@mz8xEjh$>?S>LD-2$JDgFA8Fpl&)XZ)AAfSHxqa!a2_yp5(pGw z7o`rl8PoL=t@&_QQlhG=6e1rF2a&R#OFS6>F^m8!DeVZB^d&;?;vLWia}AI&A9l~$JfHIeJ+v2LzKP8e7y>3Fv* z-M9}6JblSNvpBtN&DQ2I3G>E1m9leXxtXz=Pq}i6(zW;1tfGqR6H%HJ^VHOOMR6pQ z7?t6s_b4jjgQd8-2ATnMPV7onUSBzR( z8qe;j@_@*~%~R!7g)KWtc#sB#L-C-;#SKcX2h;{BPN3GJLXjtfPioaz4}#DgMyu^E zQpH6rG1n}$Trc7=5?AlLg%8;&t}X`SZw9WN*bWD6MO$t%a=?UyPGQ~JVq!YtQ*X&P zdQH9LUJg7HW;B~FiXwSbOEh-G=ADq%mz9-JuMKpBLx7t3_nS}Jt+7MX!46IcT%8Vb zB^WqG`ezqf%Ee|#V{4ncyGIq&Bot5K#~w_DddDx`QHN&BQW_ZvI`0m-35d05`pXz z0d39DT`(j9C5pl7ipl8c>Ep~D(5ePxyrC?`mmp_!l&bdkBKTe4fuhhI85!KbgN$w6 zj?;pZ=oGBJS`0_8n#qk1#PMwNG&y>0r*+ZR1e_{<2&a$5nyI;HTm4)dqKx;oX$D4x z3bSokY=~X>8{&uF?3SCal}xU5b~N_AkX;nzG%Qe?#nRCC~p$n{FB9xDmU%!g2%eJXN@NV}ESN z2I_sMgtusOX94Nw+gX~=kA0orbLVNz;})+1^|7mRP8_j){K*1^0?m=`D5W%2wPjP* zNTHf7PmeXB7W43?9yrRf?ghU3@y%(qghSgaBb8C$OVxmQZ0OGLf|^~im~XZoB}oDn z%n?{X(>nup7W5i)H|PRw3#&p75s}Wf^r+-UDZkin72WRq)8;5uV14w$7ya)Brl$D8h-d%pXK{(Jti8WoHPFl1y_!;5kTm(K}^5|n&i0d=&N;k{9m8E8cIDj>;b zC8hHniAV(_Yw8K`B5;BJD*Bg?yV&dDCA%gguhOpoj&lg`{sz%J!?g|m3NpF6aEp^t4ePki$%I-k(Q zJxcss^_6^4M$ghh?OlGU+H$0js(<}kNZFCXLs_nM7W8_0pF|wd0ZYxnI-x~n z6x+Ur^Oz;+bxx{HY9qrH>CO2`*^(ZW1)E2EMK=#yYN9ULezmb15LmP74vcet+vLM& zf{dSM`jV)QXqt@J5!m05rn`Sb7JY~Kr2;iIH7%6_{NRI3N`4(6;R*2foPUWA)GH^p zOAVJ^`a#32+o&X4Y9@O@AyzO9=Xu>!NZP#Fil?S$;^D;-m5p5Q%byBmh+f?X!`|NC zn~f|AMP0e5EG4gOcK^KH=Iy2=Q&vq<&dv$D!DTgD4wgVd#g%Oy9&lXrviapoZhpx^ zq~vV< zOh21`+d?1T=o>Xr$9Wv3l)+TW-eygF*B>KMU=>^AP-aq<}=QzqDW#>2|G8)`n@*llkr>7SI zq=akSaJ%)(XFW5N4`Tx@zQeST@GWaf>-~Bga0)ZbP!b@u`<5>rU&_Yg!k0jJKZ}-tjHFCRhws zU`nAH?O8Emj53q8!Svbk&pXxi>%3&kRD}dRa|-Xq)-6zqvdB7=`fKIoD?u9*m=DMB zAM(^cq}hHLPwn?>U5qf=YgacN0*JrY7SPX#lhL|pj7psRFQNa3BVyAbo#651cEbPo zI4-Cp&aw!+o1U14%4G-4Q8{??1SW=p%ebi2EVL2TS|OhWmKO9PE2l&42oxThoxf0U z`JCi*fP(3zT&a+xUKEG;qUghc@xmjIsq`!>)Gu}E)l_<4-uUTbpU#7)B_?ErE+3K3 zncTopxg;FbL$AT@KU^@8V4XOrlrh}sB}Iegg;E_RjSCYSieAxxoOl01npK!ZA~;qE zj9qMFk1OqY(Dw%+sHHXL@Y9Bpv*mDRj=#fTeV=KZws924XFjaBhjq2*)&-Nv*VBm~ zE#e6o2j=1;Z@3?79$c@rU7bd7JgbI3w_!iHop;sGeYN@YRmn|9Pmi~r T(n5X{j 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≦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

pURA8L@ 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


|K*Pi9*VS^C$WC~R~n9o*nJ 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

LNKG5N||ci@Dkwr#!C}SlZ6e@n20Q8 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 literal 0 HcmV?d00001 diff --git a/discover/icons/sc-apps-plasmadiscover.svgz b/discover/icons/sc-apps-plasmadiscover.svgz new file mode 100644 index 0000000000000000000000000000000000000000..b581cac99e9562be3b54023e5df23a961dc9e121 GIT binary patch literal 240726 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

5rk-is+s(caW0~KTb}?roz%-_ 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%0A{#l0I_=pqkk2*}n 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 DV6Ka| literal 0 HcmV?d00001 diff --git a/discover/main.cpp b/discover/main.cpp new file mode 100644 index 0000000..aab825c --- /dev/null +++ b/discover/main.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +// #define QT_QML_DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include "DiscoverMainWindow.h" +#include +#include "DiscoverVersion.h" +#include +#include + +DiscoverMainWindow::CompactMode decodeCompactMode(const QString &str) +{ + if (str == QLatin1String("auto")) + return DiscoverMainWindow::Auto; + else if (str == QLatin1String("compact")) + return DiscoverMainWindow::Compact; + else if (str == QLatin1String("full")) + return DiscoverMainWindow::Full; + return DiscoverMainWindow::Full; +} + +QCommandLineParser* createParser() +{ + QCommandLineParser* parser = new QCommandLineParser; + parser->addOption(QCommandLineOption(QStringLiteral("application"), i18n("Directly open the specified application by its package name."), QStringLiteral("name"))); + parser->addOption(QCommandLineOption(QStringLiteral("mime"), i18n("Open with a program that can deal with the given mimetype."), QStringLiteral("name"))); + parser->addOption(QCommandLineOption(QStringLiteral("category"), i18n("Display a list of entries with a category."), QStringLiteral("name"))); + parser->addOption(QCommandLineOption(QStringLiteral("mode"), i18n("Open Discover in a said mode. Modes correspond to the toolbar buttons."), QStringLiteral("name"))); + parser->addOption(QCommandLineOption(QStringLiteral("listmodes"), i18n("List all the available modes."))); + parser->addOption(QCommandLineOption(QStringLiteral("compact"), i18n("Compact Mode (auto/compact/full)."), QStringLiteral("mode"), QStringLiteral("auto"))); + parser->addOption(QCommandLineOption(QStringLiteral("test"), QStringLiteral("Test file"), QStringLiteral("file.qml"))); + parser->addPositionalArgument(QStringLiteral("urls"), i18n("Supports appstream: url scheme")); + DiscoverBackendsFactory::setupCommandLine(parser); + KAboutData::applicationData().setupCommandLine(parser); + parser->addHelpOption(); + parser->addVersionOption(); + return parser; +} + +void processArgs(QCommandLineParser* parser, DiscoverMainWindow* mainWindow) +{ + if(parser->isSet(QStringLiteral("application"))) + mainWindow->openApplication(parser->value(QStringLiteral("application"))); + else if(parser->isSet(QStringLiteral("mime"))) + mainWindow->openMimeType(parser->value(QStringLiteral("mime"))); + else if(parser->isSet(QStringLiteral("category"))) + mainWindow->openCategory(parser->value(QStringLiteral("category"))); + + if(parser->isSet(QStringLiteral("mode"))) + mainWindow->openMode(parser->value(QStringLiteral("mode"))); + + foreach(const QString &arg, parser->positionalArguments()) { + QUrl url(arg); + if (url.scheme() == QLatin1String("appstream")) { + QTextStream(stdout) << "opening appstream resource" << url.host() << "from" << url.toString() << '\n'; + if (url.host().isEmpty()) + mainWindow->showPassiveNotification(i18n("Malformed url '%1'", url.toDisplayString())); + else + mainWindow->openApplication(url.host()); + } else { + const QString msg = i18n("Unrecognized url: %1", url.toDisplayString()); + QTextStream(stdout) << msg << '\n'; + mainWindow->showPassiveNotification(msg); + } + } +} + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + app.setWindowIcon(QIcon::fromTheme(QStringLiteral("plasmadiscover"))); + app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); + app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); + KCrash::initialize(); + KLocalizedString::setApplicationDomain("plasma-discover"); + KAboutData about(QStringLiteral("discover"), i18n("Discover"), version, i18n("An application explorer"), + KAboutLicense::GPL, i18n("© 2010-2016 Plasma Development Team")); + about.addAuthor(i18n("Aleix Pol Gonzalez"), QString(), QStringLiteral("aleixpol@blue-systems.com")); + about.addAuthor(i18n("Jonathan Thomas"), QString(), QStringLiteral("echidnaman@kubuntu.org")); + about.setProductName("discover/discover"); + KAboutData::setApplicationData(about); + + DiscoverMainWindow *mainWindow = nullptr; + { + QScopedPointer parser(createParser()); + parser->process(app); + about.processCommandLine(parser.data()); + DiscoverBackendsFactory::processCommandLine(parser.data(), parser->isSet(QStringLiteral("test"))); + + if (parser->isSet(QStringLiteral("test"))) { + QStandardPaths::setTestModeEnabled(true); + } + + KDBusService* service = new KDBusService(KDBusService::Unique, &app); + + mainWindow = new DiscoverMainWindow(decodeCompactMode(parser->value(QStringLiteral("compact")))); + QObject::connect(&app, &QApplication::aboutToQuit, mainWindow, &DiscoverMainWindow::deleteLater); + QObject::connect(service, &KDBusService::activateRequested, mainWindow, [mainWindow](const QStringList &arguments, const QString &/*workingDirectory*/){ + mainWindow->rootObject()->raise(); + if (arguments.isEmpty()) + return; + QScopedPointer parser(createParser()); + parser->process(arguments); + processArgs(parser.data(), mainWindow); + }); + + processArgs(parser.data(), mainWindow); + + if(parser->isSet(QStringLiteral("listmodes"))) { + QTextStream(stdout) << i18n("Available modes:\n"); + foreach(const QString& mode, mainWindow->modes()) + QTextStream(stdout) << " * " << mode << '\n'; + return 0; + } + + if (parser->isSet(QStringLiteral("test"))) { + const QUrl testFile = QUrl::fromUserInput(parser->value(QStringLiteral("test")), {}, QUrl::AssumeLocalFile); + Q_ASSERT(!testFile.isEmpty() && testFile.isLocalFile()); + + mainWindow->loadTest(testFile); + } + } + + return app.exec(); +} diff --git a/discover/org.kde.discover.appdata.xml b/discover/org.kde.discover.appdata.xml new file mode 100644 index 0000000..b5b4dd3 --- /dev/null +++ b/discover/org.kde.discover.appdata.xml @@ -0,0 +1,161 @@ + + + org.kde.discover.desktop + CC0-1.0 + GPL-2.0+ + Discover + Discover + Discover + Discover + Opdag + Discover + Discover + Discover + Avastusretk + Discover + Discover + Discover + Discover + 발견 + Ontdekken + Oppdag + Odkrywca + Discover + Discover + Центр приложений Discover + Objaviť + Programsko središče + Oткривач + Otkrivač + Oткривач + Otkrivač + Discover + Discover + xxDiscoverxx + 发现 + Discover +

Discover + Discover + Discover + Discover + Opdag + Discover + Discover + Discover + Avastusretk + Discover + Discover + Discover + Discover + 발견 + Ontdekken + Oppdag + Odkrywca + Discover + Discover + Центр приложений Discover + Objaviť + Programsko središče + Oткривач + Otkrivač + Oткривач + Otkrivač + Discover + Discover + xxDiscoverxx + 发现 + Discover + +

Haven’t you ever found a tool that was perfect for your need but you only found it after some time stumbling upon it on the net? When considering to install an application, don’t you wonder sometimes if it’s really worth it? Or if it’s actually what you’re looking for?

+

Alguna vegada heu trobat una eina que era perfecta per a les vostres necessitats però l'heu vist després d'ensopegar-hi per la xarxa? Quan considereu instal·lar una aplicació, voleu saber si val la pena? O si és la que realment esteu cercant?

+

Alguna vegada heu trobat una eina que era perfecta per a les vostres necessitats però l'heu vist després d'ensopegar-hi per la xarxa? Quan considereu instal·lar una aplicació, voleu saber si val la pena? O si és la que realment esteu cercant?

+

Haven’t you ever found a tool that was perfect for your need but you only found it after some time stumbling upon it on the net? When considering to install an application, don’t you wonder sometimes if it’s really worth it? Or if it’s actually what you’re looking for?

+

¿Ha encontrado alguna vez una herramienta perfecta para sus necesidades aunque solo la ha encontrado tras perder un tiempo valioso en Internet? Cuando considera instalar una aplicación, ¿no se pregunta a veces si realmente merece la pena o si realmente es lo que estaba buscando?

+

Kahtlemata on sulgi ette tulnud, et oled leidnud täpselt sobiva ja vajaliku tööriista täiesti kogemata sellele internetis peale komistades. Või oled mõne rakenduse puhul kaalunud, kas ikka tasub seda üldse paigaldada või kas see on üldse see, mida sulle tegelikult vaja läheb.

+

Oletko koskaan törmännyt työkaluun, joka täyttää täysin tarpeesi mutta jonka löysit vasta pitkään verkossa etsittyäsi? Harkitessasi sovelluksen asentamista, etkö joskus mieti, onko se sen arvoista, tai onko se mitä todella etsit?

+

Nunca lle pasou que atopou unha ferramenta perfecta para o que necesitaba, pero que para atopala tivo que pasar un bo anaco buscando en internet? Á hora de instalar un programa, non se pregunta ás veces se paga a pena? Ou se realmente é o programa que está a buscar?

+

Apakah kamu tidak pernah menemukan sebuah alat yang sempurna untuk kebutuhanmu, tetapi hanya kamu yang menemukannya setelah beberapa waktu tersandung atas itu di internet? Ketika mempertimbangkan untuk memasang aplikasi, tidakkah kamu bertanya-tanya kadang-kadang apakah itu benar-benar layak? Atau jika itu benar demikian apa yang kamu cari?

+

Non hai mai trovato uno strumento che fosse perfetto per le tue esigenze, ma lo hai trovato solo dopo esserci incappato in Internet? Quando decidi se installare un'applicazione, non ti chiedi a volte se ne valga davvero la pena? O se è effettivamente ciò che stai cercando?

+

인터넷을 오랫동안 검색한 결과 끝에 필요한 도구가 무엇인지 찾은 적이 있었습니까? 프로그램을 설치할 때 이 프로그램이 유용한지 알고 싶은 적이 있었습니까? 아니면 목적에 맞는 프로그램인지 생각해 본 적이 있었습니까?

+

Hebt u niet ooit een hulpmiddel gevonden dat perfect was voor uw behoefte maar dat u alleen na enige tijd toevallig vond op het internet? Bij de overweging om een toepassing te installeren, hebt u uzelf dan soms niet afgevraagd of het dat werkelijk waard was? Of of het echt was waarnaar u op zoek was?

+

Har du nokon gong funne eit program som var midt i blinken for deg, men berre etter ein lengre ekspedisjon på nettet? Når du vurderer å installera eit program, lurer du nokon gong på om det er verdt det? Eller på om det eigentleg er programmet du treng?

+

Czy miałeś kiedyś tak, że znalazłeś idealne narzędzie, jednak na jego poszukiwania spędziłeś wiele czasu w sieci? Czy przy wgrywaniu programu na swój komputer, zastanawiasz się czasami czy jest on tego warty, albo czy jest to to czego właśnie szukasz?

+

Nunca encontrou uma ferramenta que fosse perfeita para as suas necessidades, mas que só a tivesse encontrado depois de "tropeçar" nela na Internet? Ao considerar instalar uma aplicação, não se questionou algumas vezes se realmente vale a pena? Ou se é realmente o que procura?

+

Em algum momento você já procurou uma ferramenta que fosse perfeita para as suas necessidades, mas só encontrou depois de "tropeçar" nela na Internet? Ao considerar a instalação de um aplicativo, não se questionou algumas vezes se realmente vale a pena, ou se é realmente o que procura?

+

Našli ste už nástroj, ktorý vám výborne vyhovuje, ale našli ste ho až po dlhom čase hľadania na nete? Keď zvážime inštaláciu aplikácie, nedivíte sa niekedy, či sa to naozaj oplatí? Alebo či je to naozaj to, čo hľadáte?

+

Ali ste kdaj našli orodje, ki je bilo odlično za vas, šele po mukotrpnem iskanju po spletu? Se ob nameščanju programa kdaj vprašate, če je res vreden namestitve? Ali pa, če je sploh to, kar iščete?

+

Зар нисте бар једном нашли алатку која савршено пристаје вашим потребама, али тако што сте на њу случајно натрапали на Интернету? Када размишљате да ли да инсталирате неки програм, зар се не питате да ли је вредно труда? И да ли заиста одговара ономе што сте тражили?

+

Zar niste bar jednom našli alatku koja savršeno pristaje vašim potrebama, ali tako što ste na nju slučajno natrapali na Internetu? Kada razmišljate da li da instalirate neki program, zar se ne pitate da li je vredno truda? I da li zaista odgovara onome što ste tražili?

+

Зар нисте бар једном нашли алатку која савршено пристаје вашим потребама, али тако што сте на њу случајно натрапали на Интернету? Када размишљате да ли да инсталирате неки програм, зар се не питате да ли је вредно труда? И да ли заиста одговара ономе што сте тражили?

+

Zar niste bar jednom našli alatku koja savršeno pristaje vašim potrebama, ali tako što ste na nju slučajno natrapali na Internetu? Kada razmišljate da li da instalirate neki program, zar se ne pitate da li je vredno truda? I da li zaista odgovara onome što ste tražili?

+

Har du aldrig hittat ett verktyg som är perfekt för dina behov, men bara efter att ha stött på det på nätet av en slump? När du funderar på att installera ett program, undrar du inte ibland om det verkligen är värt att göra? Eller om det verkligen är vad du behöver?

+

Чи траплялося вам знаходити програму, яка повністю задовольняє ваші потреби, після довгих пошуків у інтернеті? Чи не кортіло вам дізнатися про те, чи варто встановлювати програму, ще до її встановлення? Чи хотіли б ви наперед знати, чи та це програма, яка вам потрібна?

+

xxHaven’t you ever found a tool that was perfect for your need but you only found it after some time stumbling upon it on the net? When considering to install an application, don’t you wonder sometimes if it’s really worth it? Or if it’s actually what you’re looking for?xx

+

您是否只网络上搜索之后才找到一个完美符合需求的工具?当安装一个程序时,您没有想过知道是否真的值得安装吗?或者它确实是您想要找的目标?

+

您曾在網路上找到一些原先看起來很完美,但到最後卻一直阻礙您生活的工具嗎?當考慮安裝應用程式時,您不會想到它是否真的符合我的需要嗎?又或著,您實際上是在找些什麼東西?

+

Discover helps users easily and quickly find applications or tools. By allowing to navigate a software library by search, software categories, top lists along with detailed application information that includes screenshots and reviews, users can more quickly find applications that suit their needs.

+

El Discover ajuda als usuaris a cercar aplicacions i eines fàcilment i ràpidament. Permet explorar una biblioteca de programari cercant per categories de programari, llistes més valorades, junt amb informació detallada que inclou captures de pantalla i ressenyes. Els usuaris poden cercar ràpidament aplicacions que s'ajustin a les seves necessitats.

+

El Discover ajuda als usuaris a cercar aplicacions i eines fàcilment i ràpidament. Permet explorar una biblioteca de programari cercant per categories de programari, llistes més valorades, junt amb informació detallada que inclou captures de pantalla i ressenyes. Els usuaris poden cercar ràpidament aplicacions que s'ajusten a les seues necessitats.

+

Discover helps users easily and quickly find applications or tools. By allowing to navigate a software library by search, software categories, top lists along with detailed application information that includes screenshots and reviews, users can more quickly find applications that suit their needs.

+

Discover le ayuda a encontrar aplicaciones y herramientas de una forma rápida y fácil. Al poder explorar una biblioteca de software usando búsquedas, categorías de software y listas de puntuaciones, junto a una detallada información sobre las aplicaciones que incluye capturas de pantalla y comentarios, los usuarios pueden encontrar más rápidamente aplicaciones que satisfagan sus necesidades.

+

Avastusretk aitab kasutajatel kiiresti ja vähese vaevaga leida vajaliku tööriista või rakenduse. Kui kasutaja saab tarkvarakogus hõlpsasti ringi liikuda ja olemasolevat näha nii otsides, kategooriate kaupa või mitmel alusel järjestatavate edetabelite abil, kusjuures alati pakutakse rakenduste kohta põhjalikku teavet koos ekraanipiltide ja arvustustega, ei ole täpselt sobiva tööriista või rakenduse leidmine enam kuigi keeruline.

+

Discover auttaa käyttäjiä löytämään sovellukset helposti ja nopeasti. Selaamalla ohjelmistokirjastoja hakujen, sovellusluokkien, suosikkiluetteloiden sekä ruutukaappauksia ja arvosteluja sisältävien yksityiskohtaisten lisätietojen avulla käyttäjät löytävät nopeammin tarpeitaan vastaavat sovellukset.

+

Discover permite atopar programas e ferramentas de maneira fácil e rápida. Atope rapidamente programas que se axustan ás súas necesidades explorando a biblioteca de software mediante buscas, categorías de software, e listas de programas máis usados con información detallada dos programas, incluíndo capturas de pantalla e opinións de usuarios.

+

Discover membantu pengguna dengan mudah dan cepat menemukan aplikasi atau alat-alat. Oleh karena itu memungkinkan untuk menavigasi sebuah perpustakaan software dengan menelusuri, kategori software, daftar-daftar atas bersama dengan informasi aplikasi terinci yang meliputi cuplikan layar dan ulasan, pengguna bisa lebih cepat menemukan aplikasi yang sesuai dengan kebutuhan mereka.

+

Discover aiuta gli utenti a trovare in modo semplice e rapido applicazioni o strumenti. Permettendo di navigare una raccolta di software tramite ricerca, categorie di software, liste preferite oltre alle informazioni dettagliate sulle applicazioni che includono schermate e recensioni, gli utenti possono trovare più rapidamente applicazioni che si adattano alle loro esigenze.

+

발견을 통하여 프로그램과 도구를 쉽고 빠르게 발견할 수 있습니다. 소프트웨어 라이브러리를 직접 검색하거나, 분류별 및 상위 목록으로 볼 수 있으며 스크린샷과 리뷰를 포함한 소프트웨어 정보를 통해서 필요한 프로그램을 찾을 수 있습니다.

+

Discover helpt gebruikers om gemakkelijk en snel een toepassing of hulpmiddel te vinden. Door navigatie te bieden in een softwarebibliotheek door zoeken in softwarecategorieën, lijsten met toppers, samen met gedetailleerde informatie over toepassingen die schermafdrukken en reviews bevatten, kunnen gebruikers sneller toepassingen vinden die in hun behoeften voorzien.

+

Men Oppdag vert det lettare å finna program og verktøy. Du kan søkja etter program eller sjå gjennom programkategoriar og lister over populære program, og du får detaljert informasjon om kvart program, med bilete og brukaromtalar.

+

Odkrywca pomaga użytkownikowi w szybkim i łatwym wyszukiwaniu potrzebnych aplikacji i narzędzi. Umożliwia on przeglądanie biblioteki oprogramowania poprzez wyszukiwania, kategorie oprogramowania, listy najlepszych aplikacji wraz ze szczegółami takimi jak zrzuty ekranu i recenzje. W ten sposób użytkownicy znajdują szybciej to czego szukają.

+

O Discover ajuda os utilizadores a procurar fácil e rapidamente aplicações ou ferramentas. Ao permitir navegar numa biblioteca de 'software' com a pesquisa, as categorias de aplicações, as listas de topo com informações detalhadas, incluindo fotografias e revisões, os utilizadores poderão encontrar mais rapidamente as aplicações que se adequam às suas necessidades.

+

O Discover ajuda os usuários a encontrar os aplicativos e ferramentas de forma rápida e fácil. Ao fornecer acesso a uma biblioteca de software com uma ferramenta de pesquisa, por categorias de software, por listas das ferramentas mais populares e com informações detalhadas, incluindo capturas de tela e avaliações, os usuários poderão encontrar mais rapidamente os aplicativos que se adequam às suas necessidades.

+

Discover vám pomôže ľahko a rýchlo nájsť aplikácie alebo nástroje. Umožní vám navigáciu cez knižnicu softvéru cez hľadanie, kategórie softvéru, najlepšie zoznamy spolu s podrobnými informáciami, ktoré obsahujú obrazovky a recenzie, teda môžete ľahšie nájsť aplikáciu, ktorá vám vyhovuje.

+

Programsko središče vam pomaga na enostaven način najti programe ali orodja. Omogoča vam krmarjenje po knjižnicah s programi preko iskalnika, kategorij programov in seznamov najboljših programov. Ogledali si boste lahko podrobnosti o programu vključno s posnetki zaslona in ocenami ter tako hitreje našli programe, ki zadoščajo vašim potrebam.

+

Oткривач помаже корисницима да лако и брзо налазе програме и алатке. Кретањем кроз библиотеку софтвера путем претраге, категорија, топ‑листа, праћеним детаљним описима програма, снимцима екрана и рецензијама, корисник може брзо да пронађе програм према својим потребама.

+

Otkrivač pomaže korisnicima da lako i brzo nalaze programe i alatke. Kretanjem kroz biblioteku softvera putem pretrage, kategorija, top‑lista, praćenim detaljnim opisima programa, snimcima ekrana i recenzijama, korisnik može brzo da pronađe program prema svojim potrebama.

+

Oткривач помаже корисницима да лако и брзо налазе програме и алатке. Кретањем кроз библиотеку софтвера путем претраге, категорија, топ‑листа, праћеним детаљним описима програма, снимцима екрана и рецензијама, корисник може брзо да пронађе програм према својим потребама.

+

Otkrivač pomaže korisnicima da lako i brzo nalaze programe i alatke. Kretanjem kroz biblioteku softvera putem pretrage, kategorija, top‑lista, praćenim detaljnim opisima programa, snimcima ekrana i recenzijama, korisnik može brzo da pronađe program prema svojim potrebama.

+

Discover hjälper användare att enkelt och snabbt hitta program eller verktyg. Genom att göra det möjligt att gå igenom ett programvarubibliotek via sökning, enligt programvarukategorier och i topplistor tillsammans med detaljerad programinformation som innehåller skärmbilder och recensioner, kan användare snabbare hitta program som passar deras behov.

+

Discover допомагає користувачам просто і швидко знаходити програми або інструменти. Користувач може просто мандрувати бібліотекою програмного забезпечення, шукаючи програми, передивляючись списки категорій програм, найкращих програм, та ознайомлюючись із докладною інформацією щодо програм, знімками вікон та відгуками інших користувачів. Знайти потрібну програму у такий спосіб можна набагато швидше.

+

xxDiscover helps users easily and quickly find applications or tools. By allowing to navigate a software library by search, software categories, top lists along with detailed application information that includes screenshots and reviews, users can more quickly find applications that suit their needs.xx

+

发现能够帮助用户简单快捷的找到程序或者工具。通过对软件库的搜索,软件分类,热门列表和包括截图和评论的细节的程序信息,用户可以更快的找到符合要求的程序。

+

Discover 協助使用者簡單且快速地找到應用程式或工具。透過搜尋、軟體類別、精選軟體清單等等的方式瀏覽軟體庫,其中並包含了詳細的應用程式資訊,如螢幕截圖、使用感想等,使用者可以更快速地找到符合他們需求的應用程式。

+

Furthermore, Discover will let you manage the different sources of software you have and manage the applications you’ve already installed in the past but you don’t want anymore.

+

Per altra banda, el Discover permet gestionar les diferents fonts de programari que tingueu i gestionar les aplicacions que ja heu instal·lat en el passat però ja no desitgeu.

+

Per altra banda, el Discover permet gestionar les diferents fonts de programari que tingueu i gestionar les aplicacions que ja heu instal·lat en el passat però ja no desitgeu.

+

Furthermore, Discover will let you manage the different sources of software you have and manage the applications you’ve already installed in the past but you don’t want anymore.

+

Además, Discover le permite gestionar las distintas fuentes de software de las que disponga y las aplicaciones que ya hubiera instalado en el pasado y que ya no desee.

+

Lisaks laseb Avastusretk sul mitmekülgselt hallata kõiki sinu käsutuses olevaid tarkvaraallikaid ega jäta sind hätta ka siis, kui sul leidub tarkvara, mille oled kunagi paigaldanud, aga enam sugugi ei vaja.

+

Discover sallii sinun lisäksi hallita erilaisia ohjelmalähteitä sekä sovelluksia, jotka olet jo asentanut mutta joita et enää halua.

+

Ademais, Discover permitiralle xestionar as distintas fontes de software de que dispón e xestionar os programas que ten instalados pero que xa non lle interesan.

+

Selanjutnya, Discover akan membiarkan kamu mengelola sumber software yang berbeda-beda yang kamu miliki dan mengelola aplikasi yang sudah kamu pasang di masa lalu tetapi kamu tidak menginginkan lagi.

+

Inoltre, Discover ti consentirà di gestire le diverse fonti del software disponibili e gestire le applicazioni che hai già installato in passato, ma che non ti servono più.

+

발견을 통하여 여러 소프트웨어 저장소를 관리하고 이전에 설치했지만 필요하지 않은 프로그램을 관리할 수 있습니다.

+

Verder laat Discover u de verschillende bronnen van software die u hebt beheren, evenals de al eerder geïnstalleerde toepassingen maar die u niet meer wilt.

+

Du får òg kontroll over dei ulike programvarekjeldene du har, og kan lett avinstallera program du tidlegare har installert men som du ikkje lenger treng.

+

Dodatkowo, Odkrywca umożliwia zarządzanie wieloma źródłami oprogramowania i oprogramowaniem, które jest już na twoim komputerze i którego chcesz się pozbyć.

+

Para além disso, o Discover permitir-lhe-á gerir as diferentes fontes de aplicações que tem e gerir as aplicações que já instalou no passado e que não quer mais.

+

Além disso, o Discover possibilita gerenciar as diferentes fontes de software que você possui e os aplicativos que já foram instalados e que não são mais necessários.

+

Okrem toho, Discover vám umožní spracovať rôzne zdroje softvéru a spravovať aplikácie, ktoré máte nainštalované, ale už ich nechcete.

+

Programsko središče vam tudi omogoča upravljati s programskimi viri in že nameščenimi programi.

+

Затим, Oткривач вам омогућава да управљате различитим изворима софтвера, као и програмима које сте инсталирали раније али их више не желите.

+

Zatim, Otkrivač vam omogućava da upravljate različitim izvorima softvera, kao i programima koje ste instalirali ranije ali ih više ne želite.

+

Затим, Oткривач вам омогућава да управљате различитим изворима софтвера, као и програмима које сте инсталирали раније али их више не желите.

+

Zatim, Otkrivač vam omogućava da upravljate različitim izvorima softvera, kao i programima koje ste instalirali ranije ali ih više ne želite.

+

Dessutom låter Discover dig hantera olika programvarukällor du använder och hantera program som du redan tidigare har installerat men inte lägre vill ha.

+

Крім того, Discover надасть вам змогу керувати різними джерелами програмного забезпечення та вилучати програми, у яких уже немає потреби.

+

xxFurthermore, Discover will let you manage the different sources of software you have and manage the applications you’ve already installed in the past but you don’t want anymore.xx

+

进一步,发现还可以管理多个不同软件源并且管理过去已安装但不再需要的程序。

+

此外,Discover 讓您管理您所擁有的不同的軟體來源,也可以管理您以前安裝,但現在並不想要了的應用程式。

+
+ https://bugs.kde.org/enter_bug.cgi?format=guided&product=Discover + + + https://www.kde.org/announcements/plasma-5.5/discover.png + + + KDE + + plasma-discover + + diff --git a/discover/org.kde.discover.desktop b/discover/org.kde.discover.desktop new file mode 100644 index 0000000..ac37e4e --- /dev/null +++ b/discover/org.kde.discover.desktop @@ -0,0 +1,115 @@ +[Desktop Entry] +Name=Discover +Name[ar]=استكشف +Name[ca]=Discover +Name[ca@valencia]=Discover +Name[da]=Opdagelse +Name[de]=Discover +Name[el]=Discover +Name[en_GB]=Discover +Name[es]=Discover +Name[et]=Avastusretk +Name[fi]=Discover +Name[fr]=Découvrir +Name[gl]=Descubrir +Name[he]=מרכז התוכנות Discover +Name[id]=Discover +Name[it]=Discover +Name[ko]=발견 +Name[nl]=Ontdekken +Name[nn]=Oppdag +Name[pl]=Odkrywca +Name[pt]=Discover +Name[pt_BR]=Discover +Name[ru]=Discover +Name[sk]=Objaviť +Name[sl]=Programsko središče +Name[sr]=Oткривач +Name[sr@ijekavian]=Oткривач +Name[sr@ijekavianlatin]=Otkrivač +Name[sr@latin]=Otkrivač +Name[sv]=Upptäck +Name[uk]=Discover +Name[x-test]=xxDiscoverxx +Name[zh_CN]=发现者 +Name[zh_TW]=Discover +MimeType=x-scheme-handler/appstream; +Exec=plasma-discover %U +Icon=plasmadiscover +Type=Application +X-DocPath=plasma-discover/index.html +InitialPreference=5 +GenericName=Software Center +GenericName[ar]=مركز برمجيّات +GenericName[ast]=Centru de software +GenericName[ca]=Centre de programari +GenericName[ca@valencia]=Centre de programari +GenericName[cs]=Centrum softwaru +GenericName[da]=Softwarecenter +GenericName[de]=Programmverwaltung +GenericName[el]=Κέντρο λογισμικού +GenericName[en_GB]=Software Centre +GenericName[es]=Centro de software +GenericName[et]=Tarkvarakeskus +GenericName[fi]=Sovellusvalikoima +GenericName[fr]=Logithèque +GenericName[gl]=Centro de Software +GenericName[he]=מרכז התוכנות +GenericName[id]=Software Center +GenericName[it]=Software Center +GenericName[ko]=소프트웨어 센터 +GenericName[nb]=Programvaresenter +GenericName[nl]=Softwarecentrum +GenericName[nn]=Programvaresenter +GenericName[pl]=Ośrodek programów +GenericName[pt]=Centro de Aplicações +GenericName[pt_BR]=Central de aplicativos +GenericName[ru]=Центр программ +GenericName[sk]=Softwareové centum +GenericName[sl]=Programsko središče +GenericName[sr]=Софтверски центар +GenericName[sr@ijekavian]=Софтверски центар +GenericName[sr@ijekavianlatin]=Softverski centar +GenericName[sr@latin]=Softverski centar +GenericName[sv]=Programvarucentral +GenericName[uk]=Центр програм +GenericName[x-test]=xxSoftware Centerxx +GenericName[zh_CN]=软件中心 +GenericName[zh_TW]=軟體中心 +Categories=Qt;KDE;System; +Keywords=program;software;repository;package;install;remove;update;apps;applications; +Keywords[ar]=برنامج;برمجيّة;برمجية;مستودع;حزمة;تثبيت;إزالة;ازالة;تحديث;تطبيقات;تطبيق; +Keywords[ca]=programa;programari;repositori;paquet;instal·la;suprimeix;actualitza;apps;aplicacions; +Keywords[ca@valencia]=programa;programari;repositori;paquet;instal·la;suprimeix;actualitza;apps;aplicacions; +Keywords[cs]=program;software;repozitář;balíček;instalovat;odstranit;aktualizovat;programy;aplikace; +Keywords[da]=program;software;softwarekilde;repository;pakke;installer;fjern;opdater;apps;applikationer; +Keywords[de]=Programm;Software;Archiv;Repository;Paket;Installieren;Entfernen;Aktualisieren;Programme;Anwendungen; +Keywords[el]=πρόγραμμα;λογισμικό;αποθετήριο;πακέτο;εγκατάσταση;αφαίρεση;ενημέρωση;εφαρμογές; +Keywords[en_GB]=program;software;repository;package;install;remove;update;apps;applications; +Keywords[es]=programa;software;repositorio;paquete;instalar;eliminar;actualizar;apps;aplicaciones; +Keywords[et]=programm,rakendus,tarkvara,hoidla,pakk,pakett,paigaldamine,installimine,eemaldamine,uuendamine,rakendused,äpid; +Keywords[fi]=program;software;repository;package;install;remove;update;apps;applications;ohjelma;ohjelmisto;ohjelmalähde;lähteet;arkisto;paketti;asenna;poista;päivitä;sovellukset; +Keywords[fr]=programme ; logiciel ; dépôt ; archive ; paquet ; installation ; suppression ; mise à jour ; deb +Keywords[gl]=aplicativo,software,repositorio,paquete,instalar,eliminar,actualizar,deb +Keywords[he]=program;software;repository;package;install;remove;update;apps;applications;תוכנות;התקנה;הסרה;חבילה;מקורות;יישומים; +Keywords[id]=program;software;repositori;paket;pasang;copot;perbarui;apl;aplikasi; +Keywords[it]=programma;software;deposito;pacchetto;installa;rimuovi;aggiorna;app;applicazioni; +Keywords[ko]=program;software;repository;archive;package;install;remove;update;deb;프로그램;소프트웨어;저장소;리포지토리;패키지;꾸러미;설치;삭제;업데이트; +Keywords[nb]=program;programvare;pakkebrønn;pakke;installere;fjerne;oppdatere;app;apper; +Keywords[nl]=programma;software;opslagruimte;pakket;installeren;verwijderen;bijwerken;apps;toepassingen;applicaties; +Keywords[nn]=program;programvare;pakkebrønn;pakke;pakkar;installera;installering;fjerna;fjerning;oppdatera;oppdatering;app;appar;applikasjonar; +Keywords[pl]=program,oprogramowanie,repozytorium,archiwum,pakiet,paczka,instaluj,zainstaluj,usuń,odinstaluj,uaktualnij,aktualizuj,programy,aplikacje,deb +Keywords[pt]=programa;software;repositório;pacote;instalar;remover;actualizar;aplicações; +Keywords[pt_BR]=programa;software;repositório;pacote;instalar;instalação;remover;atualizar;aplicativos;apps;aplicações; +Keywords[ru]=program;software;repository;package;install;remove;update;apps;applications;программа;приложение;репозиторий;пакет;установка;удаление;deb; +Keywords[sk]=program;softvér;repozitár;archív;balík;inštalácia;odstránenie;appky;aplikácie;aktualizácia; +Keywords[sl]=program;programska oprema;skladišče;paket;namesti;odstrani;posodobi;programi; +Keywords[sr]=program;software;repository;package;install;remove;update;apps;applications;програм;софтвер;ризница;пакет;инсталирати;уклонити;ажурирати; +Keywords[sr@ijekavian]=program;software;repository;package;install;remove;update;apps;applications;програм;софтвер;ризница;пакет;инсталирати;уклонити;ажурирати; +Keywords[sr@ijekavianlatin]=program;software;repository;package;install;remove;update;apps;applications;program;softver;riznica;paket;instalirati;ukloniti;ažurirati; +Keywords[sr@latin]=program;software;repository;package;install;remove;update;apps;applications;program;softver;riznica;paket;instalirati;ukloniti;ažurirati; +Keywords[sv]=program;programvara;arkiv;paket;installera;ta bort;uppdatera;appar;program; +Keywords[uk]=program;software;repository;package;install;remove;update;app;apps;applications;програма;програмне забезпечення;сховище;архів;пакунок;встановити;встановлення;вилучити;вилучення;оновлення;оновити; +Keywords[x-test]=xxprogramxx;xxsoftwarexx;xxrepositoryxx;xxpackagexx;xxinstallxx;xxremovexx;xxupdatexx;xxappsxx;xxapplicationsxx; +Keywords[zh_CN]=program;software;repository;package;install;remove;update;apps;applications;程序;软件;软件源;包;安装;移除;更新;应用程序;应用; +Keywords[zh_TW]=program;software;repository;package;install;remove;update;apps;applications; diff --git a/discover/plasmadiscoverui.rc b/discover/plasmadiscoverui.rc new file mode 100644 index 0000000..cfd3837 --- /dev/null +++ b/discover/plasmadiscoverui.rc @@ -0,0 +1,10 @@ + + + + + diff --git a/discover/qml/ActionBridge.qml b/discover/qml/ActionBridge.qml new file mode 100644 index 0000000..10170ca --- /dev/null +++ b/discover/qml/ActionBridge.qml @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright © 2015 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +import QtQml 2.0 +import QtQuick.Controls 1.0 + +Action +{ + property QtObject action: null + + function removeAmpersand(text) { + return text.replace("&", ""); + } + text: action ? removeAmpersand(action.text) : "" + checked: action && action.checked + enabled: action && action.enabled + tooltip: action ? action.toolTip : "" + iconName: action ? app.iconName(action.icon) : "" + shortcut: action ? action.shortcut : undefined + + onTriggered: action.trigger() +} diff --git a/discover/qml/AddSourceDialog.qml b/discover/qml/AddSourceDialog.qml new file mode 100644 index 0000000..9cb936e --- /dev/null +++ b/discover/qml/AddSourceDialog.qml @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 + +Dialog { + id: newSourceDialog + title: i18n("Specify the new source for %1", source.name) + standardButtons: StandardButton.Ok | StandardButton.Close + property QtObject source + + ColumnLayout { + id: info + anchors { + left: parent.left + right: parent.right + } + + Label { + id: description + Layout.fillWidth: true + Layout.fillHeight: true + wrapMode: Text.WordWrap + textFormat: Text.PlainText + text: source.idDescription + } + + TextField { + id: repository + Layout.fillWidth: true + Keys.onEnterPressed: newSourceDialog.accept() + focus: true + } + } + onAccepted: source.addSource(repository.text) +} diff --git a/discover/qml/AddonsView.qml b/discover/qml/AddonsView.qml new file mode 100644 index 0000000..1a473ad --- /dev/null +++ b/discover/qml/AddonsView.qml @@ -0,0 +1,97 @@ +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.discover 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import "navigation.js" as Navigation +import org.kde.kirigami 1.0 as Kirigami + +Kirigami.OverlaySheet +{ + id: addonsView + property alias application: addonsModel.application + property bool isInstalling: false + readonly property bool containsAddons: rep.count>0 || isExtended + readonly property bool isExtended: ResourcesModel.isExtended(application.appstreamId) + + ColumnLayout + { + visible: addonsView.containsAddons + enabled: !addonsView.isInstalling + spacing: 5 + + Heading { + text: i18n("Addons") + } + + Repeater + { + id: rep + model: ApplicationAddonsModel { id: addonsModel } + + delegate: RowLayout { + Layout.fillWidth: true + + CheckBox { + enabled: !addonsView.isInstalling + checked: model.checked + onClicked: addonsModel.changeState(packageName, checked) + } + QIconItem { + icon: "applications-other" + smooth: true + Layout.minimumWidth: content.implicitHeight + Layout.minimumHeight: content.implicitHeight + opacity: addonsView.isInstalling ? 0.3 : 1 + } + + ColumnLayout { + id: content + Layout.fillWidth: true + spacing: 0 + Label { + Layout.fillWidth: true + elide: Text.ElideRight + text: display + } + Label { + Layout.fillWidth: true + elide: Text.ElideRight + font.italic: true + text: toolTip + } + } + } + } + + RowLayout { + readonly property bool active: addonsModel.hasChanges && !addonsView.isInstalling + spacing: 5 + + Button { + iconName: "dialog-ok" + text: i18n("Apply Changes") + onClicked: addonsModel.applyChanges() + + visible: parent.active + } + Button { + iconName: "document-revert" + text: i18n("Discard") + onClicked: addonsModel.discardChanges() + + visible: parent.active + } + Item { + Layout.fillWidth: true + height: 5 + } + Button { + Layout.alignment: Qt.AlignRight + text: i18n("More...") + visible: application.appstreamId.length>0 && addonsView.isExtended + onClicked: Navigation.openExtends(application.appstreamId) + } + } + } +} diff --git a/discover/qml/ApplicationDelegate.qml b/discover/qml/ApplicationDelegate.qml new file mode 100644 index 0000000..a6b405a --- /dev/null +++ b/discover/qml/ApplicationDelegate.qml @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.discover.app 1.0 +import QtQuick.Window 2.1 +import org.kde.kcoreaddons 1.0 +import "navigation.js" as Navigation +import org.kde.kirigami 1.0 as Kirigami + +Kirigami.AbstractListItem +{ + id: delegateArea + property alias application: installButton.application + property bool compact: false + + onClicked: { + if (ListView.view) + ListView.view.currentIndex = index + Navigation.openApplication(application) + } + + Item { + id: lowLayout + anchors { + left: parent.left + right: parent.right + margins: Kirigami.Units.largeSpacing + } + + height: Kirigami.Units.gridUnit * (compact ? 7 : 10) + QIconItem { + id: resourceIcon + icon: application.icon + + readonly property real contHeight: lowLayout.height * 0.8 + width: contHeight + height: contHeight + anchors.verticalCenter: parent.verticalCenter + } + + ColumnLayout { + id: conts + anchors { + leftMargin: Kirigami.Units.largeSpacing + left: resourceIcon.right + bottom: installButton.top + top: parent.top + right: parent.right + } + + RowLayout { + Layout.fillWidth: true + Heading { + Layout.fillWidth: true + elide: Text.ElideRight + text: name + maximumLineCount: 1 + } + Label { + Layout.fillWidth: true + elide: Text.ElideRight + horizontalAlignment: Text.AlignRight + text: categoryDisplay + color: Kirigami.Theme.linkColor + visible: parent.width > implicitWidth + } + } + + Rectangle { + color: Kirigami.Theme.linkColor + Layout.fillWidth: true + height: Kirigami.Units.devicePixelRatio + } + + Label { + Layout.fillWidth: true + + elide: Text.ElideRight + text: comment + maximumLineCount: 1 + font: SystemFonts.titleFont + } + + Label { + Layout.fillWidth: true + Layout.maximumHeight: parent.height/2 + + horizontalAlignment: Text.AlignJustify + wrapMode: Text.WordWrap + elide: Text.ElideRight + textFormat: Text.StyledText + text: longDescription + } + } + InstallApplicationButton { + id: installButton + anchors { + right: parent.right + bottom: parent.bottom + } + canUpgrade: false + } + } +} diff --git a/discover/qml/ApplicationHeader.qml b/discover/qml/ApplicationHeader.qml new file mode 100644 index 0000000..a84503d --- /dev/null +++ b/discover/qml/ApplicationHeader.qml @@ -0,0 +1,50 @@ +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Window 2.1 +import QtQuick.Layouts 1.1 +import org.kde.kquickcontrolsaddons 2.0 + +PageHeader { + property alias application: installButton.application + readonly property alias isInstalling: installButton.isActive + + RowLayout { + anchors.fill: parent + + QIconItem { + id: icon + Layout.preferredHeight: parent.height + Layout.preferredWidth: parent.height + + icon: application.icon + } + + ColumnLayout { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.maximumHeight: parent.height + spacing: 0 + Heading { + text: application.name + Layout.fillWidth: true + elide: Text.ElideRight + } + Label { + Layout.fillWidth: true + text: application.comment + wrapMode: Text.WordWrap + elide: Text.ElideRight + maximumLineCount: 1 + } + } + InstallApplicationButton { + id: installButton + application: appInfo.application + additionalItem: Rating { + readonly property QtObject ratingInstance: application.rating + visible: ratingInstance!=null + rating: ratingInstance==null ? 0 : ratingInstance.rating + } + } + } +} diff --git a/discover/qml/ApplicationIndicator.qml b/discover/qml/ApplicationIndicator.qml new file mode 100644 index 0000000..e661514 --- /dev/null +++ b/discover/qml/ApplicationIndicator.qml @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 + +Rectangle { + id: root + property string state: "none" + border.width: 0 + + readonly property var colors: { + "none": "transparent", + "installed": "#090", + "upgradeable": "#339" + } + color: colors[state] +} diff --git a/discover/qml/ApplicationPage.qml b/discover/qml/ApplicationPage.qml new file mode 100644 index 0000000..427ad8f --- /dev/null +++ b/discover/qml/ApplicationPage.qml @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Window 2.1 +import QtQuick.Layouts 1.1 +import QtGraphicalEffects 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import org.kde.kirigami 1.0 as Kirigami +import "navigation.js" as Navigation + +DiscoverPage { + id: appInfo + property QtObject application: null + clip: true + + title: application.name + + background: Rectangle { color: Kirigami.Theme.viewBackgroundColor } + + ReviewsPage { + id: reviewsSheet + model: reviewsModel + } + + pageOverlay: Item { + InstallApplicationButton { + id: button + anchors { + right: parent.right + bottom: parent.bottom + bottomMargin: Kirigami.Units.gridUnit + rightMargin: appInfo.width - appInfo.flickable.width + } + + Layout.alignment: Qt.AlignRight + application: appInfo.application + fill: true + additionalItem: Button { + Layout.fillWidth: true + visible: application.isInstalled && application.canExecute + text: i18n("Launch") + onClicked: application.invokeApplication() + } + } + + DropShadow { + anchors.fill: button + source: button + horizontalOffset: 3 + verticalOffset: 3 + radius: 8 + samples: 10 + color: "#000000" + } + } + + ColumnLayout { + RowLayout { + Layout.fillWidth: true + spacing: Kirigami.Units.gridUnit + QIconItem { + Layout.preferredHeight: 128 + Layout.preferredWidth: 128 + + icon: appInfo.application.icon + Layout.alignment: Qt.AlignVCenter + } + ColumnLayout { + id: conts + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.bottomMargin: Kirigami.Units.largeSpacing + spacing: 0 + + Heading { + id: title + text: appInfo.application.name + Layout.fillWidth: true + elide: Text.ElideRight + } + Rectangle { + color: Kirigami.Theme.linkColor + Layout.fillWidth: true + height: 1 + } + Label { + Layout.fillWidth: true + text: appInfo.application.comment + wrapMode: Text.WordWrap + elide: Text.ElideRight + maximumLineCount: 1 + } + Label { + Layout.fillWidth: true + elide: Text.ElideRight + text: appInfo.application.categoryDisplay + color: Kirigami.Theme.linkColor + } + + Item { + Layout.fillWidth: true + Layout.fillHeight: true + } + Label { + text: i18n("Version: %1", appInfo.application.isInstalled ? appInfo.application.installedVersion : appInfo.application.availableVersion) + } + Label { + text: i18n("Size: %1", appInfo.application.sizeDescription) + } + Label { + visible: text.length>0 + text: appInfo.application.license ? i18n("License: %1", appInfo.application.license) : "" + } + } + } + + ApplicationScreenshots { + Layout.fillWidth: true + resource: appInfo.application + page: appInfo + } + + Heading { + text: i18n("Description") + Layout.fillWidth: true + visible: appInfo.application.longDescription.length > 0 + } + Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignJustify + wrapMode: Text.WordWrap + text: appInfo.application.longDescription + } + + RowLayout { + visible: button.text.length > 0 + Label { + text: i18n("Homepage: ") + } + LinkButton { + id: button + text: application.homepage + onClicked: Qt.openUrlExternally(application.homepage) + } + } + + LinkButton { + id: addonsButton + text: i18n("Addons") + visible: addonsView.containsAddons + onClicked: addonsView.opened = true + } + + LinkButton { + readonly property QtObject rating: appInfo.application.rating + visible: rating && rating.ratingCount>0 && reviewsModel.count + text: i18n("Show comments (%1)...", rating ? rating.ratingCount : 0) + + ReviewsModel { + id: reviewsModel + resource: appInfo.application + } + + onClicked: { + reviewsSheet.open() + } + } + + Item { + height: addonsButton.height + width: 5 + } + } + + readonly property var addons: AddonsView { + id: addonsView + application: appInfo.application + parent: overlay + } +} diff --git a/discover/qml/ApplicationScreenshots.qml b/discover/qml/ApplicationScreenshots.qml new file mode 100644 index 0000000..e3b66c5 --- /dev/null +++ b/discover/qml/ApplicationScreenshots.qml @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import org.kde.discover 1.0 +import org.kde.kirigami 1.0 as Kirigami + +Flow { + id: root + property alias resource: screenshotsModel.application + + spacing: Kirigami.Units.smallSpacing + + readonly property real side: Kirigami.Units.gridUnit * 8 + property QtObject page + visible: screenshotsModel.count>0 + + readonly property var fu: Kirigami.OverlaySheet { + id: overlay + parent: root.page + Image { + id: overlayImage + fillMode: Image.PreserveAspectFit + smooth: true + } + } + + Repeater { + model: ScreenshotsModel { + id: screenshotsModel + } + + delegate: Image { + source: small_image_url + height: root.side + width: root.side + fillMode: Image.PreserveAspectCrop + smooth: true + opacity: mouse.containsMouse? 0.7 : 1 + + Behavior on opacity { NumberAnimation { easing.type: Easing.OutQuad; duration: 500 } } + + MouseArea { + id: mouse + anchors.fill: parent + hoverEnabled: true + onClicked: { + overlayImage.source = large_image_url + overlay.open() + } + } + } + } + + Behavior on opacity { NumberAnimation { easing.type: Easing.OutQuad; duration: 500 } } +} diff --git a/discover/qml/ApplicationsListPage.qml b/discover/qml/ApplicationsListPage.qml new file mode 100644 index 0000000..169753c --- /dev/null +++ b/discover/qml/ApplicationsListPage.qml @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.5 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.2 +import "navigation.js" as Navigation +import org.kde.discover.app 1.0 +import org.kde.discover 1.0 +import org.kde.kirigami 1.0 as Kirigami + +DiscoverPage { + id: page + readonly property var model: appsModel + property alias category: appsModel.filteredCategory + property alias sortRole: appsModel.stringSortRole + property alias sortOrder: appsModel.sortOrder + property alias originFilter: appsModel.originFilter + property alias mimeTypeFilter: appsModel.mimeTypeFilter + property alias stateFilter: appsModel.stateFilter + property alias extend: appsModel.extends + property alias search: appsModel.search + property alias shouldShowTechnical: appsModel.isShowingTechnical + property alias count: apps.count + property alias header: apps.header + property bool compact: false + property bool canNavigate: true + readonly property alias subcategories: appsModel.subcategories + title: category ? category.name : "" + + onSearchChanged: { + if (search.length === 0) + Navigation.openHome() + appsModel.sortOrder = Qt.AscendingOrder + } + signal clearSearch() + + ListView { + id: apps + anchors.fill: parent + section.delegate: Label { + text: section + anchors { + right: parent.right + } + } + + header: CategoryDisplay { + category: appsModel.filteredCategory + search: appsModel.search + anchors { + left: parent.left + right: parent.right + } + z: 5000 + } + model: ApplicationProxyModel { + id: appsModel + isSortingByRelevancy: true + stringSortRole: "ratingPoints" + sortOrder: Qt.DescendingOrder + isShowingTechnical: category && category.shouldShowTechnical + + Component.onCompleted: sortModel() + } + spacing: Kirigami.Units.gridUnit + delegate: ApplicationDelegate { + x: Kirigami.Units.gridUnit + width: ListView.view.width - Kirigami.Units.gridUnit*2 + application: model.application + compact: page.compact + } + } +} diff --git a/discover/qml/ApplicationsTop.qml b/discover/qml/ApplicationsTop.qml new file mode 100644 index 0000000..3ede424 --- /dev/null +++ b/discover/qml/ApplicationsTop.qml @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import "navigation.js" as Navigation +import org.kde.kirigami 1.0 as Kirigami + +ColumnLayout { + id: topView + property alias sortRole: appsModel.stringSortRole + property alias filteredCategory: appsModel.filteredCategory + property string title: "" + property bool extended: false + readonly property alias titleHeight: title.height + + spacing: Kirigami.Units.gridUnit + Label { + id: title + text: topView.title + Layout.fillWidth: true + font.weight: Font.Bold + Layout.minimumHeight: paintedHeight*1.5 + } + Repeater { + id: rep + model: PaginateModel { + pageSize: 5 + staticRowCount: true + sourceModel: ApplicationProxyModel { + id: appsModel + sortOrder: Qt.DescendingOrder +// onRowsInserted: sortModel() + } + } + delegate: ConditionalLoader { + Layout.fillWidth: parent + condition: model["name"] !== undefined + componentFalse: Item {} + componentTrue: ApplicationDelegate { + application: model.application + } + } + } +} diff --git a/discover/qml/AwesomeGrid.qml b/discover/qml/AwesomeGrid.qml new file mode 100644 index 0000000..1019e68 --- /dev/null +++ b/discover/qml/AwesomeGrid.qml @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2012-2013 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Window 2.2 +import org.kde.discover.app 1.0 + +Flickable { + readonly property int columnCount: Helpers.isCompact ? 1 : Math.max(Math.floor(conts.width/(minCellWidth+dataFlow.spacing*2)), 1) + readonly property real cellWidth: (conts.width-(columnCount-1)*dataFlow.spacing)/columnCount + readonly property alias count: dataRepeater.count + readonly property int minCellWidth: SystemFonts.generalFont.pointSize*20 + property alias header: headerLoader.sourceComponent + property alias footer: footerLoader.sourceComponent + property alias delegate: dataRepeater.delegate + property alias model: dataRepeater.model + property alias section: sectionLoader.sourceComponent + contentHeight: conts.height + + Column { + id: conts + width: parent.width-20 + anchors.horizontalCenter: parent.horizontalCenter + spacing: 10 + Loader { + id: headerLoader + width: parent.width + } + Loader { + id: sectionLoader + width: parent.width + } + + Flow { + id: dataFlow + width: parent.width + spacing: 10 + Repeater { + id: dataRepeater + } + } + + Loader { + id: footerLoader + width: parent.width + } + } +} diff --git a/discover/qml/Breadcrumbs.qml b/discover/qml/Breadcrumbs.qml new file mode 100644 index 0000000..c646a1f --- /dev/null +++ b/discover/qml/Breadcrumbs.qml @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.0 +import QtQuick.Layouts 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.kirigami 1.0 as Kirigami +import "navigation.js" as Navigation + +RowLayout { + id: bread + property alias model: rep.model + property bool shadow: false + spacing: Kirigami.Units.smallSpacing + + readonly property Action homeAction: Kirigami.Action { + text: i18n("Home") + onTriggered: Navigation.openHome() + } + + Repeater { + id: rep + + delegate: RowLayout { + Layout.leftMargin: Kirigami.Units.smallSpacing + spacing: Kirigami.Units.smallSpacing + Text { + visible: index > 0 + text: ">" + color: button.textColor + } + LinkButton { + id: button + shadow: bread.shadow + Layout.fillHeight: true + Layout.topMargin: Kirigami.Units.smallSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + action: modelData + } + } + } + Item { + Layout.fillWidth: true + } +} diff --git a/discover/qml/BrowsingPage.qml b/discover/qml/BrowsingPage.qml new file mode 100644 index 0000000..de997aa --- /dev/null +++ b/discover/qml/BrowsingPage.qml @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.discover 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.discover.app 1.0 +import "navigation.js" as Navigation +import org.kde.kirigami 1.0 as Kirigami + +DiscoverPage +{ + title: i18n("Home") + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + + function searchFor(text) { + if (text.length === 0) + return; + Navigation.openCategory(null, "") + } + pageHeader: Item {} + CategoryDisplay { + category: null + width: parent.width + background: "https://c2.staticflickr.com/8/7193/6900377481_76367f973a_o.jpg" + + ApplicationsTop { + Layout.fillWidth: true + Layout.leftMargin: Kirigami.Units.gridUnit + Layout.rightMargin: Kirigami.Units.gridUnit + sortRole: "ratingCount" + title: i18n("Most Popular") + extended: true + } + } +} diff --git a/discover/qml/CategoryBreadcrumbs.qml b/discover/qml/CategoryBreadcrumbs.qml new file mode 100644 index 0000000..768425a --- /dev/null +++ b/discover/qml/CategoryBreadcrumbs.qml @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import org.kde.kirigami 1.0 as Kirigami +import "navigation.js" as Navigation + +Breadcrumbs { + id: root + property var category + property string search + + spacing: 2 + + Kirigami.Action { + id: searchAction + text: root.search ? i18n("Search: %1", root.search) : "" + onTriggered: Navigation.openCategory(category, ""); + } + + Component { + id: categoryActionComponent + Kirigami.Action { + property QtObject category + text: category.name + onTriggered: Navigation.openCategory(category, root.search) + } + } + + function breadcrumbs(search, category) { + var ret = []; + + while(category) { + var categoryAction = categoryActionComponent.createObject(searchAction, { category: category }) + ret.unshift(categoryAction) + category = category.parent + } + ret.unshift(homeAction) + if (search.length > 0) + ret.unshift(searchAction); + return ret + } + model: breadcrumbs(search, category) +} diff --git a/discover/qml/CategoryDisplay.qml b/discover/qml/CategoryDisplay.qml new file mode 100644 index 0000000..1cdaa06 --- /dev/null +++ b/discover/qml/CategoryDisplay.qml @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012-2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import "navigation.js" as Navigation +import org.kde.kirigami 1.0 as Kirigami + +PageHeader { + id: header + property QtObject category: null + Layout.fillWidth: true + background: category.decoration + + Item { + Layout.fillWidth: true + height: Kirigami.Units.largeSpacing + } +} diff --git a/discover/qml/ConditionalLoader.qml b/discover/qml/ConditionalLoader.qml new file mode 100644 index 0000000..5f11241 --- /dev/null +++ b/discover/qml/ConditionalLoader.qml @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright © 2015 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +import QtQuick 2.1 + +Loader +{ + id: root + + property Component componentTrue + property Component componentFalse + property bool condition + + sourceComponent: condition ? componentTrue : componentFalse +} diff --git a/discover/qml/DefaultBanner.qml b/discover/qml/DefaultBanner.qml new file mode 100644 index 0000000..ce04de4 --- /dev/null +++ b/discover/qml/DefaultBanner.qml @@ -0,0 +1,33 @@ +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import org.kde.kquickcontrolsaddons 2.0 + +Rectangle +{ + color: "white" + QIconItem { + id: icon + icon: "kde" + anchors.verticalCenter: parent.verticalCenter + width: parent.width/3 + height: width + } + + Label { + text: i18n("Discover\nall the possibilities!") + anchors { + right: parent.right + top: parent.top + bottom: parent.bottom + left: icon.right + rightMargin: 20 + } + + font.pointSize: 72 + minimumPixelSize: 10 + verticalAlignment: Text.AlignVCenter + + horizontalAlignment: Text.AlignHCenter + fontSizeMode: Text.Fit + } +} diff --git a/discover/qml/DiscoverDrawer.qml b/discover/qml/DiscoverDrawer.qml new file mode 100644 index 0000000..616d399 --- /dev/null +++ b/discover/qml/DiscoverDrawer.qml @@ -0,0 +1,217 @@ +/*************************************************************************** + * Copyright © 2015 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import org.kde.kirigami 1.0 as Kirigami +import "navigation.js" as Navigation + +Kirigami.GlobalDrawer { + id: drawer + bannerImageSource: "qrc:/icons/banner.svg" + topPadding: -50 + leftPadding: 0 + rightPadding: 0 + bottomPadding: 0 + + resetMenuOnTriggered: false + + onBannerClicked: { + Navigation.openHome(); + } + + function clearSearch() { + searchField.text = "" + } + + onCurrentSubMenuChanged: { + if (currentSubMenu) + currentSubMenu.trigger() + else if (searchField.text !== "") + window.leftPage.category = null + else + Navigation.openHome() + + } + + topContent: TextField { + id: searchField + Layout.fillWidth: true + Layout.leftMargin: Kirigami.Units.smallSpacing + Layout.rightMargin: Kirigami.Units.smallSpacing + + enabled: window.leftPage && (window.leftPage.searchFor != null || window.leftPage.hasOwnProperty("search")) + + Component.onCompleted: { + searchField.forceActiveFocus() + } + Shortcut { + sequence: "Ctrl+F" + onActivated: { + searchField.forceActiveFocus() + searchField.selectAll() + } + } + + placeholderText: (!enabled || window.leftPage.title.length === 0) ? i18n("Search...") : i18n("Search in '%1'...", window.leftPage.title) + onTextChanged: { + if(window.stack.depth > 0) + searchTimer.running = true + } + + Connections { + ignoreUnknownSignals: true + target: window.leftPage + onClearSearch: { + drawer.clearSearch() + } + } + + Timer { + id: searchTimer + running: false + repeat: false + interval: 200 + onTriggered: { + var curr = window.leftPage; + if (!curr.hasOwnProperty("search")) { + Navigation.clearStack() + Navigation.openApplicationList( { search: parent.text }) + } else + curr.search = parent.text; + } + } + } + + ColumnLayout { + spacing: 0 + Layout.fillWidth: true + + Kirigami.Separator { + Layout.fillWidth: true + } + + ProgressView { + separatorVisible: false + } + + Kirigami.BasicListItem { + checked: installedAction.checked + icon: installedAction.iconName + label: installedAction.text + separatorVisible: false + onClicked: { + installedAction.trigger() + drawer.resetMenu() + } + } + Kirigami.BasicListItem { + checked: settingsAction.checked + icon: settingsAction.iconName + label: settingsAction.text + separatorVisible: false + onClicked: { + settingsAction.trigger() + drawer.resetMenu() + } + } + Kirigami.BasicListItem { + enabled: updateAction.enabled + checked: updateAction.checked + icon: updateAction.iconName + label: updateAction.text + separatorVisible: false + onClicked: { + updateAction.trigger() + drawer.resetMenu() + } + + backgroundColor: enabled ? "orange" : Kirigami.Theme.viewBackgroundColor + } + } + + function rootCategory(cat) { + var ret = null + while (cat) { + ret = cat + cat = cat.parent + } + return ret + } + + Component { + id: categoryActionComponent + Kirigami.Action { + property QtObject category + readonly property bool itsMe: window.leftPage && window.leftPage.hasOwnProperty("category") && (window.leftPage.category == category) + text: category.name + checkable: itsMe + checked: itsMe + visible: (!window.leftPage + || !window.leftPage.subcategories + || window.leftPage.subcategories === undefined + || searchField.text.length === 0 + || category.contains(window.leftPage.subcategories) + ) + onTriggered: { + if (!window.leftPage.canNavigate) + Navigation.openCategory(category, searchField.text) + else { + window.leftPage.category = category + pageStack.currentIndex = 0 + } + checked = Qt.binding(function () { return itsMe }); + } + } + } + + function createCategoryActions(parent, categories) { + var actions = [] + for(var i in categories) { + var cat = categories[i]; + var catAction = categoryActionComponent.createObject(parent, {category: cat}); + catAction.children = createCategoryActions(catAction, cat.subcategories); + actions.push(catAction) + } + return actions; + } + + CategoryModel { + id: rootCategories + Component.onCompleted: { + resetCategories(); + drawer.actions = createCategoryActions(rootCategories, rootCategories.categories) + } + } + + modal: Helpers.isCompact + handleVisible: Helpers.isCompact + + states: [ + State { + name: "full" + when: !Helpers.isCompact + PropertyChanges { target: drawer; opened: true } + } + ] +} diff --git a/discover/qml/DiscoverPage.qml b/discover/qml/DiscoverPage.qml new file mode 100644 index 0000000..a3379a4 --- /dev/null +++ b/discover/qml/DiscoverPage.qml @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.5 +import org.kde.kirigami 1.0 as Kirigami + +Kirigami.ScrollablePage +{ + id: root + + /** + * pageHeader: Component + * Places an item on top of the view when the user scrolls, so that we can + * have some UI available at all time. + */ + property alias pageHeader: pageHeaderLoader.sourceComponent + property alias pageOverlay: overlayLoader.sourceComponent + + readonly property Item overlay: Item { + parent: root + anchors.fill: parent + + Loader { + id: overlayLoader + anchors.fill: parent + } + + Loader { + id: pageHeaderLoader + anchors { + left: parent.left + right: parent.right + rightMargin: root.flickable ? root.width - root.contentItem.width : 0 + } + visible: y>-height + + Behavior on y { + NumberAnimation { + duration: Kirigami.Units.longDuration + easing.type: Easing.InOutQuad + } + } + + states: [ + State { + name: "top" + when: root.flickable.contentY > 0 + PropertyChanges { target: pageHeaderLoader; y: 0 } + }, + State { + name: "scrolled" + when: root.flickable.contentY <= 0 + PropertyChanges { target: pageHeaderLoader; y: -height } + } + ] + } + } +} diff --git a/discover/qml/DiscoverSystemPalette.qml b/discover/qml/DiscoverSystemPalette.qml new file mode 100644 index 0000000..69f4b8e --- /dev/null +++ b/discover/qml/DiscoverSystemPalette.qml @@ -0,0 +1,5 @@ +pragma Singleton +import QtQuick 2.1 + +SystemPalette { +} diff --git a/discover/qml/DiscoverWindow.qml b/discover/qml/DiscoverWindow.qml new file mode 100644 index 0000000..3a8d994 --- /dev/null +++ b/discover/qml/DiscoverWindow.qml @@ -0,0 +1,208 @@ +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.1 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import org.kde.kirigami 1.0 as Kirigami +import "navigation.js" as Navigation + +Kirigami.ApplicationWindow +{ + id: window + readonly property Component applicationListComp: Qt.createComponent("qrc:/qml/ApplicationsListPage.qml") + readonly property Component applicationComp: Qt.createComponent("qrc:/qml/ApplicationPage.qml") + readonly property Component reviewsComp: Qt.createComponent("qrc:/qml/ReviewsPage.qml") + + //toplevels + readonly property Component topBrowsingComp: Qt.createComponent("qrc:/qml/BrowsingPage.qml") + readonly property Component topInstalledComp: Qt.createComponent("qrc:/qml/InstalledPage.qml") + readonly property Component topUpdateComp: Qt.createComponent("qrc:/qml/UpdatesPage.qml") + readonly property Component topSourcesComp: Qt.createComponent("qrc:/qml/SourcesPage.qml") + readonly property QtObject stack: window.pageStack + property Component currentTopLevel: defaultStartup ? topBrowsingComp : loadingComponent + property bool defaultStartup: true + property bool navigationEnabled: true + + objectName: "DiscoverMainWindow" + title: leftPage ? leftPage.title : "" + + header: null + visible: true + + minimumWidth: 300 + minimumHeight: 300 + + pageStack.defaultColumnWidth: Kirigami.Units.gridUnit * 25 + + readonly property var leftPage: window.stack.depth>0 ? window.stack.get(0) : null + + Component.onCompleted: { + Helpers.mainWindow = window + if (app.isRoot) + showPassiveNotification(i18n("Running as root is discouraged and unnecessary.")); + } + + Component { + id: loadingComponent + Kirigami.Page { + title: label.text + Label { + id: label + text: i18n("Loading...") + font.pointSize: 52 + anchors.centerIn: parent + } + } + } + + ExclusiveGroup { id: appTabs } + + property list awesome: [ + TopLevelPageData { + iconName: "tools-wizard" + text: i18n("Discover") + component: topBrowsingComp + objectName: "discover" + shortcut: "Alt+D" + } + ] + TopLevelPageData { + id: installedAction + text: TransactionModel.count == 0 ? i18n("Installed") : i18n("Installing...") + component: topInstalledComp + objectName: "installed" + shortcut: "Alt+I" + } + TopLevelPageData { + id: updateAction + iconName: enabled ? "update-low" : "update-none" + text: !enabled ? i18n("No Updates") : i18nc("Update section name", "Update (%1)", ResourcesModel.updatesCount) + enabled: ResourcesModel.updatesCount>0 + component: topUpdateComp + objectName: "update" + shortcut: "Alt+U" + } + TopLevelPageData { + id: settingsAction + iconName: "settings" + text: i18n("Settings") + component: topSourcesComp + objectName: "settings" + shortcut: "Alt+S" + } + TopLevelPageData { + id: sources + text: i18n("Configure Sources...") + iconName: "repository" + shortcut: "Alt+S" + component: topSourcesComp + } + + Connections { + target: app + onOpenApplicationInternal: { + Navigation.clearStack() + Navigation.openApplication(app) + } + onListMimeInternal: { + currentTopLevel = topBrowsingComp; + Navigation.openApplicationMime(mime) + } + onListCategoryInternal: { + currentTopLevel = topBrowsingComp; + Navigation.openCategory(cat, "") + } + + onPreventedClose: showPassiveNotification(i18n("Could not close the application, there are tasks that need to be done."), 3000) + onUnableToFind: { + showPassiveNotification(i18n("Unable to find resource: %1", resid)); + Navigation.openHome() + } + } + + Component { + id: proceedDialog + Kirigami.OverlaySheet { + id: sheet + property QtObject transaction + property alias title: heading.text + property alias description: desc.text + property bool acted: false + ColumnLayout { + Kirigami.Heading { + id: heading + } + Kirigami.Label { + id: desc + Layout.fillWidth: true + wrapMode: Text.WordWrap + } + Button { + Layout.alignment: Qt.AlignRight + iconName: "dialog-ok" + onClicked: { + transaction.proceed() + sheet.acted = true + sheet.close() + } + } + } + onVisibleChanged: if(!visible) { + sheet.destroy(1000) + if (!sheet.acted) + transaction.cancel() + } + } + } + + Instantiator { + model: TransactionModel + + delegate: Connections { + target: model.transaction ? model.transaction : null + + onProceedRequest: { + var dialog = proceedDialog.createObject(window, {transaction: transaction, title: title, description: description}) + dialog.open() + } + onPassiveMessage: { + window.showPassiveNotification(message) + } + } + } + + globalDrawer: DiscoverDrawer {} + + onCurrentTopLevelChanged: { + if(currentTopLevel && currentTopLevel.status==Component.Error) { + console.log("status error: "+currentTopLevel.errorString()) + } + var stackView = window.pageStack; + stackView.clear() + if (currentTopLevel) + stackView.push(currentTopLevel, {}, window.status!=Component.Ready) + } + + Menu { + id: actionsMenu + } + + Instantiator { + model: MessageActionsModel {} + delegate: MenuItem { + action: ActionBridge { action: model.action } + } + onObjectAdded: { + actionsMenu.insertItem(index, object) + } + onObjectRemoved: { + object.destroy() + } + } + + UnityLauncher { + launcherId: "org.kde.discover.desktop" + progressVisible: TransactionModel.count > 0 + progress: TransactionModel.progress + } +} diff --git a/discover/qml/FeaturedBanner.qml b/discover/qml/FeaturedBanner.qml new file mode 100644 index 0000000..684418f --- /dev/null +++ b/discover/qml/FeaturedBanner.qml @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtGraphicalEffects 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.discover.app 1.0 +import "navigation.js" as Navigation + +Information { + id: info + + model: FeaturedModel { + id: featuredModel + } + readonly property real side: Math.min(info.height*0.9, info.width/1.618) + + delegate: MouseArea { + id: itemDelegate + readonly property QtObject modelData: model + readonly property int d1: Math.abs(info.currentIndex - model.index) + readonly property int distance: Math.min(d1, info.count - d1) + property real size: 1/((distance+3)/3) + enabled: modelData.package.length>0 + + width: info.side*1.618 * size + height: info.side * size + + Behavior on size { + NumberAnimation { + duration: 500 + easing.type: Easing.InQuad + } + } + + onClicked: { + if(model.packageName.length > 0) + Navigation.openApplication(ResourcesModel.resourceByPackageName(modelData.packageName)) + else + Qt.openUrlExternally(modelData.url) + } + z: -itemDelegate.distance + PathView.isCurrentItem + + Loader { + id: flick + anchors.fill: parent + + function endsWith(str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + + source: modelData.image && endsWith(modelData.image, ".qml") ? modelData.image : "qrc:/qml/FeaturedImage.qml" + clip: true + } + + Rectangle { + anchors.fill: titleBar + color: DiscoverSystemPalette.midlight + opacity: 0.7 + z: 20 + } + + RowLayout { + id: titleBar + height: description.implicitHeight + z: 23 + spacing: 10 + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + + QIconItem { + Layout.fillHeight: true + Layout.minimumWidth: height + icon: itemDelegate.modelData ? itemDelegate.modelData.icon : "kde" + } + + ColumnLayout { + id: description + Layout.fillWidth: true + + spacing: 0 + Label { + Layout.fillWidth: true + text: itemDelegate.modelData.text + font.bold: true + elide: Text.ElideRight + maximumLineCount: 1 + } + + Label { + Layout.fillWidth: true + text: itemDelegate.modelData.comment + visible: text.length > 0 + elide: Text.ElideRight + maximumLineCount: 1 + } + } + } + + DropShadow { + anchors.fill: flick + horizontalOffset: 3 + verticalOffset: 3 + radius: 8.0 + samples: 16 + color: "#80000000" + source: flick + } + + Desaturate { + anchors.fill: flick + source: flick + desaturation: parent.PathView.isCurrentItem ? 0 : 0.8 + + Behavior on desaturation { + NumberAnimation { + duration: 500 + easing.type: Easing.InQuad + } + } + } + } +} diff --git a/discover/qml/FeaturedImage.qml b/discover/qml/FeaturedImage.qml new file mode 100644 index 0000000..a7fb230 --- /dev/null +++ b/discover/qml/FeaturedImage.qml @@ -0,0 +1,56 @@ +import QtQuick 2.1 + +Flickable { + id: flick + + clip: true + contentY: 0 + interactive: false + contentWidth: Math.max(image.width, width) + contentHeight: Math.max(image.height, height) + property bool isCurrentItem: itemDelegate.PathView.isCurrentItem + + states: [ + State { + name: "shownSmall" + when: image.status==Image.Ready && image.height<(flick.height-titleBar.height) + PropertyChanges { target: flick; contentY: (flick.contentHeight+titleBar.height)/2-flick.height/2 } + }, + State { + name: "shownIdeal" + when: image.status==Image.Ready && image.height + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.discover.app 1.0 +import org.kde.kirigami 1.0 as Kirigami + +Item +{ + property alias text: theLabel.text + property real progress: 1. + readonly property real margin: 5 + implicitWidth: theLabel.implicitWidth + margin*2 + implicitHeight: theLabel.implicitHeight + margin*2 + width: implicitWidth + height: implicitHeight + + Rectangle { + color: Kirigami.Theme.disabledTextColor + anchors.fill: parent + radius: parent.margin + } + + Rectangle { + anchors { + fill: parent + rightMargin: (1-parent.progress) * parent.width + } + color: Kirigami.Theme.highlightColor + radius: parent.margin + } + + Label { + id: theLabel + anchors.centerIn: parent + color: Kirigami.Theme.highlightedTextColor + } +} diff --git a/discover/qml/LinkButton.qml b/discover/qml/LinkButton.qml new file mode 100644 index 0000000..d00f0b4 --- /dev/null +++ b/discover/qml/LinkButton.qml @@ -0,0 +1,29 @@ +import QtQuick 2.2 +import QtGraphicalEffects 1.0 +import org.kde.kirigami 1.0 + +Text { + id: control + + property Action action: null + text: action ? action.text : "" + enabled: !action || action.enabled + onClicked: if (action) action.trigger() + + font: control.font + color: control.shadow ? Theme.highlightedTextColor : Theme.linkColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + signal clicked() + MouseArea { + anchors.fill: parent + hoverEnabled: true + + onContainsMouseChanged: { + control.font.underline = containsMouse && control.enabled + } + + onClicked: control.clicked() + } +} diff --git a/discover/qml/Main.qml b/discover/qml/Main.qml new file mode 100644 index 0000000..402236f --- /dev/null +++ b/discover/qml/Main.qml @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.1 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import "navigation.js" as Navigation + +Rectangle +{ + color: DiscoverSystemPalette.base + implicitHeight: 800 + implicitWidth: 900 +} diff --git a/discover/qml/MessageAction.qml b/discover/qml/MessageAction.qml new file mode 100644 index 0000000..96e62fc --- /dev/null +++ b/discover/qml/MessageAction.qml @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.discover.app 1.0 + +Rectangle { + id: msg + property QtObject theAction: null + Layout.minimumHeight: row.Layout.minimumHeight + + visible: theAction.enabled + color: DiscoverSystemPalette.highlight + + RowLayout { + id: row + anchors { + fill: parent + leftMargin: 5 + rightMargin: 5 + } + + Label { + Layout.fillWidth: true + text: theAction.whatsThis || theAction.tooltip + color: DiscoverSystemPalette.highlightedText + } + Button { + text: theAction.text + onClicked: theAction.trigger() + } + Button { + iconName: "dialog-close" + onClicked: msg.visible = false + } + } +} diff --git a/discover/qml/PageHeader.qml b/discover/qml/PageHeader.qml new file mode 100644 index 0000000..1b315d9 --- /dev/null +++ b/discover/qml/PageHeader.qml @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2015 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.0 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 1.2 +import QtGraphicalEffects 1.0 +import org.kde.discover.app 1.0 +import org.kde.kirigami 1.0 as Kirigami + +ColumnLayout { + id: root + readonly property QtObject _page: findPage() + property string background + property string search: "" + readonly property bool shadow: background.length > 0 && decorationImage.status !== Image.Error + + function findPage() { + var obj = root; + while(obj && !obj.hasOwnProperty("title")) { + obj = obj.parent + } + return obj; + } + spacing: 0 + + Component.onCompleted: { + if (!root._page.pageHeader) + root._page.pageHeader = tinyHeader + } + + Component { + id: tinyHeader + Item { + height: layout.implicitHeight + DropShadow { + anchors.fill: source + source: backgroundColor.visible ? backgroundColor : bg + horizontalOffset: 0 + verticalOffset: 3 + radius: 8.0 + samples: 17 + color: "gray" + } + Rectangle { + id: backgroundColor + anchors.fill: parent + color: Kirigami.Theme.highlightColor + visible: bg.status != Image.Ready + } + Image { + id: bg + anchors.fill: parent + source: root.background + fillMode: Image.PreserveAspectCrop + } + + RowLayout { + id: layout + anchors { + left: parent.left + right: parent.right + rightMargin: Kirigami.Units.largeSpacing + } + Item { + Layout.fillWidth: true + Layout.fillHeight: true + } + Item { + Layout.topMargin: Kirigami.Units.smallSpacing*2 + Layout.bottomMargin: Kirigami.Units.smallSpacing*2 + Layout.preferredHeight: title.paintedHeight + Layout.preferredWidth: title.paintedWidth + LinkButton { + id: title + text: titleLabel.text + font: SystemFonts.titleFont + color: Kirigami.Theme.highlightedTextColor + onClicked: { + var flic = root._page.flickable + if (flic.positionViewAtBeginning) + flic.positionViewAtBeginning(); + else + flic.contentY = 0; + } + } + DropShadow { + horizontalOffset: 2 + verticalOffset: 2 + radius: 8.0 + samples: 17 + color: "#f0000000" + source: title + anchors.fill: title + } + } + } + } + } + + Image { + id: decorationImage + fillMode: Image.PreserveAspectCrop + Layout.preferredHeight: root.shadow ? titleLabel.paintedHeight * 4 : titleLabel.paintedHeight * 2 + Layout.fillWidth: true + source: root.background + + Label { + id: titleLabel + anchors { + fill: parent + margins: Kirigami.Units.gridUnit + } + font.pointSize: SystemFonts.titleFont.pointSize * 3 + text: root.search.length>0 && root._page.title.length>0 ? i18n("Search: %1 + %2", root.search, root._page.title) + : root.search.length>0 ? i18n("Search: %1", root.search) + : root._page.title + color: root.shadow ? Kirigami.Theme.highlightedTextColor : Kirigami.Theme.linkColor + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignBottom + elide: Text.ElideRight + } + + DropShadow { + horizontalOffset: 3 + verticalOffset: 3 + radius: 8.0 + samples: 17 + color: "#80000000" + source: titleLabel + anchors.fill: titleLabel + visible: root.shadow + } + } + Rectangle { + color: Kirigami.Theme.linkColor + Layout.fillWidth: true + height: 3 + } +} diff --git a/discover/qml/ProgressView.qml b/discover/qml/ProgressView.qml new file mode 100644 index 0000000..12f316a --- /dev/null +++ b/discover/qml/ProgressView.qml @@ -0,0 +1,107 @@ +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.discover 1.0 +import org.kde.kirigami 1.0 as Kirigami +import "navigation.js" as Navigation + +Kirigami.BasicListItem { + id: page + label: TransactionModel.count ? i18n("Tasks (%1%)", TransactionModel.progress) : i18n("Tasks") + visible: progressModel.count > 0 + + onClicked: { + sheet.open() + } + + readonly property var v1: Connections { + target: TransactionModel + onTransactionAdded: { + if(page.enabled && trans.resource && progressModel.appAt(trans.resource)<0) + progressModel.append({app: trans.resource}) + } + + onTransactionCancelled: { + var id = progressModel.appAt(trans.resource) + if(id>=0) + progressModel.remove(id) + } + } + + readonly property var v2: ListModel { + id: progressModel + function appAt(app) { + for(var i=0; i + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.discover.app 1.0 + +RowLayout +{ + id: view + property bool editable: false + property int max: 10 + property int rating: 2 + property real starSize: SystemFonts.generalFont.pointSize*2 + + clip: true + spacing: 0 + + readonly property var ratingIndex: (theRepeater.count/view.max)*view.rating + + Repeater { + id: theRepeater + model: view.rating>0 ? 5 : 0 + delegate: QIconItem { + Layout.minimumWidth: view.starSize + Layout.minimumHeight: view.starSize + Layout.preferredWidth: view.starSize + Layout.preferredHeight: view.starSize + + width: height + icon: "rating" + opacity: (view.editable && mouse.item.containsMouse ? 0.7 + : index>=view.ratingIndex ? 0.2 + : 1) + + ConditionalLoader { + id: mouse + + anchors.fill: parent + condition: view.editable + componentTrue: MouseArea { + hoverEnabled: true + onClicked: rating = (max/theRepeater.model*(index+1)) + } + componentFalse: null + } + } + } +} diff --git a/discover/qml/ReviewDelegate.qml b/discover/qml/ReviewDelegate.qml new file mode 100644 index 0000000..a6625b3 --- /dev/null +++ b/discover/qml/ReviewDelegate.qml @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import org.kde.kirigami 1.0 +import org.kde.discover 1.0 + +AbstractListItem +{ + id: item + visible: model.shouldShow + height: Math.max(layout.implicitHeight, 0) + 2*Units.smallSpacing + + signal markUseful(bool useful) + + function usefulnessToString(favorable, total) + { + return total==0 + ? i18n("Tell us about this review!") + : i18n("%1 out of %2 people found this review useful", favorable, total) + } + ColumnLayout { + id: layout + anchors { + left: parent.left + right: parent.right + margins: Units.gridUnit + } + Layout.fillWidth: true + + RowLayout { + Layout.fillWidth: true + Label { + id: content + Layout.fillWidth: true + text: i18n("%1 by %2", summary, reviewer) + } + Rating { + id: rating + rating: model.rating + starSize: content.font.pointSize + } + } + Label { + Layout.fillWidth: true + text: display + wrapMode: Text.Wrap + } + Label { + text: usefulnessToString(usefulnessFavorable, usefulnessTotal) + } + + Label { + opacity: item.containsMouse ? 1 : 0.2 + + text: { + switch(usefulChoice) { + case ReviewsModel.Yes: + i18n("Useful?
Yes/No") + break; + case ReviewsModel.No: + i18n("Useful? Yes/No") + break; + default: + i18n("Useful? Yes/No") + break; + } + } + onLinkActivated: item.markUseful(link=='true') + } + } +} diff --git a/discover/qml/ReviewDialog.qml b/discover/qml/ReviewDialog.qml new file mode 100644 index 0000000..4c23fa5 --- /dev/null +++ b/discover/qml/ReviewDialog.qml @@ -0,0 +1,49 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 +import QtQuick.Window 2.0 +import org.kde.kirigami 1.0 as Kirigami + +Kirigami.OverlaySheet +{ + id: reviewDialog + + property QtObject application + readonly property alias rating: ratingInput.rating + readonly property alias summary: summaryInput.text + readonly property alias review: reviewInput.text + + signal accepted() + + ColumnLayout { + Heading { text: i18n("Reviewing '%1'", application.name) } + Label { text: i18n("Rating:") } + Rating { + id: ratingInput + editable: true + } + + Label { text: i18n("Summary:") } + TextField { + id: summaryInput + Layout.fillWidth: true + placeholderText: i18n("Short summary...") + } + + TextArea { + id: reviewInput + Layout.fillWidth: true + Layout.fillHeight: true + } + + Button { + Layout.alignment: Qt.AlignRight + text: i18n("Accept") + onClicked: { + reviewDialog.accepted() + reviewDialog.opened = false + } + } + } +} diff --git a/discover/qml/ReviewsPage.qml b/discover/qml/ReviewsPage.qml new file mode 100644 index 0000000..ac3daa5 --- /dev/null +++ b/discover/qml/ReviewsPage.qml @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import org.kde.kirigami 1.0 as Kirigami + +Kirigami.OverlaySheet { + id: page + property alias model: reviewsView.model + readonly property QtObject reviewsBackend: resource.backend.reviewsBackend + readonly property var resource: model.resource + + readonly property var rd: ReviewDialog { + id: reviewDialog + application: page.resource + parent: overlay + onAccepted: page.reviewsBackend.submitReview(resource, summary, review, rating) + } + + ListView { + id: reviewsView + implicitWidth: page.width*2/3 + + clip: true + spacing: 5 + + header: Button { + visible: page.reviewsBackend != null && page.resource.isInstalled + text: i18n("Review") + onClicked: reviewDialog.opened = true + } + + delegate: ReviewDelegate { + width: reviewsView.implicitWidth + onMarkUseful: page.reviewsModel.markUseful(index, useful) + } + } +} diff --git a/discover/qml/SourcesPage.qml b/discover/qml/SourcesPage.qml new file mode 100644 index 0000000..5859ab1 --- /dev/null +++ b/discover/qml/SourcesPage.qml @@ -0,0 +1,163 @@ +import QtQuick 2.1 +import QtQuick.Controls 1.1 +import QtQuick.Layouts 1.1 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.kirigami 1.0 as Kirigami +import "navigation.js" as Navigation + +DiscoverPage { + id: page + clip: true + title: i18n("Settings") + + ListView { + model: SourcesModel + + Menu { id: sourcesMenu } + + header: PageHeader { + anchors { + left: parent.left + right: parent.right + } + + RowLayout { + Layout.fillWidth: true + Layout.leftMargin: Kirigami.Units.gridUnit + Layout.rightMargin: Kirigami.Units.gridUnit + Layout.topMargin: Kirigami.Units.smallSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + ToolButton { +// iconName: "list-add" + text: i18n("Add Source") + + visible: sourcesMenu.items.count > 0 + tooltip: text + menu: sourcesMenu + } + Repeater { + model: SourcesModel.actions + + delegate: RowLayout { + QIconItem { + icon: modelData.icon + } + ToolButton { + height: parent.height + action: Action { + readonly property QtObject action: modelData + text: action.text + onTriggered: action.trigger() + enabled: action.enabled + } + } + } + } + + ToolButton { + text: i18n("More...") + menu: actionsMenu + enabled: actionsMenu.items.length>0 + } + + ToolButton { + text: i18n("Help...") + menu: Menu { + MenuItem { action: ActionBridge { action: app.action("help_about_app") } } + MenuItem { action: ActionBridge { action: app.action("help_report_bug") } } + } + } + } + } + + delegate: ColumnLayout { + id: sourceDelegate + anchors { + left: parent.left + right: parent.right + leftMargin: Kirigami.Units.largeSpacing + rightMargin: Kirigami.Units.largeSpacing + } + + readonly property QtObject sourceBackend: model.sourceBackend + + Connections { + target: sourceDelegate.sourceBackend + onPassiveMessage: window.showPassiveNotification(message) + } + AddSourceDialog { + id: addSourceDialog + source: sourceDelegate.sourceBackend + } + + MenuItem { + id: menuItem + text: model.display + onTriggered: { + try { + addSourceDialog.open() + addSourceDialog.visible = true + } catch (e) { + console.log("error loading dialog:", e) + } + } + } + + Component.onCompleted: { + sourcesMenu.insertItem(0, menuItem) + } + + + Kirigami.Heading { + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + text: sourceBackend.name + } + spacing: 0 + Repeater { + model: sourceBackend.sources + + delegate: Kirigami.SwipeListItem { + enabled: display.length>0 + onClicked: Navigation.openApplicationListSource(model.display) + + actions: [ + Kirigami.Action { + enabled: display.length>0 + iconName: "view-filter" + tooltip: i18n("Browse the origin's resources") + onTriggered: Navigation.openApplicationListSource(model.display) + }, + Kirigami.Action { + iconName: "edit-delete" + tooltip: i18n("Delete the origin") + onTriggered: sourceDelegate.sourceBackend.removeSource(model.display) + } + ] + + RowLayout { + anchors { + left: parent.left + right: parent.right + } + CheckBox { + id: enabledBox + checked: model.checked != Qt.Unchecked + enabled: model.checked !== undefined + onClicked: { + model.checked = checkedState + } + } + Label { + text: model.display + " - " + model.toolTip + "" + elide: Text.ElideRight + Layout.fillWidth: true + } + } + } + } + } + } +} diff --git a/discover/qml/TopLevelPageData.qml b/discover/qml/TopLevelPageData.qml new file mode 100644 index 0000000..9a0d26f --- /dev/null +++ b/discover/qml/TopLevelPageData.qml @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 2.1 +import QtQuick.Controls 1.2 +import "navigation.js" as Navigation + +Action { + property Component component + checkable: window.currentTopLevel==component + checked: window.currentTopLevel==component + enabled: window.navigationEnabled + exclusiveGroup: appTabs + + onTriggered: { + if(window.currentTopLevel!=component) + window.currentTopLevel=component + } +} diff --git a/discover/qml/UpdatesPage.qml b/discover/qml/UpdatesPage.qml new file mode 100644 index 0000000..d7754c2 --- /dev/null +++ b/discover/qml/UpdatesPage.qml @@ -0,0 +1,253 @@ +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.1 +import QtQuick 2.1 +import org.kde.discover 1.0 +import org.kde.discover.app 1.0 +import org.kde.kquickcontrolsaddons 2.0 +import org.kde.kcoreaddons 1.0 +import "navigation.js" as Navigation +import org.kde.kirigami 1.0 as Kirigami + +DiscoverPage +{ + id: page + title: i18n("Updates") + + function start() { + resourcesUpdatesModel.updateAll() + } + + property string footerLabel: "" + + //TODO: use supportsRefreshing to fetch updates + + ListView + { + id: updatesView + ResourcesUpdatesModel { + id: resourcesUpdatesModel + onIsProgressingChanged: { + window.navigationEnabled = !isProgressing + + if (!isProgressing) { + resourcesUpdatesModel.prepare() + } + } + + Component.onCompleted: { + if (!isProgressing) { + resourcesUpdatesModel.prepare() + } + } + } + + UpdateModel { + id: updateModel + backend: resourcesUpdatesModel + } + + header: PageHeader { + id: header + anchors { + left: parent.left + right: parent.right + } + background: "qrc:/icons/updatescrop.jpg" + + RowLayout { + Layout.fillWidth: true + Layout.leftMargin: Kirigami.Units.gridUnit + Layout.rightMargin: Kirigami.Units.gridUnit + Layout.topMargin: Kirigami.Units.smallSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + + visible: resourcesUpdatesModel.isProgressing || updateModel.hasUpdates + + LabelBackground { + text: updateModel.toUpdateCount + " (" + updateModel.updateSize+")" + } + Label { + text: i18n("updates selected") + } + LabelBackground { + id: unselectedItem + readonly property int unselected: (updateModel.totalUpdatesCount - updateModel.toUpdateCount) + text: unselected + visible: unselected>0 + } + Label { + text: i18n("updates not selected") + visible: unselectedItem.visible + } + Item { Layout.fillWidth: true} + Button { + id: startButton + Layout.minimumWidth: Kirigami.Units.gridUnit * 6 + Layout.rightMargin: Kirigami.Units.smallSpacing + text: unselectedItem.visible ? i18n("Update Selected") : i18n("Update All") + enabled: !resourcesUpdatesModel.isProgressing + onClicked: page.start() + } + } + } + + footer: ColumnLayout { + anchors.right: parent.right + anchors.left: parent.left + Kirigami.Heading { + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + visible: page.footerLabel !== "" + text: page.footerLabel + } + QIconItem { + Layout.alignment: Qt.AlignHCenter + visible: page.footerLabel !== "" + icon: "update-none" + opacity: 0.3 + width: 200 + height: 200 + } + Item { + visible: page.footerLabel === "" + height: Kirigami.Units.gridUnit + width: 1 + } + } + + model: updateModel + + section { + property: "section" + delegate: Kirigami.Heading { + x: Kirigami.Units.gridUnit + level: 2 + text: section + } + } + + spacing: Kirigami.Units.smallSpacing + + delegate: Kirigami.AbstractListItem { + x: Kirigami.Units.gridUnit + width: ListView.view.width - Kirigami.Units.gridUnit * 2 + onEnabledChanged: if (!enabled) { + layout.extended = false; + } + + ColumnLayout { + id: layout + anchors { + left: parent.left + right: parent.right + } + property bool extended: false + RowLayout { + Layout.fillWidth: true + Layout.fillHeight: true + + CheckBox { + anchors.verticalCenter: parent.verticalCenter + checked: model.checked == Qt.Checked + onClicked: model.checked = (model.checked==Qt.Checked ? Qt.Unchecked : Qt.Checked) + } + + QIconItem { + Layout.fillHeight: true + Layout.preferredWidth: height + icon: decoration + } + + Label { + Layout.fillWidth: true + text: i18n("%1 (%2)", display, version) + elide: Text.ElideRight + } + + LabelBackground { + Layout.minimumWidth: Kirigami.Units.gridUnit * 6 + text: size + + progress: resourceProgress/100 + } + } + + ScrollView { + id: view + Layout.fillHeight: true + Layout.fillWidth: true + frameVisible: true + visible: layout.extended && changelog.length>0 + + Label { + width: view.viewport.width + text: changelog + textFormat: Text.RichText + wrapMode: Text.WordWrap + } + } + + Button { + text: i18n("Open") + visible: layout.extended + enabled: !resourcesUpdatesModel.isProgressing + onClicked: Navigation.openApplication(resource) + } + } + + onClicked: { + updateModel.fetchChangelog(index) + layout.extended = !layout.extended + } + } + } + + readonly property var secSinceUpdate: resourcesUpdatesModel.secsToLastUpdate + state: ( ResourcesModel.isFetching ? "fetching" + : updateModel.hasUpdates ? "has-updates" + : resourcesUpdatesModel.isProgressing ? "progressing" + : secSinceUpdate < 0 ? "unknown" + : secSinceUpdate === 0 ? "now-uptodate" + : secSinceUpdate < 1000 * 60 * 60 * 24 ? "uptodate" + : secSinceUpdate < 1000 * 60 * 60 * 24 * 7 ? "medium" + : "low" + ) + + states: [ + State { + name: "fetching" + PropertyChanges { target: page; title: i18nc("@info", "Loading...") } + }, + State { + name: "progressing" + PropertyChanges { target: page; title: i18nc("@info", "Updating...") } + PropertyChanges { target: page; footerLabel: resourcesUpdatesModel.progress<=0 ? i18nc("@info", "Fetching updates") : "" } + }, + State { + name: "has-updates" + PropertyChanges { target: page; title: i18nc("@info", "Updates") } + }, + State { + name: "now-uptodate" + PropertyChanges { target: page; title: i18nc("@info", "The system is up to date") } + PropertyChanges { target: page; footerLabel: i18nc("@info", "No updates") } + }, + State { + name: "uptodate" + PropertyChanges { target: page; title: i18nc("@info", "The system is up to date") } + }, + State { + name: "medium" + PropertyChanges { target: page; title: i18nc("@info", "No updates are available") } + }, + State { + name: "low" + PropertyChanges { target: page; title: i18nc("@info", "Should check for updates") } + }, + State { + name: "unknown" + PropertyChanges { target: page; title: i18nc("@info", "It is unknown when the last check for updates was") } + } + ] +} diff --git a/discover/qml/navigation.js b/discover/qml/navigation.js new file mode 100644 index 0000000..bab66a1 --- /dev/null +++ b/discover/qml/navigation.js @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +function clearStack() +{ + window.currentTopLevel=null + window.stack.clear(); +} + +function openApplicationListSource(origin) { + openApplicationList({ originFilter: origin, title: origin }) +} + +function openApplicationMime(mime) { + clearStack() + openApplicationList({ mimeTypeFilter: mime , title: i18n("Resources for '%1'", mime) }) +} + +function openApplicationList(props) { + var page = window.stack.push(applicationListComp, props) + if (props.search === "") + page.clearSearch() +} + +function openCategory(cat, search) { + clearStack() + openApplicationList({ category: cat, search: search }) +} + +function openApplication(app) { + window.stack.push(applicationComp, { application: app }) +} + +function openReviews(model) { + window.stack.push(reviewsComp, { model: model }) +} + +function openExtends(ext) { + window.stack.push(applicationListComp, { extend: ext, title: i18n("Extensions...") }) +} + +function openHome() { + window.globalDrawer.resetMenu(); + clearStack() + window.globalDrawer.clearSearch(); + window.stack.push(topBrowsingComp) +} diff --git a/discover/resources.qrc b/discover/resources.qrc new file mode 100644 index 0000000..676778a --- /dev/null +++ b/discover/resources.qrc @@ -0,0 +1,52 @@ + + + qml/Main.qml + qml/TopLevelPageData.qml + qml/CategoryDisplay.qml + qml/ApplicationsTop.qml + qml/FeaturedBanner.qml + qml/ApplicationsListPage.qml + qml/ApplicationPage.qml + qml/ReviewsPage.qml + qml/AddonsView.qml + qml/ApplicationDelegate.qml + qml/Breadcrumbs.qml + qml/CategoryBreadcrumbs.qml + qml/InstallApplicationButton.qml + qml/Rating.qml + qml/UpdatesPage.qml + qml/ReviewDialog.qml + qml/ProgressView.qml + qml/BrowsingPage.qml + qml/InstalledPage.qml + qml/Information.qml + qml/SourcesPage.qml + qml/FeaturedModel.qml + qml/DefaultBanner.qml + qml/FeaturedImage.qml + qml/ReviewDelegate.qml + qml/Heading.qml + qml/AddSourceDialog.qml + qml/MessageAction.qml + qml/JustMessageAction.qml + qml/ConditionalLoader.qml + qml/LinkButton.qml + qml/ApplicationScreenshots.qml + qml/ApplicationIndicator.qml + qml/ApplicationHeader.qml + qml/LabelBackground.qml + qml/PageHeader.qml + qml/ActionBridge.qml + qml/DiscoverSystemPalette.qml + qml/DiscoverPage.qml + qml/DiscoverWindow.qml + qml/DiscoverDrawer.qml + qml/Helpers.qml + + qml/navigation.js + + icons/banner.svg + icons/installedcrop.jpg + icons/updatescrop.jpg + + diff --git a/exporter/CMakeLists.txt b/exporter/CMakeLists.txt new file mode 100644 index 0000000..2aa1e88 --- /dev/null +++ b/exporter/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}) + +add_executable(plasma-discover-exporter main.cpp MuonExporter.cpp) + +target_link_libraries(plasma-discover-exporter Discover::Common KF5::CoreAddons KF5::I18n) diff --git a/exporter/MuonExporter.cpp b/exporter/MuonExporter.cpp new file mode 100644 index 0000000..16b7eab --- /dev/null +++ b/exporter/MuonExporter.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MuonExporter.h" +#include +#include +#include +#include +#include +#include +#include +#include + +MuonExporter::MuonExporter() + : QObject(nullptr) +{ + m_startExportingTimer = new QTimer(this); + m_startExportingTimer->setInterval(200); + m_startExportingTimer->setSingleShot(true); + connect(m_startExportingTimer, &QTimer::timeout, this, &MuonExporter::exportModel); + + m_exculdedProperties += "executables"; + m_exculdedProperties += "canExecute"; + connect(ResourcesModel::global(), &ResourcesModel::allInitialized, this, &MuonExporter::allBackendsInitialized); +} + +MuonExporter::~MuonExporter() = default; + +void MuonExporter::allBackendsInitialized() +{ + m_startExportingTimer->start(); + connect(ResourcesModel::global(), SIGNAL(rowsInserted(QModelIndex,int,int)), m_startExportingTimer, SLOT(start())); +} + +void MuonExporter::setExportPath(const QUrl& url) +{ + m_path = url; +} + +QVariantMap itemDataToMap(const AbstractResource* res, const QSet& excluded) +{ + QVariantMap ret; + int propsCount = res->metaObject()->propertyCount(); + for(int i = 0; imetaObject()->property(i); + if(prop.type() == QVariant::UserType || excluded.contains(prop.name())) + continue; + QVariant val = res->property(prop.name()); + + if(val.isNull()) + continue; + + ret.insert(QString::fromLatin1(prop.name()), val); + } + return ret; +} + +void MuonExporter::exportModel() +{ + QVariantList data; + ResourcesModel* m = ResourcesModel::global(); + + for(int i = 0; irowCount(); i++) { + QModelIndex idx = m->index(i, 0); + AbstractResource* res = qobject_cast(m->data(idx, ResourcesModel::ApplicationRole).value()); + Q_ASSERT(res); + data += itemDataToMap(res, m_exculdedProperties); + } + + QJsonDocument doc = QJsonDocument::fromVariant(data); + if(doc.isNull()) { + qWarning() << "Could not completely export the data to " << m_path; + return; + } + + QFile f(m_path.toLocalFile()); + if(f.open(QIODevice::WriteOnly|QIODevice::Text)) { + int w = f.write(doc.toJson(QJsonDocument::Indented)); + if(w<=0) + qWarning() << "Could not completely export the data to " << m_path; + } else { + qWarning() << "Could not write to " << m_path; + } + qDebug() << "exported items: " << data.count() << " to " << m_path; + emit exportDone(); +} diff --git a/exporter/MuonExporter.h b/exporter/MuonExporter.h new file mode 100644 index 0000000..0a0c76a --- /dev/null +++ b/exporter/MuonExporter.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MUONEXPORTER_H +#define MUONEXPORTER_H + +#include +#include +#include + +class MuonExporter : public QObject +{ + Q_OBJECT + public: + explicit MuonExporter(); + ~MuonExporter() override; + + void setExportPath(const QUrl& url); + + public Q_SLOTS: + void exportModel(); + void allBackendsInitialized(); + + Q_SIGNALS: + void exportDone(); + + private: + QUrl m_path; + QTimer* m_startExportingTimer; + QSet m_exculdedProperties; +}; + +#endif // MUONEXPORTER_H diff --git a/exporter/main.cpp b/exporter/main.cpp new file mode 100644 index 0000000..8e4329c --- /dev/null +++ b/exporter/main.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2012 Aleix Pol Gonzalez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library/Lesser General Public License + * version 2, or (at your option) any later version, as published by the + * Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library/Lesser General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include "MuonExporter.h" +#include +#include "DiscoverVersion.h" + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + KLocalizedString::setApplicationDomain("plasma-discover-exporter"); + KAboutData about(QStringLiteral("muonexporter"), i18n("Muon Exporter"), version, QString(), + KAboutLicense::GPL, i18n("©2013 Aleix Pol Gonzalez"), QString()); + about.addAuthor(i18n("Jonathan Thomas"), QString(), QStringLiteral("echidnaman@kubuntu.org")); + about.addAuthor(i18n("Aleix Pol Gonzalez"), QString(), QStringLiteral("aleixpol@blue-systems.com")); + about.setProductName("discover/exporter"); + + MuonExporter exp; + { + QCommandLineParser parser; + parser.addOption(QCommandLineOption(QStringLiteral("backends"), i18n("List all the backends we'll want to have loaded, separated by coma ','."), QStringLiteral("names"))); + parser.addPositionalArgument(QStringLiteral("file"), i18n("File to which we'll export")); + DiscoverBackendsFactory::setupCommandLine(&parser); + about.setupCommandLine(&parser); + parser.addHelpOption(); + parser.addVersionOption(); + parser.process(app); + about.processCommandLine(&parser); + DiscoverBackendsFactory::processCommandLine(&parser, false); + + if(parser.positionalArguments().count() != 1) { + parser.showHelp(1); + } + exp.setExportPath(QUrl::fromUserInput(parser.positionalArguments().at(0), QString(), QUrl::AssumeLocalFile)); + } + + QObject::connect(&exp, &MuonExporter::exportDone, &app, &QApplication::quit); + + return app.exec(); +} diff --git a/libdiscover/ApplicationAddonsModel.cpp b/libdiscover/ApplicationAddonsModel.cpp new file mode 100644 index 0000000..af3866d --- /dev/null +++ b/libdiscover/ApplicationAddonsModel.cpp @@ -0,0 +1,153 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ApplicationAddonsModel.h" +#include +#include +#include +#include +#include + +ApplicationAddonsModel::ApplicationAddonsModel(QObject* parent) + : QAbstractListModel(parent) + , m_app(nullptr) +{ +// new ModelTest(this, this); + + connect(TransactionModel::global(), &TransactionModel::transactionRemoved, this, &ApplicationAddonsModel::transactionOver); +} + +QHash< int, QByteArray > ApplicationAddonsModel::roleNames() const +{ + QHash roles = QAbstractItemModel::roleNames(); + roles.insert(Qt::CheckStateRole, "checked"); + roles.insert(PackageNameRole, "packageName"); + return roles; +} + +void ApplicationAddonsModel::setApplication(AbstractResource* app) +{ + if (app == m_app) + return; + + if (m_app) + disconnect(m_app, nullptr, this, nullptr); + + m_app = app; + resetState(); + emit applicationChanged(); +} + +void ApplicationAddonsModel::resetState() +{ + beginResetModel(); + m_state.clear(); + m_initial = m_app ? m_app->addonsInformation() : QList(); + endResetModel(); + + emit stateChanged(); +} + +AbstractResource* ApplicationAddonsModel::application() const +{ + return m_app; +} + +int ApplicationAddonsModel::rowCount(const QModelIndex& parent) const +{ + return parent.isValid()? 0 : m_initial.size(); +} + +QVariant ApplicationAddonsModel::data(const QModelIndex& index, int role) const +{ + if(!index.isValid() || index.row()>=m_initial.size()) + return QVariant(); + + switch(role) { + case Qt::DisplayRole: + return m_initial[index.row()].name(); + case Qt::ToolTipRole: + return m_initial[index.row()].description(); + case PackageNameRole: + return m_initial[index.row()].packageName(); + case Qt::CheckStateRole: { + const PackageState init = m_initial[index.row()]; + const AddonList::State state = m_state.addonState(init.name()); + if(state == AddonList::None) { + return init.isInstalled() ? Qt::Checked : Qt::Unchecked; + } else { + return state == AddonList::ToInstall ? Qt::Checked : Qt::Unchecked; + } + } + } + + return QVariant(); +} + +void ApplicationAddonsModel::discardChanges() +{ + //dataChanged should suffice, but it doesn't + beginResetModel(); + m_state.clear(); + emit stateChanged(); + endResetModel(); +} + +void ApplicationAddonsModel::applyChanges() +{ + ResourcesModel::global()->installApplication(m_app, m_state); +} + +void ApplicationAddonsModel::changeState(const QString& packageName, bool installed) +{ + auto it = m_initial.constBegin(); + for(; it != m_initial.constEnd(); ++it) { + if(it->packageName()==packageName) + break; + } + Q_ASSERT(it != m_initial.constEnd()); + + const bool restored = it->isInstalled()==installed; + + if(restored) + m_state.resetAddon(packageName); + else + m_state.addAddon(packageName, installed); + + emit stateChanged(); +} + +bool ApplicationAddonsModel::hasChanges() const +{ + return !m_state.isEmpty(); +} + +bool ApplicationAddonsModel::isEmpty() const +{ + return m_initial.isEmpty(); +} + +void ApplicationAddonsModel::transactionOver(Transaction* t) +{ + if (t->resource() != m_app) + return; + + resetState(); +} diff --git a/libdiscover/ApplicationAddonsModel.h b/libdiscover/ApplicationAddonsModel.h new file mode 100644 index 0000000..6b9fbaf --- /dev/null +++ b/libdiscover/ApplicationAddonsModel.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef APPLICATIONADDONSMODEL_H +#define APPLICATIONADDONSMODEL_H + +#include +#include +#include "Transaction/AddonList.h" + +#include "discovercommon_export.h" + +class Transaction; +class AbstractResource; + +class DISCOVERCOMMON_EXPORT ApplicationAddonsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(AbstractResource* application READ application WRITE setApplication NOTIFY applicationChanged) + Q_PROPERTY(bool hasChanges READ hasChanges NOTIFY stateChanged) + Q_PROPERTY(bool isEmpty READ isEmpty NOTIFY applicationChanged) + public: + enum Roles { + PackageNameRole = Qt::UserRole + }; + + explicit ApplicationAddonsModel(QObject* parent = nullptr); + + AbstractResource* application() const; + void setApplication(AbstractResource* app); + bool hasChanges() const; + + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QHash roleNames() const override; + bool isEmpty() const; + + public Q_SLOTS: + void discardChanges(); + void applyChanges(); + void changeState(const QString& packageName, bool installed); + + Q_SIGNALS: + void stateChanged(); + void applicationChanged(); + + private: + void transactionOver(Transaction* t); + void resetState(); + + AbstractResource* m_app; + QList m_initial; + AddonList m_state; +}; + +#endif // APPLICATIONADDONSMODEL_H diff --git a/libdiscover/CMakeLists.txt b/libdiscover/CMakeLists.txt new file mode 100644 index 0000000..c8be46f --- /dev/null +++ b/libdiscover/CMakeLists.txt @@ -0,0 +1,61 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"libdiscover\") + +add_subdirectory(backends) +add_subdirectory(declarative) +add_subdirectory(notifiers) +add_subdirectory(tests) + +set(discovercommon_SRCS + Category/Category.cpp + Category/CategoryModel.cpp + Category/CategoriesReader.cpp + ReviewsBackend/AbstractReviewsBackend.cpp + ReviewsBackend/Rating.cpp + ReviewsBackend/Review.cpp + ReviewsBackend/AbstractLoginBackend.cpp + ReviewsBackend/ReviewsModel.cpp + ReviewsBackend/PopConParser.cpp + Transaction/AddonList.cpp + Transaction/Transaction.cpp + Transaction/TransactionListener.cpp + Transaction/TransactionModel.cpp + UpdateModel/UpdateItem.cpp + UpdateModel/UpdateModel.cpp + resources/ResourcesModel.cpp + resources/ResourcesProxyModel.cpp + resources/PackageState.cpp + resources/ResourcesUpdatesModel.cpp + resources/StandardBackendUpdater.cpp + resources/SourcesModel.cpp + resources/AbstractResourcesBackend.cpp + resources/AbstractResource.cpp + resources/AbstractBackendUpdater.cpp + resources/AbstractSourcesBackend.cpp + MessageActionsModel + DiscoverBackendsFactory.cpp + ScreenshotsModel.cpp + ApplicationAddonsModel.cpp +) + +kconfig_add_kcfg_files(discovercommon_SRCS GENERATE_MOC MuonDataSources.kcfgc) +add_library(DiscoverCommon ${discovercommon_SRCS}) + +target_link_libraries(DiscoverCommon +LINK_PUBLIC + Qt5::Core + Qt5::Qml + Qt5::Widgets + KF5::I18n +LINK_PRIVATE + Qt5::Xml + KF5::XmlGui + KF5::CoreAddons +) +add_library(Discover::Common ALIAS DiscoverCommon) + +generate_export_header(DiscoverCommon) + +target_include_directories(DiscoverCommon PRIVATE ${PHONON_INCLUDES} PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) + +install(TARGETS DiscoverCommon DESTINATION ${CMAKE_INSTALL_LIBDIR}/plasma-discover) +install(FILES resources/discoverabstractnotifier.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR}) diff --git a/libdiscover/Category/CategoriesReader.cpp b/libdiscover/Category/CategoriesReader.cpp new file mode 100644 index 0000000..0574af4 --- /dev/null +++ b/libdiscover/Category/CategoriesReader.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "CategoriesReader.h" +#include "Category.h" +#include +#include +#include +#include + +#include +#include + +QVector CategoriesReader::loadCategoriesFile(const QString& name) +{ + QVector ret; + QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/categories/")+name+QStringLiteral("-categories.xml")); + if (path.isEmpty()) { + qWarning() << "Couldn't find a category for " << name; + return ret; + } + return loadCategoriesPath(path); +} + +QVector CategoriesReader::loadCategoriesPath(const QString& path) +{ + QVector ret; + QFile menuFile(path); + if (!menuFile.open(QIODevice::ReadOnly)) { + qWarning() << "couldn't open" << path; + return ret; + } + + QDomDocument menuDocument; + QString error; + int line; + bool correct = menuDocument.setContent(&menuFile, &error, &line); + if(!correct) + qWarning() << "error while parsing the categories file:" << error << " at: " << path << ':' << line; + + QDomElement root = menuDocument.documentElement(); + + QDomNode node = root.firstChild(); + while(!node.isNull()) + { + if (node.nodeType() == QDomNode::ElementNode) { + ret << new Category( {path} ); + ret.last()->parseData(path, node); + } + + node = node.nextSibling(); + } + return ret; +} + +bool CategoriesReader::categoryLessThan(Category *c1, const Category *c2) +{ + return (QString::localeAwareCompare(c1->name(), c2->name()) < 0); +} + +QVector CategoriesReader::populateCategories() +{ + DiscoverBackendsFactory f; + QStringList backendNames = f.allBackendNames(); + + QVector ret; + Q_FOREACH (const QString& name, backendNames) { + const QVector cats = loadCategoriesFile(name); + + if(ret.isEmpty()) { + ret = cats; + } else { + Q_FOREACH (Category* c, cats) + Category::addSubcategory(ret, c); + } + } + qSort(ret.begin(), ret.end(), categoryLessThan); + return ret; +} diff --git a/libdiscover/Category/CategoriesReader.h b/libdiscover/Category/CategoriesReader.h new file mode 100644 index 0000000..755e60e --- /dev/null +++ b/libdiscover/Category/CategoriesReader.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef CATEGORIESREADER_H +#define CATEGORIESREADER_H + +#include +#include "discovercommon_export.h" + +class Category; +class DISCOVERCOMMON_EXPORT CategoriesReader +{ + public: + QVector populateCategories(); + QVector loadCategoriesPath(const QString& path); + + static bool categoryLessThan(Category *c1, const Category *c2); + + private: + QVector loadCategoriesFile(const QString& path); +}; + +#endif // CATEGORIESREADER_H diff --git a/libdiscover/Category/Category.cpp b/libdiscover/Category/Category.cpp new file mode 100644 index 0000000..3e31fc1 --- /dev/null +++ b/libdiscover/Category/Category.cpp @@ -0,0 +1,229 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "Category.h" + +#include + +#include +#include +#include +#include + +Category::Category(QSet pluginName, QObject* parent) + : QObject(parent) + , m_iconString(QStringLiteral("applications-other")) + , m_showTechnical(false) + , m_plugins(std::move(pluginName)) +{} + +Category::~Category() = default; + +void Category::parseData(const QString& path, const QDomNode& data) +{ + for(QDomNode node = data.firstChild(); !node.isNull(); node = node.nextSibling()) + { + if(!node.isElement()) { + if(!node.isComment()) + qWarning() << "unknown node found at " << QStringLiteral("%1:%2").arg(path).arg(node.lineNumber()); + continue; + } + QDomElement tempElement = node.toElement(); + + if (tempElement.tagName() == QLatin1String("Name")) { + m_name = i18nc("Category", tempElement.text().toUtf8().constData()); + } else if (tempElement.tagName() == QLatin1String("Menu")) { + m_subCategories << new Category(m_plugins, this); + m_subCategories.last()->parseData(path, node); + } else if (tempElement.tagName() == QLatin1String("Image")) { + m_decoration = QUrl(tempElement.text()); + if (m_decoration.isRelative()) { + m_decoration = QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("discover/") + tempElement.text())); + if (m_decoration.isEmpty()) + qWarning() << "couldn't find category decoration" << tempElement.text(); + } + } else if (tempElement.tagName() == QLatin1String("Addons")) { + m_isAddons = true; + } else if (tempElement.tagName() == QLatin1String("Icon") && tempElement.hasChildNodes()) { + m_iconString = tempElement.text(); + } else if (tempElement.tagName() == QLatin1String("ShowTechnical")) { + m_showTechnical = true; + } else if (tempElement.tagName() == QLatin1String("Include")) { //previous muon format + parseIncludes(tempElement); + } else if (tempElement.tagName() == QLatin1String("Categories")) { //as provided by appstream + parseIncludes(tempElement); + } + } +} + +QVector > Category::parseIncludes(const QDomNode &data) +{ + QDomNode node = data.firstChild(); + QVector > filter; + while(!node.isNull()) + { + QDomElement tempElement = node.toElement(); + + if (tempElement.tagName() == QLatin1String("And")) { + // Parse children + m_andFilters.append(parseIncludes(node)); + } else if (tempElement.tagName() == QLatin1String("Or")) { + m_orFilters.append(parseIncludes(node)); + } else if (tempElement.tagName() == QLatin1String("Not")) { + m_notFilters.append(parseIncludes(node)); + } else if (tempElement.tagName() == QLatin1String("PkgSection")) { + filter.append({ PkgSectionFilter, tempElement.text() }); + } else if (tempElement.tagName() == QLatin1String("Category")) { + filter.append({ CategoryFilter, tempElement.text() }); + } else if (tempElement.tagName() == QLatin1String("PkgWildcard")) { + filter.append({ PkgWildcardFilter, tempElement.text() }); + } else if (tempElement.tagName() == QLatin1String("AppstreamIdWildcard")) { + filter.append({ AppstreamIdWildcardFilter, tempElement.text() }); + } else if (tempElement.tagName() == QLatin1String("PkgName")) { + filter.append({ PkgNameFilter, tempElement.text() }); + } else { + qWarning() << "unknown" << tempElement.tagName(); + } + node = node.nextSibling(); + } + + return filter; +} + +QString Category::name() const +{ + return m_name; +} + +QString Category::icon() const +{ + return m_iconString; +} + +QVector > Category::andFilters() const +{ + return m_andFilters; +} + +QVector > Category::orFilters() const +{ + return m_orFilters; +} + +QVector > Category::notFilters() const +{ + return m_notFilters; +} + +bool Category::shouldShowTechnical() const +{ + return m_showTechnical; +} + +QVector Category::subCategories() const +{ + return m_subCategories; +} + +//TODO: maybe it would be interesting to apply some rules to a said backend... +void Category::addSubcategory(QVector< Category* >& list, Category* newcat) +{ + Q_FOREACH (Category* c, list) { + if(c->name() == newcat->name()) { + if(c->icon() != newcat->icon() + || c->shouldShowTechnical() != newcat->shouldShowTechnical() + || c->m_andFilters != newcat->m_andFilters + || c->m_isAddons != newcat->m_isAddons + ) + { + qWarning() << "the following categories seem to be the same but they're not entirely" + << c->name() << newcat->name() << "--" + << c->shouldShowTechnical() << newcat->shouldShowTechnical() << "--" + << c->andFilters() << newcat->andFilters() << "--" + << c->isAddons() << newcat->isAddons(); + break; + } else { + c->m_orFilters += newcat->orFilters(); + c->m_notFilters += newcat->notFilters(); + c->m_plugins.unite(newcat->m_plugins); + Q_FOREACH (Category* nc, newcat->subCategories()) { + nc->setParent(c); + addSubcategory(c->m_subCategories, nc); + } + delete newcat; + return; + } + } + } + list << newcat; +} + +bool Category::blacklistPlugins(const QSet& pluginNames) +{ + for(QVector::iterator it = m_subCategories.begin(), itEnd = m_subCategories.end(); it!=itEnd; ) { + if ((*it)->blacklistPlugins(pluginNames)) { + delete *it; + it = m_subCategories.erase(it); + } else + ++it; + } + m_plugins.subtract(pluginNames); + + return m_plugins.isEmpty(); +} + +QUrl Category::decoration() const +{ + if (m_decoration.isEmpty()) { + Category* c = qobject_cast(parent()); + return c ? c->decoration() : QUrl(); + } else { + Q_ASSERT(!m_decoration.isLocalFile() || QFile::exists(m_decoration.toLocalFile())); + return m_decoration; + } +} + +QVariantList Category::subCategoriesVariant() const +{ + QVariantList ret; + ret.reserve(m_subCategories.count()); + for(Category* cat : m_subCategories) { + ret.append(QVariant::fromValue(cat)); + } + return ret; +} + +bool Category::contains(Category* cat) const +{ + const bool ret = cat == this || (cat && contains(qobject_cast(cat->parent()))); + return ret; +} + +bool Category::contains(const QVariantList& cats) const +{ + bool ret = false; + for(auto itCat : cats) { + if (contains(qobject_cast(itCat.value()))) { + ret = true; + break; + } + } + return ret; +} diff --git a/libdiscover/Category/Category.h b/libdiscover/Category/Category.h new file mode 100644 index 0000000..204e0e9 --- /dev/null +++ b/libdiscover/Category/Category.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef CATEGORY_H +#define CATEGORY_H + +#include +#include +#include +#include +#include + +#include "discovercommon_export.h" + +class QDomNode; + +enum FilterType { + InvalidFilter, + CategoryFilter, + PkgSectionFilter, + PkgWildcardFilter, + PkgNameFilter, + AppstreamIdWildcardFilter +}; + +class DISCOVERCOMMON_EXPORT Category : public QObject +{ +Q_OBJECT +public: + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString icon READ icon CONSTANT) + Q_PROPERTY(bool shouldShowTechnical READ shouldShowTechnical CONSTANT) + Q_PROPERTY(QObject* parent READ parent CONSTANT) + Q_PROPERTY(QUrl decoration READ decoration CONSTANT) + Q_PROPERTY(QVariantList subcategories READ subCategoriesVariant CONSTANT) + explicit Category(QSet pluginNames, QObject* parent = nullptr); + ~Category() override; + + QString name() const; + QString icon() const; + QVector > andFilters() const; + QVector > orFilters() const; + QVector > notFilters() const; + bool shouldShowTechnical() const; + QVector subCategories() const; + QVariantList subCategoriesVariant() const; + + static void addSubcategory(QVector& list, Category* cat); + void parseData(const QString& path, const QDomNode& data); + bool blacklistPlugins(const QSet& pluginName); + bool isAddons() const { return m_isAddons; } + QUrl decoration() const; + + Q_SCRIPTABLE bool contains(Category* cat) const; + Q_SCRIPTABLE bool contains(const QVariantList &cats) const; + +private: + QString m_name; + QString m_iconString; + QUrl m_decoration; + QVector > m_andFilters; + QVector > m_orFilters; + QVector > m_notFilters; + bool m_showTechnical; + QVector m_subCategories; + + QVector > parseIncludes(const QDomNode &data); + QSet m_plugins; + bool m_isAddons = false; +}; +Q_DECLARE_METATYPE(QList) + +#endif diff --git a/libdiscover/Category/CategoryModel.cpp b/libdiscover/Category/CategoryModel.cpp new file mode 100644 index 0000000..8e964c4 --- /dev/null +++ b/libdiscover/Category/CategoryModel.cpp @@ -0,0 +1,161 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +// Own includes +#include "CategoryModel.h" +#include "Category.h" +#include "CategoriesReader.h" +#include +#include + +Q_GLOBAL_STATIC_WITH_ARGS(QVector, s_categories, (CategoriesReader().populateCategories())) + +CategoryModel::CategoryModel(QObject* parent) + : QAbstractListModel(parent) +{ +} + +QHash< int, QByteArray > CategoryModel::roleNames() const +{ + QHash< int, QByteArray > names = QAbstractItemModel::roleNames(); + names[CategoryRole] = "category"; + return names; +} + +bool lessThan(Category* a, Category* b) +{ + if (a->isAddons() == b->isAddons()) + return QCollator().compare(a->name(), b->name()) < 0; + else + return b->isAddons(); +} + +void CategoryModel::setCategories(const QList &categoryList) +{ + beginResetModel(); + m_categories = categoryList; + std::sort(m_categories.begin(), m_categories.end(), lessThan); + endResetModel(); +} + +void CategoryModel::setCategories(const QVariantList& categoryList) +{ + QList cats; + foreach(const QVariant &cat, categoryList) + cats += cat.value(); + + setCategories(cats); +} + +void CategoryModel::categoryDeleted(QObject* cat) +{ + auto idx = m_categories.indexOf(static_cast(cat)); + if (idx >= 0) { + beginRemoveRows(QModelIndex(), idx, idx); + m_categories.removeAt(idx); + endRemoveRows(); + } +} + +Category* CategoryModel::categoryForRow(int row) +{ + return qobject_cast(m_categories.at(row)); +} + +static Category* recFindCategory(Category* root, const QString& name) +{ + if(root->name()==name) + return root; + else { + const auto subs = root->subCategories(); + Q_FOREACH (Category* c, subs) { + Category* ret = recFindCategory(c, name); + if(ret) + return ret; + } + } + return nullptr; +} + +QList CategoryModel::rootCategories() +{ + return s_categories->toList(); +} + +Category* CategoryModel::findCategoryByName(const QString& name) +{ + const auto cats = *s_categories; + Q_FOREACH (Category* cat, cats) { + Category* ret = recFindCategory(cat, name); + if(ret) + return ret; + } + return nullptr; +} + +void CategoryModel::blacklistPlugin(const QString& name) +{ + const QSet plugins = {name}; + for(auto it = s_categories->begin(), itEnd = s_categories->end(); it!=itEnd; ) { + if ((*it)->blacklistPlugins(plugins)) { + delete *it; + it = s_categories->erase(it); + } else + ++it; + } +} + +void CategoryModel::resetCategories() +{ + setCategories(rootCategories()); +} + +int CategoryModel::rowCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : m_categories.count(); +} + +QVariant CategoryModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid() || index.row()<0 || index.row() >= m_categories.count()) + return {}; + + Category* c = m_categories[index.row()]; + Q_ASSERT(c); + + switch (role) { + case Qt::DisplayRole: + return c->name(); + case Qt::DecorationRole: + return c->icon(); + case CategoryRole: + return QVariant::fromValue(c); + } + return {}; +} + +QVariantList CategoryModel::categories() const +{ + QVariantList ret; + for(Category* cat : m_categories) { + ret.append(QVariant::fromValue(cat)); + } + return ret; +} diff --git a/libdiscover/Category/CategoryModel.h b/libdiscover/Category/CategoryModel.h new file mode 100644 index 0000000..daa8816 --- /dev/null +++ b/libdiscover/Category/CategoryModel.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef CATEGORYMODEL_H +#define CATEGORYMODEL_H + +#include +#include +#include "Category.h" + +#include "discovercommon_export.h" + +class DISCOVERCOMMON_EXPORT CategoryModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(QVariantList categories READ categories WRITE setCategories NOTIFY categoryChanged) + public: + enum CategoryModelRole { + CategoryRole = Qt::UserRole + 1 + }; + + explicit CategoryModel(QObject* parent = nullptr); + + Category* categoryForRow(int row); + + QHash< int, QByteArray > roleNames() const override; + + Q_SCRIPTABLE static Category* findCategoryByName(const QString& name); + static void blacklistPlugin(const QString& name); + static QList rootCategories(); + + void setCategories(const QList &categoryList); + void setCategories(const QVariantList &categoryList); + QVariantList categories() const; + Q_SCRIPTABLE void resetCategories(); + + QVariant data(const QModelIndex & index, int role) const override; + int rowCount(const QModelIndex & parent) const override; + + Q_SIGNALS: + void categoryChanged(); + + private: + void categoryDeleted(QObject* cat); + + QList m_categories; +}; + +#endif // CATEGORYMODEL_H diff --git a/libdiscover/DiscoverBackendsFactory.cpp b/libdiscover/DiscoverBackendsFactory.cpp new file mode 100644 index 0000000..9b6be37 --- /dev/null +++ b/libdiscover/DiscoverBackendsFactory.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "DiscoverBackendsFactory.h" +#include "resources/AbstractResourcesBackend.h" +#include "resources/ResourcesModel.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Q_GLOBAL_STATIC(QStringList, s_requestedBackends) + +DiscoverBackendsFactory::DiscoverBackendsFactory() +{} + +AbstractResourcesBackend* DiscoverBackendsFactory::backend(const QString& name) const +{ + if (QDir::isAbsolutePath(name) && QStandardPaths::isTestModeEnabled()) { + QString path = name; + return backendForFile(path, QFileInfo(name).fileName()); + } else { + QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/backends/%1.desktop").arg(name)); + return backendForFile(path, name); + } +} + +AbstractResourcesBackend* DiscoverBackendsFactory::backendForFile(const QString& path, const QString& name) const +{ + Q_ASSERT(!path.isEmpty()); + KDesktopFile cfg(path); + KConfigGroup group = cfg.group("Desktop Entry"); + QString libname = group.readEntry("X-KDE-Library", QString()); + QPluginLoader* loader = new QPluginLoader(QStringLiteral("discover/") + libname, ResourcesModel::global()); + + // qDebug() << "trying to load plugin:" << loader->fileName(); + AbstractResourcesBackendFactory* f = qobject_cast(loader->instance()); + if(!f) { + qWarning() << "error loading" << path << loader->errorString() << loader->metaData(); + return nullptr; + } + AbstractResourcesBackend* instance = f->newInstance(ResourcesModel::global()); + if(!instance) { + qWarning() << "Couldn't find the backend: " << path << "among" << allBackendNames(false) << "because" << loader->errorString(); + return instance; + } + instance->setName(name); + instance->setMetaData(path); + + return instance; +} + +QStringList DiscoverBackendsFactory::allBackendNames(bool whitelist) const +{ + if (whitelist) { + QStringList whitelist = *s_requestedBackends; + if (!whitelist.isEmpty()) + return whitelist; + } + + QStringList ret; + QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/backends/"), QStandardPaths::LocateDirectory); + foreach (const QString& dir, dirs) { + QDir d(dir); + foreach(const QFileInfo& file, d.entryInfoList(QDir::Files)) { + if (file.baseName()!= QLatin1String("dummy-backend")) { + ret.append(file.baseName()); + } + } + } + + return ret; +} + +QList DiscoverBackendsFactory::allBackends() const +{ + QList ret; + QStringList names = allBackendNames(); + foreach(const QString& name, names) + ret += backend(name); + + ret.removeAll(nullptr); + + if(ret.isEmpty()) + qWarning() << "Didn't find any Discover backend!"; + return ret; +} + +int DiscoverBackendsFactory::backendsCount() const +{ + return allBackendNames().count(); +} + +void DiscoverBackendsFactory::setupCommandLine(QCommandLineParser* parser) +{ + parser->addOption(QCommandLineOption(QStringLiteral("listbackends"), i18n("List all the available backends."))); + parser->addOption(QCommandLineOption(QStringLiteral("backends"), i18n("List all the backends we'll want to have loaded, separated by coma ','."), QStringLiteral("names"))); +} + +void DiscoverBackendsFactory::processCommandLine(QCommandLineParser* parser, bool test) +{ + *s_requestedBackends = test ? QStringList{ QStringLiteral("dummy-backend") } : parser->value(QStringLiteral("backends")).split(QLatin1Char(','), QString::SkipEmptyParts); + if(parser->isSet(QStringLiteral("listbackends"))) { + fprintf(stdout, "%s", qPrintable(i18n("Available backends:\n"))); + DiscoverBackendsFactory f; + foreach(const QString& name, f.allBackendNames(false)) + fprintf(stdout, " * %s\n", qPrintable(name)); + qApp->exit(0); + } +} diff --git a/libdiscover/DiscoverBackendsFactory.h b/libdiscover/DiscoverBackendsFactory.h new file mode 100644 index 0000000..9d68bb4 --- /dev/null +++ b/libdiscover/DiscoverBackendsFactory.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef DISCOVERBACKENDSFACTORY_H +#define DISCOVERBACKENDSFACTORY_H + +#include "discovercommon_export.h" +#include + +class QCommandLineParser; +class QStringList; +class KPluginInfo; +class AbstractResourcesBackend; + +class DISCOVERCOMMON_EXPORT DiscoverBackendsFactory +{ +public: + DiscoverBackendsFactory(); + + AbstractResourcesBackend* backendForFile(const QString& path, const QString& name) const; + AbstractResourcesBackend* backend(const QString& name) const; + QList allBackends() const; + QStringList allBackendNames(bool whitelist = true) const; + int backendsCount() const; + + static void setupCommandLine(QCommandLineParser* parser); + static void processCommandLine(QCommandLineParser* parser, bool test); +}; + +#endif // MUONBACKENDSFACTORY_H diff --git a/libdiscover/MessageActionsModel.cpp b/libdiscover/MessageActionsModel.cpp new file mode 100644 index 0000000..fe7860e --- /dev/null +++ b/libdiscover/MessageActionsModel.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "MessageActionsModel.h" +#include "resources/ResourcesModel.h" +#include + +MessageActionsModel::MessageActionsModel(QObject* parent) + : QAbstractListModel(parent) + , m_priority(-1) +{ + connect(ResourcesModel::global(), &ResourcesModel::backendsChanged, this, &MessageActionsModel::reload); +} + +QHash< int, QByteArray > MessageActionsModel::roleNames() const +{ + return { { Qt::UserRole, "action" }}; +} + +QVariant MessageActionsModel::data(const QModelIndex& index, int role) const +{ + if(!index.isValid() || role!=Qt::UserRole) + return QVariant(); + return QVariant::fromValue(m_actions[index.row()]); +} + +int MessageActionsModel::rowCount(const QModelIndex& parent) const +{ + return parent.isValid() ? 0 : m_actions.count(); +} + +void MessageActionsModel::reload() +{ + const auto actions = ResourcesModel::global()->messageActions(); + if (actions == m_actions) + return; + + beginResetModel(); + m_actions = actions; + if (m_priority>=0) { + for(auto it=m_actions.begin(); it!=m_actions.end(); ) { + if ((*it)->priority() == m_priority) { + ++it; + } else + it = m_actions.erase(it); + } + } + endResetModel(); +} + +int MessageActionsModel::filterPriority() const +{ + return m_priority; +} + +void MessageActionsModel::setFilterPriority(int p) +{ + if (m_priority != p) { + m_priority = p; + reload(); + } +} diff --git a/libdiscover/MessageActionsModel.h b/libdiscover/MessageActionsModel.h new file mode 100644 index 0000000..a004deb --- /dev/null +++ b/libdiscover/MessageActionsModel.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef MESSAGEACTIONSMODEL_H +#define MESSAGEACTIONSMODEL_H + +#include +#include "discovercommon_export.h" + +class QAction; + +class DISCOVERCOMMON_EXPORT MessageActionsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(int filterPriority READ filterPriority WRITE setFilterPriority) + public: + explicit MessageActionsModel(QObject* parent = nullptr); + + QHash roleNames() const override; + QVariant data(const QModelIndex& index, int role) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + + void setFilterPriority(int p); + int filterPriority() const; + + private: + void reload(); + + QList m_actions; + int m_priority; +}; + +#endif diff --git a/libdiscover/MuonDataSources.kcfgc b/libdiscover/MuonDataSources.kcfgc new file mode 100644 index 0000000..d1acf46 --- /dev/null +++ b/libdiscover/MuonDataSources.kcfgc @@ -0,0 +1,6 @@ +File=muondatasources.kcfg +ClassName=MuonDataSources +Singleton=true +Mutators=false +IncludeFiles=\"discovercommon_export.h\" +Visibility=DISCOVERCOMMON_EXPORT diff --git a/libdiscover/ReviewsBackend/AbstractLoginBackend.cpp b/libdiscover/ReviewsBackend/AbstractLoginBackend.cpp new file mode 100644 index 0000000..a90e543 --- /dev/null +++ b/libdiscover/ReviewsBackend/AbstractLoginBackend.cpp @@ -0,0 +1,25 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "AbstractLoginBackend.h" + +AbstractLoginBackend::AbstractLoginBackend(QObject* parent) + : QObject(parent) +{} diff --git a/libdiscover/ReviewsBackend/AbstractLoginBackend.h b/libdiscover/ReviewsBackend/AbstractLoginBackend.h new file mode 100644 index 0000000..ff5d723 --- /dev/null +++ b/libdiscover/ReviewsBackend/AbstractLoginBackend.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef ABSTRACTLOGINBACKEND_H +#define ABSTRACTLOGINBACKEND_H + +#include +#include "discovercommon_export.h" + +class DISCOVERCOMMON_EXPORT AbstractLoginBackend : public QObject +{ + Q_OBJECT + public: + explicit AbstractLoginBackend(QObject* parent=nullptr); + virtual bool hasCredentials() const = 0; + virtual QString displayName() const = 0; + + public Q_SLOTS: + virtual void login() = 0; + virtual void registerAndLogin() = 0; + virtual void logout() = 0; + virtual QByteArray token() const = 0; + virtual QByteArray tokenSecret() const = 0; + virtual QByteArray consumerKey() const = 0; + virtual QByteArray consumerSecret() const = 0; + + Q_SIGNALS: + void connectionStateChanged(); +}; + +#endif // ABSTRACTLOGINBACKEND_H diff --git a/libdiscover/ReviewsBackend/AbstractReviewsBackend.cpp b/libdiscover/ReviewsBackend/AbstractReviewsBackend.cpp new file mode 100644 index 0000000..401f85b --- /dev/null +++ b/libdiscover/ReviewsBackend/AbstractReviewsBackend.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez . * + ***************************************************************************/ + +#include "AbstractReviewsBackend.h" + +AbstractReviewsBackend::AbstractReviewsBackend(QObject* parent) + : QObject(parent) +{} + +bool AbstractReviewsBackend::isReviewable() const +{ + return true; +} + +QString AbstractReviewsBackend::errorMessage() const +{ + return QString(); +} diff --git a/libdiscover/ReviewsBackend/AbstractReviewsBackend.h b/libdiscover/ReviewsBackend/AbstractReviewsBackend.h new file mode 100644 index 0000000..bcece0c --- /dev/null +++ b/libdiscover/ReviewsBackend/AbstractReviewsBackend.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez . * + ***************************************************************************/ + +#ifndef ABSTRACTREVIEWSBACKEND_H +#define ABSTRACTREVIEWSBACKEND_H + +#include + +#include "discovercommon_export.h" + +class Rating; +class AbstractResource; +class Review; + +class DISCOVERCOMMON_EXPORT AbstractReviewsBackend : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool isReviewable READ isReviewable CONSTANT) + Q_PROPERTY(bool hasCredentials READ hasCredentials NOTIFY loginStateChanged) + Q_PROPERTY(QString name READ userName NOTIFY loginStateChanged) + public: + explicit AbstractReviewsBackend(QObject* parent = nullptr); + + virtual QString userName() const = 0; + virtual bool hasCredentials() const = 0; + + Q_SCRIPTABLE virtual Rating *ratingForApplication(AbstractResource *app) const = 0; + Q_INVOKABLE virtual QString errorMessage() const; + public Q_SLOTS: + virtual void login() = 0; + virtual void registerAndLogin() = 0; + virtual void logout() = 0; + virtual void submitUsefulness(Review* r, bool useful) = 0; + virtual void submitReview(AbstractResource* app, const QString& summary, + const QString& review_text, const QString& rating) = 0; + virtual void deleteReview(Review* r) = 0; + virtual void flagReview(Review* r, const QString& reason, const QString &text) = 0; + virtual bool isFetching() const = 0; + virtual void fetchReviews(AbstractResource* app, int page=1) = 0; + virtual bool isReviewable() const; + + Q_SIGNALS: + void reviewsReady(AbstractResource *app, const QList &); + void loginStateChanged(); +}; + +#endif // ABSTRACTREVIEWSBACKEND_H diff --git a/libdiscover/ReviewsBackend/PopConParser.cpp b/libdiscover/ReviewsBackend/PopConParser.cpp new file mode 100644 index 0000000..52553bd --- /dev/null +++ b/libdiscover/ReviewsBackend/PopConParser.cpp @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright © 2016 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "PopConParser.h" +#include "Rating.h" +#include +#include + +QHash PopConParser::parsePopcon(QObject* parent, QIODevice* dev) +{ + QHash ratings; + QRegularExpression rx(QStringLiteral("^Package: ([^ ]+) +(\\d+) +(\\d+) +(\\d+) +(\\d+)\\s*$")); + QString buff; + buff.resize(512); + QTextStream stream(dev); + while(stream.readLineInto(&buff, 0)) { + auto match = rx.match(buff); + if (!match.hasMatch()) + continue; + + const QString pkgName = match.captured(1); + + //according to popcon spec + const int inst = match.capturedRef(2).toInt(); + const int vote = match.capturedRef(3).toInt(); + const int old = match.capturedRef(4).toInt(); + const int recent = match.capturedRef(5).toInt(); + + Rating *rating = new Rating(pkgName, inst, vote, old, recent); + if (!rating->ratingCount()) { + delete rating; + continue; + } + rating->setParent(parent); + ratings[rating->packageName()] = rating; + } + + return ratings; +} diff --git a/libdiscover/ReviewsBackend/PopConParser.h b/libdiscover/ReviewsBackend/PopConParser.h new file mode 100644 index 0000000..a93ccff --- /dev/null +++ b/libdiscover/ReviewsBackend/PopConParser.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright © 2016 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef POPCONPARSER_H +#define POPCONPARSER_H + +#include +#include +#include "discovercommon_export.h" + +class Rating; + +namespace PopConParser +{ + DISCOVERCOMMON_EXPORT QHash parsePopcon(QObject* parent, QIODevice* device); +} + +#endif diff --git a/libdiscover/ReviewsBackend/Rating.cpp b/libdiscover/ReviewsBackend/Rating.cpp new file mode 100644 index 0000000..1292cb9 --- /dev/null +++ b/libdiscover/ReviewsBackend/Rating.cpp @@ -0,0 +1,163 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "Rating.h" +#include +#include +#include + +inline double fastPow(double a, double b) { + union { + double d; + int x[2]; + } u = { a }; + +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + u.x[1] = (int)(b * (u.x[1] - 1072632447) + 1072632447); + u.x[0] = 0; +#else + u.x[1] = 0; + u.x[0] = (int)(b * (u.x[1] - 1072632447) + 1072632447); +#endif + + return u.d; +} + +// Converted from a Ruby example, returns an inverse normal distribution +double pnormaldist(double qn) +{ + double b[] = {1.570796288, 0.03706987906, -0.8364353589e-3, -0.2250947176e-3, 0.6841218299e-5, 0.5824238515e-5, -0.104527497e-5, 0.8360937017e-7, -0.3231081277e-8, 0.3657763036e-10, 0.6936233982e-12}; + + if(qn < 0.0 || 1.0 < qn) + return 0.0; + + if(qn == 0.5) + return 0.0; + + double w1 = qn; + if(qn > 0.5) + w1 = 1.0 - w1; + double w3 = -qLn(4.0 * w1 * (1.0 - w1)); + w1 = b[0]; + + for(int i = 1; i < 11; i++) + w1 += b[i] * fastPow(w3,i); + + if(qn > 0.5) + return qSqrt(w1*w3); + return -qSqrt(w1*w3); +} + +double wilson_score(int pos, int n, double power = 0.2) +{ + if (n == 0) + return 0; + + double z = pnormaldist(1 - power / 2); + double phat = 1.0 * pos / n; + return (phat + z * z / (2 * n) - z * qSqrt( + (phat * (1 - phat) + z * z / (4 * n)) / n)) / (1 + z * z / n); +} + +double dampenedRating(const QVector &ratings, double power = 0.1) +{ + if (ratings.count() != 5) + return 0; + + int tot_ratings = 0; + Q_FOREACH (const int rating, ratings) + tot_ratings = rating + tot_ratings; + + double sum_scores = 0.0; + + for (int i = 0; i < ratings.count(); i++) { + const int rating = ratings.at(i); + double ws = wilson_score(rating, tot_ratings, power); + sum_scores = sum_scores + float((i + 1) - 3) * ws; + } + + return sum_scores + 3; +} + +Rating::Rating(const QVariantMap &data) + : Rating(data.value(QStringLiteral("package_name")).toString(), + data.value(QStringLiteral("ratings_total")).toULongLong(), data.value(QStringLiteral("ratings_average")).toDouble() * 2, data.value(QStringLiteral("histogram")).toString()) +{ +} + +Rating::Rating(QString packageName, int inst, int /*vote*/, int /*old*/, int /*recent*/) + : QObject() + , m_packageName(std::move(packageName)) + , m_ratingCount(inst) + , m_rating(0) + , m_ratingPoints(0) + , m_sortableRating(m_rating) +{ +} + +Rating::Rating(const QString& packageName, quint64 ratingCount, int rating, const QString& histogram) + : QObject() + , m_packageName(packageName) + , m_ratingCount(ratingCount) + , m_rating(rating) + , m_ratingPoints(0) + , m_sortableRating(0) +{ + Q_ASSERT(rating <= 10 && rating>=-1); + + const auto histo = histogram.midRef(1,histogram.size()-2).split(QStringLiteral(", ")); + QVector spread; + spread.reserve(histo.size()); + + for(int i=0; i * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef RATING_H +#define RATING_H + +#include +#include + +#include "discovercommon_export.h" + +class DISCOVERCOMMON_EXPORT Rating : public QObject +{ +Q_OBJECT +Q_PROPERTY(double sortableRating READ sortableRating CONSTANT) +Q_PROPERTY(int rating READ rating CONSTANT) +Q_PROPERTY(int ratingPoints READ ratingPoints CONSTANT) +Q_PROPERTY(quint64 ratingCount READ ratingCount CONSTANT) +public: + explicit Rating(const QVariantMap &data); + explicit Rating(const QString& packageName, quint64 ratingCount, int rating, const QString& histogram); + explicit Rating(QString packageName, int inst, int vote, int old, int recent); + ~Rating() override; + + QString packageName() const; + quint64 ratingCount() const; + // 0.0 - 10.0 ranged rating + int rating() const; + int ratingPoints() const; + // Returns a dampened rating calculated with the Wilson Score Interval algorithm + double sortableRating() const; + +private: + const QString m_packageName; + const quint64 m_ratingCount; + const int m_rating; + int m_ratingPoints; + double m_sortableRating; +}; + +#endif diff --git a/libdiscover/ReviewsBackend/Review.cpp b/libdiscover/ReviewsBackend/Review.cpp new file mode 100644 index 0000000..74f118a --- /dev/null +++ b/libdiscover/ReviewsBackend/Review.cpp @@ -0,0 +1,128 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "Review.h" +#include + +Review::Review(QString name, QString pkgName, QString language, QString summary, + QString reviewText, QString userName, const QDateTime& date, bool show, quint64 id, + int rating, int usefulTotal, int usefulFavorable, QString packageVersion) + : m_appName(std::move(name)) + , m_creationDate(date) + , m_shouldShow(show) + , m_id(id) + , m_language(std::move(language)) + , m_packageName(std::move(pkgName)) + , m_rating(rating) + , m_reviewText(std::move(reviewText)) + , m_reviewer(std::move(userName)) + , m_usefulnessTotal(usefulTotal) + , m_usefulnessFavorable(usefulFavorable) + , m_usefulChoice(ReviewsModel::None) + , m_summary(std::move(summary)) + , m_packageVersion(std::move(packageVersion)) +{} + +Review::~Review() = default; + +bool Review::operator<(const Review &other) const +{ + return m_creationDate < other.m_creationDate; +} + +bool Review::operator>(const Review &other) const +{ + return m_creationDate > other.m_creationDate; +} + +QString Review::applicationName() const +{ + return m_appName; +} + +QString Review::packageName() const +{ + return m_packageName; +} + +QString Review::packageVersion() const +{ + return m_packageVersion; +} + +QString Review::language() const +{ + return m_language; +} + +QString Review::summary() const +{ + return m_summary; +} + +QString Review::reviewText() const +{ + return m_reviewText; +} + +QString Review::reviewer() const +{ + return m_reviewer; +} + +QDateTime Review::creationDate() const +{ + return m_creationDate; +} + +bool Review::shouldShow() const +{ + return m_shouldShow; +} + +quint64 Review::id() const +{ + return m_id; +} + +int Review::rating() const +{ + return m_rating; +} + +int Review::usefulnessTotal() const +{ + return m_usefulnessTotal; +} + +int Review::usefulnessFavorable() const +{ + return m_usefulnessFavorable; +} + +ReviewsModel::UserChoice Review::usefulChoice() const +{ + return m_usefulChoice; +} + +void Review::setUsefulChoice(ReviewsModel::UserChoice useful) +{ + m_usefulChoice = useful; +} diff --git a/libdiscover/ReviewsBackend/Review.h b/libdiscover/ReviewsBackend/Review.h new file mode 100644 index 0000000..7f69bf2 --- /dev/null +++ b/libdiscover/ReviewsBackend/Review.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef REVIEW_H +#define REVIEW_H + +#include +#include + +#include "ReviewsModel.h" +#include "discovercommon_export.h" + +class AbstractResource; + +class DISCOVERCOMMON_EXPORT Review +{ +public: + Review(QString name, QString pkgName, QString language, QString summary, + QString reviewText, QString userName, const QDateTime& date, bool show, quint64 id, + int rating, int usefulTotal, int usefulFavorable, QString packageVersion); + ~Review(); + + // Creation date determines greater than/less than + bool operator<(const Review &rhs) const; + bool operator>(const Review &rhs) const; + + QString applicationName() const; + QString packageName() const; + QString packageVersion() const; + QString language() const; + QString summary() const; + QString reviewText() const; + QString reviewer() const; + QDateTime creationDate() const; + bool shouldShow() const; + quint64 id() const; + int rating() const; + int usefulnessTotal() const; + int usefulnessFavorable() const; + ReviewsModel::UserChoice usefulChoice() const; + void setUsefulChoice(ReviewsModel::UserChoice useful); + +private: + QString m_appName; + QDateTime m_creationDate; + bool m_shouldShow; + quint64 m_id; + QString m_language; + QString m_packageName; + int m_rating; + QString m_reviewText; + QString m_reviewer; + int m_usefulnessTotal; + int m_usefulnessFavorable; + ReviewsModel::UserChoice m_usefulChoice; + QString m_summary; + QString m_packageVersion; +}; + +#endif diff --git a/libdiscover/ReviewsBackend/ReviewsModel.cpp b/libdiscover/ReviewsBackend/ReviewsModel.cpp new file mode 100644 index 0000000..d630dbc --- /dev/null +++ b/libdiscover/ReviewsBackend/ReviewsModel.cpp @@ -0,0 +1,186 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ReviewsModel.h" +#include +#include +#include +#include +#include +#include + +ReviewsModel::ReviewsModel(QObject* parent) + : QAbstractListModel(parent) + , m_app(nullptr) + , m_backend(nullptr) + , m_lastPage(0) + , m_canFetchMore(true) +{} + +ReviewsModel::~ReviewsModel() +{ + qDeleteAll(m_reviews); +} + +QHash< int, QByteArray > ReviewsModel::roleNames() const +{ + QHash roles = QAbstractItemModel::roleNames(); + roles.insert(ShouldShow, "shouldShow"); + roles.insert(Reviewer, "reviewer"); + roles.insert(CreationDate, "date"); + roles.insert(UsefulnessTotal, "usefulnessTotal"); + roles.insert(UsefulnessFavorable, "usefulnessFavorable"); + roles.insert(UsefulChoice, "usefulChoice"); + roles.insert(Rating, "rating"); + roles.insert(Summary, "summary"); + return roles; +} + +QVariant ReviewsModel::data(const QModelIndex& index, int role) const +{ + if(!index.isValid()) + return QVariant(); + switch(role) { + case Qt::DisplayRole: + return m_reviews.at(index.row())->reviewText(); + case ShouldShow: + return m_reviews.at(index.row())->shouldShow(); + case Reviewer: + return m_reviews.at(index.row())->reviewer(); + case CreationDate: + return m_reviews.at(index.row())->creationDate(); + case UsefulnessTotal: + return m_reviews.at(index.row())->usefulnessTotal(); + case UsefulnessFavorable: + return m_reviews.at(index.row())->usefulnessFavorable(); + case UsefulChoice: + return m_reviews.at(index.row())->usefulChoice(); + case Rating: + return m_reviews.at(index.row())->rating(); + case Summary: + return m_reviews.at(index.row())->summary(); + } + return QVariant(); +} + +int ReviewsModel::rowCount(const QModelIndex& parent) const +{ + if(parent.isValid()) + return 0; + return m_reviews.count(); +} + +AbstractResource* ReviewsModel::resource() const +{ + return m_app; +} + +AbstractReviewsBackend* ReviewsModel::backend() const +{ + return m_backend; +} + +void ReviewsModel::setResource(AbstractResource* app) +{ + if(m_app!=app) { + beginResetModel(); + qDeleteAll(m_reviews); + m_reviews.clear(); + m_lastPage = 0; + endResetModel(); + + if(m_backend) { + disconnect(m_backend, &AbstractReviewsBackend::reviewsReady, this, &ReviewsModel::addReviews); + } + m_app = app; + m_backend = app ? app->backend()->reviewsBackend() : nullptr; + if(m_backend) { + connect(m_backend, &AbstractReviewsBackend::reviewsReady, this, &ReviewsModel::addReviews); + + QMetaObject::invokeMethod(this, "restartFetching", Qt::QueuedConnection); + } + emit rowsChanged(); + emit resourceChanged(); + } +} + +void ReviewsModel::restartFetching() +{ + if(!m_app || !m_backend) + return; + + m_canFetchMore=true; + m_lastPage = 0; + fetchMore(); + emit rowsChanged(); +} + +void ReviewsModel::fetchMore(const QModelIndex& parent) +{ + if(!m_backend || !m_app || m_app->backend()->isFetching() || m_backend->isFetching() || parent.isValid() || !m_canFetchMore) + return; + + m_lastPage++; + m_backend->fetchReviews(m_app, m_lastPage); +// qDebug() << "fetching reviews... " << m_lastPage; +} + +void ReviewsModel::addReviews(AbstractResource* app, const QList& reviews) +{ + if(app!=m_app) + return; + + m_canFetchMore=!reviews.isEmpty(); +// qDebug() << "reviews arrived..." << m_lastPage << reviews.size(); + + if(!reviews.isEmpty()) { + beginInsertRows(QModelIndex(), rowCount(), rowCount()+reviews.size()-1); + m_reviews += reviews; + endInsertRows(); + emit rowsChanged(); + } +} + +bool ReviewsModel::canFetchMore(const QModelIndex& /*parent*/) const +{ + return m_canFetchMore; +} + +void ReviewsModel::markUseful(int row, bool useful) +{ + Review* r = m_reviews[row]; + r->setUsefulChoice(useful ? Yes : No); +// qDebug() << "submitting usefulness" << r->applicationName() << r->id() << useful; + m_backend->submitUsefulness(r, useful); + const QModelIndex ind = index(row, 0, QModelIndex()); + emit dataChanged(ind, ind, {UsefulnessTotal, UsefulnessFavorable, UsefulChoice}); +} + +void ReviewsModel::deleteReview(int row) +{ + Review* r = m_reviews[row]; + m_backend->deleteReview(r); +} + +void ReviewsModel::flagReview(int row, const QString& reason, const QString& text) +{ + Review* r = m_reviews[row]; + m_backend->flagReview(r, reason, text); +} diff --git a/libdiscover/ReviewsBackend/ReviewsModel.h b/libdiscover/ReviewsBackend/ReviewsModel.h new file mode 100644 index 0000000..bd25cf2 --- /dev/null +++ b/libdiscover/ReviewsBackend/ReviewsModel.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef REVIEWSMODEL_H +#define REVIEWSMODEL_H + +#include +#include "discovercommon_export.h" + +class Review; +class AbstractResource; +class AbstractReviewsBackend; +class DISCOVERCOMMON_EXPORT ReviewsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(AbstractReviewsBackend* backend READ backend) + Q_PROPERTY(AbstractResource* resource READ resource WRITE setResource NOTIFY resourceChanged) + Q_PROPERTY(int count READ rowCount NOTIFY rowsChanged) + public: + enum Roles { + ShouldShow=Qt::UserRole+1, + Reviewer, + CreationDate, + UsefulnessTotal, + UsefulnessFavorable, + UsefulChoice, + Rating, + Summary + }; + enum UserChoice { + None, + Yes, + No + }; + Q_ENUM(UserChoice) + + explicit ReviewsModel(QObject* parent = nullptr); + ~ReviewsModel() override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + + AbstractReviewsBackend* backend() const; + void setResource(AbstractResource* app); + AbstractResource* resource() const; + void fetchMore(const QModelIndex& parent=QModelIndex()) override; + bool canFetchMore(const QModelIndex& /*parent*/) const override; + QHash roleNames() const override; + + public Q_SLOTS: + void deleteReview(int row); + void flagReview(int row, const QString& reason, const QString& text); + void markUseful(int row, bool useful); + + private Q_SLOTS: + void addReviews(AbstractResource* app, const QList& reviews); + void restartFetching(); + + Q_SIGNALS: + void rowsChanged(); + void resourceChanged(); + + private: + AbstractResource* m_app; + AbstractReviewsBackend* m_backend; + QList m_reviews; + int m_lastPage; + bool m_canFetchMore; +}; + +#endif // REVIEWSMODEL_H + diff --git a/libdiscover/ScreenshotsModel.cpp b/libdiscover/ScreenshotsModel.cpp new file mode 100644 index 0000000..a31446d --- /dev/null +++ b/libdiscover/ScreenshotsModel.cpp @@ -0,0 +1,100 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ScreenshotsModel.h" +#include +#include +// #include + +ScreenshotsModel::ScreenshotsModel(QObject* parent) + : QAbstractListModel(parent) + , m_resource(nullptr) +{} + +QHash< int, QByteArray > ScreenshotsModel::roleNames() const +{ + QHash roles = QAbstractItemModel::roleNames(); + roles.insert(ThumbnailUrl, "small_image_url"); + roles.insert(ScreenshotUrl, "large_image_url"); + return roles; +} + +void ScreenshotsModel::setResource(AbstractResource* res) +{ + if(res == m_resource) + return; + + if(m_resource) { + disconnect(m_resource, &AbstractResource::screenshotsFetched, this, &ScreenshotsModel::screenshotsFetched); + } + m_resource = res; + + if(res) { + connect(m_resource, &AbstractResource::screenshotsFetched, this, &ScreenshotsModel::screenshotsFetched); + res->fetchScreenshots(); + } else + qWarning() << "empty resource!"; +} + +AbstractResource* ScreenshotsModel::resource() const +{ + return m_resource; +} + +void ScreenshotsModel::screenshotsFetched(const QList< QUrl >& thumbnails, const QList< QUrl >& screenshots) +{ + Q_ASSERT(thumbnails.count()==screenshots.count()); + if (thumbnails.isEmpty()) + return; + + beginInsertRows(QModelIndex(), m_thumbnails.size(), m_thumbnails.size()+thumbnails.size()-1); + m_thumbnails += thumbnails; + m_screenshots += screenshots; + endInsertRows(); + emit countChanged(); +} + +QVariant ScreenshotsModel::data(const QModelIndex& index, int role) const +{ + if(!index.isValid() || index.parent().isValid()) + return QVariant(); + + switch(role) { + case ThumbnailUrl: return m_thumbnails[index.row()]; + case ScreenshotUrl: return m_screenshots[index.row()]; + } + + return QVariant(); +} + +int ScreenshotsModel::rowCount(const QModelIndex& parent) const +{ + return !parent.isValid() ? m_screenshots.count() : 0; +} + +QUrl ScreenshotsModel::screenshotAt(int row) const +{ + return m_screenshots[row]; +} + +int ScreenshotsModel::count() const +{ + return m_screenshots.count(); +} diff --git a/libdiscover/ScreenshotsModel.h b/libdiscover/ScreenshotsModel.h new file mode 100644 index 0000000..dd3a212 --- /dev/null +++ b/libdiscover/ScreenshotsModel.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef SCREENSHOTSMODEL_H +#define SCREENSHOTSMODEL_H + +#include +#include +#include "discovercommon_export.h" + +class AbstractResource; + +class DISCOVERCOMMON_EXPORT ScreenshotsModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(AbstractResource* application READ resource WRITE setResource) + Q_PROPERTY(int count READ count NOTIFY countChanged) + public: + enum Roles { ThumbnailUrl=Qt::UserRole+1, ScreenshotUrl }; + + explicit ScreenshotsModel(QObject* parent = nullptr); + QHash roleNames() const override; + + AbstractResource* resource() const; + void setResource(AbstractResource* res); + + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + Q_SCRIPTABLE QUrl screenshotAt(int row) const; + int count() const; + + private Q_SLOTS: + void screenshotsFetched(const QList& thumbnails, const QList& screenshots); + + Q_SIGNALS: + void countChanged(); + + private: + AbstractResource* m_resource; + QList m_thumbnails; + QList m_screenshots; + +}; + +#endif // SCREENSHOTSMODEL_H diff --git a/libdiscover/Transaction/AddonList.cpp b/libdiscover/Transaction/AddonList.cpp new file mode 100644 index 0000000..0b3fbf1 --- /dev/null +++ b/libdiscover/Transaction/AddonList.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright © 2012 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "AddonList.h" + +AddonList::AddonList() +{} + +bool AddonList::isEmpty() const +{ + return m_toInstall.isEmpty() && m_toRemove.isEmpty(); +} + +QStringList AddonList::addonsToInstall() const +{ + return m_toInstall; +} + +QStringList AddonList::addonsToRemove() const +{ + return m_toRemove; +} + +void AddonList::addAddon(const QString &addon, bool toInstall) +{ + if (toInstall) { + m_toInstall.append(addon); + m_toRemove.removeAll(addon); + } else { + m_toInstall.removeAll(addon); + m_toRemove.append(addon); + } +} + +void AddonList::resetAddon(const QString &addon) +{ + m_toInstall.removeAll(addon); + m_toRemove.removeAll(addon); +} + +void AddonList::clear() +{ + m_toInstall.clear(); + m_toRemove.clear(); +} + +AddonList::State AddonList::addonState(const QString& addonName) const +{ + if(m_toInstall.contains(addonName)) + return ToInstall; + else if(m_toRemove.contains(addonName)) + return ToRemove; + else + return None; +} diff --git a/libdiscover/Transaction/AddonList.h b/libdiscover/Transaction/AddonList.h new file mode 100644 index 0000000..1f68d80 --- /dev/null +++ b/libdiscover/Transaction/AddonList.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright © 2012 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef ADDONLIST_H +#define ADDONLIST_H + +#include +#include + +#include "discovercommon_export.h" + +class DISCOVERCOMMON_EXPORT AddonList +{ +public: + enum State { + None, + ToInstall, + ToRemove + }; + AddonList(); + AddonList(const AddonList &other) = default; + + bool isEmpty() const; + QStringList addonsToInstall() const; + QStringList addonsToRemove() const; + State addonState(const QString& addonName) const; + + void addAddon(const QString &addon, bool toInstall); + void resetAddon(const QString &addon); + void clear(); + +private: + QStringList m_toInstall; + QStringList m_toRemove; +}; + +#endif // ADDONLIST_H diff --git a/libdiscover/Transaction/Transaction.cpp b/libdiscover/Transaction/Transaction.cpp new file mode 100644 index 0000000..8eacdd9 --- /dev/null +++ b/libdiscover/Transaction/Transaction.cpp @@ -0,0 +1,100 @@ +/*************************************************************************** + * Copyright © 2012 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "Transaction.h" + +#include "TransactionModel.h" +#include + +Transaction::Transaction(QObject *parent, AbstractResource *resource, + Role role, const AddonList& addons) + : QObject(parent) + , m_resource(resource) + , m_role(role) + , m_status(CommittingStatus) + , m_addons(addons) + , m_isCancellable(true) + , m_progress(0) +{ +} + +AbstractResource *Transaction::resource() const +{ + return m_resource; +} + +Transaction::Role Transaction::role() const +{ + return m_role; +} + +Transaction::Status Transaction::status() const +{ + return m_status; +} + +AddonList Transaction::addons() const +{ + return m_addons; +} + +bool Transaction::isCancellable() const +{ + return m_isCancellable; +} + +int Transaction::progress() const +{ + return m_progress; +} + +void Transaction::setStatus(Status status) +{ + if(m_status != status) { + m_status = status; + emit statusChanged(m_status); + + if (m_status == DoneStatus) { + setCancellable(false); + } + } +} + +void Transaction::setCancellable(bool isCancellable) +{ + if(m_isCancellable != isCancellable) { + m_isCancellable = isCancellable; + emit cancellableChanged(m_isCancellable); + } +} + +void Transaction::setProgress(int progress) +{ + if(m_progress != progress) { + Q_ASSERT(qBound(0, progress, 100) == progress); + m_progress = qBound(0, progress, 100); + emit progressChanged(m_progress); + } +} + +bool Transaction::isActive() const +{ + return m_status == DownloadingStatus || m_status == CommittingStatus; +} diff --git a/libdiscover/Transaction/Transaction.h b/libdiscover/Transaction/Transaction.h new file mode 100644 index 0000000..d7bc8fa --- /dev/null +++ b/libdiscover/Transaction/Transaction.h @@ -0,0 +1,167 @@ +/*************************************************************************** + * Copyright © 2012 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef TRANSACTION_H +#define TRANSACTION_H + +// Qt includes +#include + +// Own includes +#include "AddonList.h" + +#include "discovercommon_export.h" + +class AbstractResource; + +/** + * \class Transaction Transaction.h "Transaction.h" + * + * \brief This is the base class of all transactions. + * + * When there are transactions running inside Muon, the backends should + * provide the corresponding Transaction objects with proper information. + */ +class DISCOVERCOMMON_EXPORT Transaction : public QObject +{ + Q_OBJECT + + Q_PROPERTY(AbstractResource* resource READ resource CONSTANT) + Q_PROPERTY(Role role READ role CONSTANT) + Q_PROPERTY(Status status READ status NOTIFY statusChanged) + Q_PROPERTY(bool isCancellable READ isCancellable NOTIFY cancellableChanged) + Q_PROPERTY(int progress READ progress NOTIFY progressChanged) + +public: + enum Status { + /// Not queued, newly created + SetupStatus = 0, + /// Queued, but not yet run + QueuedStatus, + /// Transaction is in the downloading phase + DownloadingStatus, + /// Transaction is doing an installation/removal + CommittingStatus, + /// Transaction is done + DoneStatus + }; + Q_ENUM(Status) + + enum Role { + ///The transaction is going to install a resource + InstallRole = 0, + ///The transaction is going to remove a resource + RemoveRole, + ///The transaction is going to change the addons of a resource + ChangeAddonsRole + }; + Q_ENUM(Role) + + Transaction(QObject *parent, AbstractResource *resource, + Transaction::Role role, const AddonList &addons = {}); + + /** + * @returns the AbstractResource which this transaction works with + */ + AbstractResource *resource() const; + /** + * @returns the role which this transaction executes + */ + Role role() const; + /** + * @returns the current status + */ + Status status() const; + /** + * @returns the addons which this transaction works on + */ + AddonList addons() const; + /** + * @returns true when the transaction can be canceled + */ + bool isCancellable() const; + /** + * @returns a percentage of how much the transaction is already done + */ + int progress() const; + + /** + * Sets the status of the transaction + * @param status the new status + */ + void setStatus(Status status); + /** + * Sets whether the transaction can be canceled or not + * @param isCancellable should be true if the transaction can be canceled + */ + void setCancellable(bool isCancellable); + /** + * Sets the progress of the transaction + * @param progress this should be a percentage of how much of the transaction is already done + */ + void setProgress(int progress); + + /** + * Cancels the transaction + */ + Q_SCRIPTABLE virtual void cancel() = 0; + + /** + * @returns if the transaction is either downloading or committing + */ + bool isActive() const; + + Q_SCRIPTABLE virtual void proceed() {} + +private: + AbstractResource * const m_resource; + const Role m_role; + Status m_status; + const AddonList m_addons; + bool m_isCancellable; + int m_progress; + +Q_SIGNALS: + /** + * This gets emitted when the status of the transaction changed + */ + void statusChanged(Transaction::Status status); + /** + * This gets emitted when the ability to cancel the transaction or not changed + */ + void cancellableChanged(bool cancellable); + /** + * This gets emitted when the transaction changed the percentage of how much of it is already done + */ + void progressChanged(int progress); + + /** + * Provides a message to be shown to the user + * + * The user gets to acknowledge and proceed or cancel the transaction. + * + * @sa proceed(), cancel() + */ + void proceedRequest(const QString &title, const QString &description); + + void passiveMessage(const QString &message); +}; + +#endif // TRANSACTION_H diff --git a/libdiscover/Transaction/TransactionListener.cpp b/libdiscover/Transaction/TransactionListener.cpp new file mode 100644 index 0000000..268acdd --- /dev/null +++ b/libdiscover/Transaction/TransactionListener.cpp @@ -0,0 +1,173 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "TransactionListener.h" + +#include "TransactionModel.h" +#include +#include + +TransactionListener::TransactionListener(QObject *parent) + : QObject(parent) + , m_resource(nullptr) + , m_transaction(nullptr) +{ + connect(TransactionModel::global(), &TransactionModel::transactionAdded, this, &TransactionListener::transactionAdded); + connect(TransactionModel::global(), &TransactionModel::transactionRemoved, this, &TransactionListener::transactionRemoved); + connect(TransactionModel::global(), &TransactionModel::transactionCancelled, this, &TransactionListener::transactionCancelled); +} + +void TransactionListener::cancel() +{ + if(!isCancellable()) { + qWarning() << "cannot cancel the transaction" << m_transaction; + return; + } + m_transaction->cancel(); +} + +AbstractResource *TransactionListener::resource() const +{ + return m_resource; +} + +bool TransactionListener::isCancellable() const +{ + return m_transaction && m_transaction->isCancellable(); +} + +bool TransactionListener::isActive() const +{ + return m_transaction && m_transaction->status() != Transaction::SetupStatus; +} + +QString TransactionListener::statusText() const +{ + QModelIndex index = TransactionModel::global()->indexOf(m_resource); + + return index.data(TransactionModel::StatusTextRole).toString(); +} + +void TransactionListener::setResource(AbstractResource *resource) +{ + if (m_resource == resource) + return; + + m_resource = resource; + + // Catch already-started transactions + setTransaction(TransactionModel::global()->transactionFromResource(resource)); + + emit resourceChanged(); +} + +void TransactionListener::transactionAdded(Transaction *trans) +{ + if (trans->resource() != m_resource) + return; + + setTransaction(trans); +} + +class CheckChange +{ +public: + CheckChange(QObject* obj, const QByteArray& prop) + : m_object(obj) + , m_prop(obj->metaObject()->property(obj->metaObject()->indexOfProperty(prop.constData()))) + , m_oldValue(m_prop.read(obj)) + { + Q_ASSERT(obj->metaObject()->indexOfProperty(prop.constData())>=0); + } + + ~CheckChange() { + const QVariant newValue = m_prop.read(m_object); + if (newValue != m_oldValue) { + QMetaMethod m = m_prop.notifySignal(); + m.invoke(m_object, Qt::DirectConnection); + } + } + +private: + QObject* m_object; + QMetaProperty m_prop; + QVariant m_oldValue; +}; + +void TransactionListener::setTransaction(Transaction* trans) +{ + Q_ASSERT(!trans || trans->resource()==m_resource); + if (m_transaction == trans) { + return; + } + + if(m_transaction) { + disconnect(m_transaction, nullptr, this, nullptr); + } + + CheckChange change1(this, "isCancellable"); + CheckChange change2(this, "isActive"); + CheckChange change3(this, "statusText"); + CheckChange change4(this, "progress"); + + m_transaction = trans; + if(m_transaction) { + connect(m_transaction, &Transaction::cancellableChanged, this, &TransactionListener::cancellableChanged); + connect(m_transaction, &Transaction::statusChanged, this, &TransactionListener::transactionStatusChanged); + connect(m_transaction, &Transaction::progressChanged, this, &TransactionListener::progressChanged); + } +} + +void TransactionListener::transactionStatusChanged(Transaction::Status status) +{ + switch (status) { + case Transaction::DoneStatus: + setTransaction(nullptr); + break; + case Transaction::QueuedStatus: + emit runningChanged(); + break; + default: + break; + } + + emit statusTextChanged(); +} + +void TransactionListener::transactionRemoved(Transaction* trans) +{ + if(m_transaction == trans) { + setTransaction(nullptr); + } +} + +void TransactionListener::transactionCancelled(Transaction* trans) +{ + if(m_transaction == trans) { + setTransaction(nullptr); + } + emit cancelled(); +} + +int TransactionListener::progress() const +{ + return m_transaction ? m_transaction->progress() : 0; +} diff --git a/libdiscover/Transaction/TransactionListener.h b/libdiscover/Transaction/TransactionListener.h new file mode 100644 index 0000000..d74b790 --- /dev/null +++ b/libdiscover/Transaction/TransactionListener.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef TRANSACTIONLISTENER_H +#define TRANSACTIONLISTENER_H + +#include + +#include "Transaction.h" +#include "discovercommon_export.h" + +class AbstractResource; + +class DISCOVERCOMMON_EXPORT TransactionListener : public QObject +{ + Q_OBJECT + Q_PROPERTY(AbstractResource* resource READ resource WRITE setResource NOTIFY resourceChanged) + Q_PROPERTY(bool isCancellable READ isCancellable NOTIFY cancellableChanged) + Q_PROPERTY(bool isActive READ isActive NOTIFY runningChanged) + Q_PROPERTY(QString statusText READ statusText NOTIFY statusTextChanged) + Q_PROPERTY(int progress READ progress NOTIFY progressChanged) +public: + explicit TransactionListener(QObject *parent = nullptr); + + AbstractResource *resource() const; + bool isCancellable() const; + bool isActive() const; + QString statusText() const; + int progress() const; + + Q_SCRIPTABLE void cancel(); + + void setResource(AbstractResource* resource); + +private: + void setTransaction(Transaction *trans); + + AbstractResource *m_resource; + Transaction *m_transaction; + +private Q_SLOTS: + void transactionAdded(Transaction *trans); + void transactionRemoved(Transaction* trans); + void transactionCancelled(Transaction* trans); + void transactionStatusChanged(Transaction::Status status); + +Q_SIGNALS: + void resourceChanged(); + void cancellableChanged(); + void runningChanged(); + void statusTextChanged(); + void cancelled(); + void progressChanged(); +}; + +#endif // TRANSACTIONLISTENER_H diff --git a/libdiscover/Transaction/TransactionModel.cpp b/libdiscover/Transaction/TransactionModel.cpp new file mode 100644 index 0000000..39a9343 --- /dev/null +++ b/libdiscover/Transaction/TransactionModel.cpp @@ -0,0 +1,212 @@ +/*************************************************************************** + * Copyright © 2012 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "TransactionModel.h" + +// Qt includes +#include +#include + +// Own includes +#include "resources/AbstractResource.h" + +Q_GLOBAL_STATIC(TransactionModel, globalTransactionModel) + +TransactionModel *TransactionModel::global() +{ + return globalTransactionModel; +} + +TransactionModel::TransactionModel(QObject *parent) + : QAbstractListModel(parent) +{ + connect(this, &QAbstractItemModel::rowsInserted, this, &TransactionModel::countChanged); + connect(this, &QAbstractItemModel::rowsRemoved, this, &TransactionModel::countChanged); + connect(this, &TransactionModel::countChanged, this, &TransactionModel::progressChanged); +} + +QHash< int, QByteArray > TransactionModel::roleNames() const +{ + QHash roles; + roles[TransactionRoleRole] = "transactionRole"; + roles[TransactionStatusRole] = "status"; + roles[CancellableRole] = "cancellable"; + roles[ProgressRole] = "progress"; + roles[StatusTextRole] = "statusText"; + roles[ResourceRole] = "resource"; + roles[TransactionRole] = "transaction"; + return roles; +} + +int TransactionModel::rowCount(const QModelIndex &parent) const +{ + // Root element parents all children + if (!parent.isValid()) + return m_transactions.size(); + + // Child elements have no children themselves + return 0; +} + +QVariant TransactionModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + Transaction *trans = transactionFromIndex(index); + switch (role) { + case TransactionRoleRole: + return trans->role(); + case TransactionStatusRole: + return trans->status(); + case CancellableRole: + return trans->isCancellable(); + case ProgressRole: + return trans->progress(); + case StatusTextRole: + switch (trans->status()) { + case Transaction::SetupStatus: + return i18nc("@info:status", "Starting"); + case Transaction::QueuedStatus: + return i18nc("@info:status", "Waiting"); + case Transaction::DownloadingStatus: + return i18nc("@info:status", "Downloading"); + case Transaction::CommittingStatus: + switch (trans->role()) { + case Transaction::InstallRole: + return i18nc("@info:status", "Installing"); + case Transaction::RemoveRole: + return i18nc("@info:status", "Removing"); + case Transaction::ChangeAddonsRole: + return i18nc("@info:status", "Changing Addons"); + } + break; + case Transaction::DoneStatus: + return i18nc("@info:status", "Done"); + } + break; + case TransactionRole: + return qVariantFromValue(trans); + case ResourceRole: + return qVariantFromValue(trans->resource()); + } + + return QVariant(); +} + +Transaction *TransactionModel::transactionFromIndex(const QModelIndex &index) const +{ + Transaction *trans = nullptr; + + if (index.isValid() && index.row() < m_transactions.size()) + trans = m_transactions.at(index.row()); + + return trans; +} + +Transaction *TransactionModel::transactionFromResource(AbstractResource *resource) const +{ + Transaction *ret = nullptr; + + Q_FOREACH (Transaction *trans, m_transactions) { + if (trans->resource() == resource) { + ret = trans; + break; + } + } + + return ret; +} + +QModelIndex TransactionModel::indexOf(Transaction *trans) const +{ + int row = m_transactions.indexOf(trans); + QModelIndex ret = index(row); + Q_ASSERT(!trans || ret.isValid()); + return ret; +} + +QModelIndex TransactionModel::indexOf(AbstractResource *res) const +{ + Transaction *trans = transactionFromResource(res); + + return indexOf(trans); +} + +void TransactionModel::addTransaction(Transaction *trans) +{ + if (m_transactions.contains(trans)) + return; + + if (m_transactions.isEmpty()) + emit startingFirstTransaction(); + + int before = m_transactions.size(); + beginInsertRows(QModelIndex(), before, before + 1); + m_transactions.append(trans); + endInsertRows(); + + connect(trans, &Transaction::statusChanged, this, [this](){ transactionChanged(StatusTextRole); }); + connect(trans, &Transaction::cancellableChanged, this, [this](){ transactionChanged(CancellableRole); }); + connect(trans, &Transaction::progressChanged, this, [this](){ transactionChanged(ProgressRole); Q_EMIT progressChanged(); }); + + emit transactionAdded(trans); +} + +void TransactionModel::cancelTransaction(Transaction *trans) +{ + removeTransaction(trans); + + emit transactionCancelled(trans); +} + +void TransactionModel::removeTransaction(Transaction *trans) +{ + Q_ASSERT(trans); + int r = indexOf(trans).row(); + Q_ASSERT(r>=0); + + beginRemoveRows(QModelIndex(), r, r); + m_transactions.removeAt(r); + endRemoveRows(); + emit transactionRemoved(trans); + if (m_transactions.isEmpty()) + emit lastTransactionFinished(); +} + +void TransactionModel::transactionChanged(int role) +{ + Transaction *trans = qobject_cast(sender()); + QModelIndex transIdx = indexOf(trans); + emit dataChanged(transIdx, transIdx, {role}); +} + +int TransactionModel::progress() const +{ + int sum = 0; + int count = 0; + foreach(Transaction* t, m_transactions) { + if (t->isActive()) { + sum += t->progress(); + ++count; + } + } + return count==0 ? 0 : sum / count; +} diff --git a/libdiscover/Transaction/TransactionModel.h b/libdiscover/Transaction/TransactionModel.h new file mode 100644 index 0000000..fb4c9e8 --- /dev/null +++ b/libdiscover/Transaction/TransactionModel.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright © 2012 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef TRANSACTIONMODEL_H +#define TRANSACTIONMODEL_H + +#include + +#include "Transaction.h" + +#include "discovercommon_export.h" + +class DISCOVERCOMMON_EXPORT TransactionModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(int progress READ progress NOTIFY progressChanged) + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) +public: + enum Roles { + TransactionRoleRole = Qt::UserRole, + TransactionStatusRole, + CancellableRole, + ProgressRole, + StatusTextRole, + ResourceRole, + TransactionRole + }; + + explicit TransactionModel(QObject *parent = nullptr); + static TransactionModel *global(); + + // Reimplemented from QAbstractListModel + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QHash roleNames() const override; + + Transaction *transactionFromIndex(const QModelIndex &index) const; + Q_SCRIPTABLE Transaction *transactionFromResource(AbstractResource *resource) const; + QModelIndex indexOf(Transaction *trans) const; + QModelIndex indexOf(AbstractResource *res) const; + + void addTransaction(Transaction *trans); + void cancelTransaction(Transaction *trans); + void removeTransaction(Transaction *trans); + + int progress() const; + +private: + QVector m_transactions; + +Q_SIGNALS: + void startingFirstTransaction(); + void lastTransactionFinished(); + void transactionAdded(Transaction *trans); + void transactionCancelled(Transaction *trans); + void transactionRemoved(Transaction* trans); + void countChanged(); + void progressChanged(); + void proceedRequest(Transaction* transaction, const QString &title, const QString &description); + +private Q_SLOTS: + void transactionChanged(int role); +}; + +#endif // TRANSACTIONMODEL_H diff --git a/libdiscover/UpdateModel/UpdateItem.cpp b/libdiscover/UpdateModel/UpdateItem.cpp new file mode 100644 index 0000000..3677be1 --- /dev/null +++ b/libdiscover/UpdateModel/UpdateItem.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "UpdateItem.h" +#include +#include +#include + +#include +#include +#include + +UpdateItem::UpdateItem(AbstractResource *app) + : m_app(app) + , m_progress(0) +{ +} + +UpdateItem::~UpdateItem() +{ +} + +AbstractResource *UpdateItem::app() const +{ + return m_app; +} + +QString UpdateItem::name() const +{ + return m_app->name(); +} + +QString UpdateItem::version() const +{ + return m_app->availableVersion(); +} + +QVariant UpdateItem::icon() const +{ + return m_app->icon(); +} + +qint64 UpdateItem::size() const +{ + return m_app->size(); +} + +static bool isMarked(AbstractResource* res) +{ + return res->backend()->backendUpdater()->isMarked(res); +} + +Qt::CheckState UpdateItem::checked() const +{ + return isMarked(app()) ? Qt::Checked : Qt::Unchecked; +} + +qreal UpdateItem::progress() const +{ + return m_progress; +} + +void UpdateItem::setProgress(qreal progress) +{ + m_progress = progress; +} + +QString UpdateItem::changelog() const +{ + return m_changelog; +} + +void UpdateItem::setChangelog(const QString& changelog) +{ + m_changelog = changelog; +} diff --git a/libdiscover/UpdateModel/UpdateItem.h b/libdiscover/UpdateModel/UpdateItem.h new file mode 100644 index 0000000..63496d7 --- /dev/null +++ b/libdiscover/UpdateModel/UpdateItem.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef UPDATEITEM_H +#define UPDATEITEM_H + +// Qt includes +#include +#include +#include "discovercommon_export.h" + +#include + +class AbstractResource; +class DISCOVERCOMMON_EXPORT UpdateItem +{ +public: + explicit UpdateItem(AbstractResource *app); + + ~UpdateItem(); + + + void setSection(const QString §ion) { m_section = section; } + QString section() const { return m_section; } + void setProgress(qreal progress); + qreal progress() const; + + QString changelog() const; + void setChangelog(const QString &changelog); + + AbstractResource *app() const; + QString name() const; + QString version() const; + QVariant icon() const; + qint64 size() const; + Qt::CheckState checked() const; + + AbstractResource* resource() const { return m_app; } + +private: + AbstractResource * const m_app; + + const QString m_categoryName; + const QIcon m_categoryIcon; + qreal m_progress; + QString m_changelog; + QString m_section; +}; + +#endif // UPDATEITEM_H diff --git a/libdiscover/UpdateModel/UpdateModel.cpp b/libdiscover/UpdateModel/UpdateModel.cpp new file mode 100644 index 0000000..9bab2d0 --- /dev/null +++ b/libdiscover/UpdateModel/UpdateModel.cpp @@ -0,0 +1,287 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "UpdateModel.h" + +// Qt includes +#include +#include + +// KDE includes +#include +#include + +// Own includes +#include "UpdateItem.h" +#include +#include +#include + +UpdateModel::UpdateModel(QObject *parent) + : QAbstractListModel(parent) + , m_updates(nullptr) +{ + + connect(ResourcesModel::global(), &ResourcesModel::fetchingChanged, this, &UpdateModel::activityChanged); + connect(ResourcesModel::global(), &ResourcesModel::updatesCountChanged, this, &UpdateModel::activityChanged); + connect(ResourcesModel::global(), &ResourcesModel::resourceDataChanged, this, &UpdateModel::resourceDataChanged); +} + +UpdateModel::~UpdateModel() = default; + +QHash UpdateModel::roleNames() const +{ + return QAbstractItemModel::roleNames().unite({ + { Qt::CheckStateRole, "checked" }, + { ResourceProgressRole, "resourceProgress" }, + { ResourceRole, "resource" }, + { SizeRole, "size" }, + { VersionRole, "version" }, + { SectionRole, "section" }, + { ChangelogRole, "changelog" } + } ); +} + +void UpdateModel::setBackend(ResourcesUpdatesModel* updates) +{ + if (m_updates) { + disconnect(m_updates, nullptr, this, nullptr); + } + + m_updates = updates; + + connect(m_updates, &ResourcesUpdatesModel::progressingChanged, this, &UpdateModel::activityChanged); + connect(m_updates, &ResourcesUpdatesModel::resourceProgressed, this, &UpdateModel::resourceHasProgressed); + + activityChanged(); +} + +void UpdateModel::resourceHasProgressed(AbstractResource* res, qreal progress) +{ + UpdateItem* item = itemFromResource(res); + Q_ASSERT(item); + item->setProgress(progress); + + const QModelIndex idx = indexFromItem(item); + Q_EMIT dataChanged(idx, idx, { ResourceProgressRole }); +} + +void UpdateModel::activityChanged() +{ + if(ResourcesModel::global()->isFetching()) { + setResources(QList()); + } else if(!m_updates->isProgressing()) { + m_updates->prepare(); + setResources(m_updates->toUpdate()); + } +} + +QVariant UpdateModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + UpdateItem *item = itemFromIndex(index); + + switch (role) { + case Qt::DisplayRole: + return item->name(); + case Qt::DecorationRole: + return item->icon(); + case Qt::CheckStateRole: + return item->checked(); + case VersionRole: + return item->version(); + case SizeRole: + return KFormat().formatByteSize(item->size()); + case ResourceRole: + return QVariant::fromValue(item->resource()); + case ResourceProgressRole: + return item->progress(); + case ChangelogRole: + return item->changelog(); + case SectionRole: + return item->section(); + default: + break; + } + + return QVariant(); +} + +void UpdateModel::checkResources(const QList& resource, bool checked) +{ + if(checked) + m_updates->addResources(resource); + else + m_updates->removeResources(resource); +} + +Qt::ItemFlags UpdateModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return nullptr; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +int UpdateModel::rowCount(const QModelIndex &parent) const +{ + return !parent.isValid() ? m_updateItems.count() : 0; +} + +bool UpdateModel::setData(const QModelIndex &idx, const QVariant &value, int role) +{ + if (role == Qt::CheckStateRole) { + UpdateItem *item = itemFromIndex(idx); + const bool newValue = value.toInt() == Qt::Checked; + const QList apps = { item->app() }; + + checkResources(apps, newValue); + Q_ASSERT(idx.data(Qt::CheckStateRole) == value); + Q_EMIT dataChanged(idx, idx, { Qt::CheckStateRole }); + Q_EMIT toUpdateChanged(); + + return true; + } + + return false; +} + +void UpdateModel::fetchChangelog(int row) +{ + UpdateItem *item = itemFromIndex(index(row, 0)); + Q_ASSERT(item); + if (!item) return; + + item->app()->fetchChangelog(); +} + +void UpdateModel::integrateChangelog(const QString &changelog) +{ + auto app = qobject_cast(sender()); + Q_ASSERT(app); + auto item = itemFromResource(app); + if (!item) + return; + + item->setChangelog(changelog); + + const QModelIndex idx = indexFromItem(item); + Q_ASSERT(idx.isValid()); + emit dataChanged(idx, idx, { ChangelogRole }); +} + +void UpdateModel::setResources(const QList< AbstractResource* >& resources) +{ + beginResetModel(); + qDeleteAll(m_updateItems); + m_updateItems.clear(); + + const QString importantUpdatesSection = i18nc("@item:inlistbox", "Important Security Updates"); + const QString appUpdatesSection = i18nc("@item:inlistbox", "Application Updates"); + const QString systemUpdateSection = i18nc("@item:inlistbox", "System Updates"); + QVector securityItems, appItems, systemItems; + foreach(AbstractResource* res, resources) { + connect(res, &AbstractResource::changelogFetched, this, &UpdateModel::integrateChangelog, Qt::UniqueConnection); + + UpdateItem *updateItem = new UpdateItem(res); + + if (res->isFromSecureOrigin()) { + updateItem->setSection(importantUpdatesSection); + securityItems += updateItem; + } else if(!res->isTechnical()) { + updateItem->setSection(appUpdatesSection); + appItems += updateItem; + } else { + updateItem->setSection(systemUpdateSection); + systemItems += updateItem; + } + } + const auto sortUpdateItems = [](UpdateItem *a, UpdateItem *b) { return a->name() < b->name(); }; + qSort(securityItems.begin(), securityItems.end(), sortUpdateItems); + qSort(appItems.begin(), appItems.end(), sortUpdateItems); + qSort(systemItems.begin(), systemItems.end(), sortUpdateItems); + m_updateItems = (QVector() << securityItems << appItems << systemItems); + endResetModel(); + + Q_EMIT hasUpdatesChanged(!resources.isEmpty()); + Q_EMIT toUpdateChanged(); +} + +bool UpdateModel::hasUpdates() const +{ + return rowCount() > 0; +} + +ResourcesUpdatesModel* UpdateModel::backend() const +{ + return m_updates; +} + +int UpdateModel::toUpdateCount() const +{ + int ret = 0; + foreach (UpdateItem* item, m_updateItems) { + ret += item->checked() != Qt::Unchecked ? 1 : 0; + } + return ret; +} + +UpdateItem * UpdateModel::itemFromResource(AbstractResource* res) +{ + foreach (UpdateItem* item, m_updateItems) { + if (item->app() == res) + return item; + } + return nullptr; +} + +QString UpdateModel::updateSize() const +{ + double ret = 0; + foreach (UpdateItem* item, m_updateItems) { + if (item->checked() == Qt::Checked) + ret += item->size(); + } + return KFormat().formatByteSize(ret); +} + +QModelIndex UpdateModel::indexFromItem(UpdateItem* item) const +{ + return index(m_updateItems.indexOf(item), 0, {}); +} + +UpdateItem * UpdateModel::itemFromIndex(const QModelIndex& index) const +{ + return m_updateItems[index.row()]; +} + +void UpdateModel::resourceDataChanged(AbstractResource* res, const QVector& properties) +{ + auto item = itemFromResource(res); + if (!item) + return; + + const auto index = indexFromItem(item); + if (properties.contains("state")) + dataChanged(index, index, {SizeRole, VersionRole}); +} diff --git a/libdiscover/UpdateModel/UpdateModel.h b/libdiscover/UpdateModel/UpdateModel.h new file mode 100644 index 0000000..5c72f60 --- /dev/null +++ b/libdiscover/UpdateModel/UpdateModel.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef UPDATEMODEL_H +#define UPDATEMODEL_H + +#include +#include "discovercommon_export.h" + +class ResourcesUpdatesModel; +class AbstractResource; +class UpdateItem; + +class DISCOVERCOMMON_EXPORT UpdateModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(ResourcesUpdatesModel* backend READ backend WRITE setBackend) + Q_PROPERTY(bool hasUpdates READ hasUpdates NOTIFY hasUpdatesChanged) + Q_PROPERTY(int toUpdateCount READ toUpdateCount NOTIFY toUpdateChanged) + Q_PROPERTY(int totalUpdatesCount READ totalUpdatesCount NOTIFY hasUpdatesChanged) + Q_PROPERTY(QString updateSize READ updateSize NOTIFY toUpdateChanged) +public: + + enum Roles { + VersionRole = Qt::UserRole + 1, + SizeRole, + ResourceRole, + ResourceProgressRole, + ChangelogRole, + SectionRole + }; + + explicit UpdateModel(QObject *parent = nullptr); + ~UpdateModel() override; + + QVariant data(const QModelIndex &index, int role) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + void setResources(const QList& res); + UpdateItem *itemFromIndex(const QModelIndex &index) const; + + void checkResources(const QList& resource, bool checked); + QHash roleNames() const override; + + bool hasUpdates() const; + + ///all upgradeable packages + int totalUpdatesCount() const { return m_updateItems.count(); } + + ///packages marked to upgrade + int toUpdateCount() const; + + Q_SCRIPTABLE void fetchChangelog(int row); + + QString updateSize() const; + + ResourcesUpdatesModel* backend() const; + +public Q_SLOTS: + void setBackend(ResourcesUpdatesModel* updates); + +Q_SIGNALS: + void hasUpdatesChanged(bool hasUpdates); + void toUpdateChanged(); + +private: + void resourceDataChanged(AbstractResource* res, const QVector &properties); + void integrateChangelog(const QString &changelog); + QModelIndex indexFromItem(UpdateItem* item) const; + UpdateItem* itemFromResource(AbstractResource* res); + void resourceHasProgressed(AbstractResource* res, qreal progress); + void activityChanged(); + + QVector m_updateItems; + ResourcesUpdatesModel* m_updates; +}; + +#endif // UPDATEMODEL_H diff --git a/libdiscover/backends/ApplicationBackend/Application.cpp b/libdiscover/backends/ApplicationBackend/Application.cpp new file mode 100644 index 0000000..ae1d95e --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/Application.cpp @@ -0,0 +1,546 @@ +/*************************************************************************** + * Copyright © 2010-2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "Application.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include + +// KDE includes +#include +#include +#include +#include +#include +#include +#include +#include + +// QApt includes +#include +#include +#include +#include + +#include + +#include "ApplicationBackend.h" +#include "resources/PackageState.h" + +Application::Application(const Appstream::Component &component, QApt::Backend* backend) + : AbstractResource(nullptr) + , m_data(component) + , m_package(nullptr) + , m_isValid(true) + , m_isTechnical(component.kind() != Appstream::Component::KindDesktop) + , m_isExtrasApp(false) + , m_sourceHasScreenshot(true) +{ + static QByteArray currentDesktop = qgetenv("XDG_CURRENT_DESKTOP"); + + Q_ASSERT(component.packageNames().count() == 1); + if (!component.packageNames().isEmpty()) + m_packageName = component.packageNames().at(0); + + m_package = backend->package(packageName()); + m_isValid = bool(m_package); +} + +Application::Application(QApt::Package* package, QApt::Backend* backend) + : AbstractResource(nullptr) + , m_package(package) + , m_packageName(m_package->name()) + , m_isValid(true) + , m_isTechnical(true) + , m_isExtrasApp(false) +{ + QString arch = m_package->architecture(); + if (arch != backend->nativeArchitecture() && arch != QLatin1String("all")) { + m_packageName.append(QLatin1Char(':')); + m_packageName.append(arch); + } + + if (m_package->origin() == QLatin1String("LP-PPA-app-review-board")) { + if (!m_package->controlField(QLatin1String("Appname")).isEmpty()) { + m_isExtrasApp = true; + m_isTechnical = false; + } + } +} + +QString Application::name() +{ + QString name = m_data.isValid() ? m_data.name() : QString(); + if (name.isEmpty() && package()) { + // extras.ubuntu.com packages can have this + if (m_isExtrasApp) + name = m_package->controlField(QLatin1String("Appname")); + else + name = m_package->name(); + } + + if (package() && m_package->isForeignArch()) + name = i18n("%1 (%2)", name, m_package->architecture()); + + return name; +} + +QString Application::comment() +{ + QString comment = m_data.isValid() ? m_data.summary() : QString(); + if (comment.isEmpty()) { + return package()->shortDescription(); + } + + return i18n(comment.toUtf8().constData()); +} + +QString Application::packageName() const +{ + return m_packageName; +} + +QApt::Package *Application::package() +{ + if (!m_package && parent()) { + m_package = backend()->package(packageName()); + Q_EMIT stateChanged(); + } + + // Packages removed from archive will remain in app-install-data until the + // next refresh, so we can have valid .desktops with no package + if (!m_package) { + m_isValid = false; + } + + return m_package; +} + +QVariant Application::icon() const +{ + QIcon ret; + + const auto icons = m_appdata.iconUrls(); + if (icons.isEmpty()) + return m_appdata.name(); + else { + for (auto it = icons.constBegin(), itEnd = icons.constEnd(); it!=itEnd; ++it) { + if (it->isLocalFile()) + ret.addFile(it->toLocalFile(), it.key()); + } + } + return ret; +} + +QStringList Application::findProvides(Appstream::Provides::Kind kind) const +{ + QStringList ret; + Q_FOREACH (Appstream::Provides p, m_data.provides()) + if (p.kind() == kind) + ret += p.value(); + return ret; +} + +QStringList Application::mimetypes() const +{ + return findProvides(Appstream::Provides::KindMimetype); +} + +QStringList Application::categories() +{ + QStringList categories = m_data.isValid() ? m_data.categories() : QStringList(); + + if (categories.isEmpty()) { + // extras.ubuntu.com packages can have this field + if (m_isExtrasApp) + categories = package()->controlField(QLatin1String("Category")).split(QLatin1Char(';')); + } + return categories; +} + +QUrl Application::thumbnailUrl() +{ + QUrl url(package()->controlField(QLatin1String("Thumbnail-Url"))); + if(m_sourceHasScreenshot) { + url = QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/thumbnail/") + packageName()); + } + return url; +} + +QUrl Application::screenshotUrl() +{ + QUrl url(package()->controlField(QLatin1String("Screenshot-Url"))); + if(m_sourceHasScreenshot) { + url = QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/screenshot/") + packageName()); + } + return url; +} + +QString Application::license() +{ + QString component = package()->component(); + if (component == QLatin1String("main") || component == QLatin1String("universe")) { + return i18nc("@info license", "Open Source"); + } else if (component == QLatin1String("restricted")) { + return i18nc("@info license", "Proprietary"); + } else { + return i18nc("@info license", "Unknown"); + } +} + +QApt::PackageList Application::addons() +{ + QApt::PackageList addons; + + QApt::Package *pkg = package(); + if (!pkg) { + return addons; + } + + QStringList tempList; + // Only add recommends or suggests to the list if they aren't already going to be + // installed + if (!backend()->config()->readEntry(QStringLiteral("APT::Install-Recommends"), true)) { + tempList << m_package->recommendsList(); + } + if (!backend()->config()->readEntry(QStringLiteral("APT::Install-Suggests"), false)) { + tempList << m_package->suggestsList(); + } + tempList << m_package->enhancedByList(); + + QStringList languagePackages; + QFile l10nFilterFile(QStringLiteral("/usr/share/language-selector/data/pkg_depends")); + + if (l10nFilterFile.open(QFile::ReadOnly)) { + QString contents = QString::fromLatin1(l10nFilterFile.readAll()); + + foreach (const QString &line, contents.split(QLatin1Char('\n'))) { + if (line.startsWith(QLatin1Char('#'))) { + continue; + } + languagePackages << line.split(QLatin1Char(':')).last(); + } + + languagePackages.removeAll(QString()); + } + + foreach (const QString &addon, tempList) { + bool shouldShow = true; + QApt::Package *package = backend()->package(addon); + + if (!package || QString(package->section()).contains(QLatin1String("lib")) || addons.contains(package)) { + continue; + } + + foreach (const QString &langpack, languagePackages) { + if (addon.contains(langpack)) { + shouldShow = false; + break; + } + } + + if (shouldShow) { + addons << package; + } + } + + return addons; +} + +QList Application::addonsInformation() +{ + QList ret; + QApt::PackageList pkgs = addons(); + foreach(QApt::Package* p, pkgs) { + ret += PackageState(p->name(), p->shortDescription(), p->isInstalled()); + } + return ret; +} + +bool Application::isValid() const +{ + return m_isValid; +} + +bool Application::isTechnical() const +{ + return m_isTechnical; +} + +QUrl Application::homepage() +{ + if(!m_package) return QUrl(); + return QUrl(m_package->homepage()); +} + +QString Application::origin() const +{ + if(!m_package) return QString(); + return m_package->origin(); +} + +QString Application::longDescription() +{ + const QString comment = m_data.isValid() ? m_data.description() : QString(); + if(!comment.isEmpty()) return comment; + if(m_package) return QString(); + return m_package->longDescription(); +} + +QString Application::availableVersion() const +{ + if(!m_package) return QString(); + return m_package->availableVersion(); +} + +QString Application::installedVersion() const +{ + if(!m_package) return QString(); + return m_package->installedVersion(); +} + +QString Application::sizeDescription() +{ + KFormat f; + if (!isInstalled()) { + return i18nc("@info app size", "%1 to download, %2 on disk", + f.formatByteSize(package()->downloadSize()), + f.formatByteSize(package()->availableInstalledSize())); + } else { + return i18nc("@info app size", "%1 on disk", + f.formatByteSize(package()->currentInstalledSize())); + } +} + +int Application::size() +{ + return m_package->downloadSize(); +} + +void Application::clearPackage() +{ + m_package = nullptr; +} + +QVector Application::findExecutables() const +{ + QVector ret; + if (!m_package) { + qWarning() << "trying to find the executables for an uninitialized package!" << packageName(); + return ret; + } + + QRegExp rx(QStringLiteral(".+\\.desktop$"), Qt::CaseSensitive); + foreach (const QString &desktop, m_package->installedFilesList().filter(rx)) { + // Important to use serviceByStorageId to ensure we get a service even + // if the KSycoca database doesn't have our .desktop file yet. + KService::Ptr service = KService::serviceByStorageId(desktop); + if (service && + service->isApplication() && + !service->noDisplay() && + !service->exec().isEmpty()) + { + ret << service; + } + } + return ret; +} + +void Application::emitStateChanged() +{ + emit stateChanged(); +} + +void Application::invokeApplication() const +{ + QVector< KService::Ptr > execs = findExecutables(); + Q_ASSERT(!execs.isEmpty()); + KToolInvocation::startServiceByDesktopName(execs.first()->desktopEntryName()); +} + +bool Application::canExecute() const +{ + return !findExecutables().isEmpty(); +} + +QString Application::section() +{ + return package()->section(); +} + +AbstractResource::State Application::state() +{ + if (!package()) + return Broken; + + int s = package()->state(); + + if (s & QApt::Package::Upgradeable) { +#if QAPT_VERSION >= QT_VERSION_CHECK(3, 1, 0) + if (package()->isInUpdatePhase()) + return Upgradeable; +#else + return Upgradeable; +#endif + } + + if (s & QApt::Package::Installed) { + return Installed; + } + + return None; // Actually: none of interest to us here in plasma-discover. +} + +void Application::fetchScreenshots() +{ + if(!m_sourceHasScreenshot) + return; + + QString dest = QStandardPaths::locate(QStandardPaths::TempLocation, QStringLiteral("screenshots.")+m_packageName); + const QUrl packageUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/json/package/")+m_packageName); + KIO::StoredTransferJob* job = KIO::storedGet(packageUrl, KIO::NoReload, KIO::HideProgressInfo); + connect(job, &KIO::StoredTransferJob::finished, this, &Application::downloadingScreenshotsFinished); +} + +void Application::downloadingScreenshotsFinished(KJob* j) +{ + KIO::StoredTransferJob* job = qobject_cast< KIO::StoredTransferJob* >(j); + bool done = false; + if(job) { + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error); + if(error.error != QJsonParseError::NoError) { + QVariantMap values = doc.toVariant().toMap(); + QVariantList screenshots = values[QStringLiteral("screenshots")].toList(); + + QList thumbnailUrls, screenshotUrls; + foreach(const QVariant& screenshot, screenshots) { + QVariantMap s = screenshot.toMap(); + thumbnailUrls += s[QStringLiteral("small_image_url")].toUrl(); + screenshotUrls += s[QStringLiteral("large_image_url")].toUrl(); + } + emit screenshotsFetched(thumbnailUrls, screenshotUrls); + done = true; + } + } + if(!done) { + QList thumbnails, screenshots; + if(!thumbnailUrl().isEmpty()) { + thumbnails += thumbnailUrl(); + screenshots += screenshotUrl(); + } + emit screenshotsFetched(thumbnails, screenshots); + } + +} + +void Application::setHasScreenshot(bool has) +{ + m_sourceHasScreenshot = has; +} + +QStringList Application::executables() const +{ + QStringList ret; + const QVector exes = findExecutables(); + for(KService::Ptr exe : exes) { + ret += exe->exec(); + } + return ret; +} + +bool Application::isFromSecureOrigin() const +{ + Q_FOREACH (const QString &archive, m_package->archives()) { + if (archive.contains(QLatin1String("security"))) { + return true; + } + } + return false; +} + +void Application::fetchChangelog() +{ + KIO::StoredTransferJob* getJob = KIO::storedGet(m_package->changelogUrl(), KIO::NoReload, KIO::HideProgressInfo); + connect(getJob, &KIO::StoredTransferJob::result, this, &Application::processChangelog); +} + +void Application::processChangelog(KJob* j) +{ + KIO::StoredTransferJob* job = qobject_cast(j); + if (!m_package || !job) { + return; + } + + QString changelog; + if(j->error()==0) + changelog = buildDescription(job->data(), m_package->sourcePackage()); + + if (changelog.isEmpty()) { + if (m_package->origin() == QStringLiteral("Ubuntu")) { + changelog = xi18nc("@info/rich", "The list of changes is not yet available. " + "Please use Launchpad instead.", + QStringLiteral("http://launchpad.net/ubuntu/+source/") + m_package->sourcePackage()); + } else { + changelog = xi18nc("@info", "The list of changes is not yet available."); + } + } + emit changelogFetched(changelog); +} + +QString Application::buildDescription(const QByteArray& data, const QString& source) +{ + QApt::Changelog changelog(QString::fromLatin1(data), source); + QString description; + + QApt::ChangelogEntryList entries = changelog.newEntriesSince(m_package->installedVersion()); + + if (entries.size() < 1) { + return description; + } + + foreach(const QApt::ChangelogEntry &entry, entries) { + description += i18nc("@info:label Refers to a software version, Ex: Version 1.2.1:", + "Version %1:", entry.version()); + + KFormat f; + QString issueDate = entry.issueDateTime().toString(Qt::DefaultLocaleShortDate); + description += QLatin1String("

") + + i18nc("@info:label", "This update was issued on %1", issueDate) + + QLatin1String("

"); + + QString updateText = entry.description(); + updateText.replace(QLatin1Char('\n'), QLatin1String("
")); + description += QLatin1String("

") + updateText + QLatin1String("

"); + } + + return description; +} + +QApt::Backend *Application::backend() const +{ + return qobject_cast(parent())->backend(); +} diff --git a/libdiscover/backends/ApplicationBackend/Application.h b/libdiscover/backends/ApplicationBackend/Application.h new file mode 100644 index 0000000..7414280 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/Application.h @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright © 2010-2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef APPLICATION_H +#define APPLICATION_H + +#include +#include +#include + +#include + +#include +#include + +#include "discovercommon_export.h" +#include "resources/AbstractResource.h" + +class KJob; +class KConfig; +namespace QApt { + class Backend; +} + +class DISCOVERCOMMON_EXPORT Application : public AbstractResource +{ +Q_OBJECT +public: + explicit Application(const Appstream::Component &component, QApt::Backend *backend); + explicit Application(QApt::Package *package, QApt::Backend *backend); + + QString name() override; + QString comment() override; + QApt::Package *package(); + QVariant icon() const override; + QStringList mimetypes() const override; + QStringList categories() override; + QString license() override; + QUrl screenshotUrl() override; + QUrl thumbnailUrl() override; + QList< PackageState > addonsInformation() override; + bool isValid() const; + bool isTechnical() const override; + QString packageName() const override; + + //QApt::Package forwarding + QUrl homepage() override; + QString longDescription() override; + QString installedVersion() const override; + QString availableVersion() const override; + QString sizeDescription() override; + QString origin() const override; + int size() override; + + bool hasScreenshot() const { return m_sourceHasScreenshot; } + void setHasScreenshot(bool has); + + void clearPackage(); + QVector findExecutables() const; + QStringList executables() const override; + + /** Used to trigger the stateChanged signal from the ApplicationBackend */ + void emitStateChanged(); + + void invokeApplication() const override; + + bool canExecute() const override; + QString section() override; + + State state() override; + void fetchScreenshots() override; + void fetchChangelog() override; + + bool isFromSecureOrigin() const; + +private Q_SLOTS: + void processChangelog(KJob*); + void downloadingScreenshotsFinished(KJob*); + +private: + QApt::Backend *backend() const; + QStringList findProvides(Appstream::Provides::Kind kind) const; + QString buildDescription(const QByteArray& data, const QString& source); + + const Appstream::Component m_data; + QApt::Package *m_package; + QString m_packageName; + + bool m_isValid; + bool m_isTechnical; + bool m_isExtrasApp; + bool m_sourceHasScreenshot; + + QApt::PackageList addons(); +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp b/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp new file mode 100644 index 0000000..c5993e5 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp @@ -0,0 +1,676 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ApplicationBackend.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// KDE includes +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// QApt/DebconfKDE includes +#include +#include +#include + +//libmuonapt includes +#include "MuonStrings.h" +#include "ChangesDialog.h" +#include "QAptActions.h" + +// Own includes +#include "AptSourcesBackend.h" +#include "Application.h" +#include "ReviewsBackend.h" +#include "Transaction/Transaction.h" +#include "Transaction/TransactionModel.h" +#include "ApplicationUpdates.h" +#include +#include + +MUON_BACKEND_PLUGIN(ApplicationBackend) + +class AptTransaction : public Transaction +{ +public: + AptTransaction(QObject *parent, AbstractResource *resource, Transaction::Role role, const AddonList &addons = {}) + : Transaction(parent, resource, role, addons), m_aptTrans(nullptr) {} + + void cancel() { + m_aptTrans->cancel(); + } + + QApt::Transaction *aptTrans() const { return m_aptTrans; } + void setAptTrans(QApt::Transaction *t) { m_aptTrans = t; } + +private: + QApt::Transaction *m_aptTrans; +}; + +ApplicationBackend::ApplicationBackend(QObject* parent) + : AbstractResourcesBackend(parent) + , m_backend(new QApt::Backend(this)) + , m_reviewsBackend(new ReviewsBackend(this)) + , m_isFetching(true) + , m_currentTransaction(nullptr) + , m_backendUpdater(new ApplicationUpdates(this)) + , m_aptify(nullptr) + , m_aptBackendInitialized(false) +{ + KIconLoader::global()->reconfigure(QString(), QStringList(QStringLiteral("/usr/share/app-install/icons/"))); + + m_watcher = new QFutureWatcher >(this); + connect(m_watcher, &QFutureWatcher >::finished, this, &ApplicationBackend::setApplications); + connect(m_reviewsBackend, &ReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady); + + QTimer::singleShot(10, this, SLOT(initBackend())); +} + +ApplicationBackend::~ApplicationBackend() +{ + qDeleteAll(m_appList); +} + +QVector init(QApt::Backend *backend, QThread* thread) +{ + Appstream::Database appdata; + bool opened = appdata.open(); + Q_ASSERT(opened); + + QVector tempList; + QSet packages; + foreach(const Appstream::Component &component, appdata.allComponents()) { + if (component.packageNames().isEmpty()) + continue; + Application *app = new Application(component, backend); + packages.insert(app->packageName()); + tempList << app; + } + + foreach (QApt::Package *package, backend->availablePackages()) { + //Don't create applications twice + if(packages.contains(package->name())) + continue; + + if (package->isMultiArchDuplicate()) + continue; + + Application *app = new Application(package, backend); + tempList << app; + } + + // To be added an Application must have a package that: + // a) exists + // b) is not on the blacklist + // c) if not downloadable, then it must already be installed + QVector appList; + appList.reserve(tempList.size()); + Q_FOREACH (Application *app, tempList) { + QApt::Package *pkg = app->package(); + if (app->isValid() && pkg) + { + appList << app; + app->moveToThread(thread); + } + else + delete app; + } + + return appList; +} + +void ApplicationBackend::setApplications() +{ + m_appList = m_watcher->future().result(); + Q_FOREACH (Application* app, m_appList) + app->setParent(this); + + KIO::StoredTransferJob* job = KIO::storedGet(QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/json/packages")),KIO::NoReload, KIO::DefaultFlags|KIO::HideProgressInfo); + connect(job, &KIO::StoredTransferJob::finished, this, &ApplicationBackend::initAvailablePackages); + + if (m_aptify) + QAptActions::self()->setCanExit(true); + setFetching(false); +} + +void ApplicationBackend::reload() +{ + if(isFetching()) { + qWarning() << "Reloading while already reloading... Please report."; + return; + } + setFetching(true); + if (m_aptify) + QAptActions::self()->setCanExit(false); + foreach(Application* app, m_appList) + app->clearPackage(); + qDeleteAll(m_transQueue); + m_transQueue.clear(); + m_reviewsBackend->stopPendingJobs(); + + if (!m_backend->reloadCache()) + QAptActions::self()->initError(); + + foreach(Application* app, m_appList) + app->package(); + + if (m_aptify) + QAptActions::self()->setCanExit(true); + setFetching(false); +} + +bool ApplicationBackend::isFetching() const +{ + return m_isFetching; +} + +bool ApplicationBackend::isValid() const +{ + // ApplicationBackend will force an application quit if it is invalid, so + // if it has not done that, the backend is valid. + return true; +} + +void ApplicationBackend::aptTransactionsChanged(QString active) +{ + // Find the newly-active QApt transaction in our list + AptTransaction* discTrans = nullptr; + + Q_FOREACH (AptTransaction *t, m_transQueue) { + if (t->aptTrans()->transactionId() == active) { + discTrans = t; + break; + } + } + + if (!discTrans || discTrans == m_currentTransaction) + return; + + m_currentTransaction = discTrans; + QApt::Transaction *trans = discTrans->aptTrans(); + connect(trans, &QApt::Transaction::statusChanged, this, &ApplicationBackend::transactionEvent); + connect(trans, &QApt::Transaction::errorOccurred, this, &ApplicationBackend::errorOccurred); + connect(trans, &QApt::Transaction::progressChanged, this, &ApplicationBackend::updateProgress); + // FIXME: untrusted packages, conf file prompt, media change +} + +void ApplicationBackend::transactionEvent(QApt::TransactionStatus status) +{ + if (!m_currentTransaction->aptTrans()) + return; + + TransactionModel *transModel = TransactionModel::global(); + + switch (status) { + case QApt::SetupStatus: + case QApt::AuthenticationStatus: + case QApt::WaitingStatus: + case QApt::WaitingLockStatus: + case QApt::WaitingMediumStatus: + case QApt::WaitingConfigFilePromptStatus: + case QApt::LoadingCacheStatus: + m_currentTransaction->setStatus(Transaction::SetupStatus); + break; + case QApt::RunningStatus: + m_currentTransaction->setStatus(Transaction::QueuedStatus); + break; + case QApt::DownloadingStatus: + m_currentTransaction->setStatus(Transaction::DownloadingStatus); + m_currentTransaction->setCancellable(false); + break; + case QApt::CommittingStatus: + m_currentTransaction->setStatus(Transaction::CommittingStatus); + + // Set up debconf + m_debconfGui = new DebconfKde::DebconfGui(m_currentTransaction->aptTrans()->debconfPipe()); + m_debconfGui->connect(m_debconfGui, &DebconfKde::DebconfGui::activated, m_debconfGui, &DebconfKde::DebconfGui::show); + m_debconfGui->connect(m_debconfGui, &DebconfKde::DebconfGui::deactivated, m_debconfGui, &DebconfKde::DebconfGui::hide); + break; + case QApt::FinishedStatus: + m_currentTransaction->setStatus(Transaction::DoneStatus); + + // Clean up manually created debconf pipe + QApt::Transaction *trans = m_currentTransaction->aptTrans(); + if (!trans->debconfPipe().isEmpty()) + QFile::remove(trans->debconfPipe()); + + // Cleanup + trans->deleteLater(); + + if (trans->exitStatus() == QApt::ExitCancelled) + transModel->cancelTransaction(m_currentTransaction); + else + transModel->removeTransaction(m_currentTransaction); + m_transQueue.removeAll(m_currentTransaction); + + qobject_cast(m_currentTransaction->resource())->emitStateChanged(); + delete m_currentTransaction; + m_currentTransaction = nullptr; + + if (m_transQueue.isEmpty()) + reload(); + break; + } +} + +void ApplicationBackend::errorOccurred(QApt::ErrorCode error) +{ + if (m_transQueue.isEmpty()) // Shouldn't happen + return; + + if( error == QApt::AuthError){ + m_currentTransaction->cancel(); + m_transQueue.removeAll(m_currentTransaction); + m_currentTransaction->deleteLater(); + m_currentTransaction = nullptr; + } + QAptActions::self()->displayTransactionError(error, m_currentTransaction->aptTrans()); +} + +void ApplicationBackend::updateProgress(int percentage) +{ + if(!m_currentTransaction) { + qDebug() << "missing transaction"; + return; + } + m_currentTransaction->setProgress(percentage); +} + +bool ApplicationBackend::confirmRemoval(QApt::StateChanges changes) +{ + const QApt::PackageList removeList = changes.value(QApt::Package::ToRemove); + if (removeList.isEmpty()) + return true; + + QApt::StateChanges removals; + removals[QApt::Package::ToRemove] = removeList; + + QPointer dialog = new ChangesDialog(mainWindow(), removals); + bool ret = dialog->exec() == QDialog::Accepted; + delete dialog; + return ret; +} + +void ApplicationBackend::markTransaction(Transaction *transaction) +{ + Application *app = qobject_cast(transaction->resource()); + + switch (transaction->role()) { + case Transaction::InstallRole: + app->package()->setInstall(); + markLangpacks(transaction); + break; + case Transaction::RemoveRole: + app->package()->setRemove(); + break; + default: + break; + } + + AddonList addons = transaction->addons(); + + Q_FOREACH (const QString &pkgStr, addons.addonsToInstall()) { + QApt::Package *package = m_backend->package(pkgStr); + package->setInstall(); + } + + Q_FOREACH (const QString &pkgStr, addons.addonsToRemove()) { + QApt::Package *package = m_backend->package(pkgStr); + package->setRemove(); + } +} + +void ApplicationBackend::markLangpacks(Transaction *transaction) +{ + QString prog = QStandardPaths::findExecutable(QStringLiteral("check-language-support")); + if (prog.isEmpty()){ + prog = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("discover/scripts/check-language-support")); + if ( prog.isEmpty()){ + return; + } + } + + QString language = QLocale().name(); + QString pkgName = transaction->resource()->packageName(); + + QStringList args; + args << prog << QLatin1String("-l") << language << QLatin1String("-p") << pkgName; + + KProcess proc; + proc.setOutputChannelMode(KProcess::OnlyStdoutChannel); + proc.setProgram(args); + proc.start(); + proc.waitForFinished(); + + QString res = QString::fromLatin1(proc.readAllStandardOutput()); + res.remove(QString()); + + m_backend->setCompressEvents(true); + foreach(const QString &pkg, res.split(QLatin1Char(' '))) + { + QApt::Package *langPack = m_backend->package(pkg.trimmed()); + + if (langPack) + langPack->setInstall(); + } + m_backend->setCompressEvents(false); +} + +void ApplicationBackend::addTransaction(AptTransaction *transaction) +{ + if(!transaction){ + return; + } + QApt::CacheState oldCacheState = m_backend->currentCacheState(); + m_backend->saveCacheState(); + + markTransaction(transaction); + + // Find changes due to markings + QApt::PackageList excluded; + excluded.append(qobject_cast(transaction->resource())->package()); + // Exclude addons being marked + Q_FOREACH (const QString &pkgStr, transaction->addons().addonsToInstall()) { + QApt::Package *addon = m_backend->package(pkgStr); + + if (addon) + excluded.append(addon); + } + + Q_FOREACH (const QString &pkgStr, transaction->addons().addonsToRemove()) { + QApt::Package *addon = m_backend->package(pkgStr); + + if (addon) + excluded.append(addon); + } + + QApt::StateChanges changes = m_backend->stateChanges(oldCacheState, excluded); + + if (!confirmRemoval(changes)) { + m_backend->restoreCacheState(oldCacheState); + transaction->deleteLater(); + return; + } + + Application *app = qobject_cast(transaction->resource()); + + if (app->package()->wouldBreak()) { + m_backend->restoreCacheState(oldCacheState); + //TODO Notify of error + } + + QApt::Transaction *aptTrans = m_backend->commitChanges(); + setupTransaction(aptTrans); + transaction->setAptTrans(aptTrans); + TransactionModel::global()->addTransaction(transaction); + aptTrans->run(); + m_backend->restoreCacheState(oldCacheState); // Undo temporary simulation marking + + if (m_transQueue.count() == 1) { + aptTransactionsChanged(aptTrans->transactionId()); + m_currentTransaction = transaction; + } +} + +QApt::Backend* ApplicationBackend::backend() const +{ + return m_backend; +} + +AbstractReviewsBackend *ApplicationBackend::reviewsBackend() const +{ + return m_reviewsBackend; +} + +QVector ApplicationBackend::allResources() const +{ + QVector ret; + + Q_FOREACH (Application* app, m_appList) { + ret += app; + } + return ret; +} + +void ApplicationBackend::installApplication(AbstractResource* res, const AddonList& addons) +{ + Application* app = qobject_cast(res); + Transaction::Role role = app->package()->isInstalled() ? Transaction::ChangeAddonsRole : Transaction::InstallRole; + addTransaction(new AptTransaction(this, res, role, addons)); +} + +void ApplicationBackend::installApplication(AbstractResource* app) +{ + addTransaction(new AptTransaction(this, app, Transaction::InstallRole)); +} + +void ApplicationBackend::removeApplication(AbstractResource* app) +{ + addTransaction(new AptTransaction(this, app, Transaction::RemoveRole)); +} + +int ApplicationBackend::updatesCount() const +{ + if(m_isFetching) + return 0; + + int count = 0; + foreach(Application* app, m_appList) { + count += app->canUpgrade(); + } + return count; +} + +AbstractResource* ApplicationBackend::resourceByPackageName(const QString& name) const +{ + foreach(Application* app, m_appList) { + if(app->packageName()==name) + return app; + } + return nullptr; +} + +QList ApplicationBackend::searchPackageName(const QString& searchText) +{ + QList resources; + if(m_isFetching) { + qWarning() << "searching while fetching!!!"; + return resources; + } + + QSet packages = m_backend->search(searchText).toSet(); + + foreach(Application* a, m_appList) { + if(packages.contains(a->package())) { + resources += a; + } + } + return resources; +} + +AbstractBackendUpdater* ApplicationBackend::backendUpdater() const +{ + return m_backendUpdater; +} + +void ApplicationBackend::integrateActions(KActionCollection* w) +{ + m_aptify = w; + QAptActions* apt = QAptActions::self(); + apt->setActionCollection(w); + if(!m_aptBackendInitialized) + connect(this, &ApplicationBackend::aptBackendInitialized, apt, &QAptActions::setBackend); + if (apt->reloadWhenSourcesEditorFinished()) + connect(apt, &QAptActions::sourcesEditorClosed, this, &ApplicationBackend::reload); + QAction* updateAction = w->addAction(QStringLiteral("update")); + updateAction->setIcon(QIcon::fromTheme(QStringLiteral("system-software-update"))); + updateAction->setText(i18nc("@action Checks the Internet for updates", "Check for Updates")); + updateAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R)); + updateAction->setEnabled(apt->isConnected()); + connect(updateAction, &QAction::triggered, this, &ApplicationBackend::checkForUpdates); + connect(apt, &QAptActions::shouldConnect, updateAction, &QAction::setEnabled); +} + +QWidget* ApplicationBackend::mainWindow() const +{ + return QAptActions::self()->mainWindow(); +} + +void ApplicationBackend::initBackend() +{ + setFetching(true); + if (m_aptify) { + QAptActions::self()->setCanExit(false); + QAptActions::self()->setReloadWhenEditorFinished(true); + } + + QAptActions::self()->setBackend(m_backend); + if (m_backend->xapianIndexNeedsUpdate()) + m_backend->updateXapianIndex(); + + m_aptBackendInitialized = true; + emit aptBackendInitialized(m_backend); + + m_backend->setUndoRedoCacheSize(1); + m_reviewsBackend->setAptBackend(m_backend); + m_backendUpdater->setBackend(m_backend); + + QFuture > future = QtConcurrent::run(init, m_backend, QThread::currentThread()); + m_watcher->setFuture(future); + connect(m_backend, &QApt::Backend::transactionQueueChanged, this, &ApplicationBackend::aptTransactionsChanged); + connect(m_backend, &QApt::Backend::xapianUpdateFinished, this, &ApplicationBackend::searchInvalidated); + + SourcesModel::global()->addSourcesBackend(new AptSourcesBackend(this)); +} + +void ApplicationBackend::setupTransaction(QApt::Transaction *trans) +{ + // Provide proxy/locale to the transaction + if (KProtocolManager::proxyType() == KProtocolManager::ManualProxy) { + trans->setProxy(KProtocolManager::proxyFor(QStringLiteral("http"))); + } + + trans->setLocale(QLatin1String(setlocale(LC_MESSAGES, nullptr))); + + // Debconf + QString uuid = QUuid::createUuid().toString(); + uuid.remove(QLatin1Char('{')).remove(QLatin1Char('}')).remove(QLatin1Char('-')); + QFile pipe(QDir::tempPath() % QLatin1String("/qapt-sock-") % uuid); + pipe.open(QFile::ReadWrite); + pipe.close(); + trans->setDebconfPipe(pipe.fileName()); +} + +void ApplicationBackend::sourcesEditorClosed() +{ + reload(); + emit sourcesEditorFinished(); +} + +void ApplicationBackend::initAvailablePackages(KJob* j) +{ + KIO::StoredTransferJob* job = qobject_cast(j); + Q_ASSERT(job); + + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error); + if(error.error != QJsonParseError::NoError) + qWarning() << "errors!" << error.errorString(); + else { + QVariantList data = doc.toVariant().toMap().value(QStringLiteral("packages")).toList(); + Q_ASSERT(!m_appList.isEmpty()); + QSet packages; + foreach(const QVariant& v, data) { + packages += v.toMap().value(QStringLiteral("name")).toString(); + } + Q_ASSERT(packages.count()==data.count()); + Q_FOREACH (Application* a, m_appList) { + a->setHasScreenshot(packages.contains(a->packageName())); + } + } +} + +void ApplicationBackend::checkForUpdates() +{ + QApt::Transaction* transaction = backend()->updateCache(); + m_backendUpdater->setupTransaction(transaction); + transaction->run(); + m_backendUpdater->setProgressing(true); + connect(transaction, &QApt::Transaction::finished, this, &ApplicationBackend::updateFinished); +} + +void ApplicationBackend::updateFinished(QApt::ExitStatus status) +{ + if(status != QApt::ExitSuccess) { + qWarning() << "updating was not successful"; + } + m_backendUpdater->setProgressing(false); +} + +void ApplicationBackend::setFetching(bool f) +{ + if(m_isFetching != f) { + m_isFetching = f; + emit fetchingChanged(); + if(!m_isFetching) { + emit searchInvalidated(); + emit updatesCountChanged(); + } + } +} + +QList ApplicationBackend::messageActions() const +{ + QList ret; + //high priority + ret += QAptActions::self()->actionCollection()->action(QStringLiteral("dist-upgrade")); + + //normal priority + ret += QAptActions::self()->actionCollection()->action(QStringLiteral("update")); + + //low priority + ret += QAptActions::self()->actionCollection()->action(QStringLiteral("software_properties")); + ret += QAptActions::self()->actionCollection()->action(QStringLiteral("load_archives")); + ret += QAptActions::self()->actionCollection()->action(QStringLiteral("save_package_list")); + ret += QAptActions::self()->actionCollection()->action(QStringLiteral("download_from_list")); + ret += QAptActions::self()->actionCollection()->action(QStringLiteral("history")); + Q_ASSERT(!ret.contains(nullptr)); + return ret; +} + +#include "ApplicationBackend.moc" diff --git a/libdiscover/backends/ApplicationBackend/ApplicationBackend.h b/libdiscover/backends/ApplicationBackend/ApplicationBackend.h new file mode 100644 index 0000000..6e0b732 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/ApplicationBackend.h @@ -0,0 +1,128 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef APPLICATIONBACKEND_H +#define APPLICATIONBACKEND_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "resources/AbstractResourcesBackend.h" + +namespace QApt { + class Backend; + class Transaction; +} +namespace DebconfKde { + class DebconfGui; +} + +class Application; +class ApplicationUpdates; +class ReviewsBackend; +class Transaction; +class AptTransaction; +class QAptActions; +class KJob; + +class ApplicationBackend : public AbstractResourcesBackend +{ + Q_OBJECT + Q_PROPERTY(QObject* backend READ backend) +public: + explicit ApplicationBackend(QObject *parent = nullptr); + ~ApplicationBackend() override; + + bool isValid() const override; + AbstractReviewsBackend *reviewsBackend() const override; + Q_SCRIPTABLE AbstractResource* resourceByPackageName(const QString& name) const override; + QApt::Backend* backend() const; + + int updatesCount() const override; + + bool confirmRemoval(QApt::StateChanges changes); + bool isFetching() const override; + void markTransaction(Transaction *transaction); + void markLangpacks(Transaction *transaction); + + QVector< AbstractResource* > allResources() const override; + QList searchPackageName(const QString& searchText) override; + + void installApplication(AbstractResource *res, const AddonList& addons) override; + void installApplication(AbstractResource *app) override; + void removeApplication(AbstractResource *app) override; + + AbstractBackendUpdater* backendUpdater() const override; + void integrateActions(KActionCollection* w) override; + QWidget* mainWindow() const; + QList messageActions() const override; + +private: + void setFetching(bool f); + + QApt::Backend *m_backend; + ReviewsBackend *m_reviewsBackend; + bool m_isFetching; + + QFutureWatcher >* m_watcher; + QVector m_appList; + + // Transactions + QVector m_transQueue; + QPointer m_currentTransaction; + + DebconfKde::DebconfGui *m_debconfGui; + ApplicationUpdates* m_backendUpdater; + KActionCollection *m_aptify; + bool m_aptBackendInitialized; + +public Q_SLOTS: + void reload(); + void addTransaction(AptTransaction *transaction); + //helper functions + void initAvailablePackages(KJob*); + +private Q_SLOTS: + void setApplications(); + void aptTransactionsChanged(QString active); + void transactionEvent(QApt::TransactionStatus status); + void errorOccurred(QApt::ErrorCode error); + void updateProgress(int percentage); + void initBackend(); + void setupTransaction(QApt::Transaction *trans); + void sourcesEditorClosed(); + void checkForUpdates(); + void updateFinished(QApt::ExitStatus); + +Q_SIGNALS: + void startingFirstTransaction(); + void sourcesEditorFinished(); + void aptBackendInitialized(QApt::Backend* backend); +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp b/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp new file mode 100644 index 0000000..aba5dbc --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp @@ -0,0 +1,172 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#include "ApplicationNotifier.h" + +// Qt includes +#include +#include +#include +#include +#include +#include + +// KDE includes +#include +#include +#include +#include + +ApplicationNotifier::ApplicationNotifier(QObject* parent) + : BackendNotifierModule(parent) + , m_checkerProcess(Q_NULLPTR) + , m_updateCheckerProcess(Q_NULLPTR) + , m_securityUpdates(0) + , m_normalUpdates(0) +{ + KDirWatch *stampDirWatch = new KDirWatch(this); + stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/dpkg-run-stamp")); + connect(stampDirWatch, &KDirWatch::dirty, this, &ApplicationNotifier::distUpgradeEvent); + + QTimer* t = new QTimer(this); + t->setSingleShot(true); + t->setInterval(2000); + connect(t, &QTimer::timeout, this, &ApplicationNotifier::recheckSystemUpdateNeeded); + + stampDirWatch = new KDirWatch(this); + stampDirWatch->addDir(QStringLiteral("/var/lib/apt/lists/")); + stampDirWatch->addDir(QStringLiteral("/var/lib/apt/lists/partial/")); + stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/updates-available")); + stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/dpkg-run-stamp")); + connect(stampDirWatch, &KDirWatch::dirty, t, static_cast(&QTimer::start)); +// connect(stampDirWatch, &KDirWatch::dirty, this, [](const QString& dirty){ qDebug() << "dirty path" << dirty;}); + + m_updateCheckerProcess = new QProcess(this); + m_updateCheckerProcess->setProgram(QStringLiteral("/usr/lib/update-notifier/apt-check")); + connect(m_updateCheckerProcess, static_cast(&QProcess::finished), this, &ApplicationNotifier::parseUpdateInfo); + + init(); +} + +ApplicationNotifier::~ApplicationNotifier() = default; + +void ApplicationNotifier::init() +{ + recheckSystemUpdateNeeded(); + distUpgradeEvent(); +} + +void ApplicationNotifier::distUpgradeEvent() +{ + QString checkerFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/applicationsbackend/releasechecker")); + if (checkerFile.isEmpty()) { + qWarning() << "Couldn't find the releasechecker" << checkerFile << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); + return; + } + m_checkerProcess = new QProcess(this); + connect(m_checkerProcess, static_cast(&QProcess::finished), this, &ApplicationNotifier::checkUpgradeFinished); + m_checkerProcess->start(QStringLiteral("/usr/bin/python3"), QStringList() << checkerFile); +} + +void ApplicationNotifier::checkUpgradeFinished(int exitStatus) +{ + if (exitStatus == 0) { + KNotification *n = KNotification::event(QStringLiteral("DistUpgrade"), + i18n("System update available!"), + i18nc("Notification when a new version of Kubuntu is available", + "A new version of Kubuntu is available"), + QStringLiteral("system-software-update"), + nullptr, + KNotification::CloseOnTimeout, + QStringLiteral("muonapplicationnotifier")); + n->setActions(QStringList() << i18n("Upgrade")); + connect(n, &KNotification::action1Activated, this, &ApplicationNotifier::upgradeActivated); + } + + m_checkerProcess->deleteLater(); + m_checkerProcess = nullptr; +} + +void ApplicationNotifier::upgradeActivated() +{ + const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu"); + QProcess::startDetached(kdesu, { QStringLiteral("--"), QStringLiteral("do-release-upgrade"), QStringLiteral("-m"), QStringLiteral("desktop"), QStringLiteral("-f"), QStringLiteral("DistUpgradeViewKDE") }); +} + +void ApplicationNotifier::recheckSystemUpdateNeeded() +{ + qDebug() << "should recheck..." << m_updateCheckerProcess << m_updateCheckerProcess->state(); + + if (m_updateCheckerProcess->state() == QProcess::Running) + return; + + m_updateCheckerProcess->start(); +} + +void ApplicationNotifier::parseUpdateInfo() +{ + if (!m_updateCheckerProcess) + return; + +#warning why does this parse stdout and not use qapt, wtf... + // Weirdly enough, apt-check gives output on stderr + QByteArray line = m_updateCheckerProcess->readAllStandardError(); + if (line.isEmpty()) + return; + + // Format updates;security + int eqpos = line.indexOf(';'); + + if (eqpos > 0) { + QByteArray updatesString = line.left(eqpos); + QByteArray securityString = line.right(line.size() - eqpos - 1); + + int securityUpdates = securityString.toInt(); + setUpdates(updatesString.toInt() - securityUpdates, securityUpdates); + } else { + //if the format is wrong consider as up to date + setUpdates(0, 0); + } +} + +void ApplicationNotifier::setUpdates(int normal, int security) +{ + if (m_normalUpdates != normal || security != m_securityUpdates) { + m_normalUpdates = normal; + m_securityUpdates = security; + emit foundUpdates(); + } +} + +bool ApplicationNotifier::isSystemUpToDate() const +{ + return (m_securityUpdates+m_normalUpdates)==0; +} + +uint ApplicationNotifier::securityUpdatesCount() +{ + return m_securityUpdates; +} + +uint ApplicationNotifier::updatesCount() +{ + return m_normalUpdates; +} + +#include "ApplicationNotifier.moc" diff --git a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h b/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h new file mode 100644 index 0000000..3b46ac3 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#ifndef APPLICATIONNOTIFIER_H +#define APPLICATIONNOTIFIER_H + +#include +#include + +class DistUpgradeEvent; +class UpdateEvent; +class QProcess; + +class ApplicationNotifier : public BackendNotifierModule +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kde.discover.BackendNotifierModule") + Q_INTERFACES(BackendNotifierModule) +public: + explicit ApplicationNotifier(QObject* parent = nullptr); + ~ApplicationNotifier() override; + + bool isSystemUpToDate() const final; + uint securityUpdatesCount() final; + uint updatesCount() final; + +private Q_SLOTS: + void checkUpgradeFinished(int exitStatus); + void distUpgradeEvent(); + void recheckSystemUpdateNeeded() final; + void parseUpdateInfo(); + void upgradeActivated(); + void init(); + +private: + void setUpdates(int normal, int security); + + QProcess *m_checkerProcess; + QProcess *m_updateCheckerProcess; + int m_securityUpdates; + int m_normalUpdates; +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp b/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp new file mode 100644 index 0000000..b283473 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp @@ -0,0 +1,467 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ApplicationUpdates.h" + +// Qt includes +#include +#include +#include + +// KDE includes +#include +#include +#include +#include +#include + +// Own includes +#include + +#include +#include +#include + +#include "Application.h" +#include "ApplicationBackend.h" + +ApplicationUpdates::ApplicationUpdates(ApplicationBackend* parent) + : AbstractBackendUpdater(parent) + , m_aptBackend(nullptr) + , m_appBackend(parent) + , m_lastRealProgress(0) + , m_eta(0) + , m_progressing(false) +{ + connect(m_appBackend, &ApplicationBackend::fetchingChanged, this, &ApplicationUpdates::fetchingChanged); +} + +bool ApplicationUpdates::hasUpdates() const +{ + return m_appBackend->updatesCount()>0; +} + +qreal ApplicationUpdates::progress() const +{ + return m_lastRealProgress; +} + +long unsigned int ApplicationUpdates::remainingTime() const +{ + return m_eta; +} + +void ApplicationUpdates::setBackend(QApt::Backend* backend) +{ + Q_ASSERT(!m_aptBackend || m_aptBackend==backend); + m_aptBackend = backend; + // FIXME: Debconf support was lost during the port + QApt::FrontendCaps caps = (QApt::FrontendCaps)(QApt::MediumPromptCap | + QApt::ConfigPromptCap | QApt::UntrustedPromptCap); + m_aptBackend->setFrontendCaps(caps); +} + +QList ApplicationUpdates::toUpdate() const +{ + return m_toUpdate; +} + +void ApplicationUpdates::restoreToCleanCache() +{ + if(!m_updatesCache.isEmpty()) + m_aptBackend->restoreCacheState(m_updatesCache); + else { + //this is my best bet for retrieving a clean cache, I'm unsure if there's a better way + m_updatesCache = m_aptBackend->currentCacheState(); + } + Q_ASSERT(m_aptBackend->markedPackages().isEmpty()); +} + +void ApplicationUpdates::prepare() +{ + restoreToCleanCache(); + + m_aptBackend->markPackagesForDistUpgrade(); + calculateUpdates(); +} + +void ApplicationUpdates::start() +{ + Q_ASSERT(!m_updatesCache.isEmpty()); + auto changes = m_aptBackend->stateChanges(m_updatesCache, QApt::PackageList()); + if(changes.isEmpty()) { + qWarning() << "couldn't find any apt updates"; + setProgressing(false); + return; + } + for(auto it=changes.begin(); it!=changes.end(); ) { + if(it.key()&QApt::Package::ToUpgrade) { + it = changes.erase(it); + } else { + ++it; + } + } + // Confirm additional changes beyond upgrading the files + if(!changes.isEmpty()) { + ChangesDialog d(m_appBackend->mainWindow(), changes); + if(d.exec()==QDialog::Rejected) { + setProgressing(false); + return; + } + } + + // Create and run the transaction + setupTransaction(m_aptBackend->commitChanges()); + m_trans->run(); + setProgressing(true); +} + +void ApplicationUpdates::addResources(const QList& apps) +{ + if (apps.size() > 1) { + QApplication::setOverrideCursor(Qt::WaitCursor); + } + QList packages; + foreach(AbstractResource* res, apps) { + Application* app = qobject_cast(res); + Q_ASSERT(app); + packages += app->package(); + } + m_aptBackend->markPackages(packages, QApt::Package::ToInstall); + QApplication::restoreOverrideCursor(); +} + +void ApplicationUpdates::removeResources(const QList& apps) +{ + QList packages; + foreach(AbstractResource* res, apps) { + Application* app = qobject_cast(res); + Q_ASSERT(app); + packages += app->package(); + } + m_aptBackend->markPackages(packages, QApt::Package::ToKeep); +} + +void ApplicationUpdates::setProgress(int progress) +{ + if (progress > 100) + return; + + if (progress > m_lastRealProgress || progress<0) { + m_lastRealProgress = progress; + emit progressChanged((qreal)progress); + } +} + +void ApplicationUpdates::etaChanged(quint64 eta) +{ + if(m_eta != eta) { + m_eta = eta; + emit remainingTimeChanged(); + } +} + +void ApplicationUpdates::installMessage(const QString& msg) +{ + setStatusMessage(msg); +} + +void ApplicationUpdates::errorOccurred(QApt::ErrorCode error) +{ + if(error!=QApt::Success) { + QAptActions::self()->displayTransactionError(error, m_trans); + setProgressing(false); + } +} + +void ApplicationUpdates::setupTransaction(QApt::Transaction *trans) +{ + Q_ASSERT(trans); + m_trans = trans; + + // Provide proxy/locale to the transaction + if (KProtocolManager::proxyType() == KProtocolManager::ManualProxy) { + trans->setProxy(KProtocolManager::proxyFor(QStringLiteral("http"))); + } + + trans->setLocale(QLatin1String(setlocale(LC_MESSAGES, nullptr))); + + connect(trans, SIGNAL(errorOccurred(QApt::ErrorCode)), + SLOT(errorOccurred(QApt::ErrorCode))); + connect(trans, SIGNAL(progressChanged(int)), SLOT(setProgress(int))); + connect(trans, SIGNAL(statusDetailsChanged(QString)), SLOT(installMessage(QString))); + connect(trans, SIGNAL(cancellableChanged(bool)), SIGNAL(cancelableChanged(bool))); + connect(trans, SIGNAL(finished(QApt::ExitStatus)), trans, SLOT(deleteLater())); + connect(trans, SIGNAL(statusChanged(QApt::TransactionStatus)), + this, SLOT(statusChanged(QApt::TransactionStatus))); + connect(trans, SIGNAL(mediumRequired(QString,QString)), + this, SLOT(provideMedium(QString,QString))); + connect(trans, SIGNAL(promptUntrusted(QStringList)), + this, SLOT(untrustedPrompt(QStringList))); + connect(trans, SIGNAL(configFileConflict(QString,QString)), + this, SLOT(configFileConflict(QString,QString))); + connect(trans, SIGNAL(downloadSpeedChanged(quint64)), + this, SIGNAL(downloadSpeedChanged(quint64))); + connect(trans, SIGNAL(finished(QApt::ExitStatus)), + this, SLOT(transactionFinished(QApt::ExitStatus))); +} + +void ApplicationUpdates::transactionFinished(QApt::ExitStatus ) +{ + m_lastRealProgress = 0; + m_updatesCache.clear(); + m_toUpdate.clear(); + m_appBackend->reload(); + setProgressing(false); +} + + +QDateTime ApplicationUpdates::lastUpdate() const +{ + return m_aptBackend->timeCacheLastUpdated(); +} + +bool ApplicationUpdates::isCancelable() const +{ + return m_trans && m_trans->isCancellable(); +} + +bool ApplicationUpdates::isProgressing() const +{ + return m_progressing; +} + +void ApplicationUpdates::provideMedium(const QString &label, const QString &medium) +{ + QString title = i18nc("@title:window", "Media Change Required"); + QString text = xi18nc("@label", "Please insert %1 into %2", + label, medium); + + KMessageBox::information(QAptActions::self()->mainWindow(), text, title); + m_trans->provideMedium(medium); +} + +void ApplicationUpdates::untrustedPrompt(const QStringList &untrustedPackages) +{ + QString title = i18nc("@title:window", "Warning - Unverified Software"); + QString text = xi18ncp("@label", + "The following piece of software cannot be verified. " + "Installing unverified software represents a " + "security risk, as the presence of unverifiable software " + "can be a sign of tampering. Do you wish to continue?", + "The following pieces of software cannot be verified. " + "Installing unverified software represents a " + "security risk, as the presence of unverifiable software " + "can be a sign of tampering. Do you wish to continue?", + untrustedPackages.size()); + int result = KMessageBox::warningContinueCancelList(QAptActions::self()->mainWindow(), + text, untrustedPackages, title); + + bool installUntrusted = (result == KMessageBox::Continue); + m_trans->replyUntrustedPrompt(installUntrusted); +} + +void ApplicationUpdates::configFileConflict(const QString ¤tPath, const QString &newPath) +{ + QString title = i18nc("@title:window", "Configuration File Changed"); + QString text = xi18nc("@label Notifies a config file change", + "A new version of the configuration file " + "%1 is available, but your version has " + "been modified. Would you like to keep your current version " + "or install the new version?", currentPath); + + KGuiItem useNew(i18nc("@action Use the new config file", "Use New Version")); + KGuiItem useOld(i18nc("@action Keep the old config file", "Keep Old Version")); + + // TODO: diff current and new paths + Q_UNUSED(newPath) + + int ret = KMessageBox::questionYesNo(QAptActions::self()->mainWindow(), text, title, useNew, useOld); + + m_trans->resolveConfigFileConflict(currentPath, (ret == KMessageBox::Yes)); +} + +void ApplicationUpdates::statusChanged(QApt::TransactionStatus status) +{ + switch (status) { + case QApt::SetupStatus: + setProgressing(true); + setStatusMessage(i18nc("@info Status info, widget title", + "Starting")); + setProgress(-1); + break; + case QApt::AuthenticationStatus: + setStatusMessage(i18nc("@info Status info, widget title", + "Waiting for Authentication")); + setProgress(-1); + break; + case QApt::WaitingStatus: + setStatusMessage(i18nc("@info Status information, widget title", + "Waiting")); + setStatusDetail(i18nc("@info Status info", + "Waiting for other transactions to finish")); + setProgress(-1); + break; + case QApt::WaitingLockStatus: + setStatusMessage(i18nc("@info Status information, widget title", + "Waiting")); + setStatusDetail(i18nc("@info Status info", + "Waiting for other software managers to quit")); + setProgress(-1); + break; + case QApt::WaitingMediumStatus: + setStatusMessage(i18nc("@info Status information, widget title", + "Waiting")); + setStatusDetail(i18nc("@info Status info", + "Waiting for required medium")); + setProgress(-1); + break; + case QApt::WaitingConfigFilePromptStatus: + setStatusMessage(i18nc("@info Status information, widget title", + "Waiting")); + setStatusDetail(i18nc("@info Status info", + "Waiting for configuration file")); + setProgress(-1); + break; + case QApt::RunningStatus: + setStatusMessage(QString()); + setStatusDetail(QString()); + break; + case QApt::LoadingCacheStatus: + setStatusDetail(QString()); + setStatusMessage(i18nc("@info Status info", + "Loading Software List")); + break; + case QApt::DownloadingStatus: + switch (m_trans->role()) { + case QApt::UpdateCacheRole: + setStatusMessage(i18nc("@info Status information, widget title", + "Updating software sources")); + break; + case QApt::DownloadArchivesRole: + case QApt::CommitChangesRole: + setStatusMessage(i18nc("@info Status information, widget title", + "Downloading Packages")); + break; + default: + break; + } + break; + case QApt::CommittingStatus: + emit downloadSpeedChanged(-1); + setStatusMessage(i18nc("@info Status information, widget title", + "Applying Changes")); + setStatusDetail(QString()); + break; + case QApt::FinishedStatus: + setProgress(100); + setStatusMessage(i18nc("@info Status information, widget title", + "Finished")); + break; + } +} + +void ApplicationUpdates::setProgressing(bool progressing) +{ + if(progressing!=m_progressing) { + m_progressing = progressing; + emit progressingChanged(progressing); + + if(m_progressing) + setProgress(-1); + else + restoreToCleanCache(); + } +} + +void ApplicationUpdates::setStatusDetail(const QString& msg) +{ + if(m_statusDetail!=msg) { + m_statusDetail = msg; + emit statusDetailChanged(msg); + } +} + +void ApplicationUpdates::setStatusMessage(const QString& msg) +{ + if(m_statusMessage!=msg) { + m_statusMessage = msg; + emit statusMessageChanged(msg); + } +} + +QString ApplicationUpdates::statusDetail() const +{ + return m_statusDetail; +} + +QString ApplicationUpdates::statusMessage() const +{ + return m_statusMessage; +} + +void ApplicationUpdates::cancel() +{ + Q_ASSERT(m_trans->isCancellable()); + m_trans->cancel(); +} + +quint64 ApplicationUpdates::downloadSpeed() const +{ + return m_trans->downloadSpeed(); +} + +void ApplicationUpdates::fetchingChanged() +{ + if(m_appBackend && m_appBackend->isFetching()) + return; + + calculateUpdates(); + setProgressing(false); +} + +void ApplicationUpdates::calculateUpdates() +{ + m_toUpdate.clear(); + auto changes = m_aptBackend->stateChanges(m_updatesCache, QApt::PackageList()); + Q_FOREACH (const auto &pkgList, changes) { + Q_FOREACH (QApt::Package* it, pkgList) { + AbstractResource* res = m_appBackend->resourceByPackageName(it->name()); + if(!res) //If we couldn't find it by its name, try with + res = m_appBackend->resourceByPackageName(QStringLiteral("%1:%2").arg(it->name()).arg(it->architecture())); + + if(res) { + if (res->state() == Application::Upgradeable) + m_toUpdate += res; + } else { + qWarning() << "Couldn't find the package:" << it->name(); + } + Q_ASSERT(res); + } + } +} + +bool ApplicationUpdates::isMarked(AbstractResource* res) const +{ + Q_ASSERT(!res->backend()->isFetching()); + Application* app = qobject_cast(res); + Q_ASSERT(app); + return app->package()->state() & QApt::Package::ToInstall; +} diff --git a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h b/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h new file mode 100644 index 0000000..e30b8a4 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef APPLICATIONUPDATES_H +#define APPLICATIONUPDATES_H + +// Qt includes +#include +#include + +// QApt includes +#include + +// Own includes +#include "resources/AbstractBackendUpdater.h" + +namespace QApt { + class Backend; + class Transaction; +} + +class ApplicationBackend; + +class ApplicationUpdates : public AbstractBackendUpdater +{ + Q_OBJECT +public: + explicit ApplicationUpdates(ApplicationBackend* parent); + + bool hasUpdates() const override; + qreal progress() const override; + void start() override; + void setBackend(QApt::Backend* backend); + long unsigned int remainingTime() const override; + void addResources(const QList& apps) override; + void removeResources(const QList& apps) override; + QList toUpdate() const override; + QDateTime lastUpdate() const override; + bool isCancelable() const override; + bool isProgressing() const override; + QString statusDetail() const override; + QString statusMessage() const override; + void cancel() override; + quint64 downloadSpeed() const override; + void prepare() override; + void setupTransaction(QApt::Transaction *trans); + bool isMarked(AbstractResource* res) const override; + void setProgressing(bool progressing); + +private: + void restoreToCleanCache(); + + QPointer m_trans; + QApt::Backend* m_aptBackend; + ApplicationBackend* m_appBackend; + int m_lastRealProgress; + long unsigned int m_eta; + QApt::CacheState m_updatesCache; + bool m_progressing; + QString m_statusMessage; + QString m_statusDetail; + QList m_toUpdate; + +private Q_SLOTS: + void errorOccurred(QApt::ErrorCode error); + void setProgress(int progress); + void etaChanged(quint64 eta); + void installMessage(const QString& message); + void provideMedium(const QString &label, const QString &medium); + void untrustedPrompt(const QStringList &untrustedPackages); + void configFileConflict(const QString ¤tPath, const QString &newPath); + void statusChanged(QApt::TransactionStatus status); + void setStatusMessage(const QString& msg); + void setStatusDetail(const QString& msg); + void fetchingChanged(); + void calculateUpdates(); + void transactionFinished(QApt::ExitStatus); +}; + +#endif // APPLICATIONUPDATES_H diff --git a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp b/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp new file mode 100644 index 0000000..067a69a --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp @@ -0,0 +1,244 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "AptSourcesBackend.h" +#include "ApplicationBackend.h" +#include +#include +#include +#include +#include +#include +#include +#include + +class EntryItem : public QStandardItem +{ +public: + explicit EntryItem(const QApt::SourceEntry &sEntry) + : m_sEntry(sEntry) + {} + QApt::SourceEntry& sourceEntry() { return m_sEntry; } + +private: + QApt::SourceEntry m_sEntry; +}; + +class SourceItem : public QStandardItem +{ +public: + explicit SourceItem(QUrl uri) + : m_uri(std::move(uri)) + {} + + QVariant data(int role = Qt::UserRole + 1) const override; + QUrl uri() const { return m_uri; } + +private: + QUrl m_uri; +}; + +AptSourcesBackend::AptSourcesBackend(ApplicationBackend* backend) + : AbstractSourcesBackend(backend) + , m_sources(new QStandardItemModel(this)) +{ + connect(backend, SIGNAL(fetchingChanged()), SLOT(load()), Qt::UniqueConnection); + if (!backend->isFetching()) { + load(); + } +} + +void AptSourcesBackend::load() +{ + m_sources->clear(); + + Q_FOREACH (const QApt::SourceEntry &sEntry, m_sourcesList.entries()) { + if (!sEntry.isValid()) { + continue; +} + + SourceItem* newSource = sourceForUri(sEntry.uri()); + auto entry = new EntryItem(sEntry); + newSource->appendRow(entry); + } +} + +SourceItem* AptSourcesBackend::sourceForUri(const QString& uri) +{ + QUrl uriUrl(uri); + + for(int r = 0, c = m_sources->rowCount(); r(m_sources->item(r)); + if(s->uri()==uriUrl) + return s; + } + SourceItem* s = new SourceItem(uriUrl); + s->setData(uriUrl, UriRole); + m_sources->appendRow(s); + return s; +} + +QAbstractItemModel* AptSourcesBackend::sources() +{ + return m_sources; +} + +bool AptSourcesBackend::removeSource(const QString& repository) +{ + KAuth::Action readAction(QStringLiteral("org.kde.discover.repo.modify")); + readAction.setHelperId(QStringLiteral("org.kde.discover.repo")); + QVariantMap args = { + { QStringLiteral("repository"), repository }, + { QStringLiteral("action"), QStringLiteral("remove") } + }; + readAction.setArguments(args); + qDebug() << "removing..." << args; + KAuth::ExecuteJob* reply = readAction.execute(); + removalDone(reply->error()); + return true; +} + +bool AptSourcesBackend::addSource(const QString& repository) +{ + KAuth::Action readAction(QStringLiteral("org.kde.discover.repo.modify")); + readAction.setHelperId(QStringLiteral("org.kde.discover.repo")); + QVariantMap args = { + { QStringLiteral("repository"), repository }, + { QStringLiteral("action"), QStringLiteral("add") } + }; + readAction.setArguments(args); + qDebug() << "adding..." << args; + KAuth::ExecuteJob* reply = readAction.execute(); + additionDone(reply->error()); + return true; +} + +void AptSourcesBackend::additionDone(int processErrorCode) +{ + if(processErrorCode==0) { + load(); + QMetaObject::invokeMethod(appsBackend(), "reload"); + } else { + QProcess* p = qobject_cast(sender()); + Q_ASSERT(p); + QByteArray errorMessage = p->readAllStandardOutput(); + if(!errorMessage.isEmpty()) + KMessageBox::error(0, QString::fromUtf8(errorMessage), i18n("Adding Origins...")); + } +} + +void AptSourcesBackend::removalDone(int processErrorCode) +{ + if(processErrorCode==0) { + load(); + QMetaObject::invokeMethod(appsBackend(), "reload"); + } else { + QProcess* p = qobject_cast(sender()); + Q_ASSERT(p); + QByteArray errorMessage = p->readAllStandardOutput(); + if(!errorMessage.isEmpty()) + KMessageBox::error(0, QString::fromUtf8(errorMessage), i18n("Removing Origins...")); + } +} + +ApplicationBackend* AptSourcesBackend::appsBackend() const +{ + return qobject_cast(parent()); +} + +QVariant SourceItem::data(int role) const +{ + switch(role) { + case Qt::DisplayRole: { +// modelData.name=="" ? modelData.uri : i18n("%1. %2", modelData.name, modelData.uri) + QApt::Backend* backend = qobject_cast(model()->parent())->appsBackend()->backend(); + QStringList origins = !m_uri.host().isEmpty() ? backend->originsForHost(m_uri.host()) : QStringList(); + + if(origins.size()==1) + return origins.first(); + else if(origins.size()==0) + return m_uri.toDisplayString(); + else { + QString path = m_uri.path(); + int firstSlash = path.indexOf(QLatin1Char('/'), 1); + int secondSlash = path.indexOf(QLatin1Char('/'), firstSlash+1); + QString launchpadifyUri = path.mid(1,secondSlash-1).replace(QLatin1Char('/'), QLatin1Char('-')); + QStringList results = origins.filter(launchpadifyUri, Qt::CaseInsensitive); + if(results.isEmpty()) { + launchpadifyUri = path.mid(1,firstSlash-1).replace(QLatin1Char('/'), QLatin1Char('-')); + results = origins.filter(launchpadifyUri, Qt::CaseInsensitive); + } + return results.isEmpty() ? QString() : results.first(); + } + } + case Qt::ToolTipRole: { + QMap vals; + for(int i=0, c=rowCount(); i(child(i)); + + QString suite = entry->sourceEntry().dist(); + if(!vals.contains(suite)) + vals[suite]=0; + + bool hasSource = entry->sourceEntry().type() == QLatin1String("deb-src"); + if(hasSource) + vals[suite] += 2; + else + vals[suite] += 1; + } + QStringList ret; + Q_FOREACH (const QString& e, vals.keys()) { + if(vals[e]>1) + ret.append(e); + else + ret.append(i18n("%1 (Binary)", e)); + } + + return ret.join(QStringLiteral(", ")); + } + default: + return QStandardItem::data(role); + } +} + +QString AptSourcesBackend::idDescription() +{ + return i18n( " - The apt repository source line to add. This is one of:\n" + " a complete apt line, \n" + " a repo url and areas (areas defaults to 'main')\n" + " a PPA shortcut.\n\n" + + " Examples:\n" + " deb http://myserver/path/to/repo stable myrepo\n" + " http://myserver/path/to/repo myrepo\n" + " https://packages.medibuntu.org free non-free\n" + " http://extras.ubuntu.com/ubuntu\n" + " ppa:user/repository"); +} + +QString AptSourcesBackend::name() const +{ + return i18n("Software Management"); +} + +QList AptSourcesBackend::actions() const +{ + return { QAptActions::self()->actionCollection()->action(QStringLiteral("software_properties")) }; +} diff --git a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h b/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h new file mode 100644 index 0000000..b7dcc82 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef APTSOURCESBACKEND_H +#define APTSOURCESBACKEND_H + +#include +#include +#include + +class ApplicationBackend; +class SourceItem; + +class AptSourcesBackend : public AbstractSourcesBackend +{ +Q_OBJECT +public: + enum Roles { + UriRole + }; + + explicit AptSourcesBackend(ApplicationBackend* backend); + QAbstractItemModel* sources() override; + bool removeSource(const QString& repository) override; + bool addSource(const QString& repository) override; + QString idDescription() override; + QString name() const override; + ApplicationBackend* appsBackend() const; + QList actions() const override; + +private Q_SLOTS: + void load(); + void removalDone(int processErrorCode); + void additionDone(int processErrorCode); + +private: + SourceItem* sourceForUri(const QString& uri); + + QStandardItemModel* m_sources; + QApt::SourcesList m_sourcesList; +}; + +#endif // APTSOURCESBACKEND_H diff --git a/libdiscover/backends/ApplicationBackend/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/CMakeLists.txt new file mode 100644 index 0000000..cc7b35f --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/CMakeLists.txt @@ -0,0 +1,53 @@ +# we will have our own fork of the library now, because they haven't still made their mind out of Qt5 +# find_package(QtOAuth REQUIRED) +add_subdirectory(qoauth) +add_subdirectory(libmuonapt) + +include_directories(.) + +add_subdirectory(tests) + +set(appsbackend_SRCS + ApplicationBackend.cpp + Application.cpp + ApplicationUpdates.cpp + ReviewsBackend.cpp #TODO: rename to AptReviewsBackend + UbuntuLoginBackend.cpp + AptSourcesBackend.cpp +) + +qt5_add_dbus_interface(appsbackend_SRCS ubuntu_sso_dbus_interface.xml ubuntu_sso OPTIONS -i "LoginMetaTypes.h") + +add_library(qapt-backend MODULE ${appsbackend_SRCS}) +target_link_libraries(qapt-backend Qt5::Widgets Qt5::DBus Qt5::Concurrent + KF5::Archive KF5::KIOWidgets KF5::XmlGui DebconfKDE::Main KF5::IconThemes AppstreamQt + Muon::QOAuth QApt::Main Discover::Common MuonApt +) +target_include_directories(qapt-backend PRIVATE /usr/include/Qca-qt5/QtCrypto) + +install(TARGETS qapt-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover) +install(FILES qapt-backend.desktop DESTINATION ${DATA_INSTALL_DIR}/libdiscover/backends) +install(FILES distupgradeevent/releasechecker DESTINATION ${DATA_INSTALL_DIR}/libdiscover/applicationsbackend/ + PERMISSIONS + OWNER_EXECUTE OWNER_READ OWNER_WRITE + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ +) + +foreach(testing IN ITEMS ON OFF) + set(name MuonApplicationNotifier) + set(type MODULE) + if(${testing}) + set(name MuonApplicationNotifierTestLib) + set(type STATIC) + endif() + add_library(${name} ${type} ApplicationNotifier.cpp) + target_compile_definitions(${name} PRIVATE -DCMAKE_INSTALL_FULL_LIBEXECDIR_KF5=\"${CMAKE_INSTALL_FULL_LIBEXECDIR_KF5}\") + target_link_libraries(${name} KF5::CoreAddons KF5::I18n KF5::Notifications KF5::IconThemes Discover::Notifiers) +endforeach() + +install(TARGETS MuonApplicationNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier) +install(FILES muonapplicationnotifier.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR}) + +install(FILES ../PackageKitBackend/packagekit-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories/ RENAME qapt-backend-categories.xml) +# add_subdirectory(${CMAKE_SOURCE_DIR}/libdiscover/backends/PackageKitBackend/categoryimages) diff --git a/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp b/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp new file mode 100644 index 0000000..ae97868 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp @@ -0,0 +1,411 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ReviewsBackend.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include "UbuntuLoginBackend.h" +#include +#include + +static QString getCodename(const QString& value) +{ + QString ret; + QFile f(QStringLiteral("/etc/os-release")); + if(f.open(QIODevice::ReadOnly|QIODevice::Text)) { + QRegExp rx(QStringLiteral("%1=(.+)\n").arg(value)); + while(!f.atEnd()) { + QString line = QString::fromLatin1(f.readLine()); + if(rx.exactMatch(line)) { + ret = rx.cap(1); + break; + } + } + } + return ret; +} + +ReviewsBackend::ReviewsBackend(QObject *parent) + : AbstractReviewsBackend(parent) + , m_aptBackend(nullptr) + , m_serverBase(MuonDataSources::rnRSource()) +{ + m_distId = getCodename(QStringLiteral("ID")); + m_loginBackend = new UbuntuLoginBackend(this); + connect(m_loginBackend, &AbstractLoginBackend::connectionStateChanged, this, &ReviewsBackend::loginStateChanged); + connect(m_loginBackend, &AbstractLoginBackend::connectionStateChanged, this, &ReviewsBackend::refreshConsumerKeys); + m_oauthInterface = new QOAuth::Interface(this); + + QMetaObject::invokeMethod(this, "fetchRatings", Qt::QueuedConnection); +} + +ReviewsBackend::~ReviewsBackend() = default; + +void ReviewsBackend::refreshConsumerKeys() +{ + if(m_loginBackend->hasCredentials()) { + m_oauthInterface->setConsumerKey(m_loginBackend->consumerKey()); + m_oauthInterface->setConsumerSecret(m_loginBackend->consumerSecret()); + + QList >::const_iterator it, itEnd; + for(it=m_pendingRequests.constBegin(), itEnd=m_pendingRequests.constEnd(); it!=itEnd; ++it) { + postInformation(it->first, it->second); + } + m_pendingRequests.clear(); + } +} + +void ReviewsBackend::setAptBackend(QApt::Backend *aptBackend) +{ + m_aptBackend = aptBackend; +} + +// void ReviewsBackend::clearReviewCache() +// { +// foreach (QList reviewList, m_reviewsCache) { +// qDeleteAll(reviewList); +// } +// +// m_reviewsCache.clear(); +// } + +void ReviewsBackend::fetchRatings() +{ + QString ratingsCache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/libdiscover/ratings.txt"); + QFileInfo file(ratingsCache); + QDir::temp().mkpath(file.dir().path()); + QUrl ratingsUrl(m_serverBase.toString()+QStringLiteral("review-stats/")); + //default to popcon if not using ubuntu + if(m_distId.toLower() == QLatin1String("ubuntu")){ + refreshConsumerKeys(); + // First, load our old ratings cache in case we don't have net connectivity + loadRatingsFromFile(); + // Try to fetch the latest ratings from the internet + } else { + ratingsUrl = QUrl(QStringLiteral("http://popcon.debian.org/all-popcon-results.gz")); + } + KIO::FileCopyJob *getJob = KIO::file_copy(ratingsUrl, QUrl::fromLocalFile(ratingsCache), -1, + KIO::Overwrite | KIO::HideProgressInfo); + connect(getJob, &KIO::FileCopyJob::result, this, &ReviewsBackend::ratingsFetched); +} + +void ReviewsBackend::ratingsFetched(KJob *job) +{ + if (job->error()) { + qWarning() << "Couldn't fetch the ratings" << job->errorString(); + return; + } + + loadRatingsFromFile(); +} + +void ReviewsBackend::loadRatingsFromFile() +{ + QString ratingsCache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/ratings.txt"); + QScopedPointer dev(new KCompressionDevice(ratingsCache, KCompressionDevice::GZip)); + if (!dev->open(QIODevice::ReadOnly)) { + qWarning() << "Couldn't open ratings.txt" << ratingsCache; + return; + } + if(m_distId.toLower() == QLatin1String("ubuntu")) { + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(dev->readAll(), &error); + + if (error.error != QJsonParseError::NoError) { + qDebug() << "error while parsing ratings: " << ratingsCache; + return; + } + + QVariant ratings = doc.toVariant(); + qDeleteAll(m_ratings); + m_ratings.clear(); + foreach (const QVariant &data, ratings.toList()) { + Rating *rating = new Rating(data.toMap()); + if (rating->ratingCount() == 0u) { + delete rating; + continue; + } + rating->setParent(this); + m_ratings[rating->packageName()] = rating; + } + } else { + qDeleteAll(m_ratings); + m_ratings = PopConParser::parsePopcon(this, dev.data()); + } + emit ratingsReady(); +} + +Rating *ReviewsBackend::ratingForApplication(AbstractResource* app) const +{ + return m_ratings.value(app->packageName()); +} + +void ReviewsBackend::stopPendingJobs() +{ + for(auto it = m_jobHash.constBegin(); it != m_jobHash.constEnd(); ++it) { + disconnect(it.key(), SIGNAL(result(KJob*)), this, SLOT(changelogFetched(KJob*))); + } + m_jobHash.clear(); +} + +void ReviewsBackend::fetchReviews(AbstractResource* res, int page) +{ + Q_ASSERT(!res->backend()->isFetching()); + Application* app = qobject_cast(res); + + const QList revs = m_reviewsCache.value(app); + if (revs.size()>(page*10)) { //there are 10 reviews per page + emit reviewsReady(app, revs.mid(page*10, 10)); + return; + } + + QString lang = getLanguage(); + QString origin = app->package()->origin().toLower(); + + QString version = QLatin1String("any"); + QString packageName = app->package()->name(); + QString appName = app->name(); + // Replace spaces with %2B for the url + appName.replace(QLatin1Char(' '), QLatin1String("%2B")); + + // Figuring out how this damn Django url was put together took more + // time than figuring out QJson... + // But that could be because the Ubuntu Software Center (which I used to + // figure it out) is written in python, so you have to go hunting to where + // a variable was initially initialized with a primitive to figure out its type. + QUrl reviewsUrl(m_serverBase.toString() + QLatin1String("/reviews/filter/") % lang % QLatin1Char('/') + % origin % QLatin1Char('/') % QLatin1String("any") % QLatin1Char('/') % version % QLatin1Char('/') % packageName + % QLatin1Char(';') % appName % QLatin1String("/page/") % QString::number(page)); + + KIO::StoredTransferJob* getJob = KIO::storedGet(reviewsUrl, KIO::NoReload, KIO::Overwrite | KIO::HideProgressInfo); + m_jobHash[getJob] = app; + connect(getJob, &KIO::StoredTransferJob::result, this, &ReviewsBackend::reviewsFetched); +} + +static Review* constructReview(const QVariantMap& data) +{ + QString reviewUsername = data.value(QStringLiteral("reviewer_username")).toString(); + QString reviewDisplayName = data.value(QStringLiteral("reviewer_displayname")).toString(); + QString reviewer = reviewDisplayName.isEmpty() ? reviewUsername : reviewDisplayName; + return new Review( + data.value(QStringLiteral("app_name")).toString(), + data.value(QStringLiteral("package_name")).toString(), + data.value(QStringLiteral("language")).toString(), + data.value(QStringLiteral("summary")).toString(), + data.value(QStringLiteral("review_text")).toString(), + reviewer, + QDateTime::fromString(data.value(QStringLiteral("date_created")).toString(), QStringLiteral("yyyy-MM-dd HH:mm:ss")), + !data.value(QStringLiteral("hide")).toBool(), + data.value(QStringLiteral("id")).toULongLong(), + data.value(QStringLiteral("rating")).toInt() * 2, + data.value(QStringLiteral("usefulness_total")).toInt(), + data.value(QStringLiteral("usefulness_favorable")).toInt(), + data.value(QStringLiteral("version")).toString()); +} + +void ReviewsBackend::reviewsFetched(KJob *j) +{ + KIO::StoredTransferJob* job = qobject_cast(j); + Application *app = m_jobHash.take(job); + if (job->error() || !app) { + return; + } + + QJsonParseError error; + QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error); + + if (error.error != QJsonParseError::NoError) { + return; + } + QVariant reviews = doc.toVariant(); + + QList reviewsList; + foreach (const QVariant &data, reviews.toList()) { + reviewsList << constructReview(data.toMap()); + } + + m_reviewsCache[app].append(reviewsList); + + emit reviewsReady(app, reviewsList); +} + +QString ReviewsBackend::getLanguage() +{ + // The reviews API abbreviates all langs past the _ char except these + const QStringList fullLangs = { QStringLiteral("pt_BR"), QStringLiteral("zh_CN"), QStringLiteral("zh_TW") }; + + QString language = QLocale().bcp47Name(); + + if (fullLangs.contains(language)) { + return language; + } + + return language.split(QLatin1Char('_')).first(); +} + +void ReviewsBackend::submitUsefulness(Review* r, bool useful) +{ + QVariantMap data = { { QStringLiteral("useful"), useful } }; + + postInformation(QStringLiteral("reviews/%1/recommendations/").arg(r->id()), data); +} + +void ReviewsBackend::submitReview(AbstractResource* application, const QString& summary, + const QString& review_text, const QString& rating) +{ + Application* app = qobject_cast(application); + + QVariantMap data = { + { QStringLiteral("app_name"), app->name() }, + { QStringLiteral("package_name"), app->packageName() }, + { QStringLiteral("summary"), summary }, + { QStringLiteral("version"), app->package()->version() }, + { QStringLiteral("review_text"), review_text }, + { QStringLiteral("rating"), rating }, + { QStringLiteral("language"), getLanguage() }, + { QStringLiteral("origin"), app->package()->origin() } + }; + + QString distroSeries = getCodename(QStringLiteral("VERSION")); + if(!distroSeries.isEmpty()){ + data[QStringLiteral("distroseries")] = distroSeries.split(QLatin1Char(' ')).last().remove(QLatin1Char('(')).remove(QLatin1Char(')')); + }else{ + data[QStringLiteral("distroseries")] = getCodename(QStringLiteral("PRETTY_NAME")).split(QLatin1Char(' ')).last(); + } + data[QStringLiteral("arch_tag")] = app->package()->architecture(); + + postInformation(QStringLiteral("reviews/"), data); +} + +void ReviewsBackend::deleteReview(Review* r) +{ + postInformation(QStringLiteral("reviews/delete/%1/").arg(r->id()), QVariantMap()); +} + +void ReviewsBackend::flagReview(Review* r, const QString& reason, const QString& text) +{ + QVariantMap data = { + { QStringLiteral("reason"), reason }, + { QStringLiteral("text"), text } + }; + + postInformation(QStringLiteral("reviews/%1/flags/").arg(r->id()), data); +} + +QByteArray authorization(QOAuth::Interface* oauth, const QUrl& url, AbstractLoginBackend* login) +{ + return oauth->createParametersString(url.url(), QOAuth::POST, login->token(), login->tokenSecret(), + QOAuth::HMAC_SHA1, QOAuth::ParamMap(), QOAuth::ParseForHeaderArguments); +} + +void ReviewsBackend::postInformation(const QString& path, const QVariantMap& data) +{ + if(!hasCredentials()) { + m_pendingRequests += qMakePair(path, data); + login(); + return; + } + + QUrl url(m_serverBase.toString() +QLatin1Char('/')+ path); + url.setScheme(QStringLiteral("https")); + + KIO::StoredTransferJob* job = KIO::storedHttpPost(QJsonDocument::fromVariant(data).toJson(), url, KIO::Overwrite | KIO::HideProgressInfo); //TODO port to QJsonDocument + job->addMetaData(QStringLiteral("content-type"), QStringLiteral("Content-Type: application/json") ); + job->addMetaData(QStringLiteral("customHTTPHeader"), QStringLiteral("Authorization: ") + QString::fromLatin1(authorization(m_oauthInterface, url, m_loginBackend))); + connect(job, &KIO::StoredTransferJob::result, this, &ReviewsBackend::informationPosted); + job->start(); +} + +void ReviewsBackend::informationPosted(KJob* j) +{ + KIO::StoredTransferJob* job = qobject_cast(j); + if(job->error()==0) { + qDebug() << "success" << job->data(); + } else { + qDebug() << "error..." << job->error() << job->errorString() << job->errorText(); + } +} + +bool ReviewsBackend::isFetching() const +{ + return !m_jobHash.isEmpty(); +} + +bool ReviewsBackend::hasCredentials() const +{ + return m_loginBackend->hasCredentials(); +} + +QString ReviewsBackend::userName() const +{ + Q_ASSERT(m_loginBackend->hasCredentials()); + return m_loginBackend->displayName(); +} + +void ReviewsBackend::login() +{ + Q_ASSERT(!m_loginBackend->hasCredentials()); + m_loginBackend->login(); +} + +void ReviewsBackend::registerAndLogin() +{ + Q_ASSERT(!m_loginBackend->hasCredentials()); + m_loginBackend->registerAndLogin(); +} + +void ReviewsBackend::logout() +{ + Q_ASSERT(m_loginBackend->hasCredentials()); + m_loginBackend->logout(); +} + +QString ReviewsBackend::errorMessage() const +{ + return i18n("No reviews available for Debian."); +} + +bool ReviewsBackend::isReviewable() const +{ + QString m_distId = getCodename(QLatin1String("ID")); + return m_distId == QLatin1String("ubuntu"); +} + diff --git a/libdiscover/backends/ApplicationBackend/ReviewsBackend.h b/libdiscover/backends/ApplicationBackend/ReviewsBackend.h new file mode 100644 index 0000000..3164831 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/ReviewsBackend.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef REVIEWSBACKEND_H +#define REVIEWSBACKEND_H + +#include +#include +#include + +#include "discovercommon_export.h" +#include + +namespace QOAuth { + class Interface; +} + +class KJob; +class KTemporaryFile; + +namespace QApt { + class Backend; +} + +class AbstractLoginBackend; +class Application; +class Rating; +class Review; + +class DISCOVERCOMMON_EXPORT ReviewsBackend : public AbstractReviewsBackend +{ + Q_OBJECT +public: + explicit ReviewsBackend(QObject *parent); + ~ReviewsBackend() override; + + Rating *ratingForApplication(AbstractResource *app) const override; + + void setAptBackend(QApt::Backend *aptBackend); + void fetchReviews(AbstractResource* res, int page=1) override; +// void clearReviewCache(); + void stopPendingJobs(); + bool isFetching() const override; + + QString userName() const override; + bool hasCredentials() const override; + QString errorMessage() const override; + bool isReviewable() const override; + +Q_SIGNALS: + void ratingsReady(); + +private: + QApt::Backend *m_aptBackend; + + QString m_distId; + const QUrl m_serverBase; + QHash m_ratings; + // cache key is package name + app name, since both by their own may not be unique + QHash > m_reviewsCache; + QHash m_jobHash; + + void loadRatingsFromFile(); + QString getLanguage(); + AbstractLoginBackend* m_loginBackend; + QOAuth::Interface* m_oauthInterface; + QList > m_pendingRequests; + +private Q_SLOTS: + void ratingsFetched(KJob *job); + void reviewsFetched(KJob *j); + void informationPosted(KJob* j); + void postInformation(const QString& path, const QVariantMap& data); + void fetchRatings(); + +public Q_SLOTS: + void login() override; + void registerAndLogin() override; + void logout() override; + void submitUsefulness(Review* r, bool useful) override; + void submitReview(AbstractResource* application, const QString& summary, + const QString& review_text, const QString& rating) override; + void deleteReview(Review* r) override; + void flagReview(Review* r, const QString& reason, const QString &text) override; + void refreshConsumerKeys(); +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp b/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp new file mode 100644 index 0000000..f73a8cb --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "UbuntuLoginBackend.h" +#include +#include +#include +#include +#include +#include "ubuntu_sso.h" + +//NOTE: this is needed because the method is called register. see the xml file for more info +struct HackedComUbuntuSsoCredentialsManagementInterface : public ComUbuntuSsoCredentialsManagementInterface +{ + HackedComUbuntuSsoCredentialsManagementInterface(const QString& service, const QString& path, const QDBusConnection& connection, QObject* parent = nullptr) + : ComUbuntuSsoCredentialsManagementInterface(service, path, connection, parent) + {} + + inline QDBusPendingReply<> register_hack(const QString &app_name, const QMap& args) + { + QList argumentList; + argumentList << QVariant::fromValue(app_name) << QVariant::fromValue(args); + return asyncCallWithArgumentList(QLatin1String("register"), argumentList); + } +}; + +UbuntuLoginBackend::UbuntuLoginBackend(QObject* parent) + : AbstractLoginBackend(parent) +{ + qDBusRegisterMetaType< QMap >(); + m_interface = new HackedComUbuntuSsoCredentialsManagementInterface( QStringLiteral("com.ubuntu.sso"), QStringLiteral("/com/ubuntu/sso/credentials"), QDBusConnection::sessionBus(), this); + connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::CredentialsError, this, &UbuntuLoginBackend::credentialsError); + connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::AuthorizationDenied, this, &UbuntuLoginBackend::authorizationDenied); + connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::CredentialsFound, this, &UbuntuLoginBackend::successfulLogin); + + m_interface->find_credentials(appname(), QMap()); +} + +void UbuntuLoginBackend::login() +{ + QMap data; + data[QStringLiteral("help_text")] = i18n("Log in to the Ubuntu SSO service"); + data[QStringLiteral("window_id")] = winId(); + QDBusPendingReply< void > ret = m_interface->login(appname(), data); +} + +void UbuntuLoginBackend::registerAndLogin() +{ + QMap data; + data[QStringLiteral("help_text")] = i18n("Log in to the Ubuntu SSO service"); + data[QStringLiteral("window_id")] = winId(); + m_interface->register_hack(appname(), data); +} + +QString UbuntuLoginBackend::displayName() const +{ + return m_credentials[QStringLiteral("name")]; +} + +bool UbuntuLoginBackend::hasCredentials() const +{ + return !m_credentials.isEmpty(); +} + +void UbuntuLoginBackend::successfulLogin(const QString& app, const QMap& credentials) +{ +// qDebug() << "logged in" << appname() << app << credentials; + if(app==appname()) { + m_credentials = credentials; + emit connectionStateChanged(); + } +} + +QString UbuntuLoginBackend::appname() const +{ + return QCoreApplication::instance()->applicationName(); +} + +QString UbuntuLoginBackend::winId() const +{ + QString windowId; + QApplication *app = qobject_cast(qApp); + + if (app->activeWindow()) + windowId = QString::number(app->activeWindow()->winId()); + + return windowId; +} + +void UbuntuLoginBackend::authorizationDenied(const QString& app) +{ + qDebug() << "denied" << app; + if(app==appname()) + emit connectionStateChanged(); +} + +void UbuntuLoginBackend::credentialsError(const QString& app, const QMap& a) +{ + //TODO: provide error message? + qDebug() << "error" << app << a; + if(app==appname()) + emit connectionStateChanged(); +} + +void UbuntuLoginBackend::logout() +{ + m_interface->clear_credentials(appname(), QMap()); + m_credentials.clear(); + emit connectionStateChanged(); +} + +QByteArray UbuntuLoginBackend::token() const +{ + return m_credentials[QStringLiteral("token")].toLatin1(); +} + +QByteArray UbuntuLoginBackend::tokenSecret() const +{ + return m_credentials[QStringLiteral("token_secret")].toLatin1(); +} + +QByteArray UbuntuLoginBackend::consumerKey() const +{ + return m_credentials[QStringLiteral("consumer_key")].toLatin1(); +} + +QByteArray UbuntuLoginBackend::consumerSecret() const +{ + return m_credentials[QStringLiteral("consumer_secret")].toLatin1(); +} diff --git a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h b/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h new file mode 100644 index 0000000..741bb00 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef UBUNTULOGINBACKEND_H +#define UBUNTULOGINBACKEND_H + +#include +#include + +struct HackedComUbuntuSsoCredentialsManagementInterface; +class UbuntuLoginBackend : public AbstractLoginBackend +{ + Q_OBJECT + public: + explicit UbuntuLoginBackend(QObject* parent=nullptr); + + void login() override; + void registerAndLogin() override; + void logout() override; + QString displayName() const override; + bool hasCredentials() const override; + + QByteArray token() const override; + QByteArray tokenSecret() const override; + QByteArray consumerKey() const override; + QByteArray consumerSecret() const override; + + private Q_SLOTS: + void credentialsError(const QString& app, const QMap& a); + void authorizationDenied(const QString& app); + void successfulLogin(const QString& app, const QMap& credentials); + + private: + QString appname() const; + QString winId() const; + HackedComUbuntuSsoCredentialsManagementInterface* m_interface; + QMap m_credentials; +}; + +#endif // UBUNTULOGINBACKEND_H diff --git a/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker b/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker new file mode 100644 index 0000000..d045f37 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker @@ -0,0 +1,46 @@ +#! /usr/bin/python3 + +# releasechecker.py +# +# Copyright (c) 2010 Jonathan Thomas +# +# Author: Jonathan Thomas +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License or (at your option) version 3 or any later version +# accepted by the membership of KDE e.V. (or its successor approved +# by the membership of KDE e.V.), which shall act as a proxy +# defined in Section 14 of version 3 of the license. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import sys, time +sys.path.insert(0, '/usr/lib/python3/dist-packages/') + +from UpdateManager.Core.MetaRelease import MetaReleaseCore +from UpdateManager.Core.utils import init_proxy + +if __name__ == "__main__": + """ check for updates, if there are any say so """ + + init_proxy() + #FIXME: implement command line options for MetaReleaseCore args + metaRelease = MetaReleaseCore(False, False) + while metaRelease.downloading: + time.sleep(0.5) + new_dist = metaRelease.new_dist + + if new_dist is not None: + print("Found a release") + sys.exit(0) + else: + sys.exit(1) + diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp new file mode 100644 index 0000000..7b43707 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp @@ -0,0 +1,41 @@ +#include "AddRepositoryHelper.h" +#include +#include +#include +#include +#include + +ActionReply AddRepositoryHelper::modify(QVariantMap args) +{ + ActionReply reply = ActionReply::SuccessReply(); + if(args[QStringLiteral("repository")].isNull() || args[QStringLiteral("action")].isNull()) { + reply.setErrorDescription(QStringLiteral("Invalid action arguments.")); + reply = ActionReply::HelperErrorReply(); + return reply; + } + QProcess *p = new QProcess(this); + p->setProcessChannelMode(QProcess::MergedChannels); + QString modRepo(QStringLiteral("apt-add-repository")); + QStringList arguments; + if(args[QStringLiteral("action")].toString() == QLatin1String("add")) { + arguments.append(QStringLiteral("-y")); + arguments.append(args[QStringLiteral("repository")].toString()); + } else { + if(args[QStringLiteral("action")] == QLatin1String("remove")) + { + arguments.append(QStringLiteral("--remove")); + arguments.append(QStringLiteral("-y")); + arguments.append(args[QStringLiteral("repository")].toString()); + } + } + p->start(modRepo,arguments); + p->waitForFinished(); + if(p->exitCode() != 0) { + reply.setErrorDescription(QStringLiteral("Could not modify source.")); + reply= ActionReply::HelperErrorReply(); + } + p->deleteLater(); + return reply; +} + +KAUTH_HELPER_MAIN("org.kde.muon.repo", AddRepositoryHelper) diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h b/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h new file mode 100644 index 0000000..4244ca4 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h @@ -0,0 +1,15 @@ +#ifndef ADDREPOSITORYHELPER_H +#define ADDREPOSITORYHELPER_H + +#include + +using namespace KAuth; + +class AddRepositoryHelper : public QObject +{ + Q_OBJECT +public Q_SLOTS: + ActionReply modify(QVariantMap args); +}; + +#endif //ADDREPOSITORYHELPER_H \ No newline at end of file diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt new file mode 100644 index 0000000..536a5c6 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt @@ -0,0 +1,26 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"libmuon\") + +add_library(MuonApt STATIC ChangesDialog.cpp + MuonStrings.cpp + QAptActions.cpp + HistoryView/HistoryProxyModel.cpp + HistoryView/HistoryView.cpp) + +target_link_libraries(MuonApt Qt5::Core + KF5::KIOWidgets KF5::XmlGui + QApt::Main KF5::I18n +) + +target_compile_definitions(MuonApt PRIVATE -DCMAKE_INSTALL_FULL_LIBEXECDIR_KF5=\"${CMAKE_INSTALL_FULL_LIBEXECDIR_KF5}\") + +target_include_directories(MuonApt PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +add_executable(muon_repo_helper AddRepositoryHelper.cpp) +target_link_libraries(muon_repo_helper Qt5::Core KF5::Auth) + +install(TARGETS muon_repo_helper DESTINATION ${LIBEXEC_INSTALL_DIR}) +kauth_install_actions(org.kde.muon.repo policies/org.kde.muon.repo.action) +kauth_install_helper_files(muon_repo_helper org.kde.muon.repo root) + +install(TARGETS MuonApt ${INSTALL_TARGETS_DEFAULT_ARGS}) + diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp new file mode 100644 index 0000000..048decc --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp @@ -0,0 +1,118 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ChangesDialog.h" + +// Qt includes +#include +#include +#include +#include + +// KDE includes +#include +#include + +// Own includes +#include "../libmuonapt/MuonStrings.h" + +ChangesDialog::ChangesDialog(QWidget *parent, const QApt::StateChanges &changes) + : QDialog(parent) +{ + setWindowTitle(i18nc("@title:window", "Confirm Additional Changes")); + QVBoxLayout *layout = new QVBoxLayout(this); + setLayout(layout); + + QLabel *headerLabel = new QLabel(this); + headerLabel->setText(i18nc("@info", "

Mark additional changes?

")); + + int count = countChanges(changes); + QLabel *label = new QLabel(this); + label->setText(i18np("This action requires a change to another package:", + "This action requires changes to other packages:", + count)); + + QTreeView *packageView = new QTreeView(this); + packageView->setHeaderHidden(true); + packageView->setRootIsDecorated(false); + + QWidget *bottomBox = new QWidget(this); + QHBoxLayout *bottomLayout = new QHBoxLayout(bottomBox); + bottomLayout->setSpacing(0); + bottomLayout->setMargin(0); + bottomBox->setLayout(bottomLayout); + + QWidget *bottomSpacer = new QWidget(bottomBox); + bottomSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + + QPushButton *okButton = new QPushButton(bottomBox); + KGuiItem okItem = KStandardGuiItem::ok(); + okButton->setText(okItem.text()); + okButton->setIcon(okItem.icon()); + connect(okButton, &QPushButton::clicked, this, &ChangesDialog::accept); + + QPushButton *cancelButton = new QPushButton(bottomBox); + KGuiItem cancelItem = KStandardGuiItem::cancel(); + cancelButton->setText(cancelItem.text()); + cancelButton->setIcon(cancelItem.icon()); + connect(cancelButton, &QPushButton::clicked, this, &ChangesDialog::reject); + + bottomLayout->addWidget(bottomSpacer); + bottomLayout->addWidget(okButton); + bottomLayout->addWidget(cancelButton); + + m_model = new QStandardItemModel(this); + packageView->setModel(m_model); + addPackages(changes); + packageView->expandAll(); + packageView->setEditTriggers(QAbstractItemView::NoEditTriggers); + + layout->addWidget(headerLabel); + layout->addWidget(label); + layout->addWidget(packageView); + layout->addWidget(bottomBox); +} + +void ChangesDialog::addPackages(const QApt::StateChanges &changes) +{ + for (auto i = changes.constBegin(); i != changes.constEnd(); ++i) { + QStandardItem *root = new QStandardItem; + root->setText(MuonStrings::global()->packageStateName(i.key())); + + QFont font = root->font(); + font.setBold(true); + root->setFont(font); + + Q_FOREACH (QApt::Package *package, *i) { + root->appendRow(new QStandardItem(QIcon::fromTheme(QStringLiteral("muon")), package->name())); + } + + m_model->appendRow(root); + } +} + +int ChangesDialog::countChanges(const QApt::StateChanges &changes) +{ + int count = 0; + foreach (const QApt::PackageList& pkgs, changes) { + count += pkgs.size(); + } + return count; +} diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h b/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h new file mode 100644 index 0000000..ed17c46 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright © 2011 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef CHANGESDIALOG_H +#define CHANGESDIALOG_H + +// Qt includes +#include +#include + +// QApt includes +#include + +class QStandardItemModel; + +class ChangesDialog : public QDialog +{ +public: + ChangesDialog(QWidget *parent, const QApt::StateChanges &changes); + +private: + QStandardItemModel *m_model; + + void addPackages(const QApt::StateChanges &changes); + int countChanges(const QApt::StateChanges &changes); +}; + +#endif // CHANGESDIALOG_H diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp new file mode 100644 index 0000000..09c9037 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "HistoryProxyModel.h" + +#include +#include + +HistoryProxyModel::HistoryProxyModel(QObject *parent) + : QSortFilterProxyModel(parent) + , m_stateFilter(static_cast(0)) +{ +} + +HistoryProxyModel::~HistoryProxyModel() = default; + +void HistoryProxyModel::search(const QString &searchText) +{ + m_searchText = searchText; + invalidate(); +} + +void HistoryProxyModel::setStateFilter(QApt::Package::State state) +{ + m_stateFilter = state; + invalidate(); +} + +bool HistoryProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); + for(int i = 0 ; i < sourceModel()->rowCount(sourceIndex); i++) { + if (filterAcceptsRow(i, sourceIndex)) { + return true; + } + } + + //Our "main"-method + QStandardItem *item = static_cast(sourceModel())->itemFromIndex(sourceModel()->index(sourceRow, 0, sourceParent)); + + if (!item) { + return false; + } + + if (!m_stateFilter == 0) { + if ((bool)(item->data(HistoryActionRole).toInt() & m_stateFilter) == false) { + return false; + } + } + + if (!m_searchText.isEmpty()) { + if ((bool)(item->data(Qt::DisplayRole).toString().contains(m_searchText)) == false) { + return false; + } + } + + return true; +} + +bool HistoryProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + QStandardItemModel *parentModel = dynamic_cast(sourceModel()); + + QStandardItem *leftItem = parentModel->itemFromIndex(left); + QStandardItem *rightItem = parentModel->itemFromIndex(right); + + return (leftItem->data(HistoryDateRole).toDateTime() > rightItem->data(HistoryDateRole).toDateTime()); +} diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h new file mode 100644 index 0000000..f5e2cc6 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef HISTORYPROXYMODEL_H +#define HISTORYPROXYMODEL_H + +#include + +#include + +class HistoryProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + enum { + HistoryDateRole = Qt::UserRole + 1, + HistoryActionRole = Qt::UserRole + 2 + }; + explicit HistoryProxyModel(QObject *parent); + ~HistoryProxyModel() override; + + void search(const QString &searchText); + void setStateFilter(QApt::Package::State state); + + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + +protected: + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + +private: + QString m_searchText; + QApt::Package::State m_stateFilter; +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp new file mode 100644 index 0000000..88e6cc5 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp @@ -0,0 +1,238 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "HistoryView.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "HistoryProxyModel.h" + +HistoryView::HistoryView(QWidget *parent) + : QWidget(parent) +{ + QVBoxLayout* layout = new QVBoxLayout(this); + setLayout(layout); + m_history = new QApt::History(this); + + QWidget *headerWidget = new QWidget(this); + QHBoxLayout *headerLayout = new QHBoxLayout(headerWidget); + headerWidget->setLayout(headerLayout); + + QLabel *headerLabel = new QLabel(headerWidget); + headerLabel->setText(xi18nc("@info", "History")); + + QWidget *headerSpacer = new QWidget(headerWidget); + headerSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + m_searchEdit = new QLineEdit(headerWidget); + m_searchEdit->setPlaceholderText(i18nc("@label Line edit click message", "Search")); + m_searchEdit->setClearButtonEnabled(true); + + m_searchTimer = new QTimer(this); + m_searchTimer->setInterval(300); + m_searchTimer->setSingleShot(true); + connect(m_searchTimer, &QTimer::timeout, this, &HistoryView::startSearch); + connect(m_searchEdit, &QLineEdit::textChanged, m_searchTimer, static_cast(&QTimer::start)); + + m_filterBox = new QComboBox(headerWidget); + m_filterBox->insertItem(AllChangesItem, QIcon::fromTheme(QStringLiteral("bookmark-new-list")), + i18nc("@item:inlistbox Filters all changes in the history view", + "All changes"), + 0); + m_filterBox->insertItem(InstallationsItem, QIcon::fromTheme(QStringLiteral("download")), + i18nc("@item:inlistbox Filters installations in the history view", + "Installations"), + QApt::Package::ToInstall); + m_filterBox->insertItem(UpdatesItem, QIcon::fromTheme(QStringLiteral("system-software-update")), + i18nc("@item:inlistbox Filters updates in the history view", + "Updates"), + QApt::Package::ToUpgrade); + m_filterBox->insertItem(RemovalsItem, QIcon::fromTheme(QStringLiteral("edit-delete")), + i18nc("@item:inlistbox Filters removals in the history view", + "Removals"), + (QApt::Package::State)(QApt::Package::ToRemove | QApt::Package::ToPurge)); + connect(m_filterBox, static_cast(&QComboBox::currentIndexChanged), this, &HistoryView::setStateFilter); + + headerLayout->addWidget(headerLabel); + headerLayout->addWidget(headerSpacer); + headerLayout->addWidget(m_searchEdit); + headerLayout->addWidget(m_filterBox); + + m_historyModel = new QStandardItemModel(this); + m_historyModel->setColumnCount(1); + m_historyModel->setHeaderData(0, Qt::Horizontal, i18nc("@title:column", "Date")); + m_historyView = new QTreeView(this); + + layout->addWidget(headerWidget); + layout->addWidget(m_historyView); + + QIcon itemIcon(QIcon::fromTheme(QStringLiteral("applications-other"))); + + QHash categoryHash; + + QHash actionHash; + actionHash[InstalledAction] = i18nc("@info:status describes a past-tense action", "Installed"); + actionHash[UpgradedAction] = i18nc("@info:status describes a past-tense action", "Upgraded"); + actionHash[DowngradedAction] = i18nc("@status describes a past-tense action", "Downgraded"); + actionHash[RemovedAction] = i18nc("@status describes a past-tense action", "Removed"); + actionHash[PurgedAction] = i18nc("@status describes a past-tense action", "Purged"); + + Q_FOREACH (const QApt::HistoryItem &item, m_history->historyItems()) { + QDateTime startDateTime = item.startDate(); + QString formattedTime = startDateTime.toString(); + QString category; + + QString date = startDateTime.date().toString(); + if (categoryHash.contains(date)) { + category = categoryHash.value(date); + } else { + category = startDateTime.date().toString(Qt::DefaultLocaleShortDate); + categoryHash[date] = category; + } + + QStandardItem *parentItem = nullptr; + + if (!m_categoryHash.contains(category)) { + parentItem = new QStandardItem; + parentItem->setEditable(false); + parentItem->setText(category); + parentItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); + + m_historyModel->appendRow(parentItem); + m_categoryHash[category] = parentItem; + } else { + parentItem = m_categoryHash.value(category); + } + + foreach (const QString &package, item.installedPackages()) { + QStandardItem *historyItem = new QStandardItem; + historyItem->setEditable(false); + historyItem->setIcon(itemIcon); + + QString action = actionHash.value(InstalledAction); + QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", + package, action, formattedTime); + historyItem->setText(text); + historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); + historyItem->setData(QApt::Package::ToInstall, HistoryProxyModel::HistoryActionRole); + + parentItem->appendRow(historyItem); + } + + foreach (const QString &package, item.upgradedPackages()) { + QStandardItem *historyItem = new QStandardItem; + historyItem->setEditable(false); + historyItem->setIcon(itemIcon); + + QString action = actionHash.value(UpgradedAction); + QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", + package, action, formattedTime); + historyItem->setText(text); + historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); + historyItem->setData(QApt::Package::ToUpgrade, HistoryProxyModel::HistoryActionRole); + + parentItem->appendRow(historyItem); + } + + foreach (const QString &package, item.downgradedPackages()) { + QStandardItem *historyItem = new QStandardItem; + historyItem->setEditable(false); + historyItem->setIcon(itemIcon); + + QString action = actionHash.value(DowngradedAction); + QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", + package, action, formattedTime); + historyItem->setText(text); + historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); + historyItem->setData(QApt::Package::ToDowngrade, HistoryProxyModel::HistoryActionRole); + + parentItem->appendRow(historyItem); + } + + foreach (const QString &package, item.removedPackages()) { + QStandardItem *historyItem = new QStandardItem; + historyItem->setEditable(false); + historyItem->setIcon(itemIcon); + + QString action = actionHash.value(RemovedAction); + QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", + package, action, formattedTime); + historyItem->setText(text); + historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); + historyItem->setData(QApt::Package::ToRemove, HistoryProxyModel::HistoryActionRole); + + parentItem->appendRow(historyItem); + } + + foreach (const QString &package, item.purgedPackages()) { + QStandardItem *historyItem = new QStandardItem; + historyItem->setEditable(false); + historyItem->setIcon(itemIcon); + + QString action = actionHash.value(PurgedAction); + QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", + package, action, formattedTime); + historyItem->setText(text); + historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); + historyItem->setData(QApt::Package::ToPurge, HistoryProxyModel::HistoryActionRole); + + parentItem->appendRow(historyItem); + } + } + + m_historyView->setMouseTracking(true); + m_historyView->setVerticalScrollMode(QListView::ScrollPerPixel); + + m_proxyModel = new HistoryProxyModel(this); + m_proxyModel->setSourceModel(m_historyModel); + m_proxyModel->sort(0); + + m_historyView->setModel(m_proxyModel); + + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); +} + +QSize HistoryView::sizeHint() const +{ + return QWidget::sizeHint().expandedTo(QSize(500, 500)); +} + +void HistoryView::setStateFilter(int index) +{ + QApt::Package::State state = (QApt::Package::State)m_filterBox->itemData(index).toInt(); + m_proxyModel->setStateFilter(state); +} + +void HistoryView::startSearch() +{ + m_proxyModel->search(m_searchEdit->text()); +} + diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h new file mode 100644 index 0000000..7ffb2b0 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef HISTORYVIEW_H +#define HISTORYVIEW_H + +#include + +#include + +class QStandardItem; +class QStandardItemModel; +class QTimer; +class QTreeView; +class QLineEdit; +class QComboBox; + +namespace QApt { + class History; +} + +class HistoryProxyModel; + +class HistoryView : public QWidget +{ + Q_OBJECT +public: + enum ComboItems { + AllChangesItem = 0, + InstallationsItem = 1, + UpdatesItem = 2, + RemovalsItem = 3 + }; + enum PastActions { + InvalidAction = 0, + InstalledAction = 1, + UpgradedAction = 2, + DowngradedAction = 3, + RemovedAction = 4, + PurgedAction = 5 + }; + explicit HistoryView(QWidget *parent); + + QSize sizeHint() const override; + +private: + QApt::History *m_history; + QStandardItemModel *m_historyModel; + HistoryProxyModel *m_proxyModel; + QHash m_categoryHash; + + QLineEdit *m_searchEdit; + QTimer *m_searchTimer; + QComboBox *m_filterBox; + QTreeView *m_historyView; + +private Q_SLOTS: + void setStateFilter(int index); + void startSearch(); +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp new file mode 100644 index 0000000..16eb44f --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp @@ -0,0 +1,167 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "MuonStrings.h" + +#include +#include + +#include + +Q_GLOBAL_STATIC_WITH_ARGS(MuonStrings, globalMuonStrings, (0)) + +using namespace QApt; + +MuonStrings *MuonStrings::global() +{ + return globalMuonStrings; +} + +MuonStrings::MuonStrings(QObject *parent) + : QObject(parent) + , m_stateHash(stateHash()) +{ +} + +QHash MuonStrings::stateHash() +{ + QHash hash; + hash[Package::ToKeep] = i18nc("@info:status Package state", "No Change"); + hash[Package::ToInstall] = i18nc("@info:status Requested action", "Install"); + hash[Package::NewInstall] = i18nc("@info:status Requested action", "Install"); + hash[Package::ToReInstall] = i18nc("@info:status Requested action", "Reinstall"); + hash[Package::ToUpgrade] = i18nc("@info:status Requested action", "Upgrade"); + hash[Package::ToDowngrade] = i18nc("@info:status Requested action", "Downgrade"); + hash[Package::ToRemove] = i18nc("@info:status Requested action", "Remove"); + hash[Package::Held] = i18nc("@info:status Package state" , "Held"); + hash[Package::Installed] = i18nc("@info:status Package state", "Installed"); + hash[Package::Upgradeable] = i18nc("@info:status Package state", "Upgradeable"); + hash[Package::NowBroken] = i18nc("@info:status Package state", "Broken"); + hash[Package::InstallBroken] = i18nc("@info:status Package state", "Install Broken"); + hash[Package::Orphaned] = i18nc("@info:status Package state", "Orphaned"); + hash[Package::Pinned] = i18nc("@info:status Package state", "Locked"); + hash[Package::New] = i18nc("@info:status Package state", "New in repository"); + hash[Package::ResidualConfig] = i18nc("@info:status Package state", "Residual Configuration"); + hash[Package::NotDownloadable] = i18nc("@info:status Package state", "Not Downloadable"); + hash[Package::ToPurge] = i18nc("@info:status Requested action", "Purge"); + hash[Package::IsImportant] = i18nc("@info:status Package state", "Important for base install"); + hash[Package::OverrideVersion] = i18nc("@info:status Package state", "Version overridden"); + hash[Package::IsAuto] = i18nc("@info:status Package state", "Required by other packages"); + hash[Package::IsGarbage] = i18nc("@info:status Package state", "Installed (auto-removable)"); + hash[Package::NowPolicyBroken] = i18nc("@info:status Package state", "Policy Broken"); + hash[Package::InstallPolicyBroken] = i18nc("@info:status Package state", "Policy Broken"); + hash[Package::NotInstalled] = i18nc("@info:status Package state" , "Not Installed"); + hash[Package::IsPinned] = i18nc("@info:status Package locked at a certain version", + "Locked"); + hash[Package::IsManuallyHeld] = i18nc("@info:status Package state", "Manually held back"); + + return hash; +} + +QString MuonStrings::packageStateName(Package::State state) const +{ + return m_stateHash.value(state); +} + +QString MuonStrings::packageChangeStateName(Package::State state) const +{ + int ns = state & (Package::ToKeep | Package::ToInstall | Package::ToReInstall | Package::NewInstall + | Package::ToUpgrade | Package::ToRemove + | Package::ToPurge | Package::ToDowngrade); + return m_stateHash.value(ns); +} + +QString MuonStrings::errorTitle(ErrorCode error) const +{ + switch (error) { + case InitError: + return i18nc("@title:window", "Initialization Error"); + case LockError: + return i18nc("@title:window", "Unable to Obtain Package System Lock"); + case DiskSpaceError: + return i18nc("@title:window", "Low Disk Space"); + case FetchError: + case CommitError: + return i18nc("@title:window", "Failed to Apply Changes"); + case AuthError: + return i18nc("@title:window", "Authentication error"); + case WorkerDisappeared: + return i18nc("@title:window", "Unexpected Error"); + case UntrustedError: + return i18nc("@title:window", "Untrusted Packages"); + case UnknownError: + default: + return i18nc("@title:window", "Unknown Error"); + } +} + +QString MuonStrings::errorText(ErrorCode error, Transaction *trans) const +{ + QString text; + + switch (error) { + case InitError: + text = i18nc("@label", "The package system could not be initialized, your " + "configuration may be broken."); + break; + case LockError: + text = i18nc("@label", + "Another application seems to be using the package " + "system at this time. You must close all other package " + "managers before you will be able to install or remove " + "any packages."); + break; + case DiskSpaceError: + text = i18nc("@label", + "You do not have enough disk space in the directory " + "at %1 to continue with this operation.", trans->errorDetails()); + break; + case FetchError: + text = i18nc("@label", "Could not download packages"); + break; + case CommitError: + text = i18nc("@label", "An error occurred while applying changes:"); + break; + case AuthError: + text = i18nc("@label", + "This operation cannot continue since proper " + "authorization was not provided"); + break; + case WorkerDisappeared: + text = i18nc("@label", "It appears that the QApt worker has either crashed " + "or disappeared. Please report a bug to the QApt maintainers"); + break; + case UntrustedError: + text = i18ncp("@label", + "The following package has not been verified by its author. " + "Downloading untrusted packages has been disallowed " + "by your current configuration.", + "The following packages have not been verified by " + "their authors. " + "Downloading untrusted packages has " + "been disallowed by your current configuration.", + trans->untrustedPackages().size()); + break; + default: + break; + } + + return text; +} diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h b/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h new file mode 100644 index 0000000..d7886d3 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright © 2010 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef MUONSTRINGS_H +#define MUONSTRINGS_H + +#include + +#include + +namespace QApt { + class Transaction; +} + +class MuonStrings : public QObject +{ + Q_OBJECT +public: + explicit MuonStrings(QObject *parent); + + static MuonStrings* global(); + + /** @returns the state name for a given @p state, for displaying it to the user */ + QString packageStateName(QApt::Package::State state) const; + + /** @returns the state name for the given @p state changes, for displaying it to the user + * This means, the flags that are related to a state change, like ToInstall, ToUpgrade, etc + */ + QString packageChangeStateName(QApt::Package::State state) const; + QString errorTitle(QApt::ErrorCode error) const; + QString errorText(QApt::ErrorCode error, QApt::Transaction *trans) const; + +private: + const QHash m_stateHash; + + static QHash stateHash(); +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp new file mode 100644 index 0000000..74810c7 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp @@ -0,0 +1,537 @@ +/*************************************************************************** + * Copyright © 2012 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "QAptActions.h" +#include "MuonStrings.h" +#include "HistoryView/HistoryView.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// KDE includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// QApt includes +#include +#include +#include + +QAptActions::QAptActions() + : QObject(nullptr) + , m_backend(nullptr) + , m_actionsDisabled(false) + , m_reloadWhenEditorFinished(false) + , m_historyDialog(nullptr) + , m_distUpgradeAvailable(false) + , m_config(new QNetworkConfigurationManager(this)) +{ + connect(m_config, &QNetworkConfigurationManager::onlineStateChanged, this, &QAptActions::shouldConnect); +} + +QAptActions* QAptActions::self() +{ + static QPointer self; + if(!self) { + self = new QAptActions; + } + return self; +} + +void QAptActions::setActionCollection(KActionCollection* actions) +{ + setParent(actions); + m_actionCollection = actions; + + setupActions(); +} + +QWidget* QAptActions::mainWindow() const +{ + return nullptr; +} + +void QAptActions::setBackend(QApt::Backend* backend) +{ + if(backend == m_backend) + return; + m_backend = backend; + if (!m_backend->init()) + initError(); + + connect(m_backend, SIGNAL(packageChanged()), this, SLOT(setActionsEnabled())); + + setOriginalState(m_backend->currentCacheState()); + + setReloadWhenEditorFinished(true); + // Some actions need an initialized backend to be able to set their enabled state + setActionsEnabled(true); + checkDistUpgrade(); +} + +void QAptActions::setupActions() +{ + QAction* undoAction = KStandardAction::undo(this, SLOT(undo()), actionCollection()); + actionCollection()->addAction(QStringLiteral("undo"), undoAction); + m_actions.append(undoAction); + + QAction* redoAction = KStandardAction::redo(this, SLOT(redo()), actionCollection()); + actionCollection()->addAction(QStringLiteral("redo"), redoAction); + m_actions.append(redoAction); + + QAction* revertAction = actionCollection()->addAction(QStringLiteral("revert")); + revertAction->setIcon(QIcon::fromTheme(QStringLiteral("document-revert"))); + revertAction->setText(i18nc("@action Reverts all potential changes to the cache", "Unmark All")); + connect(revertAction, &QAction::triggered, this, &QAptActions::revertChanges); + m_actions.append(revertAction); + + QAction* softwarePropertiesAction = actionCollection()->addAction(QStringLiteral("software_properties")); + softwarePropertiesAction->setPriority(QAction::LowPriority); + softwarePropertiesAction->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); + softwarePropertiesAction->setText(i18nc("@action Opens the software sources configuration dialog", "Configure Software Sources")); + connect(softwarePropertiesAction, &QAction::triggered, this, &QAptActions::runSourcesEditor); + m_actions.append(softwarePropertiesAction); + + QAction* loadSelectionsAction = actionCollection()->addAction(QStringLiteral("open_markings")); + loadSelectionsAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); + loadSelectionsAction->setText(i18nc("@action", "Read Markings...")); + connect(loadSelectionsAction, &QAction::triggered, this, &QAptActions::loadSelections); + m_actions.append(loadSelectionsAction); + + QAction* saveSelectionsAction = actionCollection()->addAction(QStringLiteral("save_markings")); + saveSelectionsAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as"))); + saveSelectionsAction->setText(i18nc("@action", "Save Markings As...")); + connect(saveSelectionsAction, &QAction::triggered, this, &QAptActions::saveSelections); + m_actions.append(saveSelectionsAction); + + QAction* createDownloadListAction = actionCollection()->addAction(QStringLiteral("save_download_list")); + createDownloadListAction->setPriority(QAction::LowPriority); + createDownloadListAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as"))); + createDownloadListAction->setText(i18nc("@action", "Save Package Download List...")); + connect(createDownloadListAction, &QAction::triggered, this, &QAptActions::createDownloadList); + m_actions.append(createDownloadListAction); + + QAction* downloadListAction = actionCollection()->addAction(QStringLiteral("download_from_list")); + downloadListAction->setPriority(QAction::LowPriority); + downloadListAction->setIcon(QIcon::fromTheme(QStringLiteral("download"))); + downloadListAction->setText(i18nc("@action", "Download Packages From List...")); + connect(downloadListAction, &QAction::triggered, this, &QAptActions::downloadPackagesFromList); + downloadListAction->setEnabled(isConnected()); + connect(this, &QAptActions::shouldConnect, downloadListAction, &QAction::setEnabled); + m_actions.append(downloadListAction); + + QAction* loadArchivesAction = actionCollection()->addAction(QStringLiteral("load_archives")); + loadArchivesAction->setPriority(QAction::LowPriority); + loadArchivesAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); + loadArchivesAction->setText(i18nc("@action", "Add Downloaded Packages")); + connect(loadArchivesAction, &QAction::triggered, this, &QAptActions::loadArchives); + m_actions.append(loadArchivesAction); + + QAction* saveInstalledAction = actionCollection()->addAction(QStringLiteral("save_package_list")); + saveInstalledAction->setPriority(QAction::LowPriority); + saveInstalledAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as"))); + saveInstalledAction->setText(i18nc("@action", "Save Installed Packages List...")); + connect(saveInstalledAction, &QAction::triggered, this, &QAptActions::saveInstalledPackagesList); + + QAction* historyAction = actionCollection()->addAction(QStringLiteral("history")); + historyAction->setPriority(QAction::LowPriority); + historyAction->setIcon(QIcon::fromTheme(QStringLiteral("view-history"))); + historyAction->setText(i18nc("@action::inmenu", "History...")); + actionCollection()->setDefaultShortcut(historyAction, QKeySequence(Qt::CTRL + Qt::Key_H)); + connect(historyAction, &QAction::triggered, this, &QAptActions::showHistoryDialog); + + QAction *distUpgradeAction = actionCollection()->addAction(QStringLiteral("dist-upgrade")); + distUpgradeAction->setIcon(QIcon::fromTheme(QStringLiteral("system-software-update"))); + distUpgradeAction->setText(i18nc("@action", "Upgrade")); + distUpgradeAction->setPriority(QAction::HighPriority); + distUpgradeAction->setWhatsThis(i18nc("Notification when a new version of Kubuntu is available", + "A new version of Kubuntu is available.")); + distUpgradeAction->setEnabled(m_distUpgradeAvailable); + connect(distUpgradeAction, &QAction::triggered, this, &QAptActions::launchDistUpgrade); + + m_actions.append(saveInstalledAction); +} + +void QAptActions::setActionsEnabled(bool enabled) +{ + m_actionsDisabled = !enabled; + + Q_FOREACH (QAction *action, m_actions) { + action->setEnabled(enabled); + } + + if (!enabled || !actionCollection()) + return; + + actionCollection()->action(QStringLiteral("update"))->setEnabled(isConnected() && enabled); + + actionCollection()->action(QStringLiteral("undo"))->setEnabled(m_backend && !m_backend->isUndoStackEmpty()); + actionCollection()->action(QStringLiteral("redo"))->setEnabled(m_backend && !m_backend->isRedoStackEmpty()); + actionCollection()->action(QStringLiteral("revert"))->setEnabled(m_backend && !m_backend->isUndoStackEmpty()); + + actionCollection()->action(QStringLiteral("save_download_list"))->setEnabled(isConnected()); + + bool changesPending = m_backend && m_backend->areChangesMarked(); + actionCollection()->action(QStringLiteral("save_markings"))->setEnabled(changesPending); + actionCollection()->action(QStringLiteral("save_download_list"))->setEnabled(changesPending); + actionCollection()->action(QStringLiteral("dist-upgrade"))->setEnabled(m_distUpgradeAvailable); +} + +bool QAptActions::reloadWhenSourcesEditorFinished() const +{ + return m_reloadWhenEditorFinished; +} + +bool QAptActions::isConnected() const +{ + return m_config->isOnline(); +} + +bool QAptActions::saveSelections() +{ + QString filename = QFileDialog::getSaveFileName(mainWindow(), i18nc("@title:window", "Save Markings As")); + + if (filename.isEmpty()) { + return false; + } + + if (!m_backend->saveSelections(filename)) { + QString text = xi18nc("@label", "The document could not be saved, as it " + "was not possible to write to " + "%1\n\nCheck " + "that you have write access to this file " + "or that enough disk space is available.", + filename); + KMessageBox::error(mainWindow(), text, QString()); + return false; + } + + return true; +} + +bool QAptActions::saveInstalledPackagesList() +{ + QString filename; + + filename = QFileDialog::getSaveFileName(mainWindow(), + i18nc("@title:window", "Save Installed Packages List As")); + + if (filename.isEmpty()) { + return false; + } + + if (!m_backend->saveInstalledPackagesList(filename)) { + QString text = xi18nc("@label", "The document could not be saved, as it " + "was not possible to write to " + "%1\n\nCheck " + "that you have write access to this file " + "or that enough disk space is available.", + filename); + KMessageBox::error(mainWindow(), text, QString()); + return false; + } + + return true; +} + +bool QAptActions::createDownloadList() +{ + QString filename; + filename = QFileDialog::getSaveFileName(mainWindow(), + i18nc("@title:window", "Save Download List As")); + + if (filename.isEmpty()) { + return false; + } + + if (!m_backend->saveDownloadList(filename)) { + QString text = xi18nc("@label", "The document could not be saved, as it " + "was not possible to write to " + "%1\n\nCheck " + "that you have write access to this file " + "or that enough disk space is available.", + filename); + KMessageBox::error(mainWindow(), text, QString()); + return false; + } + + return true; +} + +void QAptActions::downloadPackagesFromList() +{ + QString filename = QFileDialog::getOpenFileName(mainWindow(), i18nc("@title:window", "Open File")); + + if (filename.isEmpty()) { + return; + } + + QString dirName = filename.left(filename.lastIndexOf(QLatin1Char('/'))); + + setActionsEnabled(false); + QApt::Transaction *trans = m_backend->downloadArchives(filename, dirName % QLatin1String("/packages")); + + if (trans) + emit downloadArchives(trans); +} + +void QAptActions::loadSelections() +{ + QString filename = QFileDialog::getOpenFileName(mainWindow(), i18nc("@title:window", "Open File")); + + if (filename.isEmpty()) { + return; + } + + m_backend->saveCacheState(); + if (!m_backend->loadSelections(filename)) { + QString text = i18nc("@label", "Could not mark changes. Please make sure " + "that the file is a markings file created by " + "either the Muon Package Manager or the " + "Synaptic Package Manager."); + KMessageBox::error(mainWindow(), text, QString()); + } +} + +void QAptActions::loadArchives() +{ + QString dirName = QFileDialog::getExistingDirectory(mainWindow(), + i18nc("@title:window", "Choose a Directory")); + + if (dirName.isEmpty()) { + // User canceled + return; + } + + QDir dir(dirName); + QStringList archiveFiles = dir.entryList(QDir::Files, QDir::Name); + + int successCount = 0; + foreach (const QString &archiveFile, archiveFiles) { + const QApt::DebFile debFile(dirName % QLatin1Char('/') % archiveFile); + + if (debFile.isValid()) { + if (m_backend->addArchiveToCache(debFile)) { + successCount++; + } + } + } + + if (successCount != 0) { + QString message = i18ncp("@label", + "%1 package was successfully added to the cache", + "%1 packages were successfully added to the cache", + successCount); + KMessageBox::information(mainWindow(), message, QString()); + } else { + QString message = i18nc("@label", + "No valid packages could be found in this directory. " + "Please make sure the packages are compatible with your " + "computer and are at the latest version."); + KMessageBox::error(mainWindow(), message, i18nc("@title:window", + "Packages Could Not be Found")); + } +} + +void QAptActions::undo() +{ + m_backend->undo(); +} + +void QAptActions::redo() +{ + m_backend->redo(); +} + +void QAptActions::revertChanges() +{ + m_backend->restoreCacheState(m_originalState); + emit changesReverted(); +} + +void QAptActions::runSourcesEditor() +{ + KProcess *proc = new KProcess(this); + QStringList arguments; + int winID = 0; + foreach(QWindow* w, QGuiApplication::allWindows()) { + if (w->objectName() == QLatin1String("DiscoverMainWindow")) { + winID = w->winId(); + } + } + + const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu"); + const QString editor = QStandardPaths::findExecutable(QStringLiteral("software-properties-kde")); + + arguments << kdesu << QStringLiteral("--") << editor << QStringLiteral("--attach") << QString::number(winID); + if (m_reloadWhenEditorFinished) { + arguments << QStringLiteral("--dont-update"); + } + + proc->setProgram(arguments); + proc->start(); + connect(proc, static_cast(&KProcess::finished), this, &QAptActions::sourcesEditorFinished); +} + +void QAptActions::sourcesEditorFinished(int exitStatus) +{ + bool reload = (exitStatus != 0); + if (m_reloadWhenEditorFinished && reload) { + actionCollection()->action(QStringLiteral("update"))->trigger(); + } + + emit sourcesEditorClosed(reload); +} + +KActionCollection* QAptActions::actionCollection() +{ + return m_actionCollection; +} + +void QAptActions::setOriginalState(QApt::CacheState state) +{ + m_originalState = state; +} + +void QAptActions::setReloadWhenEditorFinished(bool reload) +{ + m_reloadWhenEditorFinished = reload; +} + +void QAptActions::initError() +{ + QString details = m_backend->initErrorMessage(); + + MuonStrings *muonStrings = MuonStrings::global(); + + QString title = muonStrings->errorTitle(QApt::InitError); + QString text = muonStrings->errorText(QApt::InitError, nullptr); + + KMessageBox::detailedError(mainWindow(), text, details, title); + exit(-1); +} + +void QAptActions::displayTransactionError(QApt::ErrorCode error, QApt::Transaction* trans) +{ + if (error == QApt::Success) + return; + + MuonStrings *muonStrings = MuonStrings::global(); + + QString title = muonStrings->errorTitle(error); + QString text = muonStrings->errorText(error, trans); + + switch (error) { + case QApt::InitError: + case QApt::FetchError: + case QApt::CommitError: + KMessageBox::detailedError(QAptActions::self()->mainWindow(), text, trans->errorDetails(), title); + break; + default: + KMessageBox::error(QAptActions::self()->mainWindow(), text, title); + break; + } +} + +void QAptActions::showHistoryDialog() +{ + if (!m_historyDialog) { + m_historyDialog = new QDialog(mainWindow()); + QVBoxLayout* layout = new QVBoxLayout(m_historyDialog); + m_historyDialog->setLayout(layout); + m_historyDialog->setWindowTitle(i18nc("@title:window", "Package History")); + m_historyDialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("view-history"))); + + KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("muonrc")), QStringLiteral("HistoryDialog")); + KWindowConfig::restoreWindowSize(m_historyDialog->windowHandle(), dialogConfig); + + HistoryView *historyView = new HistoryView(m_historyDialog); + layout->addWidget(historyView); + + QDialogButtonBox* box = new QDialogButtonBox(m_historyDialog); + box->setStandardButtons(QDialogButtonBox::Close); + connect(box, &QDialogButtonBox::accepted, m_historyDialog.data(), &QDialog::accept); + connect(box, &QDialogButtonBox::rejected, m_historyDialog.data(), &QDialog::reject); + connect(m_historyDialog, &QDialog::finished, this, &QAptActions::closeHistoryDialog); + layout->addWidget(box); + + m_historyDialog->show(); + } else { + m_historyDialog->raise(); + } +} + +void QAptActions::closeHistoryDialog() +{ + KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("muonrc")), "HistoryDialog"); + KWindowConfig::restoreWindowSize(m_historyDialog->windowHandle(), dialogConfig); + m_historyDialog->deleteLater(); + m_historyDialog = nullptr; +} + +void QAptActions::launchDistUpgrade() +{ + const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu"); + QProcess::startDetached(kdesu, {QStringLiteral("--"), QStringLiteral("do-release-upgrade"), QStringLiteral("-m"), QStringLiteral("desktop"), QStringLiteral("-f"), QStringLiteral("DistUpgradeViewKDE")}); +} + +void QAptActions::checkDistUpgrade() +{ + if(!QFile::exists(QStringLiteral("/usr/lib/python3/dist-packages/DistUpgrade/DistUpgradeFetcherKDE.py"))) { + qWarning() << "Couldn't find the /usr/lib/python3/dist-packages/DistUpgrade/DistUpgradeFetcherKDE.py file"; + return; + } + QString checkerFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/applicationsbackend/releasechecker")); + if(checkerFile.isEmpty()) { + qWarning() << "Couldn't find the releasechecker script" << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); + return; + } + + KProcess* checkerProcess = new KProcess(this); + checkerProcess->setProgram({ QStringLiteral("/usr/bin/python3"), checkerFile }); + connect(checkerProcess, static_cast(&KProcess::finished), this, &QAptActions::checkerFinished); + connect(checkerProcess, static_cast(&KProcess::finished), checkerProcess, &KProcess::deleteLater); + checkerProcess->start(); +} + +void QAptActions::checkerFinished(int res) +{ + m_distUpgradeAvailable = (res == 0); + if (!actionCollection()) + return; + actionCollection()->action(QStringLiteral("dist-upgrade"))->setEnabled(m_distUpgradeAvailable); +} diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h b/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h new file mode 100644 index 0000000..b71b290 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright © 2012 Jonathan Thomas * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef QAPTACTIONS_H +#define QAPTACTIONS_H + +#include +#include +#include + +#include + +class KXmlGuiWindow; +class KDialog; +class KXmlGuiWindow; +class KActionCollection; +class QAction; +class QDialog; +class QNetworkConfigurationManager; + +namespace QApt { + class Backend; + class Transaction; +} + +class QAptActions : public QObject +{ + Q_OBJECT +public: + static QAptActions* self(); + void setActionCollection(KActionCollection* actions); + Q_DECL_DEPRECATED QWidget* mainWindow() const; + + bool reloadWhenSourcesEditorFinished() const; + bool isConnected() const; + void setOriginalState(QApt::CacheState state); + void setReloadWhenEditorFinished(bool reload); + void initError(); + void displayTransactionError(QApt::ErrorCode error, QApt::Transaction* trans); + KActionCollection* actionCollection(); + + void setCanExit(bool e) { m_canExit = e; } + bool canExit() const { return m_canExit; } + +Q_SIGNALS: + void shouldConnect(bool isConnected); + void changesReverted(); + void sourcesEditorClosed(bool reload); + void downloadArchives(QApt::Transaction *trans); + +public Q_SLOTS: + void setBackend(QApt::Backend *backend); + void setupActions(); + + // KAction slots + bool saveSelections(); + bool saveInstalledPackagesList(); + void loadSelections(); + bool createDownloadList(); + void downloadPackagesFromList(); + void loadArchives(); + void undo(); + void redo(); + void revertChanges(); + void runSourcesEditor(); + void sourcesEditorFinished(int exitStatus); + void showHistoryDialog(); + void setActionsEnabled(bool enabled = true); + +private Q_SLOTS: + void closeHistoryDialog(); + void checkDistUpgrade(); + void launchDistUpgrade(); + void checkerFinished(int res); + +private: + QAptActions(); + + QApt::Backend *m_backend; + QApt::CacheState m_originalState; + bool m_actionsDisabled; + KActionCollection* m_actionCollection; + bool m_reloadWhenEditorFinished; + + QPointer m_historyDialog; + QList m_actions; + bool m_distUpgradeAvailable; + QNetworkConfigurationManager* m_config; + bool m_canExit; + +}; + +#endif // QAPTACTIONS_H diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action b/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action new file mode 100644 index 0000000..dd6ad20 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action @@ -0,0 +1,5 @@ +[org.kde.muon.repo.modify] +Name=Add Repo +Description=The system is attempting to modify the sources +Policy=auth_admin +Persistence=session \ No newline at end of file diff --git a/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc b/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc new file mode 100644 index 0000000..f9e38bc --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc @@ -0,0 +1,112 @@ +[Global] +IconName=muondiscover +Comment=Muon Application Backend Notifier +Comment[ar]=مُخطر سند تطبيقات ميون +Comment[ca]=Notificador del dorsal d'aplicacions del Muon +Comment[ca@valencia]=Notificador del dorsal d'aplicacions del Muon +Comment[cs]=Podpůrná vrstva upozorňování pro Muon +Comment[da]=Muon-program-backend-bekendtgørelser +Comment[de]=Muon-Dienstprogramm für Anwendungs-Benachrichtigungen +Comment[el]=Πρόγραμμα ειδοποιήσεων εφαρμογών υποστήριξης Muon +Comment[en_GB]=Muon Application Backend Notifier +Comment[es]=Notificador del motor de la aplicación Muon +Comment[et]=Muoni rakenduse taustaprogrammi märguanded +Comment[fi]=Muonin sovellustaustajärjestelmän ilmoitukset +Comment[fr]=Notifieur du moteur de l'application Muon +Comment[gl]=Motor de notificacións de aplicacións de Muon +Comment[id]=Pemberitahu Backend Aplikasi Muon +Comment[it]=Notifiche motore applicazioni di Muon +Comment[ko]=Muon 프로그램 백엔드 알림이 +Comment[nb]=Muon varsler for program-bakgrunnsmotor +Comment[nl]=Muon backend van melder van toepassingen +Comment[nn]=Muon-varslar for program-bakgrunnsmotor +Comment[pl]=Silnik powiadamiania o programach Muon +Comment[pt]=Notificação da Infra-Estrutura de Aplicações do Muon +Comment[pt_BR]=Notificador da Infraestrutura de Aplicativos do Muon +Comment[ru]=Модуль уведомлений Muon +Comment[sk]=Backendový oznamovač aplikácií Muon +Comment[sl]=Zaledja obvestilnika za programe Muon +Comment[sr]=Муонова позадина за извештавање о програмима +Comment[sr@ijekavian]=Муонова позадина за извештавање о програмима +Comment[sr@ijekavianlatin]=Muonova pozadina za izveštavanje o programima +Comment[sr@latin]=Muonova pozadina za izveštavanje o programima +Comment[sv]=Muon programgränssnittsunderrättelser +Comment[uk]=Сповіщувач модуля програми Muon +Comment[x-test]=xxMuon Application Backend Notifierxx +Comment[zh_CN]=Muon 应用程序后端提示器 +Comment[zh_TW]=Muon 應用程式後端介面通知器 + +[Event/DistUpgrade] +Name=Upgrade Available +Name[ar]=التّرقيّة متوفّرة +Name[ca]=Hi ha una actualització disponible +Name[ca@valencia]=Hi ha una actualització disponible +Name[cs]=Dostupná aktualizace distribuce +Name[da]=Opgradering tilgængelig +Name[de]=Paketaktualisierung verfügbar +Name[el]=Διαθέσιμη αναβάθμιση +Name[en_GB]=Upgrade Available +Name[es]=Actualización disponible +Name[et]=Saadaval on uuendus +Name[fi]=Versiopäivitys saatavilla +Name[fr]=Mise à niveau disponible +Name[gl]=Dispoñíbel unha actualización +Name[he]=יש שדרוג זמים +Name[id]=Pembaruan Tersedia +Name[it]=Aggiornamento disponibile +Name[ko]=업그레이드 사용 가능 +Name[nb]=Oppgradering tilgjengelig +Name[nl]=Opwaardering beschikbaar +Name[nn]=Oppgradering tilgjengeleg +Name[pl]=Dostępne uaktualnienie +Name[pt]=Actualização Disponível +Name[pt_BR]=Atualização disponível +Name[ru]=Доступно обновление дистрибутива +Name[sk]=Dostupné vylepšenia systému +Name[sl]=Na voljo je nadgradnja +Name[sr]=Доступна надоградња +Name[sr@ijekavian]=Доступна надоградња +Name[sr@ijekavianlatin]=Dostupna nadogradnja +Name[sr@latin]=Dostupna nadogradnja +Name[sv]=Uppgradering tillgänglig +Name[uk]=Доступне оновлення дистрибутива +Name[x-test]=xxUpgrade Availablexx +Name[zh_CN]=更新可用 +Name[zh_TW]=有可用的更新 +Comment=A new version of Kubuntu is available +Comment[ar]=إصدارة جديدة من كوبونتو متوفّرة +Comment[ca]=Hi ha disponible una nova versió del Kubuntu +Comment[ca@valencia]=Hi ha disponible una nova versió del Kubuntu +Comment[cs]=Je dostupná nová verze Kubuntu +Comment[da]=En ny version af Kubuntu er tilgængelig +Comment[de]=Eine neue Version von Kubuntu ist verfügbar +Comment[el]=Μια νέα έκδοση του Kubuntu είναι διαθέσιμη +Comment[en_GB]=A new version of Kubuntu is available +Comment[es]=Está disponible una nueva versión de Kubuntu +Comment[et]=Saadaval on Kubuntu uus versioon +Comment[fi]=Uusi Kubuntun versio on saatavilla +Comment[fr]=Une nouvelle version de Kubuntu est disponible +Comment[gl]=Hai dispoñíbel unha nova versión de Kubuntu. +Comment[he]=גרסה חדשה של Kubuntu זמינה +Comment[id]=Sebuah versi baru Kubuntu telah tersedia +Comment[it]=È disponibile una nuova versione di Kubuntu +Comment[ko]=Kubuntu 새 버전 사용 가능 +Comment[nb]=En ny versjon av Kubuntu er tilgjengelig +Comment[nl]=Er is een nieuwe versie van Kubuntu beschikbaar +Comment[nn]=Ein ny versjon av Kubuntu er tilgjengeleg +Comment[pl]=Dostępna jest nowa wersja Kubuntu +Comment[pt]=Está disponível uma nova versão do Kubuntu +Comment[pt_BR]=Está disponível uma nova versão do Kubuntu +Comment[ru]=Доступна новая версия Kubuntu +Comment[sk]=Nová verzia Kubuntu je dostupná +Comment[sl]=Na voljo je nova različica Kubuntu +Comment[sr]=Доступно је ново издање Кубунтуа +Comment[sr@ijekavian]=Доступно је ново издање Кубунтуа +Comment[sr@ijekavianlatin]=Dostupno je novo izdanje Kubuntua +Comment[sr@latin]=Dostupno je novo izdanje Kubuntua +Comment[sv]=En ny version av Kubuntu är tillgänglig +Comment[uk]=Випущено нову версію Kubuntu +Comment[x-test]=xxA new version of Kubuntu is availablexx +Comment[zh_CN]=有新版本的 Kubuntu 可用 +Comment[zh_TW]=已經有新版本的 Kubuntu +Action=Popup diff --git a/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml b/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml new file mode 100644 index 0000000..80f310a --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml @@ -0,0 +1,559 @@ + + + + + Accessories + applications-utilities + + + Utility + Accessibility + + + + + + Accessibility + preferences-desktop-accessibility + + + Accessibility + Settings + + + + + + Developer Tools + applications-development + + + Development + devel + restricted/devel + universe/devel + multiverse/devel + + emacs.desktop + + + + + Debugging + tools-report-bug + + + Debugger + + + + + + Graphic Interface Design + + + GUIDesigner + + + + + + Haskell + text-x-haskell + + + haskell + restricted/haskell + universe/haskell + multiverse/haskell + + + + + + IDEs + + + IDE + + + + + + Java + application-x-java + + + java + restricted/java + universe/java + multiverse/java + + + + + + Localization + preferences-desktop-locale + + + Translation + + + + + + Perl + + + perl + restricted/perl + universe/perl + multiverse/perl + + + + + + Profiling + + + Profiling + + + + + + Python + text-x-python + + + python + restricted/python + universe/python + multiverse/python + + + + + + Version Control + text-x-patch + + + vcs + restricted/vcs + universe/vcs + multiverse/vcs + RevisionControl + + + + + + Web Development + + + WebDevelopment + + + applications-internet + + + + + + + Education + applications-education + + + Education + + Science + + + + + + + + Science & Engineering + applications-science + + + Science + Engineering + + + + Astronomy + + + Astronomy + + + + + Biology + + + Biology + + + + + Chemistry + applications-science + + + Chemistry + + + + + Computer Science & Robotics + computer + + + ArtificialIntelligence + ComputerScience + Robotics + + + + + Electronics + audio-card + + + Electronics + + + + + Engineering + applications-engineering + + + Engineering + + + + + Geography + + + Geography + + + + + Geology + + + Geology + Geoscience + + + + + Mathematics + applications-education-mathematics + + + DataVisualization + Math + NumericalAnalysis + math + restricted/math + universe/math + multiverse/math + gnu-r + restricted/gnu-r + universe/gnu-r + multiverse/gnu-r + + + + + Physics + step + + + Physics + + + + + + + Fonts + preferences-desktop-font + true + + + ttf-* + otf-* + fonts + restricted/fonts + universe/fonts + multiverse/fonts + + + + + + Games + applications-games + + + Game + + + + + Arcade + applications-games-arcade + + + ArcadeGame + + + + + Board Games + applications-games-board + + + BoardGame + + + + + Card Games + applications-games-card + + + CardGame + + + + + Puzzles + applications-games + + + LogicGame + + + + + Role Playing + applications-games + + + RolePlaying + + + + + Simulation + applications-games-strategy + + + Simulation + + + + + Sports + applications-games + + + SportsGame + + + + + + + + + Graphics + applications-graphics + + + Graphics + + + + 3D + + + 3DGraphics + + + + + Drawing + draw-freehand + + + VectorGraphics + + Viewer + + + + + + Painting & Editing + draw-brush + + + RasterGraphics + + Viewer + Scanning + + + + + + Photography + image-x-generic + + + Photography + + + + + Publishing + document-export + + + Publishing + + + + + Scanning & OCR + scanner + + + Scanning + OCR + + + + + Viewers + graphics-viewer-document + + + Viewer + + + + + + + + Internet + applications-internet + + + Network + + + + Chat + kopete + + + InstantMessaging + IRCClient + + + + + File Sharing + ktorrent + + + FileTransfer + + + + + Mail + internet-mail + + + Email + + + + + Web Browsers + internet-web-browser + + + WebBrowser + + + + + + + + Multimedia + applications-multimedia + + + AudioVideo + + + + + + + Office + applications-office + + + Office + + + + + + System & Settings + preferences-system + + + Settings + System + + + + + + Plasma Addons + plasma + + + Plasma Desktop Widgets + plasma + true + + + plasma-widget-* + + + + + + diff --git a/libdiscover/backends/ApplicationBackend/qapt-backend.desktop b/libdiscover/backends/ApplicationBackend/qapt-backend.desktop new file mode 100644 index 0000000..726dabd --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/qapt-backend.desktop @@ -0,0 +1,114 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Icon=applications-other +Comment=Install and browse applications in APT +Comment[ar]=ثبّت التّطبيقات في APT وتصفّحها +Comment[ca]=Instal·la i mostra aplicacions en l'APT +Comment[ca@valencia]=Instal·la i mostra aplicacions en l'APT +Comment[cs]=Instalujte a prohlížejte aplikace v APT +Comment[da]=Installér og gennemse programmer i APT +Comment[de]=Anwendungen in APT installieren und durchsuchen +Comment[el]=Εγκαταστήστε και περιηγηθείτε σε εφαρμογές με το APT +Comment[en_GB]=Install and browse applications in APT +Comment[es]=Instalar y explorar aplicaciones en APT +Comment[et]=Rakenduste paigaldamine ja sirvimine APT-is +Comment[fi]=Asenna ja selaa APT:n välityksellä tarjolla olevia sovelluksia +Comment[fr]=Installer et parcourir des applications dans « APT » +Comment[gl]=Instalar e buscar aplicacións en APT +Comment[he]=התקן ודפדפף ביישומים ב־APT +Comment[id]=Pasang dan jelajahi aplikasi di APT +Comment[it]=Installa e sfoglia le applicazioni in APT +Comment[ko]=APT에서 프로그램을 찾고 설치하기 +Comment[nb]=Installer og bla i programmer i APT +Comment[nl]=Installeer en blader door toepassingen in APT +Comment[nn]=Installer og bla gjennom program i APT +Comment[pl]=Wgrywaj i przeglądaj programy w APT +Comment[pt]=Instalar e navegar nas aplicações do APT +Comment[pt_BR]=Instala e navega pelos aplicativos no APT +Comment[ru]=Установка и обзор приложений в APT +Comment[sk]=Inštalácia a prehliadanie aplikácií v APT +Comment[sl]=Namestite in brskajte po programih v APT +Comment[sr]=Инсталирајте и прегледајте програме из АПТ‑а +Comment[sr@ijekavian]=Инсталирајте и прегледајте програме из АПТ‑а +Comment[sr@ijekavianlatin]=Instalirajte i pregledajte programe iz APT‑a +Comment[sr@latin]=Instalirajte i pregledajte programe iz APT‑a +Comment[sv]=Installera och bläddra bland program med APT +Comment[uk]=Встановіть і перегляньте встановлені програми у APT +Comment[x-test]=xxInstall and browse applications in APTxx +Comment[zh_CN]=安装浏览 APT 中的程序 +Comment[zh_TW]=在 APT 內安裝並瀏覽應用程式 +Name=Applications Backend +Name[ar]=سند التّطبيقات +Name[ca]=Dorsal d'aplicacions +Name[ca@valencia]=Dorsal d'aplicacions +Name[cs]=Podpůrná vrstva aplikace +Name[da]=Program-backend +Name[de]=Dienstprogramm für Anwendungen +Name[el]=Σύστημα υποστήριξης εφαρμογών +Name[en_GB]=Applications Backend +Name[es]=Motor de aplicaciones +Name[et]=Rakenduse taustaprogramm +Name[fi]=Sovellukset-taustajärjestelmä +Name[fr]=Moteur des applications +Name[gl]=Infraestrutura de programas +Name[id]=Backend Aplikasi +Name[it]=Motore applicazioni +Name[ko]=프로그램 백엔드 +Name[nb]=Program-bakgrunnsmotor +Name[nl]=Backend van toepassing +Name[nn]=Program-bakgrunnsmotor +Name[pl]=Silnik programów +Name[pt]=Infra-Estrutura de Aplicações +Name[pt_BR]=Infraestrutura de aplicativos +Name[ru]=Модуль приложений +Name[sk]=Backend aplikácií +Name[sl]=Zaledje programov +Name[sr]=Позадина за програме +Name[sr@ijekavian]=Позадина за програме +Name[sr@ijekavianlatin]=Pozadina za programe +Name[sr@latin]=Pozadina za programe +Name[sv]=Programgränssnitt +Name[uk]=Модуль програм +Name[x-test]=xxApplications Backendxx +Name[zh_CN]=应用程序后端 +Name[zh_TW]=應用程式後端介面 +GenericName=APT Support +GenericName[ar]=دعم APT +GenericName[ca]=Implementació de l'APT +GenericName[ca@valencia]=Implementació de l'APT +GenericName[cs]=Podpora APT +GenericName[da]=APT-understøttelse +GenericName[de]=Unterstützung für APT +GenericName[el]=Υποστήριξη APT +GenericName[en_GB]=APT Support +GenericName[es]=Uso de APT +GenericName[et]=APT toetus +GenericName[fi]=APT-tuki +GenericName[fr]=Prise en charge de « APT » +GenericName[gl]=Soporte para APT +GenericName[he]=APT תומך +GenericName[id]=APT Support +GenericName[it]=Supporto APT +GenericName[ko]=APT 지원 +GenericName[nb]=APT-støtte +GenericName[nl]=Ondersteuning van APT +GenericName[nn]=APT-støtte +GenericName[pl]=Obsługa APT +GenericName[pt]=Suporte para o APT +GenericName[pt_BR]=Suporte ao APT +GenericName[ru]=Поддержка APT +GenericName[sk]=Podpora APT +GenericName[sl]=Podpora APT +GenericName[sr]=Подршка за АПТ +GenericName[sr@ijekavian]=Подршка за АПТ +GenericName[sr@ijekavianlatin]=Podrška za APT +GenericName[sr@latin]=Podrška za APT +GenericName[sv]=Stöd för APT +GenericName[uk]=Підтримка APT +GenericName[x-test]=xxAPT Supportxx +GenericName[zh_CN]=APT 支持 +GenericName[zh_TW]=APT 支援 +X-KDE-Library=qapt-backend +X-KDE-PluginInfo-Name=qapt-backend +X-KDE-PluginInfo-License=GPL diff --git a/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt new file mode 100644 index 0000000..06c858a --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt @@ -0,0 +1,5 @@ +find_package(Qca-qt5 REQUIRED) + +add_library(MuonQOAuth STATIC src/interface.cpp) +target_link_libraries(MuonQOAuth PUBLIC Qt5::Network qca-qt5) +add_library(Muon::QOAuth ALIAS MuonQOAuth) diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp b/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp new file mode 100644 index 0000000..179f729 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp @@ -0,0 +1,1084 @@ +/*************************************************************************** + * Copyright (C) 2009 by Dominik Kapusta * + * * + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation; either version 2.1 of * + * the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to * + * the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +#include "interface.h" +#include "interface_p.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + \mainpage + + \section sec_what What is the purpose of QOAuth? + + The main motivation to create this library was to provide an interface to OAuth + protocol for (Qt-based) C++ applications in an easy way. This is very early version + of the library, and it lacks some functionality, but in the same time it is capable + of sending OAuth authorization requests as well as preparing requests for accessing + User's Protected Resources. + + \section sec_lic License and Authors + + The project is licensed under GNU LGPL + license version 2.1 or later. The work is done by Dominik Kapusta (d at ayoy dot net). + + \section sec_inst How to install? + + \subsection ssec_deps Dependencies + + There are a few things necessary to get OAuth library working: + +
    +
  1. Qt libraries, version 4.4 or higher,
  2. +
  3. QCA (Qt Cryptographic Architecture), available from + Delta XMPP Project, version 2.0.0 + or higher,
  4. +
  5. OpenSSL plugin to QCA (qca-ossl), available from QCA page, and requiring OpenSSL.
  6. +
+ + \b Note: KDE4 users meet all the requirements out of the box. + + \subsection ssec_inst Installation + + The source code repository is hosted on GitHub + and the code can be checked out from there easily using git: + \verbatim + $ git clone git://github.com/ayoy/qoauth.git \endverbatim + + To compile the code, follow the simple procedure: + + \verbatim + $ qmake + $ make + $ sudo make install \endverbatim + + \subsection ssec_use Usage + + Configuring your project to work with QOAuth library is extremely simple. Firstly, + append a line to your project file: + \verbatim + CONFIG += oauth \endverbatim + + Then include the following header in your code: + \verbatim + #include \endverbatim + + \b Note: This follows the Qt scheme, i.e. QT += xml ==> #include , etc. + + \section sec_bugs Bugs and issues + + Please file all the bug reports to the QOAuth bug tracking system at + + lighthouseapp.com. If you wish to contribute, you're extremely welcome + to fork a GitHub repository and + add your input there. + +*/ + +/*! + \class QOAuth::Interface interface.h + \brief This class provides means for interaction with network services supporting + OAuth authorization scheme. + + The QOAuth::Interface class is meant to enable OAuth support in applications in as simple way + as possible. It provides 4 basic methods, two of which serve for authorization purposes: + \li \ref requestToken(), + \li \ref accessToken(), + + and the other two help with creation of requests for accessing Protected Resources: + \li \ref createParametersString(), + \li \ref inlineParameters(). + + \section sec_auth_scheme OAuth authorization scheme + + According to + OAuth 1.0 Core specification, the OAuth protocol enables websites or applications + (Consumers) to access Protected Resources from a web service (Service Provider) via an + API, without requiring Users to disclose their Service Provider credentials to the + Consumers. Simply, OAuth is a way of connecting an application to the Service + Provider's API without needing to provide User's login or password. The authorization + is based on an exchange of a Token (user-specific) together with a Consumer Key + (application-specific), encrypted with a combination of so called Token Secret and + Customer Secret. Getting access to Protected Resources consists in three basic steps: +
    +
  1. obtaining an unauthorized Request Token from the Service Provider,
  2. +
  3. asking the User to authorize the Request Token,
  4. +
  5. exchanging the Request Token for the Access Token.
  6. +
+ Details are covered in Section 6 of the + OAuth 1.0 Core Specification. As the authorization procedure is quite complex, the QOAuth + library helps to simplify it by doing all the dirty work behind the scenes. + + \section sec_req_token OAuth authorization with QOAuth + + First step of OAuth authorization can be done in one line using QOAuth library. + Consult the example: + + \include requestToken.cpp + + Once the unauthorized Request Token is received, User has to authorize it using + Service Provider-defined method. This is beyond the scope of this library. Once User + authorizes the Request Token, it can be exchanged for an Access Token that authorizes the + application to access User's Protected Resources. This can be done with another one line: + + \include accessToken.cpp + + Once the Access Token is received, the application is authorized. + + \section sec_acc_res Requesting Protected Resources with QOAuth + + In order to access Protected Resources, the application has to send a request containing + arguments including Customer Key and Access Token, and encrypt them with Customer Secret + and Token Secret. The process of constructing such a request can be reduced to another + one-line call with QOAuth::Interface. The example code for inlining all request parameters + (both User-specific and OAuth-related): + + \include getResources.cpp + + If Service Provider requires the OAuth authorization to be done in the Authorization + header field, then only User-specific parameters should be inlined with the URL: + + \include getResources2.cpp + + \section sec_capabilities Capabilities + + QOAuth library works with all 3 signature methods supported by the OAuth protocol, namely + HMAC-SHA1, RSA-SHA1 and PLAINTEXT. Hovewer, RSA-SHA1 and (especially) PLAINTEXT + methods may still need additional testing for various input conditions. +*/ + + +QByteArray QOAuth::supportedOAuthVersion() +{ + return InterfacePrivate::OAuthVersion; +} + +QByteArray QOAuth::tokenParameterName() +{ + return InterfacePrivate::ParamToken; +} + +QByteArray QOAuth::tokenSecretParameterName() +{ + return InterfacePrivate::ParamTokenSecret; +} + + +//! \brief The supported OAuth scheme version. +const QByteArray QOAuth::InterfacePrivate::OAuthVersion = "1.0"; + +//! \brief The token request parameter string +const QByteArray QOAuth::InterfacePrivate::ParamToken = "oauth_token"; +//! \brief The token secret request parameter string +const QByteArray QOAuth::InterfacePrivate::ParamTokenSecret = "oauth_token_secret"; + +//! \brief The consumer key request parameter string +const QByteArray QOAuth::InterfacePrivate::ParamConsumerKey = "oauth_consumer_key"; +//! \brief The nonce request parameter string +const QByteArray QOAuth::InterfacePrivate::ParamNonce = "oauth_nonce"; +//! \brief The signature request parameter string +const QByteArray QOAuth::InterfacePrivate::ParamSignature = "oauth_signature"; +//! \brief The signature method request parameter string +const QByteArray QOAuth::InterfacePrivate::ParamSignatureMethod = "oauth_signature_method"; +//! \brief The timestamp request parameter string +const QByteArray QOAuth::InterfacePrivate::ParamTimestamp = "oauth_timestamp"; +//! \brief The version request parameter string +const QByteArray QOAuth::InterfacePrivate::ParamVersion = "oauth_version"; + +QOAuth::InterfacePrivate::InterfacePrivate() : + privateKeySet( false ), + consumerKey( QByteArray() ), + consumerSecret( QByteArray() ), + manager(0), + loop(0), + requestTimeout(0), + error( NoError ) +{ +} + +void QOAuth::InterfacePrivate::init() +{ + Q_Q(QOAuth::Interface); + + ignoreSslErrors = false; + loop = new QEventLoop(q); + setupNetworkAccessManager(); + + q->connect( &eventHandler, SIGNAL(eventReady(int,QCA::Event)), SLOT(_q_setPassphrase(int,QCA::Event)) ); + eventHandler.start(); +} + +void QOAuth::InterfacePrivate::setupNetworkAccessManager() +{ + Q_Q(QOAuth::Interface); + + if (manager == 0) + manager = new QNetworkAccessManager; + + manager->setParent(q); + q->connect(manager, &QNetworkAccessManager::finished, loop, &QEventLoop::quit); + q->connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(_q_parseReply(QNetworkReply*))); + q->connect(manager, SIGNAL(sslErrors(QNetworkReply*, QList)), SLOT(_q_handleSslErrors(QNetworkReply*, QList))); +} + +QByteArray QOAuth::InterfacePrivate::httpMethodToString( HttpMethod method ) +{ + switch ( method ) { + case GET: + return "GET"; + case POST: + return "POST"; + case HEAD: + return "HEAD"; + case PUT: + return "PUT"; +#ifndef Q_WS_WIN + case DELETE: + return "DELETE"; +#endif + default: + qWarning() << __FUNCTION__ << "- Unrecognized method"; + return QByteArray(); + } +} + +QByteArray QOAuth::InterfacePrivate::signatureMethodToString( SignatureMethod method ) +{ + switch ( method ) { + case HMAC_SHA1: + return "HMAC-SHA1"; + case RSA_SHA1: + return "RSA-SHA1"; + case PLAINTEXT: + return "PLAINTEXT"; + default: + qWarning() << __FUNCTION__ << "- Unrecognized method"; + return QByteArray(); + } +} + +QOAuth::ParamMap QOAuth::InterfacePrivate::replyToMap( const QByteArray &data ) +{ + // split reply to name=value strings + QList replyParams = data.split( '&' ); + // we'll store them in a map + ParamMap parameters; + + QByteArray replyParam; + QByteArray key; + int separatorIndex; + + // iterate through name=value pairs + Q_FOREACH ( replyParam, replyParams ) { + // find occurrence of '=' + separatorIndex = replyParam.indexOf( '=' ); + // key is on the left + key = replyParam.left( separatorIndex ); + // value is on the right + parameters.insert( key , replyParam.right( replyParam.length() - separatorIndex - 1 ) ); + } + + return parameters; +} + +void QOAuth::InterfacePrivate::_q_parseReply( QNetworkReply *reply ) +{ + int returnCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt(); + + switch ( returnCode ) { + case NoError: + replyParams = replyToMap( reply->readAll() ); + if ( !replyParams.contains( InterfacePrivate::ParamToken ) ) { + qWarning() << __FUNCTION__ << "- oauth_token not present in reply!"; + } + if ( !replyParams.contains( InterfacePrivate::ParamTokenSecret ) ) { + qWarning() << __FUNCTION__ << "- oauth_token_secret not present in reply!"; + } + + case BadRequest: + case Unauthorized: + case Forbidden: + error = returnCode; + break; + default: + error = OtherError; + } + + reply->close(); +} + +void QOAuth::InterfacePrivate::_q_handleSslErrors(QNetworkReply *reply, const QList &errors) +{ + Q_UNUSED(errors); + + if (ignoreSslErrors) + reply->ignoreSslErrors(); +} + +QByteArray QOAuth::InterfacePrivate::paramsToString( const ParamMap ¶meters, ParsingMode mode ) +{ + QByteArray middleString; + QByteArray endString; + QByteArray prependString; + + switch ( mode ) { + case ParseForInlineQuery: + prependString = "?"; + case ParseForRequestContent: + case ParseForSignatureBaseString: + middleString = "="; + endString = "&"; + break; + case ParseForHeaderArguments: + prependString = "OAuth "; + middleString = "=\""; + endString = "\","; + break; + default: + qWarning() << __FUNCTION__ << "- Unrecognized mode"; + return QByteArray(); + } + + QByteArray parameter; + QByteArray parametersString; + + Q_FOREACH( parameter, parameters.uniqueKeys() ) { + QList values = parameters.values( parameter ); + if ( values.size() > 1 ) { + qSort( values.begin(), values.end() ); + } + QByteArray value; + Q_FOREACH ( value, values ) { + parametersString.append( parameter ); + parametersString.append( middleString ); + parametersString.append( value ); + parametersString.append( endString ); + } + } + + // remove the trailing end character (comma or ampersand) + parametersString.chop(1); + + // prepend with the suitable string (or none) + parametersString.prepend( prependString ); + + return parametersString; +} + + +/*! + \brief Creates a new QOAuth::Interface class instance with the given \a parent +*/ + +QOAuth::Interface::Interface( QObject *parent ) : + QObject( parent ), + d_ptr( new InterfacePrivate ) +{ + Q_D(Interface); + + d->q_ptr = this; + d->init(); +} + +/*! + \brief Creates a new QOAuth::Interface class instance with the given \a parent, + using \a manager for network connections. + + Use this constructor if you want to use your custom network access manager to + handle network connections needed by the interface. + + /sa setNetworkAccessManager() +*/ + +QOAuth::Interface::Interface(QNetworkAccessManager *manager, QObject *parent) : + QObject( parent ), + d_ptr( new InterfacePrivate ) +{ + Q_D(Interface); + + d->q_ptr = this; + d->manager = manager; + d->init(); +} + +/*! + \brief Destroys the QOAuth::Interface object +*/ + +QOAuth::Interface::~Interface() +{ + delete d_ptr; +} + +/*! + \brief Returns the network access manager used by the interface. +*/ +QNetworkAccessManager* QOAuth::Interface::networkAccessManager() const +{ + Q_D(const Interface); + + return d->manager; +} + +/*! + \brief Sets \a manager to be the network access manager used by the interface. + + The interface class takes ownership of the manager. If there already is a manager, + it's being deleted. + + /sa networkAccessManager() +*/ +void QOAuth::Interface::setNetworkAccessManager(QNetworkAccessManager* manager) +{ + Q_D(Interface); + + if (d->manager) + delete d->manager; + + d->manager = manager; + d->setupNetworkAccessManager(); +} + +/*! + \property QOAuth::Interface::ignoreSslErrors + \brief This property is used to control SSL errors handling. + + The default value is false, meaning that the interface will fail upon an SSL error. + Set it to true if you want to disregard any SSL errors encountered + during the authorization process. + + Access functions: + \li bool ignoreSslErrors() const + \li void setIgnoreSslErrors( bool enabled ) +*/ + +bool QOAuth::Interface::ignoreSslErrors() const +{ + Q_D(const QOAuth::Interface); + + return d->ignoreSslErrors; +} + +void QOAuth::Interface::setIgnoreSslErrors(bool enabled) +{ + Q_D(QOAuth::Interface); + + d->ignoreSslErrors = enabled; +} + + +/*! + \property QOAuth::Interface::consumerKey + \brief This property holds the consumer key + + The consumer key is used by the application to identify itself to the Service Provider. + + Access functions: + \li QByteArray consumerKey() const + \li void setConsumerKey( const QByteArray &consumerKey ) +*/ + +QByteArray QOAuth::Interface::consumerKey() const +{ + Q_D(const Interface); + + return d->consumerKey; +} + +void QOAuth::Interface::setConsumerKey( const QByteArray &consumerKey ) +{ + Q_D(Interface); + + d->consumerKey = consumerKey; +} + +/*! + \property QOAuth::Interface::consumerSecret + \brief This property holds the consumer secret + + The consumerSecret is used by the application for signing outgoing requests. + + Access functions: + \li QByteArray consumerSecret() const + \li void setConsumerSecret( const QByteArray &consumerSecret ) +*/ + +QByteArray QOAuth::Interface::consumerSecret() const +{ + Q_D(const Interface); + + return d->consumerSecret; +} + +void QOAuth::Interface::setConsumerSecret( const QByteArray &consumerSecret ) +{ + Q_D(Interface); + + d->consumerSecret = consumerSecret; +} + +/*! + \property QOAuth::Interface::requestTimeout + \brief This property holds the timeout value in milliseconds for issued network requests. + + The QOAuth::Interface class can send network requests when asked to do so by calling either + requestToken() or accessToken() method. By defining the \a requestTimeout, requests + can have the time constraint applied, after which they fail, setting \ref error to + \ref Timeout. The \a requestTimeout value is initially set to \c 0, which in this + case means that no timeout is applied to outgoing requests. + + Access functions: + \li uint requestTimeout() const + \li void setRequestTimeout( uint requestTimeout ) +*/ + +uint QOAuth::Interface::requestTimeout() const +{ + Q_D(const Interface); + + return d->requestTimeout; +} + +void QOAuth::Interface::setRequestTimeout( uint msec ) +{ + Q_D(Interface); + + d->requestTimeout = msec; +} + + +/*! + \property QOAuth::Interface::error + \brief This property holds the error code + + The error code is initially set to \ref NoError, and its value is updated with every + method that can cause errors. + + Access functions: + \li int error() const + + \sa ErrorCode +*/ + +int QOAuth::Interface::error() const +{ + Q_D(const Interface); + + return d->error; +} + + +/*! + This method is useful when using OAuth with RSA-SHA1 signing algorithm. It reads the RSA + private key from the string given as \a key, and stores it internally. If the key is + secured by a passphrase, it should be passed as the second argument. + + The provided string is decoded into a private RSA key, optionally using the \a passphrase. + If \a key contains a valid RSA private key, this method returns true. If any problems were + encountered during decoding (either the key or the passphrase are invalid), false is + returned and the error code is set to QOAuth::RSADecodingError. + + \sa setRSAPrivateKeyFromFile() +*/ + +// bool QOAuth::Interface::setRSAPrivateKey( const QString &key, const QCA::SecureArray &passphrase ) +// { +// Q_D(Interface); +// +// d->setPrivateKey( key, passphrase, InterfacePrivate::KeyFromString ); +// +// return ( d->error == NoError ); +// } + +/*! + This method is useful when using OAuth with RSA-SHA1 signing algorithm. It reads the RSA + private key from the given \a file, and stores it internally. If the key is secured by + a passphrase, it should be passed as the second argument. + + The provided file is read and decoded into a private RSA key, optionally using the \a passphrase. + If it contains a valid RSA private key, this method returns true. If any problems were + encountered during decoding, false is returned and the appropriate error code is set: + \li QOAuth::RSAKeyFileError - when the key file doesn't exist or is unreadable + \li QOAuth::RSADecodingError - if problems occurred during encoding (either the key + and/or password are invalid). + + \sa setRSAPrivateKey() +*/ + +// bool QOAuth::Interface::setRSAPrivateKeyFromFile( const QString &filename, const QCA::SecureArray &passphrase ) +// { +// Q_D(Interface); +// +// if ( ! QFileInfo( filename ).exists() ) { +// d->error = RSAKeyFileError; +// qWarning() << __FUNCTION__ << "- the given file does not exist..."; +// } else { +// d->setPrivateKey( filename, passphrase, InterfacePrivate::KeyFromFile ); +// } +// +// return ( d->error == NoError ); +// } + +void QOAuth::InterfacePrivate::setPrivateKey( const QString &source, + const QCA::SecureArray &passphrase, KeySource from ) +{ + + if( !QCA::isSupported( "pkey" ) || + !QCA::PKey::supportedIOTypes().contains( QCA::PKey::RSA ) ) { + qFatal( "RSA is not supported!" ); + } + + privateKeySet = false; + this->passphrase = passphrase; + + QCA::KeyLoader keyLoader; + QEventLoop localLoop; + QObject::connect(&keyLoader, &QCA::KeyLoader::finished, &localLoop, &QEventLoop::quit); + + switch (from) { + case KeyFromString: + keyLoader.loadPrivateKeyFromPEM( source ); + break; + case KeyFromFile: + keyLoader.loadPrivateKeyFromPEMFile( source ); + break; + } + + QTimer::singleShot( 3000, &localLoop, SLOT(quit()) ); + localLoop.exec(); + + readKeyFromLoader( &keyLoader ); +} + +void QOAuth::InterfacePrivate::readKeyFromLoader( QCA::KeyLoader *keyLoader ) +{ + QCA::ConvertResult result = keyLoader->convertResult(); + if ( result == QCA::ConvertGood ) { + error = NoError; + privateKey = keyLoader->privateKey(); + privateKeySet = true; + } else if ( result == QCA::ErrorDecode ) { + error = RSADecodingError; + // this one seems to never be set .... + // } else if ( result == QCA::ErrorPassphrase ) { + // error = RSAPassphraseError; + } else if ( result == QCA::ErrorFile ) { + error = RSAKeyFileError; + } +} + +void QOAuth::InterfacePrivate::_q_setPassphrase( int id, const QCA::Event &event ) +{ + if ( event.isNull() ) { + return; + } + + // we're looking only for the passphrase for the RSA key + if ( event.type() == QCA::Event::Password && + event.passwordStyle() == QCA::Event::StylePassphrase ) { + // set the passphrase to the one provided with QOAuth::Interface::setRSAPrivateKey{,FromFile}() + eventHandler.submitPassword( id, passphrase ); + } else { + eventHandler.reject( id ); + } +} + +/*! + This method constructs and sends a request for obtaining an unauthorized Request Token + from the Service Provider. This is the first step of the OAuth authentication flow, + according to OAuth 1.0 Core specification. + The PLAINTEXT signature method uses Customer Secret and (if provided) Token Secret to + sign a request. For the HMAC-SHA1 and RSA-SHA1 signature methods the + Signature Base String is created + using the given \a requestUrl and \a httpMethod. The optional request parameters + specified by the Service Provider can be passed in the \a params ParamMap. + + The Signature Base String contains the \ref consumerKey and uses \ref consumerSecret + for encrypting the message, so it's necessary to provide them both before issuing this + request. The method will check if both \ref consumerKey and \ref consumerSecret are + provided, and fail if any of them is missing. + + When the signature is created, the appropriate request is sent to the Service Provider + (namely, the \a requestUrl). Depending on the type of the request, the parameters are + passed according to the + Consumer Request Parametes section of the OAuth specification, i.e.: + \li for GET requests, in the HTTP Authorization header, as defined in + OAuth HTTP Authorization Scheme, + \li for POST requests, as a request body with \c content-type set to + \c application/x-www-form-urlencoded. + + Once the request is sent, a local event loop is executed and set up to wait for the request + to complete. If the \ref requestTimeout property is set to a non-zero value, its vaue + is applied as a request timeout, after which the request is aborted. + + \returns If request succeded, the method returns all the data passed in the Service + Provider response (including a Request Token and Token Secret), formed in a ParamMap. + If request fails, the \ref error property is set to an appropriate value, and an empty + ParamMap is returned. + + \sa accessToken(), error +*/ + +QOAuth::ParamMap QOAuth::Interface::requestToken( const QString &requestUrl, HttpMethod httpMethod, + SignatureMethod signatureMethod, const ParamMap ¶ms ) +{ + Q_D(Interface); + + return d->sendRequest( requestUrl, httpMethod, signatureMethod, + QByteArray(), QByteArray(), params ); +} + +/*! + This method constructs and sends a request for exchanging a Request Token (obtained + previously with a call to \ref requestToken()) for an Access Token, that authorizes the + application to access Protected Resources. This is the third step of the OAuth + authentication flow, according to OAuth 1.0 + Core specification. The PLAINTEXT signature method uses Customer Secret and (if + provided) Token Secret to sign a request. For the HMAC-SHA1 and RSA-SHA1 + signature methods the Signature Base String + is created using the given \a requestUrl, \a httpMethod, \a token and \a tokenSecret. + The optional request parameters specified by the Service Provider can be passed in the + \a params ParamMap. + + The Signature Base String contains the \ref consumerKey and uses \ref consumerSecret + for encrypting the message, so it's necessary to provide them both before issuing + this request. The method will check if both \ref consumerKey and \ref consumerSecret + are provided, and fail if any of them is missing. + + When the signature is created, the appropriate request is sent to the Service Provider + (namely, the \a requestUrl). Depending on the type of the request, the parameters are + passed according to the + Consumer Request Parametes section of the OAuth specification, i.e.: + \li for GET requests, in the HTTP Authorization header, as defined in + OAuth HTTP Authorization Scheme, + \li for POST requests, as a request body with \c content-type set to + \c application/x-www-form-urlencoded. + + Once the request is sent, a local event loop is executed and set up to wait for the request + to complete. If the \ref requestTimeout property is set to a non-zero value, its vaue + is applied as a request timeout, after which the request is aborted. + + \returns If request succeded, the method returns all the data passed in the Service + Provider response (including an authorized Access Token and Token Secret), formed in + a ParamMap. This request ends the authorization process, and the obtained Access Token + and Token Secret should be kept by the application and provided with every future request + authorized by OAuth, e.g. using \ref createParametersString(). If request fails, the + \ref error property is set to an appropriate value, and an empty ParamMap is returned. + + \sa requestToken(), createParametersString(), error +*/ + +QOAuth::ParamMap QOAuth::Interface::accessToken( const QString &requestUrl, HttpMethod httpMethod, const QByteArray &token, + const QByteArray &tokenSecret, SignatureMethod signatureMethod, + const ParamMap ¶ms ) +{ + Q_D(Interface); + + return d->sendRequest( requestUrl, httpMethod, signatureMethod, + token, tokenSecret, params ); + +} + +/*! + This method generates a parameters string required to access Protected Resources using + OAuth authorization. According to OAuth 1.0 + Core specification, every outgoing request for accessing Protected Resources must + contain information like the Consumer Key and Access Token, and has to be signed using one + of the supported signature methods. + + The PLAINTEXT signature method uses Customer Secret and (if provided) Token Secret to + sign a request. For the HMAC-SHA1 and RSA-SHA1 signature methods the + Signature Base String is created using + the given \a requestUrl, \a httpMethod, \a token and \a tokenSecret. The optional + request parameters specified by the Service Provider can be passed in the \a params + \ref ParamMap. + + The Signature Base String contains the \ref consumerKey and uses \ref consumerSecret + for encrypting the message, so it's necessary to provide them both before issuing + this request. The method will check if both \ref consumerKey and \ref consumerSecret + are provided, and fail if any of them is missing. + + The \a mode parameter specifies the format of the parameter string. + + \returns The parsed parameters string, that depending on \a mode and \a httpMethod is: + + + + + + + +
\b \a mode \b outcome
QOAuth::ParseForRequestContent ready to be posted as a request body
QOAuth::ParseForInlineQuery prepended with a '?' and ready to be appended to the \a requestUrl
QOAuth::ParseForHeaderArguments ready to be set as an argument for the \c Authorization HTTP header
QOAuth::ParseForSignatureBaseString meant for internal use
+ + \sa inlineParameters() +*/ + +QByteArray QOAuth::Interface::createParametersString( const QString &requestUrl, HttpMethod httpMethod, const QByteArray &token, + const QByteArray &tokenSecret, SignatureMethod signatureMethod, + const ParamMap ¶ms, ParsingMode mode ) +{ + Q_D(Interface); + + d->error = NoError; + + // copy parameters to a writeable object + ParamMap parameters = params; + // calculate the signature + QByteArray signature = d->createSignature( requestUrl, httpMethod, signatureMethod, + token, tokenSecret, ¶meters ); + + // return an empty bytearray when signature wasn't created + if ( d->error != NoError ) { + return QByteArray(); + } + + // append it to parameters + parameters.insert( InterfacePrivate::ParamSignature, signature ); + // convert the map to bytearray, according to requested mode + QByteArray parametersString = d->paramsToString( parameters, mode ); + + return parametersString; +} + +/*! + This method is provided for convenience. It generates an inline query string out of + given parameter map. The resulting string can be either sent in an HTTP POST request + as a request content, or appended directly to an HTTP GET request's URL as a query string. + When using this method for preparing an HTTP GET query string you can set the \a mode + to ParseForInlineQuery to have the string prepended with a question mark (separating + the URL path from the query string). Modes other than QOAuth::ParseForRequestContent and + QOAuth::ParseForInlineQuery produce an empty byte array. + + Use this method together with createParametersString(), when you request a header + parameters string (QOAuth::ParseForHeaderArguments) together with HTTP GET method. + In such case, apart from header arguments, you must provide a query string containing + custom request parameters (i.e. not OAuth-related). Pass the custom parameters map + to this method to receive a query string to be appended to the URL. + + \sa createParametersString() +*/ + +QByteArray QOAuth::Interface::inlineParameters( const ParamMap ¶ms, ParsingMode mode ) +{ + Q_D(Interface); + + QByteArray query; + + switch (mode) { + case ParseForInlineQuery: + case ParseForRequestContent: + query = d->paramsToString( params, mode ); + break; + case ParseForHeaderArguments: + case ParseForSignatureBaseString: + break; + } + + return query; +} + +QOAuth::ParamMap QOAuth::InterfacePrivate::sendRequest( const QString &requestUrl, HttpMethod httpMethod, + SignatureMethod signatureMethod, const QByteArray &token, + const QByteArray &tokenSecret, const ParamMap ¶ms ) +{ + if ( httpMethod != GET && httpMethod != POST ) { + qWarning() << __FUNCTION__ << "- requestToken() and accessToken() accept only GET and POST methods"; + error = UnsupportedHttpMethod; + return ParamMap(); + } + + error = NoError; + + ParamMap parameters = params; + + // create signature + QByteArray signature = createSignature( requestUrl, httpMethod, signatureMethod, + token, tokenSecret, ¶meters ); + + // if signature wasn't created, return an empty map + if ( error != NoError ) { + return ParamMap(); + } + + // add signature to parameters + parameters.insert( InterfacePrivate::ParamSignature, signature ); + + QByteArray authorizationHeader; + QNetworkRequest request; + + if ( httpMethod == GET ) { + authorizationHeader = paramsToString( parameters, ParseForHeaderArguments ); + // create the authorization header + request.setRawHeader( "Authorization", authorizationHeader ); + } else if ( httpMethod == POST ) { + authorizationHeader = paramsToString( parameters, ParseForRequestContent ); + // create a network request + request.setHeader( QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded") ); + } + + request.setUrl( QUrl( requestUrl ) ); + + // fire up a single shot timer if timeout was specified + if ( requestTimeout > 0 ) { + QTimer::singleShot( requestTimeout, loop, SLOT(quit()) ); + // if the request finishes on time, the error value is overriden + // if not, it remains equal to QOAuth::Interface::Timeout + error = Timeout; + } + + // clear the reply container and send the request + replyParams.clear(); + QNetworkReply *reply; + if ( httpMethod == GET ) { + reply = manager->get( request ); + } else if ( httpMethod == POST ) { + reply = manager->post( request, authorizationHeader ); + } + + // start the event loop and wait for the response + loop->exec(); + + // if request completed successfully, error is different than QOAuth::Interface::Timeout + // if it failed, we have to abort the request + if ( error == Timeout ) { + reply->abort(); + } + + return replyParams; +} + +QByteArray QOAuth::InterfacePrivate::createSignature( const QString &requestUrl, HttpMethod httpMethod, + SignatureMethod signatureMethod, const QByteArray &token, + const QByteArray &tokenSecret, ParamMap *params ) +{ + if ( ( signatureMethod == HMAC_SHA1 || + signatureMethod == RSA_SHA1 ) && + consumerKey.isEmpty() ) { + qWarning() << __FUNCTION__ << "- consumer key is empty, make sure that you set it" + "with QOAuth::Interface::setConsumerKey()"; + error = ConsumerKeyEmpty; + return QByteArray(); + } + if ( consumerSecret.isEmpty() ) { + qWarning() << __FUNCTION__ << "- consumer secret is empty, make sure that you set it" + "with QOAuth::Interface::setConsumerSecret()"; + error = ConsumerSecretEmpty; + return QByteArray(); + } + + if ( signatureMethod == RSA_SHA1 && + privateKey.isNull() ) { + qWarning() << __FUNCTION__ << "- RSA private key is empty, make sure that you provide it" + "with QOAuth::Interface::setRSAPrivateKey{,FromFile}()"; + error = RSAPrivateKeyEmpty; + return QByteArray(); + } + + // create nonce + QCA::InitializationVector iv( 16 ); + QByteArray nonce = iv.toByteArray().toHex(); + + // create timestamp + uint time = QDateTime::currentDateTime().toTime_t(); + QByteArray timestamp = QByteArray::number( time ); + + // create signature base string + // 1. create the method string + QByteArray httpMethodString = httpMethodToString( httpMethod ); + // 2. prepare percent-encoded request URL + QByteArray percentRequestUrl = requestUrl.toLatin1().toPercentEncoding(); + // 3. prepare percent-encoded parameters string + params->insert( InterfacePrivate::ParamConsumerKey, consumerKey ); + params->insert( InterfacePrivate::ParamNonce, nonce ); + params->insert( InterfacePrivate::ParamSignatureMethod, + signatureMethodToString( signatureMethod ) ); + params->insert( InterfacePrivate::ParamTimestamp, timestamp ); + params->insert( InterfacePrivate::ParamVersion, InterfacePrivate::OAuthVersion ); + // append token only if it is defined (requestToken() doesn't use a token at all) + if ( !token.isEmpty() ) { + params->insert( InterfacePrivate::ParamToken, token ); + } + + QByteArray parametersString = paramsToString( *params, ParseForSignatureBaseString ); + QByteArray percentParametersString = parametersString.toPercentEncoding(); + + QByteArray digest; + + // PLAINTEXT doesn't use the Signature Base String + if ( signatureMethod == PLAINTEXT ) { + digest = createPlaintextSignature( tokenSecret ); + } else { + // 4. create signature base string + QByteArray signatureBaseString; + signatureBaseString.append( httpMethodString + '&' ); + signatureBaseString.append( percentRequestUrl + '&' ); + signatureBaseString.append( percentParametersString ); + + + if ( signatureMethod == HMAC_SHA1 ) { + if( !QCA::isSupported( "hmac(sha1)" ) ) { + qFatal( "HMAC(SHA1) is not supported!" ); + } + // create key for HMAC-SHA1 hashing + QByteArray key( consumerSecret.toPercentEncoding() + '&' + tokenSecret.toPercentEncoding() ); + + // create HMAC-SHA1 digest in Base64 + QCA::MessageAuthenticationCode hmac( QStringLiteral("hmac(sha1)"), QCA::SymmetricKey( key ) ); + QCA::SecureArray array( signatureBaseString ); + hmac.update( array ); + QCA::SecureArray resultArray = hmac.final(); + digest = resultArray.toByteArray().toBase64(); + + } else if ( signatureMethod == RSA_SHA1 ) { + // sign the Signature Base String with the RSA key + digest = privateKey.signMessage( QCA::MemoryRegion( signatureBaseString ), + QCA::EMSA3_SHA1 ).toBase64(); + } + } + + // percent-encode the digest + QByteArray signature = digest.toPercentEncoding(); + return signature; +} + +QByteArray QOAuth::InterfacePrivate::createPlaintextSignature( const QByteArray &tokenSecret ) +{ + if ( consumerSecret.isEmpty() ) { + qWarning() << __FUNCTION__ << "- consumer secret is empty, make sure that you set it" + "with QOAuth::Interface::setConsumerSecret()"; + error = ConsumerSecretEmpty; + return QByteArray(); + } + + // get percent encoded consumer secret and token secret, join and return + return consumerSecret.toPercentEncoding() + '&' + tokenSecret.toPercentEncoding(); +} + +#include "moc_interface.cpp" diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h b/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h new file mode 100644 index 0000000..bddc53d --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2009 by Dominik Kapusta * + * * + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation; either version 2.1 of * + * the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to * + * the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +/*! + \file interface.h + + This file is a part of libqoauth. You should not include it directly in your + application. Instead please use \#include <QtOAuth>. +*/ + +#ifndef INTERFACE_H +#define INTERFACE_H + +#include + +#define slots Q_SLOTS +#define signals Q_SIGNALS + +#include + +#include "qoauth_global.h" +#include "qoauth_namespace.h" + +class QNetworkAccessManager; +class QNetworkReply; + +namespace QOAuth { + +class InterfacePrivate; + +class QOAUTH_EXPORT Interface : public QObject +{ + Q_OBJECT + + Q_PROPERTY( QByteArray consumerKey READ consumerKey WRITE setConsumerKey ) + Q_PROPERTY( QByteArray consumerSecret READ consumerSecret WRITE setConsumerSecret ) + Q_PROPERTY( uint requestTimeout READ requestTimeout WRITE setRequestTimeout ) + Q_PROPERTY( bool ignoreSslErrors READ ignoreSslErrors WRITE setIgnoreSslErrors ) + Q_PROPERTY( int error READ error ) + +public: + Interface( QObject *parent = 0 ); + Interface( QNetworkAccessManager *manager, QObject *parent = 0 ); + virtual ~Interface(); + + QNetworkAccessManager* networkAccessManager() const; + void setNetworkAccessManager(QNetworkAccessManager *manager); + + bool ignoreSslErrors() const; + void setIgnoreSslErrors(bool enabled); + + QByteArray consumerKey() const; + void setConsumerKey( const QByteArray &consumerKey ); + + QByteArray consumerSecret() const; + void setConsumerSecret( const QByteArray &consumerSecret ); + + uint requestTimeout() const; + void setRequestTimeout( uint msec ); + + int error() const; + +// bool setRSAPrivateKey( const QString &key, +// const QCA::SecureArray &passphrase = QCA::SecureArray() ); +// bool setRSAPrivateKeyFromFile( const QString &filename, +// const QCA::SecureArray &passphrase = QCA::SecureArray() ); + + + ParamMap requestToken( const QString &requestUrl, HttpMethod httpMethod, + SignatureMethod signatureMethod = HMAC_SHA1, const ParamMap ¶ms = ParamMap() ); + + ParamMap accessToken( const QString &requestUrl, HttpMethod httpMethod, const QByteArray &token, + const QByteArray &tokenSecret, SignatureMethod signatureMethod = HMAC_SHA1, + const ParamMap ¶ms = ParamMap() ); + + QByteArray createParametersString( const QString &requestUrl, HttpMethod httpMethod, + const QByteArray &token, const QByteArray &tokenSecret, + SignatureMethod signatureMethod, const ParamMap ¶ms, ParsingMode mode ); + + QByteArray inlineParameters( const ParamMap ¶ms, ParsingMode mode = ParseForRequestContent ); + + +protected: + InterfacePrivate * const d_ptr; + +private: + Q_DISABLE_COPY(Interface) + Q_DECLARE_PRIVATE(Interface) + Q_PRIVATE_SLOT(d_func(), void _q_parseReply(QNetworkReply *reply)) + Q_PRIVATE_SLOT(d_func(), void _q_setPassphrase(int id, const QCA::Event &event)) + Q_PRIVATE_SLOT(d_func(), void _q_handleSslErrors( QNetworkReply *reply, + const QList &errors )) + +#ifdef UNIT_TEST + friend class Ut_Interface; + friend class Ft_Interface; +#endif +}; + +} // namespace QOAuth + +#endif // INTERFACE_H diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h b/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h new file mode 100644 index 0000000..97f3a6e --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright (C) 2009 by Dominik Kapusta * + * * + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation; either version 2.1 of * + * the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to * + * the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +/*! + \file interface_p.h + + This file is a part of libqoauth and is considered strictly internal. You should not + include it in your application. Instead please use \#include <QtOAuth>. +*/ + +#ifndef QOAUTH_P_H +#define QOAUTH_P_H + +#include "interface.h" +#include +#include +// #include + +class QNetworkReply; +class QEventLoop; + +namespace QOAuth { + +class Interface; + + +class QOAUTH_EXPORT InterfacePrivate +{ + Q_DECLARE_PUBLIC(Interface) + +public: + enum Operation { + RequestToken, + Authorize, + Authenticate, + AccessToken + }; + + enum KeySource { + KeyFromString, + KeyFromFile + }; + + static const QByteArray OAuthVersion; + static const QByteArray ParamToken; + static const QByteArray ParamTokenSecret; + + static const QByteArray ParamConsumerKey; + static const QByteArray ParamNonce; + static const QByteArray ParamSignature; + static const QByteArray ParamSignatureMethod; + static const QByteArray ParamTimestamp; + static const QByteArray ParamVersion; + + + InterfacePrivate(); + void init(); + void setupNetworkAccessManager(); + + QByteArray httpMethodToString( HttpMethod method ); + QByteArray signatureMethodToString( SignatureMethod method ); + ParamMap replyToMap( const QByteArray &data ); + QByteArray paramsToString( const ParamMap ¶meters, ParsingMode mode ); + + QByteArray createSignature( const QString &requestUrl, HttpMethod httpMethod, + SignatureMethod signatureMethod, const QByteArray &token, + const QByteArray &tokenSecret, ParamMap *params ); + + // for PLAINTEXT only + QByteArray createPlaintextSignature( const QByteArray &tokenSecret ); + + ParamMap sendRequest( const QString &requestUrl, HttpMethod httpMethod, SignatureMethod signatureMethod, + const QByteArray &token, const QByteArray &tokenSecret, const ParamMap ¶ms ); + + // RSA-SHA1 stuff + void setPrivateKey( const QString &source, const QCA::SecureArray &passphrase, KeySource from ); + void readKeyFromLoader( QCA::KeyLoader *keyLoader ); + + bool privateKeySet; + + QCA::Initializer initializer; + QCA::PrivateKey privateKey; + QCA::SecureArray passphrase; + QCA::EventHandler eventHandler; + // end of RSA-SHA1 stuff + + bool ignoreSslErrors; + QByteArray consumerKey; + QByteArray consumerSecret; + + ParamMap replyParams; + + QPointer manager; + QEventLoop *loop; + + uint requestTimeout; + int error; + +protected: + Interface *q_ptr; + +public: + void _q_parseReply( QNetworkReply *reply ); + void _q_setPassphrase( int id, const QCA::Event &event ); + void _q_handleSslErrors( QNetworkReply *reply, const QList &errors ); +}; + +} // namespace QOAuth + +#endif // INTERFACE_P_H diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h b/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h new file mode 100644 index 0000000..66c0d5b --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2009 by Dominik Kapusta * + * * + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation; either version 2.1 of * + * the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to * + * the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +/*! + \file qoauth_global.h + + This file is a part of libqoauth and is considered strictly internal. You should not + include it in your application. Instead please use \#include <QtOAuth>. +*/ + +#ifndef QOAUTH_GLOBAL_H +#define QOAUTH_GLOBAL_H + +#include + +#if defined(QOAUTH) +# define QOAUTH_EXPORT Q_DECL_EXPORT +#else +# define QOAUTH_EXPORT Q_DECL_IMPORT +#endif + +#endif // QOAUTH_GLOBAL_H diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h b/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h new file mode 100644 index 0000000..fb2270b --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h @@ -0,0 +1,180 @@ +/*************************************************************************** + * Copyright (C) 2009 by Dominik Kapusta * + * * + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation; either version 2.1 of * + * the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to * + * the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + + +/*! + \file qoauth_namespace.h + + This file is a part of libqoauth. You should not include it directly in your + application. Instead please use \#include <QtOAuth>. +*/ + +#ifndef QOAUTH_NAMESPACE_H +#define QOAUTH_NAMESPACE_H + +#include +#include + +#include "qoauth_global.h" + +/*! + \namespace QOAuth + \brief This namespace encapsulates all classes and definitions provided by libqoauth. +*/ +namespace QOAuth { + + /*! + \typedef ParamMap + \brief A typedef for the data structure for storing request parameters + */ + typedef QMultiMap ParamMap; + + /*! + \enum SignatureMethod + \brief This enum type describes the signature method used by the request. + + There are 3 different signature methods defined by the + OAuth protocol. This enum + is used to specify the method used by a specific request. Hence, one of its values + must be passed as a parameter in any of the \ref QOAuth::Interface::requestToken(), + \ref QOAuth::Interface::accessToken() or \ref QOAuth::Interface::createParametersString() + method. + */ + enum SignatureMethod { + HMAC_SHA1, //!< Sets the signature method to HMAC-SHA1 + RSA_SHA1, //!< Sets the signature method to RSA-SHA1 (not implemented yet) + PLAINTEXT //!< Sets the signature method to PLAINTEXT (not implemented yet) + }; + + /*! + \enum HttpMethod + \brief This enum type specifies the HTTP method used for creating + a Signature Base String + and/or sending a request. + + The HTTP method has to be specified in QOAuth class for two reasons: + \li to know what type of request should be prepared and sent + (\ref QOAuth::Interface::requestToken() and \ref QOAuth::Interface::accessToken()), + \li to prepare a correct signature, as the Signature Base String contains a parameter + specifying the HTTP method used for request (\ref QOAuth::Interface::createParametersString()). + + \note For \ref QOAuth::Interface::requestToken() and \ref QOAuth::Interface::accessToken() methods + only \ref GET and \ref POST methods are allowed. + */ + enum HttpMethod { + GET, //!< Sets the HTTP method to GET + POST, //!< Sets the HTTP method to POST + HEAD, //!< Sets the HTTP method to HEAD + PUT //!< Sets the HTTP method to PUT +#ifndef Q_WS_WIN + , DELETE //!< Sets the HTTP method to DELETE +#endif + }; + + /*! + \enum ParsingMode + \brief This enum type specifies the method of parsing parameters into + a parameter string. + + When creating a parameters string for a custom request using + \ref QOAuth::Interface::createParametersString() the parsing mode must be defined in order + to prepare the string correctly. + + According to what is stated in + OAuth 1.0 Core specification, parameters can be passed in a request to + the Service Provider in 3 different ways. When using \ref QOAuth::Interface::createParametersString(), + choose the one that suits you by setting \a ParsingMode appropriatelly. + + \sa QOAuth::Interface::createParametersString() + */ + enum ParsingMode { + ParseForRequestContent, //!< Inline query format (foo=bar&bar=baz&baz=foo ...), suitable for POST requests + ParseForInlineQuery, /*!< Same as ParseForRequestContent, but prepends the string with a question mark - + suitable for GET requests (appending parameters to the request URL) */ + ParseForHeaderArguments, //!< HTTP request header format (parameters to be put inside a request header) + ParseForSignatureBaseString //!< Signature Base String format, meant for internal use. + }; + + /*! + \enum ErrorCode + \brief This enum type defines error types that are assigned to the + \ref QOAuth::Interface::error property + + This error codes collection contains both network-related errors and those that + can occur when incorrect arguments are provided to any of the class's methods. + + \sa QOAuth::Interface::error + */ + enum ErrorCode { + NoError = 200, //!< No error occured (so far :-) ) + BadRequest = 400, //!< Represents HTTP status code \c 400 (Bad Request) + Unauthorized = 401, //!< Represents HTTP status code \c 401 (Unauthorized) + Forbidden = 403, //!< Represents HTTP status code \c 403 (Forbidden) + Timeout = 1001, //!< Represents a request timeout error + ConsumerKeyEmpty, //!< Consumer key has not been provided + ConsumerSecretEmpty, //!< Consumer secret has not been provided + UnsupportedHttpMethod, /*!< The HTTP method is not supported by the request. + \note \ref QOAuth::Interface::requestToken() and + \ref QOAuth::Interface::accessToken() + accept only HTTP GET and POST requests. */ + + RSAPrivateKeyEmpty = 1101, //!< RSA private key has not been provided + // RSAPassphraseError, //!< RSA passphrase is incorrect (or has not been provided) + RSADecodingError, /*!< There was a problem decoding the RSA private key + (the key is invalid or the provided passphrase is incorrect)*/ + RSAKeyFileError, //!< The provided key file either doesn't exist or is unreadable. + OtherError //!< A network-related error not specified above + }; + + + /*! + \brief Returns the supported OAuth protocol version + */ + QOAUTH_EXPORT QByteArray supportedOAuthVersion(); + + /*! + \brief Returns the name of the Access Token argument parameter (oauth_token in + current implementation) + + Useful when reading Service Provider's reply for \ref QOAuth::Interface::accessToken() request, e.g: + \code + QOAuth::Interface qoauth; + QByteArray requestToken = "token"; + QByteArray requestTokenSecret = "secret"; + QOAuth::ParamMap reply = qoauth.accessToken( "http://example.com/access_token", QOAuth::POST, + token, tokenSecret, QOAuth::HMAC_SHA1 ); + + if ( qoauth.error() == QOAuth::NoError ) { + token = reply.value( QOAuth::tokenParameterName() ); + tokenSecret = reply.value( QOAuth::tokenSecretParameterName() ); + } + \endcode + */ + QOAUTH_EXPORT QByteArray tokenParameterName(); + + /*! + \brief Returns the name of the Token Secret argument parameter (oauth_token_secret in + current implementation) + \sa QOAuth::tokenParameterName() + */ + QOAUTH_EXPORT QByteArray tokenSecretParameterName(); + +} // namespace QOAuth + +#endif // QOAUTH_NAMESPACE_H diff --git a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp b/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp new file mode 100644 index 0000000..b17c15e --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp @@ -0,0 +1,154 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ApplicationBackendTest.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QTEST_MAIN( ApplicationBackendTest ) + +QString getCodename(const QString& value) +{ + QString ret; + QFile f(QStringLiteral("/etc/os-release")); + if(f.open(QIODevice::ReadOnly|QIODevice::Text)){ + QRegExp rx(QStringLiteral("%1=(.+)\n").arg(value)); + while(!f.atEnd()) { + QString line = QString::fromUtf8(f.readLine()); + if(rx.exactMatch(line)) { + ret = rx.cap(1); + break; + } + } + } + return ret; +} + +AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) +{ + QVector backends = m->backends(); + foreach(AbstractResourcesBackend* backend, backends) { + if(QString::fromLatin1(backend->metaObject()->className())==name) { + return backend; + } + } + return nullptr; +} + +ApplicationBackendTest::ApplicationBackendTest() +{ + QString ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/ratings.txt"); + QFile testRatings(QStringLiteral("~/.kde-unit-test/share/apps/libdiscover/ratings.txt")); + QFile ratings(ratingsDir); + QString codeName = getCodename(QStringLiteral("ID")); + if(!testRatings.exists()) { + if(ratings.exists()) { + ratings.copy(testRatings.fileName()); + } else { + ratings.close(); + if(codeName.toLower() == QLatin1String("ubuntu")) { + ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/rnrtestratings.txt"); + } else { + ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/popcontestratings.txt"); + } + ratings.setFileName(ratingsDir); + if(ratings.exists()) { + ratings.copy(testRatings.fileName()); + } + } + testRatings.close(); + ratings.close(); + } + ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this); + m_window = new KActionCollection(this, QStringLiteral("ApplicationBackendTest")); + m->integrateActions(m_window); + new ModelTest(m,m); + m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend")); + QVERIFY(m_appBackend); //TODO: test all backends + QSignalSpy s(m, SIGNAL(allInitialized())); + QVERIFY(s.wait()); +} + +ApplicationBackendTest::~ApplicationBackendTest() +{ + delete m_window; +} + +void ApplicationBackendTest::testReload() +{ + ResourcesModel* model = ResourcesModel::global(); + QVector apps = m_appBackend->allResources(); + QCOMPARE(apps.count(), model->rowCount()); + + QVector appNames(apps.size()); + for(int i=0; irowCount(); ++i) { + AbstractResource* app = apps[i]; + appNames[i]=app->property("packageName"); + } + + bool b = QMetaObject::invokeMethod(m_appBackend, "reload"); + QVERIFY(b); + m_appBackend->updatesCount(); + QCOMPARE(apps, m_appBackend->allResources() ); + + QVERIFY(!apps.isEmpty()); + QCOMPARE(apps.count(), model->rowCount()); + + for(int i=0; irowCount(); ++i) { + AbstractResource* app = apps[i]; + QCOMPARE(appNames[i], app->property("packageName")); +// QCOMPARE(m_model->data(m_model->index(i), ResourcesModel::NameRole).toString(), app->name()); + } +} + +void ApplicationBackendTest::testCategories() +{ + ResourcesProxyModel* proxy = new ResourcesProxyModel(this); + const auto cats = CategoryModel::rootCategories(); + for(auto cat: cats) { + proxy->setFiltersFromCategory(cat); + } +} + +void ApplicationBackendTest::testRefreshUpdates() +{ + ResourcesModel* m = ResourcesModel::global(); + + QSignalSpy spy(m, SIGNAL(fetchingChanged())); + m_window->action(QStringLiteral("update"))->trigger(); +// QTest::kWaitForSignal(m, SLOT(fetchingChanged())); + QVERIFY(!m->isFetching()); + qDebug() << spy.count(); +} diff --git a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h b/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h new file mode 100644 index 0000000..420a395 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef RESOURCESMODELTEST_H +#define RESOURCESMODELTEST_H + +#include + +class KActionCollection; +class AbstractResourcesBackend; +class ApplicationBackendTest : public QObject +{ + Q_OBJECT + public: + ApplicationBackendTest(); + ~ApplicationBackendTest() override; + + private Q_SLOTS: + void testReload(); + void testCategories(); + void testRefreshUpdates(); + + private: + AbstractResourcesBackend* m_appBackend; + KActionCollection* m_window; +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt new file mode 100644 index 0000000..c60f87f --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt @@ -0,0 +1,13 @@ +include_directories(..) + +set(EXTRA_LIBS QApt::Main MuonApt) + +install(FILES rnrtestratings.txt DESTINATION ${DATA_INSTALL_DIR}/libdiscover) +install(FILES popcontestratings.txt DESTINATION ${DATA_INSTALL_DIR}/libdiscover) + +add_unit_test(applicationbackendtest ApplicationBackendTest.cpp) +add_unit_test(reviewstest ReviewsTest.cpp) +add_unit_test(sourcestest SourcesTest.cpp) + +list(APPEND EXTRA_LIBS DiscoverNotifiers MuonApplicationNotifierTestLib) +add_unit_test(notifiertest NotifierTest.cpp) diff --git a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp b/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp new file mode 100644 index 0000000..e9bd02d --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright © 2015 Harald Sitter * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "NotifierTest.h" + +#include + +#include + +QTEST_MAIN( NotifierTest ) + +NotifierTest::NotifierTest() +{ +} + +NotifierTest::~NotifierTest() = default; + +void NotifierTest::testInit() +{ + // Ensure init order is correct and we don't run into nullptr exceptions on + // initialization. + ApplicationNotifier app(this); + app.metaObject()->invokeMethod(&app, "recheckSystemUpdateNeeded"); +} diff --git a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h b/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h new file mode 100644 index 0000000..e225a03 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright © 2015 Harald Sitter * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef NOTIFIERTEST_H +#define NOTIFIERTEST_H + +#include + +class NotifierTest : public QObject +{ + Q_OBJECT + public: + NotifierTest(); + ~NotifierTest() override; + + private Q_SLOTS: + void testInit(); +}; + +#endif diff --git a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp b/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp new file mode 100644 index 0000000..4d6c2cb --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "ReviewsTest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QTEST_MAIN( ReviewsTest ) + +AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) +{ + QVector backends = m->backends(); + foreach(AbstractResourcesBackend* backend, backends) { + if(QString::fromLatin1(backend->metaObject()->className())==name) { + return backend; + } + } + return nullptr; +} + +ReviewsTest::ReviewsTest(QObject* parent): QObject(parent) +{ + ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this); + m_window = new KActionCollection(this, QStringLiteral("ReviewsTest")); + m->integrateActions(m_window); + m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend")); + QVERIFY(QSignalSpy(m, SIGNAL(allInitialized())).wait()); + m_revBackend = m_appBackend->reviewsBackend(); +} + +void ReviewsTest::testReviewsFetch() +{ + if(m_revBackend->isFetching()) + QSignalSpy(m_revBackend, SIGNAL(ratingsReady())).wait(); + QVERIFY(!m_revBackend->isFetching()); +} + +void ReviewsTest::testReviewsModel_data() +{ + QTest::addColumn( "application" ); + QTest::newRow( "python" ) << QStringLiteral("python"); + QTest::newRow( "gedit" ) << QStringLiteral("gedit"); +} + +void ReviewsTest::testReviewsModel() +{ + QFETCH(QString, application); + ReviewsModel* model = new ReviewsModel(this); + new ModelTest(model, model); + + AbstractResource* app = m_appBackend->resourceByPackageName(application); + QVERIFY(app); + model->setResource(app); + QSignalSpy(model, SIGNAL(rowsInserted(QModelIndex,int,int))).wait(2000); + + QModelIndex root; + while(model->canFetchMore(root)) { + model->fetchMore(root); + bool arrived = QSignalSpy(model, SIGNAL(rowsInserted(QModelIndex,int,int))).wait(2000); + QCOMPARE(arrived, model->canFetchMore(root)); + } + + delete model; +} diff --git a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h b/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h new file mode 100644 index 0000000..7c638e5 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef REVIEWSTEST_H +#define REVIEWSTEST_H + +#include + +class KActionCollection; +class AbstractResourcesBackend; +class AbstractReviewsBackend; +namespace QApt { +class Backend; +} + +class ReviewsTest : public QObject +{ + Q_OBJECT + public: + explicit ReviewsTest(QObject* parent = nullptr); + + private Q_SLOTS: + void testReviewsFetch(); + + void testReviewsModel_data(); + void testReviewsModel(); + + private: + AbstractReviewsBackend* m_revBackend; + AbstractResourcesBackend* m_appBackend; + KActionCollection* m_window; + +}; + +#endif // REVIEWSTEST_H diff --git a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp b/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp new file mode 100644 index 0000000..f55d049 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "SourcesTest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QTEST_MAIN( SourcesTest ) + +AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) +{ + QVector backends = m->backends(); + foreach(AbstractResourcesBackend* backend, backends) { + if(QString::fromLatin1(backend->metaObject()->className()) == name) { + return backend; + } + } + return nullptr; +} + +SourcesTest::SourcesTest(QObject* parent): QObject(parent) +{ + ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this); + m_window = new KActionCollection(this, QStringLiteral("SourcesTest")); + m->integrateActions(m_window); + m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend")); + QVERIFY(QSignalSpy(m, SIGNAL(allInitialized())).wait()); + + SourcesModel* sources = SourcesModel::global(); + QVERIFY(sources->rowCount() == 1); + QVERIFY(!backend()->name().isEmpty()); +} + +AbstractSourcesBackend* SourcesTest::backend() const +{ + SourcesModel* sources = SourcesModel::global(); + QObject* l = sources->data(sources->index(0), SourcesModel::SourceBackend).value(); + return qobject_cast(l); +} + + +void SourcesTest::testSourcesFetch() +{ + QAbstractItemModel* aptSources = backend()->sources(); + + for(int i = 0, c=aptSources->rowCount(); iindex(i, 0); + QVERIFY(idx.data(Qt::DisplayRole).toString() != QString()); + } +} + +void SourcesTest::testResourcesMatchSources() +{ + QAbstractItemModel* aptSources = backend()->sources(); + QSet allSources; + for (int i=0, c=aptSources->rowCount(); iindex(i, 0); + allSources += idx.data(Qt::DisplayRole).toString(); + } + + ResourcesModel* rmodel = ResourcesModel::global(); + for (int i=0, c=rmodel->rowCount(); iindex(i, 0); + QString origin = idx.data(ResourcesModel::OriginRole).toString(); + bool found = allSources.contains(origin); + if (!found) { + qDebug() << "couldn't find" << origin << "for" << idx.data(ResourcesModel::NameRole).toString() << "@" << i << "/" << c << "in" << allSources; + QEXPECT_FAIL("", "I need to ask the Kubuntu guys, I don't understand", Continue); + } + QVERIFY(found); + } +} diff --git a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h b/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h new file mode 100644 index 0000000..10217a0 --- /dev/null +++ b/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef SOURCESTEST_H +#define SOURCESTEST_H + +#include + +class KActionCollection; +class AbstractSourcesBackend; +class AbstractResourcesBackend; + +class SourcesTest : public QObject +{ + Q_OBJECT + public: + explicit SourcesTest(QObject* parent = nullptr); + + private Q_SLOTS: + void testSourcesFetch(); + void testResourcesMatchSources(); + + private: + AbstractSourcesBackend* backend() const; + + AbstractResourcesBackend* m_appBackend; + KActionCollection* m_window; + +}; + +#endif // REVIEWSTEST_H diff --git a/libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt b/libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt new file mode 100644 index 0000000000000000000000000000000000000000..426669198aef98d29b3e37382a8cdad2489daddc GIT binary patch literal 111487 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

ldkA#u@oKro^-z7 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libdiscover/backends/CMakeLists.txt b/libdiscover/backends/CMakeLists.txt new file mode 100644 index 0000000..372ef88 --- /dev/null +++ b/libdiscover/backends/CMakeLists.txt @@ -0,0 +1,30 @@ +function(add_unit_test name) + add_executable(${name} ${CMAKE_SOURCE_DIR}/libdiscover/tests/modeltest.cpp ${ARGN}) + add_test(${name} ${name}) + ecm_mark_as_test(${name}) + target_link_libraries(${name} + Discover::Common + + Qt5::Test Qt5::Core ${EXTRA_LIBS}) +endfunction() + +if(KF5Attica_FOUND AND KF5NewStuff_FOUND) + add_subdirectory(KNSBackend) +endif() + +if(QApt_FOUND) + add_subdirectory(ApplicationBackend) +endif() + +if(BODEGA_FOUND) + add_subdirectory(BodegaBackend) +endif() + +if(packagekitqt5_FOUND AND (AppstreamQt_FOUND OR AppStreamQt_FOUND)) + add_subdirectory(PackageKitBackend) +endif() + +option(BUILD_DummyBackend "Build the DummyBackend" "OFF") +if(BUILD_DummyBackend) + add_subdirectory(DummyBackend) +endif() diff --git a/libdiscover/backends/DummyBackend/CMakeLists.txt b/libdiscover/backends/DummyBackend/CMakeLists.txt new file mode 100644 index 0000000..e8ecfff --- /dev/null +++ b/libdiscover/backends/DummyBackend/CMakeLists.txt @@ -0,0 +1,22 @@ +add_subdirectory(tests) + +set(dummy-backend_SRCS + DummyResource.cpp + DummyBackend.cpp + DummyReviewsBackend.cpp + DummyTransaction.cpp + DummySourcesBackend.cpp +) + +add_library(dummy-backend MODULE ${dummy-backend_SRCS}) +target_link_libraries(dummy-backend Qt5::Core Qt5::Widgets KF5::CoreAddons KF5::ConfigCore Discover::Common) + +install(TARGETS dummy-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover) +install(FILES dummy-backend.desktop DESTINATION ${DATA_INSTALL_DIR}/libdiscover/backends) +install(FILES dummy-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories) + +add_library(DummyNotifier MODULE DummyNotifier.cpp) +target_link_libraries(DummyNotifier Discover::Notifiers) +set_target_properties(DummyNotifier PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/plasma-discover) + +install(TARGETS DummyNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier) diff --git a/libdiscover/backends/DummyBackend/DummyBackend.cpp b/libdiscover/backends/DummyBackend/DummyBackend.cpp new file mode 100644 index 0000000..d5de83c --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyBackend.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "DummyBackend.h" +#include "DummyResource.h" +#include "DummyReviewsBackend.h" +#include "DummyTransaction.h" +#include "DummySourcesBackend.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MUON_BACKEND_PLUGIN(DummyBackend) + +DummyBackend::DummyBackend(QObject* parent) + : AbstractResourcesBackend(parent) + , m_updater(new StandardBackendUpdater(this)) + , m_reviews(new DummyReviewsBackend(this)) + , m_fetching(true) + , m_startElements(120) +{ + QTimer::singleShot(500, this, &DummyBackend::toggleFetching); + connect(m_reviews, &DummyReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady); +} + +void DummyBackend::setMetaData(const QString& path) +{ + Q_ASSERT(!path.isEmpty()); + KSharedConfig::Ptr cfg = KSharedConfig::openConfig(path); + KConfigGroup metadata = cfg->group(QStringLiteral("Desktop Entry")); + + populate(metadata.readEntry("Name", QString())); + if (!m_fetching) + m_reviews->initialize(); + + QAction* updateAction = new QAction(this); + updateAction->setIcon(QIcon::fromTheme(QStringLiteral("system-software-update"))); + updateAction->setText(i18nc("@action Checks the Internet for updates", "Check for Updates")); + updateAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R)); + connect(updateAction, &QAction::triggered, this, &DummyBackend::checkForUpdates); + + QAction* randomAction = new QAction(this); + randomAction->setIcon(QIcon::fromTheme(QStringLiteral("kalarm"))); + randomAction->setText(QStringLiteral("test bla bla")); + randomAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_T)); + randomAction->setPriority(QAction::LowPriority); + connect(randomAction, &QAction::triggered, this, [](){ qDebug() << "random action triggered"; }); + +// QAction* importantAction = new QAction(this); +// importantAction->setIcon(QIcon::fromTheme(QStringLiteral("kalarm")); +// importantAction->setText(QStringLiteral("Amaze!")); +// importantAction->setWhatsThis(QStringLiteral("Wo Wo I'm so important")); +// importantAction->setPriority(QAction::HighPriority); +// connect(importantAction, &QAction::triggered, this, [importantAction](){ +// importantAction->setEnabled(false); +// qDebug() << "important action triggered"; +// }); + + m_messageActions = QList() << updateAction << randomAction /*<< importantAction*/; + + SourcesModel::global()->addSourcesBackend(new DummySourcesBackend(this)); +} + +void DummyBackend::populate(const QString& n) +{ + const int start = m_resources.count(); + for(int i=start; isetState(AbstractResource::State(1+(i%3))); + m_resources.insert(name, res); + connect(res, &DummyResource::stateChanged, this, &DummyBackend::updatesCountChanged); + } + + for(int i=start; isetState(AbstractResource::State(1+(i%3))); + m_resources.insert(name, res); + connect(res, &DummyResource::stateChanged, this, &DummyBackend::updatesCountChanged); + } +} + +void DummyBackend::toggleFetching() +{ + m_fetching = !m_fetching; +// qDebug() << "fetching..." << m_fetching; + emit fetchingChanged(); + if (!m_fetching) + m_reviews->initialize(); +} + +QVector DummyBackend::allResources() const +{ + Q_ASSERT(!m_fetching); + QVector ret; + ret.reserve(m_resources.size()); + foreach(AbstractResource* res, m_resources) { + ret += res; + } + return ret; +} + +int DummyBackend::updatesCount() const +{ + return m_updater->updatesCount(); +} + +AbstractResource* DummyBackend::resourceByPackageName(const QString& name) const +{ + return m_resources.value(name); +} + +QList DummyBackend::searchPackageName(const QString& searchText) +{ + QList ret; + foreach(AbstractResource* r, m_resources) { + if(r->name().contains(searchText, Qt::CaseInsensitive) || r->comment().contains(searchText, Qt::CaseInsensitive)) + ret += r; + } + return ret; +} + +AbstractBackendUpdater* DummyBackend::backendUpdater() const +{ + return m_updater; +} + +AbstractReviewsBackend* DummyBackend::reviewsBackend() const +{ + return m_reviews; +} + +void DummyBackend::installApplication(AbstractResource* app, const AddonList& addons) +{ + TransactionModel *transModel = TransactionModel::global(); + transModel->addTransaction(new DummyTransaction(qobject_cast(app), addons, Transaction::InstallRole)); +} + +void DummyBackend::installApplication(AbstractResource* app) +{ + TransactionModel *transModel = TransactionModel::global(); + transModel->addTransaction(new DummyTransaction(qobject_cast(app), Transaction::InstallRole)); +} + +void DummyBackend::removeApplication(AbstractResource* app) +{ + TransactionModel *transModel = TransactionModel::global(); + transModel->addTransaction(new DummyTransaction(qobject_cast(app), Transaction::RemoveRole)); +} + +void DummyBackend::checkForUpdates() +{ + if(m_fetching) + return; + toggleFetching(); + populate(QStringLiteral("Moar")); + QTimer::singleShot(500, this, &DummyBackend::toggleFetching); +} + +#include "DummyBackend.moc" diff --git a/libdiscover/backends/DummyBackend/DummyBackend.h b/libdiscover/backends/DummyBackend/DummyBackend.h new file mode 100644 index 0000000..3fed5df --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyBackend.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef DUMMYBACKEND_H +#define DUMMYBACKEND_H + +#include +#include + +class QAction; +class DummyReviewsBackend; +class StandardBackendUpdater; +class DummyResource; +class DummyBackend : public AbstractResourcesBackend +{ +Q_OBJECT +Q_PROPERTY(int startElements MEMBER m_startElements) +public: + explicit DummyBackend(QObject* parent = nullptr); + + void setMetaData(const QString& path) override; + AbstractResource* resourceByPackageName(const QString& name) const override; + int updatesCount() const override; + AbstractBackendUpdater* backendUpdater() const override; + AbstractReviewsBackend* reviewsBackend() const override; + QList searchPackageName(const QString& searchText) override; + QVector allResources() const override; + bool isValid() const override { return true; } // No external file dependencies that could cause runtime errors + QList messageActions() const override { return m_messageActions; } + + void installApplication(AbstractResource* app) override; + void installApplication(AbstractResource* app, const AddonList& addons) override; + void removeApplication(AbstractResource* app) override; + bool isFetching() const override { return m_fetching; } + +public Q_SLOTS: + void checkForUpdates(); + void toggleFetching(); + +private: + void populate(const QString& name); + + QHash m_resources; + StandardBackendUpdater* m_updater; + DummyReviewsBackend* m_reviews; + bool m_fetching; + int m_startElements; + QList m_messageActions; +}; + +#endif // DUMMYBACKEND_H diff --git a/libdiscover/backends/DummyBackend/DummyNotifier.cpp b/libdiscover/backends/DummyBackend/DummyNotifier.cpp new file mode 100644 index 0000000..1ac6a73 --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyNotifier.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#include "DummyNotifier.h" + +#include + +DummyNotifier::DummyNotifier(QObject* parent) + : BackendNotifierModule(parent) +{ +} + +DummyNotifier::~DummyNotifier() +{ +} + +void DummyNotifier::recheckSystemUpdateNeeded() +{ + emit foundUpdates(); +} + +bool DummyNotifier::isSystemUpToDate() const +{ + return true; +} + +uint DummyNotifier::securityUpdatesCount() +{ + return 0; +} + +uint DummyNotifier::updatesCount() +{ + return 0; +} + +#include "DummyNotifier.moc" diff --git a/libdiscover/backends/DummyBackend/DummyNotifier.h b/libdiscover/backends/DummyBackend/DummyNotifier.h new file mode 100644 index 0000000..4b76f85 --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyNotifier.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#ifndef DUMMYNOTIFIER_H +#define DUMMYNOTIFIER_H + +#include + +class DummyNotifier : public BackendNotifierModule +{ +Q_OBJECT +Q_PLUGIN_METADATA(IID "org.kde.discover.BackendNotifierModule") +Q_INTERFACES(BackendNotifierModule) +public: + explicit DummyNotifier(QObject* parent = nullptr); + ~DummyNotifier() override; + + bool isSystemUpToDate() const override; + void recheckSystemUpdateNeeded() override; + uint securityUpdatesCount() override; + uint updatesCount() override; +}; + +#endif diff --git a/libdiscover/backends/DummyBackend/DummyResource.cpp b/libdiscover/backends/DummyBackend/DummyResource.cpp new file mode 100644 index 0000000..80ffca8 --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyResource.cpp @@ -0,0 +1,185 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "DummyResource.h" +#include +#include +#include +#include +#include + +Q_GLOBAL_STATIC_WITH_ARGS(QVector, s_icons, ({ QLatin1String("kdevelop"), QLatin1String("kalgebra"), QLatin1String("kmail"), QLatin1String("akregator"), QLatin1String("korganizer") })) + +DummyResource::DummyResource(QString name, bool isTechnical, AbstractResourcesBackend* parent) + : AbstractResource(parent) + , m_name(std::move(name)) + , m_state(State::Broken) + , m_iconName((*s_icons)[KRandom::random() % s_icons->size()]) + , m_addons({ PackageState(QStringLiteral("a"), QStringLiteral("aaaaaa"), false), PackageState(QStringLiteral("b"), QStringLiteral("aaaaaa"), false), PackageState(QStringLiteral("c"), QStringLiteral("aaaaaa"), false)}) + , m_isTechnical(isTechnical) +{ + const int nofScreenshots = KRandom::random() % 5; + m_screenshots = QList{ + QUrl(QStringLiteral("http://screenshots.debian.net/screenshots/d/dolphin/9383_large.png")), + QUrl(QStringLiteral("https://c2.staticflickr.com/6/5656/21772158034_dc84382527_o.jpg")), + QUrl(QStringLiteral("https://c1.staticflickr.com/9/8479/8166397343_b78106f353_k.jpg")), + QUrl(QStringLiteral("https://c2.staticflickr.com/4/3685/9954407993_dad10a6943_k.jpg")), + QUrl(QStringLiteral("https://c1.staticflickr.com/1/653/22527103378_8ce572e1de_k.jpg")) + }.mid(nofScreenshots); + m_screenshotThumbnails = m_screenshots; +} + +QList DummyResource::addonsInformation() +{ + return m_addons; +} + +QString DummyResource::availableVersion() const +{ + return QStringLiteral("3.0"); +} + +QStringList DummyResource::categories() +{ + return { QStringLiteral("dummy"), m_name.endsWith(QLatin1Char('3')) ? QStringLiteral("three") : QStringLiteral("notthree") }; +} + +QString DummyResource::comment() +{ + return QStringLiteral("A reasonably short comment ")+name(); +} + +int DummyResource::size() +{ + return 123; +} + +QUrl DummyResource::homepage() +{ + return QUrl(QStringLiteral("http://kde.org")); +} + +QVariant DummyResource::icon() const +{ + return isTechnical() ? QStringLiteral("kalarm") : m_iconName; +} + +QString DummyResource::installedVersion() const +{ + return QStringLiteral("2.3"); +} + +QString DummyResource::license() +{ + return QStringLiteral("GPL"); +} + +QString DummyResource::longDescription() +{ + return QStringLiteral("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur ultricies consequat nulla, ut vulputate nulla ultricies ac. Suspendisse lacinia commodo lacus, non tristique mauris dictum vitae. Sed adipiscing augue nec nisi aliquet viverra. Etiam sit amet nulla in tellus consectetur feugiat. Cras in sem tortor. Fusce a nulla at justo accumsan gravida. Maecenas dui felis, lacinia at ornare sed, aliquam et purus. Sed ut sagittis lacus. Etiam dictum pharetra rhoncus. Suspendisse auctor orci ipsum. Pellentesque vitae urna nec felis consequat lobortis dictum in urna. Phasellus a mi ac leo adipiscing varius eget a felis. Cras magna augue, commodo sed placerat vel, tempus vel ligula. In feugiat quam quis est lobortis sed accumsan nunc malesuada. Mauris quis massa sit amet felis tempus suscipit a quis diam.\n\n" + + "Aenean quis nulla erat, vel sagittis sem. Praesent vitae mauris arcu. Cras porttitor, ante at scelerisque sodales, nibh felis consectetur orci, ut hendrerit urna urna non urna. Duis eu magna id mi scelerisque adipiscing. Aliquam sed quam in eros sodales accumsan. Phasellus tempus sagittis suscipit. Aliquam rutrum dictum justo ut viverra. Nulla felis sem, molestie sed scelerisque non, consequat vitae nulla. Aliquam ullamcorper malesuada mi, vel vestibulum magna vulputate eget. In hac habitasse platea dictumst. Cras sed lacus dui, vel semper sem. Aenean sodales porta leo vel fringilla.\n\n" + + "Ut tempus massa et urna porta non mollis metus ultricies. Duis nec nulla ac metus auctor porta id et mi. Mauris aliquam nibh a ligula malesuada sed tincidunt nibh varius. Sed felis metus, porta et adipiscing non, faucibus id leo. Donec ipsum nibh, hendrerit eget aliquam nec, tempor ut mauris. Suspendisse potenti. Vestibulum scelerisque adipiscing libero tristique eleifend. Donec quis tortor eget elit mollis iaculis ac sit amet nisi. Proin non massa sed nunc rutrum pellentesque. Sed dui lectus, laoreet sed condimentum id, commodo sed urna.\n\n" + + "Praesent tincidunt mattis massa mattis porta. Nullam posuere neque at mauris vestibulum vitae elementum leo sodales. Quisque condimentum lectus in libero luctus egestas. Fusce tempor neque ac dui tincidunt eget viverra quam suscipit. In hac habitasse platea dictumst. Etiam metus mi, adipiscing nec suscipit id, aliquet sed sem. Duis urna ligula, ornare sed vestibulum vel, molestie ac nisi. Morbi varius iaculis ligula. Nunc in augue leo, sit amet aliquam elit. Suspendisse rutrum sem diam. Proin eu orci nisl. Praesent porttitor dignissim est, id fermentum arcu venenatis vitae.\n\n" + + "Integer in sapien eget quam vulputate lobortis. Morbi nibh elit, elementum vitae vehicula sed, consequat nec erat. Donec placerat porttitor est ut dapibus. Fusce augue orci, dictum et convallis vel, blandit eu tortor. Phasellus non eros nulla. In iaculis nulla fermentum nulla gravida eu mattis purus consectetur. Integer dui nunc, sollicitudin ac tincidunt nec, hendrerit bibendum nunc. Proin sit amet augue ac velit egestas varius. Sed eu ante quis orci vestibulum sagittis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus vitae urna odio, at molestie leo. In convallis neque vel mi dictum convallis lobortis turpis sagittis.\n\n"); +} + +QString DummyResource::name() +{ + return m_name; +} + +QString DummyResource::origin() const +{ + return QStringLiteral("DummySource1"); +} + +QString DummyResource::packageName() const +{ + return m_name; +} + +QUrl DummyResource::screenshotUrl() +{ + return m_screenshots.at(0); +} + +QUrl DummyResource::thumbnailUrl() +{ + return m_screenshotThumbnails.at(0); +} + +QString DummyResource::section() +{ + return QStringLiteral("dummy"); +} + +AbstractResource::State DummyResource::state() +{ + return m_state; +} + +void DummyResource::fetchChangelog() +{ + QString log = longDescription(); + log.replace(QLatin1Char('\n'), QLatin1String("
")); + + emit changelogFetched(log); +} + +void DummyResource::fetchScreenshots() +{ + Q_EMIT screenshotsFetched(m_screenshotThumbnails, m_screenshots); +} + +void DummyResource::setState(AbstractResource::State state) +{ + m_state = state; + emit stateChanged(); +} + +void DummyResource::setAddons(const AddonList& addons) +{ + Q_FOREACH (const QString& toInstall, addons.addonsToInstall()) { + setAddonInstalled(toInstall, true); + } + Q_FOREACH (const QString& toRemove, addons.addonsToRemove()) { + setAddonInstalled(toRemove, false); + } +} + +void DummyResource::setAddonInstalled(const QString& addon, bool installed) +{ + for(auto & elem : m_addons) { + if(elem.name() == addon) { + elem.setInstalled(installed); + } + } +} + + +void DummyResource::invokeApplication() const +{ + QDesktopServices d; + d.openUrl(QUrl(QStringLiteral("https://projects.kde.org/projects/extragear/sysadmin/muon"))); +} diff --git a/libdiscover/backends/DummyBackend/DummyResource.h b/libdiscover/backends/DummyBackend/DummyResource.h new file mode 100644 index 0000000..8010652 --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyResource.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef DUMMYRESOURCE_H +#define DUMMYRESOURCE_H + +#include + +class AddonList; +class DummyResource : public AbstractResource +{ +Q_OBJECT +public: + explicit DummyResource(QString name, bool isTechnical, AbstractResourcesBackend* parent); + + QList addonsInformation() override; + QString section() override; + QString origin() const override; + QString longDescription() override; + QString availableVersion() const override; + QString installedVersion() const override; + QString license() override; + int size() override; + QUrl screenshotUrl() override; + QUrl thumbnailUrl() override; + QUrl homepage() override; + QStringList categories() override; + AbstractResource::State state() override; + QVariant icon() const override; + QString comment() override; + QString name() override; + QString packageName() const override; + bool isTechnical() const override { return m_isTechnical; } + bool canExecute() const override { return true; } + void invokeApplication() const override; + void fetchChangelog() override; + void fetchScreenshots() override; + void setState(State state); + void setAddons(const AddonList& addons); + + void setAddonInstalled(const QString& addon, bool installed); + +public: + QString m_name; + AbstractResource::State m_state; + QList m_screenshots; + QList m_screenshotThumbnails; + QString m_iconName; + QList m_addons; + bool m_isTechnical; +}; + +#endif // DUMMYRESOURCE_H diff --git a/libdiscover/backends/DummyBackend/DummyReviewsBackend.cpp b/libdiscover/backends/DummyBackend/DummyReviewsBackend.cpp new file mode 100644 index 0000000..1f9c35b --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyReviewsBackend.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "DummyReviewsBackend.h" +#include "DummyBackend.h" +#include +#include +#include +#include +#include + +DummyReviewsBackend::DummyReviewsBackend(DummyBackend* parent) + : AbstractReviewsBackend(parent) +{} + +void DummyReviewsBackend::fetchReviews(AbstractResource* app, int page) +{ + if (page>=5) + return; + + QList review; + for(int i=0; i<33; i++) { + review += new Review(app->name(), app->packageName(), QStringLiteral("en_US"), QStringLiteral("good morning"), QStringLiteral("the morning is very good"), QStringLiteral("dummy"), + QDateTime(), true, page+i, i%5, 1, 1, app->packageName()); + } + emit reviewsReady(app, review); +} + +Rating* DummyReviewsBackend::ratingForApplication(AbstractResource* app) const +{ + return m_ratings[app]; +} + +void DummyReviewsBackend::initialize() +{ + DummyBackend* b = qobject_cast(parent()); + foreach(AbstractResource* app, b->allResources()) { + if (m_ratings.contains(app)) + continue; + auto randomRating = qrand()%10; + Rating* rating = new Rating(app->packageName(), 15, randomRating, QStringLiteral("\"0, 0, 0, 4, %1\"").arg(randomRating)); + rating->setParent(this); + m_ratings.insert(app, rating); + } + emit ratingsReady(); +} + +void DummyReviewsBackend::submitUsefulness(Review* r, bool useful) +{ + qDebug() << "usefulness..." << r->applicationName() << r->reviewer() << useful; + r->setUsefulChoice(useful ? ReviewsModel::Yes : ReviewsModel::No); +} + +void DummyReviewsBackend::submitReview(AbstractResource* res, const QString& a, const QString& b, const QString& c) +{ + qDebug() << "dummy submit review" << res->name() << a << b << c; +} diff --git a/libdiscover/backends/DummyBackend/DummyReviewsBackend.h b/libdiscover/backends/DummyBackend/DummyReviewsBackend.h new file mode 100644 index 0000000..f922f26 --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyReviewsBackend.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef DUMMYREVIEWSBACKEND_H +#define DUMMYREVIEWSBACKEND_H + +#include +#include +#include + +class DummyBackend; +class DummyReviewsBackend : public AbstractReviewsBackend +{ +Q_OBJECT +public: + explicit DummyReviewsBackend(DummyBackend* parent = nullptr); + + QString userName() const override { return QStringLiteral("dummy"); } + void login() override {} + void logout() override {} + void registerAndLogin() override {} + + Rating* ratingForApplication(AbstractResource* app) const override; + bool hasCredentials() const override { return false; } + void deleteReview(Review*) override {} + void fetchReviews(AbstractResource* app, int page = 1) override; + bool isFetching() const override { return false; } + void submitReview(AbstractResource*, const QString&, const QString&, const QString&) override; + void flagReview(Review*, const QString&, const QString&) override {} + void submitUsefulness(Review*, bool) override; + + void initialize(); + +Q_SIGNALS: + void ratingsReady(); + +private: + QHash m_ratings; +}; + +#endif // DUMMYREVIEWSBACKEND_H diff --git a/libdiscover/backends/DummyBackend/DummySourcesBackend.cpp b/libdiscover/backends/DummyBackend/DummySourcesBackend.cpp new file mode 100644 index 0000000..915df0e --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummySourcesBackend.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "DummySourcesBackend.h" +#include +#include + +DummySourcesBackend::DummySourcesBackend(QObject* parent) + : AbstractSourcesBackend(parent) + , m_sources(new QStandardItemModel(this)) + , m_testAction(new QAction(QIcon::fromTheme(QStringLiteral("kalgebra")), QStringLiteral("DummyAction"), this)) +{ + QHash roles = m_sources->roleNames(); + roles.insert(Qt::CheckStateRole, "checked"); + m_sources->setItemRoleNames(roles); + + for (int i = 0; i<10; ++i) + addSource(QStringLiteral("DummySource%1").arg(i)); + + connect(m_testAction, &QAction::triggered, [](){ qDebug() << "action triggered!"; }); +} + +QAbstractItemModel* DummySourcesBackend::sources() +{ + return m_sources; +} + +bool DummySourcesBackend::addSource(const QString& id) +{ + QStandardItem* it = new QStandardItem(id); + it->setData(QVariant(id + QLatin1Char(' ') + id), Qt::ToolTipRole); + m_sources->appendRow(it); + return true; +} + +bool DummySourcesBackend::removeSource(const QString& id) +{ + QList items = m_sources->findItems(id); + if (items.count()==1) { + m_sources->removeRow(items.first()->row()); + } else { + qWarning() << "couldn't find " << id << items; + } + return items.count()==1; +} + +QList DummySourcesBackend::actions() const +{ + return QList() << m_testAction; +} + diff --git a/libdiscover/backends/DummyBackend/DummySourcesBackend.h b/libdiscover/backends/DummyBackend/DummySourcesBackend.h new file mode 100644 index 0000000..8ee1663 --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummySourcesBackend.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright © 2014 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef DUMMYSOURCESBACKEND_H +#define DUMMYSOURCESBACKEND_H + +#include +#include + +class DummySourcesBackend : public AbstractSourcesBackend +{ +public: + explicit DummySourcesBackend(QObject* parent); + + QAbstractItemModel* sources() override; + bool addSource(const QString& id) override; + bool removeSource(const QString& id) override; + QString name() const override { return QStringLiteral("Dummy"); } + QString idDescription() override { return QStringLiteral("Random weird text"); } + QList actions() const override; + +private: + QStandardItemModel* m_sources; + QAction* m_testAction; +}; + +#endif // DUMMYSOURCESBACKEND_H diff --git a/libdiscover/backends/DummyBackend/DummyTransaction.cpp b/libdiscover/backends/DummyBackend/DummyTransaction.cpp new file mode 100644 index 0000000..eb519e2 --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyTransaction.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "DummyTransaction.h" +#include "DummyBackend.h" +#include "DummyResource.h" +#include +#include +#include +#include + +DummyTransaction::DummyTransaction(DummyResource* app, Role role) + : DummyTransaction(app, {}, role) +{ +} + +DummyTransaction::DummyTransaction(DummyResource* app, const AddonList& addons, Transaction::Role role) + : Transaction(app->backend(), app, role, addons) + , m_app(app) +{ + setCancellable(true); + iterateTransaction(); +} + +void DummyTransaction::iterateTransaction() +{ + if (!m_iterate) + return; + + setStatus(CommittingStatus); + if(progress()<100) { + setProgress(qBound(0, progress()+(KRandom::random()%30), 100)); + QTimer::singleShot(/*KRandom::random()%*/100, this, &DummyTransaction::iterateTransaction); + } else + finishTransaction(); +} + +void DummyTransaction::cancel() +{ + m_iterate = false; + TransactionModel::global()->cancelTransaction(this); +} + +void DummyTransaction::finishTransaction() +{ + setStatus(DoneStatus); + AbstractResource::State newState; + switch(role()) { + case InstallRole: + case ChangeAddonsRole: + newState = AbstractResource::Installed; + break; + case RemoveRole: + newState = AbstractResource::None; + break; + } + m_app->setState(newState); + m_app->setAddons(addons()); + TransactionModel::global()->removeTransaction(this); + deleteLater(); +} diff --git a/libdiscover/backends/DummyBackend/DummyTransaction.h b/libdiscover/backends/DummyBackend/DummyTransaction.h new file mode 100644 index 0000000..428c5ae --- /dev/null +++ b/libdiscover/backends/DummyBackend/DummyTransaction.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef DUMMYTRANSACTION_H +#define DUMMYTRANSACTION_H + +#include + +class DummyResource; +class DummyTransaction : public Transaction +{ + Q_OBJECT + public: + DummyTransaction(DummyResource* app, Role role); + DummyTransaction(DummyResource* app, const AddonList& list, Role role); + + void cancel() override; + + private Q_SLOTS: + void iterateTransaction(); + void finishTransaction(); + + private: + bool m_iterate = true; + DummyResource* m_app; +}; + +#endif // DUMMYTRANSACTION_H diff --git a/libdiscover/backends/DummyBackend/dummy-backend-categories.xml b/libdiscover/backends/DummyBackend/dummy-backend-categories.xml new file mode 100644 index 0000000..e058d90 --- /dev/null +++ b/libdiscover/backends/DummyBackend/dummy-backend-categories.xml @@ -0,0 +1,86 @@ + +

+ + Applications + applications + https://c1.staticflickr.com/1/44/155013466_a8596ed65a_o.jpg + + + + dummy + kalarm + https://c2.staticflickr.com/6/5308/5876407905_6f31082232_o.jpg + + dummy1 + + + + dummy addons + plasma + https://c2.staticflickr.com/4/3221/2897450915_a1fcde62b7_o.jpg + + + dummy2 + + + + dummy 1 + kontact + https://c2.staticflickr.com/2/1347/955467402_be4f5970b2_o.jpg + + dummy3 + + + + dummy with stuff + kmail + + dummy + + + + dummy 2.1 + kalgebra + + dummy + + + + + dummy with quite some stuff + kmail + + dummy2 + + + + dummy 2.1 + kalgebra + + dummy + + + + + + dummy 3 + kig + + dummy + + three + + + + + dummy 4 + kdeconnect + + dummy + + notthree + + + + + diff --git a/libdiscover/backends/DummyBackend/dummy-backend.desktop b/libdiscover/backends/DummyBackend/dummy-backend.desktop new file mode 100644 index 0000000..6293274 --- /dev/null +++ b/libdiscover/backends/DummyBackend/dummy-backend.desktop @@ -0,0 +1,114 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Icon=kalarm +Name=Dummy +Name[ar]=دمية +Name[ast]=Maniquín +Name[ca]=Prova +Name[ca@valencia]=Prova +Name[cs]=Falešný +Name[da]=Dummy +Name[de]=Dummy +Name[el]=Πλασματικό +Name[en_GB]=Dummy +Name[es]=Simulado +Name[et]=Dummy +Name[fi]=Testi +Name[fr]=Factice +Name[gl]=Ensaio +Name[id]=Dumi +Name[it]=Fittizio +Name[ko]=더미 +Name[nb]=Attrapp +Name[nl]=Dummy +Name[nn]=Eksempel +Name[pl]=Fikcyjny +Name[pt]=Teste +Name[pt_BR]=Teste +Name[ru]=Тестовый модуль +Name[sk]=Prázdne +Name[sl]=Preizkusno +Name[sr]=Лажна +Name[sr@ijekavian]=Лажна +Name[sr@ijekavianlatin]=Lažna +Name[sr@latin]=Lažna +Name[sv]=Test +Name[uk]=Макет +Name[x-test]=xxDummyxx +Name[zh_CN]=哑 +Name[zh_TW]=虛擬 +GenericName=Dummy +GenericName[ar]=دمية +GenericName[ast]=Maniquín +GenericName[ca]=Prova +GenericName[ca@valencia]=Prova +GenericName[cs]=Falešný +GenericName[da]=Dummy +GenericName[de]=Dummy +GenericName[el]=Πλασματικό +GenericName[en_GB]=Dummy +GenericName[es]=Simulado +GenericName[et]=Dummy +GenericName[fi]=Testi +GenericName[fr]=Factice +GenericName[gl]=Ensaio +GenericName[id]=Dumi +GenericName[it]=Fittizio +GenericName[ko]=더미 +GenericName[nb]=Attrapp +GenericName[nl]=Dummy +GenericName[nn]=Eksempel +GenericName[pl]=Fikcyjny +GenericName[pt]=Teste +GenericName[pt_BR]=Teste +GenericName[ru]=Тестовый модуль +GenericName[sk]=Prázdne +GenericName[sl]=Preizkusno +GenericName[sr]=Лажна +GenericName[sr@ijekavian]=Лажна +GenericName[sr@ijekavianlatin]=Lažna +GenericName[sr@latin]=Lažna +GenericName[sv]=Test +GenericName[uk]=Макет +GenericName[x-test]=xxDummyxx +GenericName[zh_CN]=哑 +GenericName[zh_TW]=虛擬 +Comment=It's some dummy backend for testing purposes +Comment[ar]=سند دمية لأغراض اختباريّة +Comment[ca]=Són alguns dorsals falsos amb la finalitat de fer proves +Comment[ca@valencia]=Són alguns dorsals falsos amb la finalitat de fer proves +Comment[cs]=Falešná podpůrná vrstva pro testovací účely +Comment[da]=Dette er en attrap-backend til testformål +Comment[de]=Ein Dummy-Backend zu Testzwecken +Comment[el]=Είναι ένα πλασματικό σύστημα υποστήριξης για δοκιμαστικούς σκοπούς +Comment[en_GB]=It's some dummy backend for testing purposes +Comment[es]=Motor simulado con la finalidad de hacer pruebas +Comment[et]=See on fiktiivne taustaprogramm testimiseks +Comment[fi]=Taustajärjestelmä testaustarkoituksiin +Comment[fr]=Ceci est un moteur factice pour des besoins de tests +Comment[gl]=É unha infraestrutura de probas +Comment[id]=Beberapa backend dumi untuk tujuan pengujian. +Comment[it]=È un motore fittizio creato a scopo di prova +Comment[ko]=테스트를 위한 더미 백엔드 +Comment[nb]=Det er en attrapp bakgrunnsmotor for testing +Comment[nl]=Het is zo'n dummy backend voor testdoeleinden +Comment[nn]=Det er ein eksempelbakgrunnsmotor for testformål +Comment[pl]=Jest to rodzaj fikcyjnego silnika na potrzeby prób +Comment[pt]=É apenas uma infra-estrutura para fins de testes +Comment[pt_BR]=Exemplo de infraestrutura para testes +Comment[ru]=Тестовый модуль +Comment[sk]=Je to nejaký prázdny backend na testovacie účely +Comment[sl]=To je preizkusno zaledje za namene preizkušanja +Comment[sr]=Лажна позадина за потребе испробавања +Comment[sr@ijekavian]=Лажна позадина за потребе испробавања +Comment[sr@ijekavianlatin]=Lažna pozadina za potrebe isprobavanja +Comment[sr@latin]=Lažna pozadina za potrebe isprobavanja +Comment[sv]=Ett bakgrundsprogram för KDE:s partitionshanterare i testsyfte +Comment[uk]=Тестовий модуль +Comment[x-test]=xxIt's some dummy backend for testing purposesxx +Comment[zh_CN]=测试用的虚拟后端 +Comment[zh_TW]=測試用的虛擬後端介面 +X-KDE-Library=dummy-backend +X-KDE-PluginInfo-Name=dummy-backend +X-KDE-PluginInfo-License=GPL diff --git a/libdiscover/backends/DummyBackend/tests/CMakeLists.txt b/libdiscover/backends/DummyBackend/tests/CMakeLists.txt new file mode 100644 index 0000000..80601f9 --- /dev/null +++ b/libdiscover/backends/DummyBackend/tests/CMakeLists.txt @@ -0,0 +1,6 @@ +include_directories(.. ../../ApplicationBackend/tests) + +add_unit_test(dummytest DummyTest.cpp) +add_unit_test(updatedummytest UpdateDummyTest.cpp) + +target_link_libraries(updatedummytest KF5::CoreAddons) diff --git a/libdiscover/backends/DummyBackend/tests/DummyTest.cpp b/libdiscover/backends/DummyBackend/tests/DummyTest.cpp new file mode 100644 index 0000000..a0c28c6 --- /dev/null +++ b/libdiscover/backends/DummyBackend/tests/DummyTest.cpp @@ -0,0 +1,229 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "DummyTest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +QTEST_MAIN(DummyTest) + +AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) +{ + QVector backends = m->backends(); + foreach(AbstractResourcesBackend* backend, backends) { + if(QString::fromLatin1(backend->metaObject()->className()) == name) { + return backend; + } + } + return nullptr; +} + +DummyTest::DummyTest(QObject* parent): QObject(parent) +{ + m_model = new ResourcesModel(QStringLiteral("dummy-backend"), this); + new ModelTest(m_model, m_model); + + m_appBackend = backendByName(m_model, QStringLiteral("DummyBackend")); +} + +void DummyTest::initTestCase() +{ + QVERIFY(m_appBackend); + while(m_appBackend->isFetching()) { + QSignalSpy spy(m_appBackend, &AbstractResourcesBackend::fetchingChanged); + QVERIFY(spy.wait()); + } +} + +void DummyTest::testReadData() +{ + QCOMPARE(m_appBackend->property("startElements").toInt()*2, m_model->rowCount()); + QBENCHMARK { + for(int i=0, c=m_model->rowCount(); iindex(i, 0); + QVERIFY(!m_model->data(idx, ResourcesModel::NameRole).isNull()); + } + } +} + +void DummyTest::testProxy() +{ + ResourcesProxyModel pm; + QVERIFY(pm.sourceModel()); + QCOMPARE(m_appBackend->property("startElements").toInt(), pm.rowCount()); + pm.setShouldShowTechnical(true); + QCOMPARE(m_appBackend->property("startElements").toInt()*2, pm.rowCount()); + pm.setSearch(QStringLiteral("techie")); + QCOMPARE(m_appBackend->property("startElements").toInt(), pm.rowCount()); + pm.setSearch(QString()); + QCOMPARE(m_appBackend->property("startElements").toInt()*2, pm.rowCount()); +} + +void DummyTest::testFetch() +{ + QCOMPARE(m_appBackend->property("startElements").toInt()*2, m_model->rowCount()); + + //fetches updates, adds new things + m_appBackend->messageActions().at(0)->trigger(); + QCOMPARE(m_model->rowCount(), 0); + QCOMPARE(m_model->isFetching(), true); + QSignalSpy spy(m_model, SIGNAL(allInitialized())); + QVERIFY(spy.wait(80000)); + QCOMPARE(m_model->isFetching(), false); + QCOMPARE(m_appBackend->property("startElements").toInt()*4, m_model->rowCount()); +} + +void DummyTest::testSort() +{ + ResourcesProxyModel pm; + + QCollator c; + QBENCHMARK_ONCE { + pm.setSortRole(ResourcesModel::NameRole); + pm.setDynamicSortFilter(true); + pm.sort(0); + QCOMPARE(pm.sortColumn(), 0); + QCOMPARE(pm.sortOrder(), Qt::AscendingOrder); + QString last; + for(int i = 0, count = pm.rowCount(); iresourceByPackageName(QStringLiteral("Dummy 1")); + QVERIFY(res); + + ApplicationAddonsModel m; + new ModelTest(&m, &m); + m.setApplication(res); + QCOMPARE(m.rowCount(), res->addonsInformation().count()); + QCOMPARE(res->addonsInformation().at(0).isInstalled(), false); + + QString firstAddonName = m.data(m.index(0,0)).toString(); + m.changeState(firstAddonName, true); + QVERIFY(m.hasChanges()); + + m.applyChanges(); + QSignalSpy sR(TransactionModel::global(), SIGNAL(transactionRemoved(Transaction* ))); + QVERIFY(sR.wait()); + QVERIFY(!m.hasChanges()); + + QCOMPARE(m.data(m.index(0,0)).toString(), firstAddonName); + QCOMPARE(res->addonsInformation().at(0).name(), firstAddonName); + QCOMPARE(res->addonsInformation().at(0).isInstalled(), true); + + m.changeState(m.data(m.index(1,0)).toString(), true); + QVERIFY(m.hasChanges()); + for(int i=0, c=m.rowCount(); iresourceByPackageName(QStringLiteral("Dummy 1")); + QVERIFY(res); + + ReviewsModel m; + new ModelTest(&m, &m); + m.setResource(res); + m.fetchMore(); + + QVERIFY(m.rowCount()>0); + + QCOMPARE(ReviewsModel::UserChoice(m.data(m.index(0,0), ReviewsModel::UsefulChoice).toInt()), ReviewsModel::None); + m.markUseful(0, true); + QCOMPARE(ReviewsModel::UserChoice(m.data(m.index(0,0), ReviewsModel::UsefulChoice).toInt()), ReviewsModel::Yes); + m.markUseful(0, false); + QCOMPARE(ReviewsModel::UserChoice(m.data(m.index(0,0), ReviewsModel::UsefulChoice).toInt()), ReviewsModel::No); + + res = m_model->resourceByPackageName(QStringLiteral("Dummy 2")); + m.setResource(res); + m.fetchMore(); + + QSignalSpy spy(&m, &ReviewsModel::rowsChanged); + QVERIFY(m.rowCount()>0); +} + +void DummyTest::testUpdateModel() +{ + const auto backend = m_model->backends().first(); + + ResourcesUpdatesModel ruModel; + new ModelTest(&ruModel, &ruModel); + UpdateModel model; + new ModelTest(&model, &model); + model.setBackend(&ruModel); + + QCOMPARE(model.rowCount(), 4*backend->property("startElements").toInt()/3); + QCOMPARE(model.hasUpdates(), true); +} + +void DummyTest::testScreenshotsModel() +{ + ScreenshotsModel m; + new ModelTest(&m, &m); + + AbstractResource* res = m_model->resourceByPackageName(QStringLiteral("Dummy 1")); + m.setResource(res); + QCOMPARE(res, m.resource()); + + int c=m.rowCount(); + for(int i=0; i * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef DUMMYTEST_H +#define DUMMYTEST_H + +#include + +class ResourcesModel; +class AbstractResourcesBackend; + +class DummyTest : public QObject +{ + Q_OBJECT +public: + explicit DummyTest(QObject* parent = nullptr); + +private Q_SLOTS: + void initTestCase(); + + void testReadData(); + void testProxy(); + void testFetch(); + void testSort(); + void testInstallAddons(); + void testReviewsModel(); + void testUpdateModel(); + void testScreenshotsModel(); + +private: + AbstractResourcesBackend* m_appBackend; + ResourcesModel* m_model; +}; + +#endif // DUMMYTEST_H diff --git a/libdiscover/backends/DummyBackend/tests/UpdateDummyTest.cpp b/libdiscover/backends/DummyBackend/tests/UpdateDummyTest.cpp new file mode 100644 index 0000000..3982f4d --- /dev/null +++ b/libdiscover/backends/DummyBackend/tests/UpdateDummyTest.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "DummyTest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +class UpdateDummyTest + : public QObject +{ + Q_OBJECT +public: + AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) + { + QVector backends = m->backends(); + foreach(AbstractResourcesBackend* backend, backends) { + if(QLatin1String(backend->metaObject()->className()) == name) { + return backend; + } + } + return nullptr; + } + + UpdateDummyTest(QObject* parent = nullptr): QObject(parent) + { + m_model = new ResourcesModel(QStringLiteral("dummy-backend"), this); + new ModelTest(m_model, m_model); + + m_appBackend = backendByName(m_model, QStringLiteral("DummyBackend")); + } + +private Q_SLOTS: + void init() + { + QVERIFY(m_appBackend); + while(m_appBackend->isFetching()) { + QSignalSpy spy(m_appBackend, &AbstractResourcesBackend::fetchingChanged); + QVERIFY(spy.wait()); + } + } + + void testUpdate() + { + ResourcesUpdatesModel* rum = new ResourcesUpdatesModel(this); + new ModelTest(rum, rum); + + UpdateModel* m = new UpdateModel(this); + new ModelTest(m, m); + m->setBackend(rum); + + rum->prepare(); + QCOMPARE(m_appBackend->updatesCount(), m_appBackend->property("startElements").toInt()*2/3); + QCOMPARE(m->hasUpdates(), true); + + for(int i=0, c=m->rowCount(); iindex(i,0); + QVERIFY(resourceIdx.isValid()); + + AbstractResource* res = qobject_cast(resourceIdx.data(UpdateModel::ResourceRole).value()); + QVERIFY(res); + QCOMPARE(resourceIdx.data(UpdateModel::SizeRole).toString(), QStringLiteral("123 B")); + + QCOMPARE(Qt::CheckState(resourceIdx.data(Qt::CheckStateRole).toInt()), Qt::Checked); + QVERIFY(m->setData(resourceIdx, int(Qt::Unchecked), Qt::CheckStateRole)); + QCOMPARE(Qt::CheckState(resourceIdx.data(Qt::CheckStateRole).toInt()), Qt::Unchecked); + QCOMPARE(resourceIdx.data(Qt::DisplayRole).toString(), res->name()); + + if (i!=0) { + QVERIFY(m->setData(resourceIdx, int(Qt::Checked), Qt::CheckStateRole)); + } + } + + QSignalSpy spy(rum, &ResourcesUpdatesModel::progressingChanged); + QVERIFY(!rum->isProgressing() || spy.wait()); + QCOMPARE(rum->isProgressing(), false); + + QCOMPARE(m_appBackend->updatesCount(), m->rowCount()); + QCOMPARE(m->hasUpdates(), true); + + rum->prepare(); + rum->updateAll(); + QVERIFY(spy.wait()); + QCOMPARE(rum->isProgressing(), true); + QVERIFY(spy.wait()); + QCOMPARE(rum->isProgressing(), false); + + QCOMPARE(m_appBackend->updatesCount(), 0); + QCOMPARE(m->hasUpdates(), false); + } + +private: + ResourcesModel* m_model; + AbstractResourcesBackend* m_appBackend; +}; + +QTEST_MAIN(UpdateDummyTest) + +#include "UpdateDummyTest.moc" diff --git a/libdiscover/backends/KNSBackend/CMakeLists.txt b/libdiscover/backends/KNSBackend/CMakeLists.txt new file mode 100644 index 0000000..9cb3e96 --- /dev/null +++ b/libdiscover/backends/KNSBackend/CMakeLists.txt @@ -0,0 +1,34 @@ +add_subdirectory(knsintegrate) +add_subdirectory(tests) + +function(makekns knsfile iconName category) + get_filename_component(RESOURCE_NAME "${knsfile}" NAME_WE) + set(backend "kns${RESOURCE_NAME}-backend") + + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${knsfile}") + install(FILES ${knsfile} DESTINATION ${KDE_INSTALL_CONFDIR}) + get_filename_component(knsfile "${knsfile}" NAME) + endif() + + add_custom_target(${knsfile} ALL + COMMAND knsintegrate ${knsfile} ${iconName} ${category} + COMMAND cmake -E copy ${CMAKE_CURRENT_BINARY_DIR}/${backend}-categories.xml ${CMAKE_CURRENT_SOURCE_DIR}/${backend}-categories.xml + DEPENDS knsintegrate + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${backend}.desktop DESTINATION ${DATA_INSTALL_DIR}/libdiscover/backends) + install(FILES ${backend}-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories) +endfunction() + +add_library(kns-backend MODULE KNSBackend.cpp + KNSResource.cpp + KNSReviews.cpp) + +target_link_libraries(kns-backend Discover::Common KF5::ConfigCore KF5::Attica KF5::NewStuff) + +install(TARGETS kns-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover) + +makekns(comic.knsrc face-smile-big "Plasma Addons/Comics") +makekns(plasmoids.knsrc plasma "Plasma Addons/Plasma Desktop Widgets") +makekns(custom/discover_ktexteditor_codesnippets_core.knsrc kate "Application Addons/Kate Snippets") diff --git a/libdiscover/backends/KNSBackend/KNSBackend.cpp b/libdiscover/backends/KNSBackend/KNSBackend.cpp new file mode 100644 index 0000000..de76cfa --- /dev/null +++ b/libdiscover/backends/KNSBackend/KNSBackend.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +// Qt includes +#include +#include +#include + +// Attica includes +#include +#include + +// KDE includes +#include +#include +#include +#include + +// DiscoverCommon includes +#include "Transaction/Transaction.h" +#include "Transaction/TransactionModel.h" + +// Own includes +#include "KNSBackend.h" +#include "KNSResource.h" +#include "KNSReviews.h" +#include + +MUON_BACKEND_PLUGIN(KNSBackend) + +KNSBackend::KNSBackend(QObject* parent) + : AbstractResourcesBackend(parent) + , m_fetching(false) + , m_isValid(true) + , m_page(0) + , m_reviews(new KNSReviews(this)) + , m_updater(new StandardBackendUpdater(this)) +{} + +KNSBackend::~KNSBackend() = default; + +void KNSBackend::markInvalid(const QString &message) +{ + qWarning() << "invalid kns backend!" << m_name << "because:" << message; + m_isValid = false; + setFetching(false); +} + +void KNSBackend::setMetaData(const QString& path) +{ + KDesktopFile cfg(path); + KConfigGroup service = cfg.group("Desktop Entry"); + + m_iconName = service.readEntry("Icon", QString()); + + const QString knsrc = service.readEntry("X-Muon-Arguments", QString()); + m_name = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, knsrc); + if (m_name.isEmpty()) { + QString p = QFileInfo(path).dir().filePath(knsrc); + if (QFile::exists(p)) + m_name = p; + + } + + if (m_name.isEmpty()) { + markInvalid(QStringLiteral("Couldn't find knsrc file: ") + knsrc); + return; + } + + const KConfig conf(m_name); + if (!conf.hasGroup("KNewStuff3")) { + markInvalid(QStringLiteral("Config group not found! Check your KNS3 installation.")); + return; + } + + const KConfigGroup group = conf.group("KNewStuff3"); + m_extends = group.readEntry("Extends", QStringList()); + m_reviews->setProviderUrl(QUrl(group.readEntry("ProvidersUrl", QString()))); + + setFetching(true); + + m_manager = new KNS3::DownloadManager(m_name, this); + connect(m_manager, &KNS3::DownloadManager::errorFound, this, &KNSBackend::markInvalid); + connect(m_manager, &KNS3::DownloadManager::searchResult, this, &KNSBackend::receivedEntries); + connect(m_manager, &KNS3::DownloadManager::entryStatusChanged, this, &KNSBackend::statusChanged); + + m_page = 0; + m_manager->search(m_page); +} + +void KNSBackend::setFetching(bool f) +{ + if(m_fetching!=f) { + m_fetching = f; + emit fetchingChanged(); + } +} + +bool KNSBackend::isValid() const +{ + return m_isValid; +} + +void KNSBackend::receivedEntries(const KNS3::Entry::List& entries) +{ + if(entries.isEmpty()) { + setFetching(false); + return; + } + + const QString filename = QFileInfo(m_name).fileName(); + foreach(const KNS3::Entry& entry, entries) { + KNSResource* r = new KNSResource(entry, filename, this); + m_resourcesByName.insert(entry.id(), r); + } + ++m_page; + m_manager->search(m_page); +} + +void KNSBackend::statusChanged(const KNS3::Entry& entry) +{ + KNSResource* r = qobject_cast(m_resourcesByName.value(entry.id())); + if(r) + r->setEntry(entry); + else + qWarning() << "unknown entry changed" << entry.id() << entry.name(); +} + +class LambdaTransaction : public Transaction +{ +public: + LambdaTransaction(QObject* parent, AbstractResource* res, Transaction::Role role) + : Transaction(parent, res, role) + { + setCancellable(false); + TransactionModel::global()->addTransaction(this); + } + + ~LambdaTransaction() override { + TransactionModel::global()->removeTransaction(this); + } + + void cancel() override {} +}; + +void KNSBackend::removeApplication(AbstractResource* app) +{ + QScopedPointer t(new LambdaTransaction(this, app, Transaction::RemoveRole)); + KNSResource* r = qobject_cast(app); + m_manager->uninstallEntry(r->entry()); +} + +void KNSBackend::installApplication(AbstractResource* app) +{ + QScopedPointer t(new LambdaTransaction(this, app, Transaction::InstallRole)); + KNSResource* r = qobject_cast(app); + m_manager->installEntry(r->entry()); +} + +void KNSBackend::installApplication(AbstractResource* app, const AddonList& /*addons*/) +{ + installApplication(app); +} + +AbstractResource* KNSBackend::resourceByPackageName(const QString& name) const +{ + return m_resourcesByName[name]; +} + +int KNSBackend::updatesCount() const +{ + return m_updater->updatesCount(); +} + +AbstractReviewsBackend* KNSBackend::reviewsBackend() const +{ + return m_reviews; +} + +QList KNSBackend::searchPackageName(const QString& searchText) +{ + QList ret; + foreach(AbstractResource* r, m_resourcesByName) { + if(r->name().contains(searchText, Qt::CaseInsensitive) || r->comment().contains(searchText, Qt::CaseInsensitive)) + ret += r; + } + return ret; +} + +QVector KNSBackend::allResources() const +{ + return containerValues>(m_resourcesByName); +} + +bool KNSBackend::isFetching() const +{ + return m_fetching; +} + +AbstractBackendUpdater* KNSBackend::backendUpdater() const +{ + return m_updater; +} + +#include "KNSBackend.moc" diff --git a/libdiscover/backends/KNSBackend/KNSBackend.h b/libdiscover/backends/KNSBackend/KNSBackend.h new file mode 100644 index 0000000..02e1079 --- /dev/null +++ b/libdiscover/backends/KNSBackend/KNSBackend.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef KNSBACKEND_H +#define KNSBACKEND_H + +// KDE includes +#include + +// DiscoverCommon includes +#include +#include "Transaction/AddonList.h" + +#include "discovercommon_export.h" + +class KConfigGroup; +class KNSReviews; +class StandardBackendUpdater; + +namespace KNS3 { class DownloadManager; } + +class DISCOVERCOMMON_EXPORT KNSBackend : public AbstractResourcesBackend +{ +Q_OBJECT +public: + explicit KNSBackend(QObject* parent = nullptr); + ~KNSBackend() override; + + void setMetaData(const QString& path) override; + void removeApplication(AbstractResource* app) override; + void installApplication(AbstractResource* app) override; + void installApplication(AbstractResource* app, const AddonList& addons) override; + AbstractResource* resourceByPackageName(const QString& name) const override; + int updatesCount() const override; + AbstractReviewsBackend* reviewsBackend() const override; + QList searchPackageName(const QString& searchText) override; + QVector< AbstractResource* > allResources() const override; + AbstractBackendUpdater* backendUpdater() const override; + bool isFetching() const override; + QList messageActions() const override { return QList(); } + + bool isValid() const override; + + QStringList extends() const { return m_extends; } + + QString iconName() const { return m_iconName; } + +public Q_SLOTS: + void receivedEntries(const KNS3::Entry::List& entries); + void statusChanged(const KNS3::Entry& entry); + +private: + void setFetching(bool f); + void markInvalid(const QString &message); + + bool m_fetching; + bool m_isValid; + KNS3::DownloadManager* m_manager; + QHash m_resourcesByName; + int m_page; + KNSReviews* const m_reviews; + QString m_name; + QString m_iconName; + StandardBackendUpdater* const m_updater; + QStringList m_extends; +}; + +#endif // KNSBACKEND_H diff --git a/libdiscover/backends/KNSBackend/KNSResource.cpp b/libdiscover/backends/KNSBackend/KNSResource.cpp new file mode 100644 index 0000000..3d89ebe --- /dev/null +++ b/libdiscover/backends/KNSBackend/KNSResource.cpp @@ -0,0 +1,180 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "KNSResource.h" +#include "KNSBackend.h" +#include +#include + +KNSResource::KNSResource(const KNS3::Entry& entry, QString category, KNSBackend* parent) + : AbstractResource(parent) + , m_category(std::move(category)) + , m_entry(entry) +{ + connect(this, &KNSResource::stateChanged, parent, &KNSBackend::updatesCountChanged); +} + +KNSResource::~KNSResource() = default; + +AbstractResource::State KNSResource::state() +{ + switch(m_entry.status()) { + case KNS3::Entry::Invalid: + return Broken; + case KNS3::Entry::Downloadable: + return None; + case KNS3::Entry::Installed: + return Installed; + case KNS3::Entry::Updateable: + return Upgradeable; + case KNS3::Entry::Deleted: + case KNS3::Entry::Installing: + case KNS3::Entry::Updating: + return None; + } + return None; +} + +QVariant KNSResource::icon() const +{ + return qobject_cast(parent())->iconName(); +} + +QString KNSResource::comment() +{ + QString ret = m_entry.shortSummary(); + if(ret.isEmpty()) { + ret = m_entry.summary(); + int newLine = ret.indexOf(QLatin1Char('\n')); + if(newLine>0) { + ret=ret.left(newLine); + } + ret = ret.replace(QRegularExpression(QStringLiteral("\\[/?[a-z]*\\]")), QString()); + } + return ret; +} + +QString KNSResource::longDescription() +{ + QString ret = m_entry.summary(); + if (m_entry.shortSummary().isEmpty()) { + const int newLine = ret.indexOf(QLatin1Char('\n')); + if (newLine<0) + ret.clear(); + else + ret = ret.mid(newLine+1).trimmed(); + } + ret = ret.replace(QLatin1Char('\r'), QString()); + ret = ret.replace(QStringLiteral("[li]"), QStringLiteral("\n* ")); + ret = ret.replace(QRegularExpression(QStringLiteral("\\[/?[a-z]*\\]")), QString()); + return ret; +} + +QString KNSResource::name() +{ + return m_entry.name(); +} + +QString KNSResource::packageName() const +{ + return m_entry.id(); +} + +QStringList KNSResource::categories() +{ + return QStringList(m_category); +} + +QUrl KNSResource::homepage() +{ + return m_entry.url(); +} + +template +static T firstIfExists(const QList &list) +{ + return list.isEmpty() ? T() : list.at(0); +} + +QUrl KNSResource::thumbnailUrl() +{ + return firstIfExists(m_entry.previewThumbnails()); +} + +QUrl KNSResource::screenshotUrl() +{ + return firstIfExists(m_entry.previewImages()); +} + +void KNSResource::setEntry(const KNS3::Entry& entry) +{ + m_entry = entry; + Q_EMIT stateChanged(); +} + +KNS3::Entry KNSResource::entry() const +{ + return m_entry; +} + +QString KNSResource::license() +{ + return m_entry.license(); +} + +int KNSResource::size() +{ + return m_entry.size(); +} + +QString KNSResource::installedVersion() const +{ + return m_entry.version(); +} + +QString KNSResource::availableVersion() const +{ + return !m_entry.updateVersion().isEmpty() ? m_entry.updateVersion() : m_entry.version(); +} + +QString KNSResource::origin() const +{ + return m_entry.providerId(); +} + +QString KNSResource::section() +{ + return m_entry.category(); +} + +void KNSResource::fetchScreenshots() +{ + emit screenshotsFetched(m_entry.previewThumbnails(), m_entry.previewImages()); +} + +void KNSResource::fetchChangelog() +{ + emit changelogFetched(m_entry.changelog()); +} + +QStringList KNSResource::extends() const +{ + return qobject_cast(parent())->extends(); +} diff --git a/libdiscover/backends/KNSBackend/KNSResource.h b/libdiscover/backends/KNSBackend/KNSResource.h new file mode 100644 index 0000000..5f75ffd --- /dev/null +++ b/libdiscover/backends/KNSBackend/KNSResource.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef KNSRESOURCE_H +#define KNSRESOURCE_H + +#include +#include +#include + +#include "discovercommon_export.h" + +class KNSBackend; +class DISCOVERCOMMON_EXPORT KNSResource : public AbstractResource +{ +Q_OBJECT +public: + explicit KNSResource(const KNS3::Entry& c, QString category, KNSBackend* parent); + ~KNSResource() override; + + AbstractResource::State state() override; + QVariant icon() const override; + QString comment() override; + QString name() override; + QString packageName() const override; + QStringList categories() override; + QUrl homepage() override; + QUrl thumbnailUrl() override; + QUrl screenshotUrl() override; + QString license() override; + QString longDescription() override; + QList addonsInformation() override { return QList(); } + QString availableVersion() const override; + QString installedVersion() const override; + QString origin() const override; + QString section() override; + void fetchScreenshots() override; + int size() override; + void fetchChangelog() override; + QStringList extends() const override; + + void setEntry(const KNS3::Entry& entry); + KNS3::Entry entry() const; + +private: + const QString m_category; + KNS3::Entry m_entry; +}; + +#endif // KNSRESOURCE_H diff --git a/libdiscover/backends/KNSBackend/KNSReviews.cpp b/libdiscover/backends/KNSBackend/KNSReviews.cpp new file mode 100644 index 0000000..d725066 --- /dev/null +++ b/libdiscover/backends/KNSBackend/KNSReviews.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "KNSReviews.h" +#include "KNSBackend.h" +#include "KNSResource.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Q_DECLARE_METATYPE(AbstractResource*) + +class SharedManager : public QObject +{ +Q_OBJECT +public: + SharedManager() { + atticaManager.loadDefaultProviders(); + } + +public: + Attica::ProviderManager atticaManager; +}; + +Q_GLOBAL_STATIC(SharedManager, s_shared) + +KNSReviews::KNSReviews(KNSBackend* backend) + : AbstractReviewsBackend(backend) + , m_backend(backend) +{ +} + +Rating* KNSReviews::ratingForApplication(AbstractResource* app) const +{ + KNSResource *resource = qobject_cast(app); + if (!resource) + { + qDebug() << app->packageName() << "<= couldn't find resource"; + return nullptr; + } + + const int noc = resource->entry().numberOfComments(); + const int rating = resource->entry().rating(); + Q_ASSERT(rating <= 100); + return new Rating( + resource->packageName(), + noc, + rating/10, + QLatin1Char('[')+QString::number(noc*rating)+QLatin1Char(']') + ); +} + +void KNSReviews::fetchReviews(AbstractResource* app, int page) +{ + Attica::ListJob< Attica::Comment >* job = + provider().requestComments(Attica::Comment::ContentComment, app->packageName(), QStringLiteral("0"), page, 10); + job->setProperty("app", qVariantFromValue(app)); + connect(job, &Attica::BaseJob::finished, this, &KNSReviews::commentsReceived); + job->start(); +} + +void KNSReviews::commentsReceived(Attica::BaseJob* j) +{ + Attica::ListJob* job = static_cast*>(j); + Attica::Comment::List comments = job->itemList(); + + QList reviews; + AbstractResource* app = job->property("app").value(); + foreach(const Attica::Comment& comment, comments) { + //TODO: language lookup? + Review* r = new Review(app->name(), app->packageName(), QStringLiteral("en"), comment.subject(), comment.text(), comment.user(), + comment.date(), true, comment.id().toInt(), comment.score()/10, 0, 0, QString() + ); + reviews += r; + } + + emit reviewsReady(app, reviews); +} + +bool KNSReviews::isFetching() const +{ + return m_backend->isFetching(); +} + +void KNSReviews::flagReview(Review* /*r*/, const QString& /*reason*/, const QString& /*text*/) +{ + qWarning() << "cannot flag reviews"; +} + +void KNSReviews::deleteReview(Review* /*r*/) +{ + qWarning() << "cannot delete comments"; +} + +void KNSReviews::submitReview(AbstractResource* app, const QString& summary, const QString& review_text, const QString& rating) +{ + provider().voteForContent(app->packageName(), rating.toUInt() * 20); + if (!summary.isEmpty()) + provider().addNewComment(Attica::Comment::ContentComment, app->packageName(), QString(), QString(), summary, review_text); +} + +void KNSReviews::submitUsefulness(Review* r, bool useful) +{ + provider().voteForComment(QString::number(r->id()), useful*5); +} + +void KNSReviews::logout() +{ + bool b = provider().saveCredentials(QString(), QString()); + if (!b) + qWarning() << "couldn't log out"; +} + +void KNSReviews::registerAndLogin() +{ + QDesktopServices::openUrl(provider().baseUrl()); +} + +void KNSReviews::login() +{ + KPasswordDialog* dialog = new KPasswordDialog; + dialog->setPrompt(i18n("Log in information for %1", provider().name())); + connect(dialog, &KPasswordDialog::gotUsernameAndPassword, this, &KNSReviews::credentialsReceived); +} + +void KNSReviews::credentialsReceived(const QString& user, const QString& password) +{ + bool b = provider().saveCredentials(user, password); + if (!b) + qWarning() << "couldn't save" << user << "credentials for" << provider().name(); +} + +bool KNSReviews::hasCredentials() const +{ + return provider().hasCredentials(); +} + +QString KNSReviews::userName() const +{ + QString user, password; + provider().loadCredentials(user, password); + return user; +} + +void KNSReviews::setProviderUrl(const QUrl& url) +{ + m_providerUrl = url; + if(!s_shared->atticaManager.providerFiles().contains(url)) { + s_shared->atticaManager.addProviderFile(url); + } +} + +Attica::Provider KNSReviews::provider() const +{ + return s_shared->atticaManager.providerFor(m_providerUrl); +} + +#include "KNSReviews.moc" diff --git a/libdiscover/backends/KNSBackend/KNSReviews.h b/libdiscover/backends/KNSBackend/KNSReviews.h new file mode 100644 index 0000000..7ac3ab9 --- /dev/null +++ b/libdiscover/backends/KNSBackend/KNSReviews.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef KNSREVIEWS_H +#define KNSREVIEWS_H + +#include +#include + +class KNSBackend; +class QUrl; +namespace Attica { +class ProviderManager; +class BaseJob; +} + +class KNSReviews : public AbstractReviewsBackend +{ + Q_OBJECT + public: + explicit KNSReviews(KNSBackend* backend); + + void fetchReviews(AbstractResource* app, int page = 1) override; + bool isFetching() const override; + void flagReview(Review* r, const QString& reason, const QString& text) override; + void deleteReview(Review* r) override; + void submitReview(AbstractResource* app, const QString& summary, const QString& review_text, const QString& rating) override; + void submitUsefulness(Review* r, bool useful) override; + void logout() override; + void registerAndLogin() override; + void login() override; + Rating* ratingForApplication(AbstractResource* app) const override; + bool hasCredentials() const override; + QString userName() const override; + + void setProviderUrl(const QUrl &url); + + private Q_SLOTS: + void commentsReceived(Attica::BaseJob* job); + void credentialsReceived(const QString& user, const QString& password); + + private: + Attica::Provider provider() const; + KNSBackend* m_backend; + QUrl m_providerUrl; +}; + +#endif // KNSREVIEWS_H diff --git a/libdiscover/backends/KNSBackend/custom/discover_ktexteditor_codesnippets_core.knsrc b/libdiscover/backends/KNSBackend/custom/discover_ktexteditor_codesnippets_core.knsrc new file mode 100644 index 0000000..0c3a458 --- /dev/null +++ b/libdiscover/backends/KNSBackend/custom/discover_ktexteditor_codesnippets_core.knsrc @@ -0,0 +1,29 @@ +[KNewStuff3] +#ProvidersUrl=http://.../provider.xml +ProvidersUrl=http://download.kde.org/ocs/providers.xml +Categories=KTextEditor Snippet +UploadCategories=KTextEditor Snippet + +# # How to check? Any number of the lines below, 'ifpossible' is default +# ChecksumPolicy=... # never/ifpossible/always +# SignaturePolicy=... # never/ifpossible/always + +# # Where to install? Exactly one of the lines below +# # Note: if all three are missing, entry is considered remote resource +# StandardResource=wallpapers # becomes $KDEHOME/share/wallpapers +# becomes $KDEHOME/share/apps/appname/datadir +TargetDir=/ktexteditor_snippets/ghns +# InstallPath=.dir/subdir # becomes $HOME/.dir/subdir + +# # How to name the files? + #doesn't use payload file name + +CustomName=true + +# # What to do after installation? Any number of the lines below +# # unpack the downloaded archive +# Uncompress=true +# # post-installation command +# InstallationCommand=dbus-send ... %f ... + +Extends=org.kde.kate.desktop diff --git a/libdiscover/backends/KNSBackend/knscomic-backend-categories.xml b/libdiscover/backends/KNSBackend/knscomic-backend-categories.xml new file mode 100644 index 0000000..20b2d83 --- /dev/null +++ b/libdiscover/backends/KNSBackend/knscomic-backend-categories.xml @@ -0,0 +1,23 @@ + + + + Plasma Addons + + plasma + https://c2.staticflickr.com/4/3148/3042248532_20bd2e38f4_b.jpg + + Comics + face-smile-big + + + comic.knsrc + + + + + + comic.knsrc + + + + diff --git a/libdiscover/backends/KNSBackend/knscomic-backend.desktop b/libdiscover/backends/KNSBackend/knscomic-backend.desktop new file mode 100644 index 0000000..493ff8e --- /dev/null +++ b/libdiscover/backends/KNSBackend/knscomic-backend.desktop @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Service +Icon=face-smile-big +X-KDE-Library=kns-backend +X-KDE-PluginInfo-Name=knscomic-backend +X-Muon-Arguments=comic.knsrc diff --git a/libdiscover/backends/KNSBackend/knsdiscover_ktexteditor_codesnippets_core-backend-categories.xml b/libdiscover/backends/KNSBackend/knsdiscover_ktexteditor_codesnippets_core-backend-categories.xml new file mode 100644 index 0000000..76ed46f --- /dev/null +++ b/libdiscover/backends/KNSBackend/knsdiscover_ktexteditor_codesnippets_core-backend-categories.xml @@ -0,0 +1,23 @@ + + + + Application Addons + + plasma + https://c2.staticflickr.com/8/7067/6847903539_d9324dcd19_o.jpg + + Kate Snippets + kate + + + discover_ktexteditor_codesnippets_core.knsrc + + + + + + discover_ktexteditor_codesnippets_core.knsrc + + + + diff --git a/libdiscover/backends/KNSBackend/knsintegrate/CMakeLists.txt b/libdiscover/backends/KNSBackend/knsintegrate/CMakeLists.txt new file mode 100644 index 0000000..b125b38 --- /dev/null +++ b/libdiscover/backends/KNSBackend/knsintegrate/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(knsintegrate main.cpp) +target_link_libraries(knsintegrate Qt5::Core) diff --git a/libdiscover/backends/KNSBackend/knsintegrate/main.cpp b/libdiscover/backends/KNSBackend/knsintegrate/main.cpp new file mode 100644 index 0000000..a2b7a95 --- /dev/null +++ b/libdiscover/backends/KNSBackend/knsintegrate/main.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + * Copyright © 2016 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + QCoreApplication app(argc, argv); + + QCommandLineParser parser; + parser.addPositionalArgument(QStringLiteral("knsfile"), QStringLiteral("*.knsrc file"), QStringLiteral("knsfile")); + parser.addPositionalArgument(QStringLiteral("iconName"), QStringLiteral("Icon to use"), QStringLiteral("icon")); + parser.addPositionalArgument(QStringLiteral("category"), QStringLiteral("Category display name (categoryA/categoryB)"), QStringLiteral("category")); + parser.addHelpOption(); + parser.process(app); + + const auto args = parser.positionalArguments(); + if (args.count()!=3) { + parser.showHelp(1); + } + + const QString knsFile = args.at(0); + const QString iconName = args.at(1); + const QStringList categoryName = args.at(2).split(QLatin1Char('/')); + + const QString outputName = QStringLiteral("kns%1-backend").arg(QFileInfo(knsFile).baseName()); + + { + QFile f(outputName + QStringLiteral("-categories.xml")); + if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream(stderr) << "Could not open file to write:" << f.fileName() << '\n'; + return 1; + } + + const QString filter = QStringLiteral( + " \n" + " \n" + " ") + knsFile + QStringLiteral("\n" + " \n" + " \n"); + const QString image = categoryName[0].contains(QLatin1String("plasma"), Qt::CaseInsensitive) + ? QStringLiteral("https://c2.staticflickr.com/4/3148/3042248532_20bd2e38f4_b.jpg") + : QStringLiteral("https://c2.staticflickr.com/8/7067/6847903539_d9324dcd19_o.jpg"); + + QTextStream fs(&f); + fs << "\n" + "\n" + " \n" + " " << categoryName[0] << "\n" + " \n" + " plasma\n" + " " << image << "\n" + " \n" + " " << categoryName[1] << "\n" + " " << iconName << "\n" + << filter << + " \n" + << filter << + " \n" + "\n"; + } + + { + QFile df(outputName + QStringLiteral(".desktop")); + if (!df.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream(stderr) << "Could not open file to write:" << df.fileName() << '\n'; + return 1; + } + + QTextStream dfs(&df); + dfs << + "[Desktop Entry]\n" + "Type=Service\n" + "Icon=" << iconName << "\n" + "X-KDE-Library=kns-backend\n" + "X-KDE-PluginInfo-Name=" << outputName <<"\n" + "X-Muon-Arguments=" << knsFile << "\n"; + } + return 0; +} diff --git a/libdiscover/backends/KNSBackend/knsktexteditor_codesnippets_core-backend-categories.xml b/libdiscover/backends/KNSBackend/knsktexteditor_codesnippets_core-backend-categories.xml new file mode 100644 index 0000000..422dbbc --- /dev/null +++ b/libdiscover/backends/KNSBackend/knsktexteditor_codesnippets_core-backend-categories.xml @@ -0,0 +1,22 @@ + + + + Application Addons + plasma + + Kate Snippets + kate + true + + + ktexteditor_codesnippets_core.knsrc + + + + + + ktexteditor_codesnippets_core.knsrc + + + + diff --git a/libdiscover/backends/KNSBackend/knsplasmoids-backend-categories.xml b/libdiscover/backends/KNSBackend/knsplasmoids-backend-categories.xml new file mode 100644 index 0000000..d3c7b84 --- /dev/null +++ b/libdiscover/backends/KNSBackend/knsplasmoids-backend-categories.xml @@ -0,0 +1,23 @@ + + + + Plasma Addons + + plasma + https://c2.staticflickr.com/4/3148/3042248532_20bd2e38f4_b.jpg + + Plasma Desktop Widgets + plasma + + + plasmoids.knsrc + + + + + + plasmoids.knsrc + + + + diff --git a/libdiscover/backends/KNSBackend/tests/CMakeLists.txt b/libdiscover/backends/KNSBackend/tests/CMakeLists.txt new file mode 100644 index 0000000..4fabe5e --- /dev/null +++ b/libdiscover/backends/KNSBackend/tests/CMakeLists.txt @@ -0,0 +1,11 @@ +include_directories(..) + +add_executable(knsbackendtest KNSBackendTest.cpp) +add_test(knsbackendtest knsbackendtest) +ecm_mark_as_test(knsbackendtest) +target_link_libraries(knsbackendtest + Discover::Common + + Qt5::Test Qt5::Core + KF5::NewStuff KF5::Attica +) diff --git a/libdiscover/backends/KNSBackend/tests/KNSBackendTest.cpp b/libdiscover/backends/KNSBackend/tests/KNSBackendTest.cpp new file mode 100644 index 0000000..4e65746 --- /dev/null +++ b/libdiscover/backends/KNSBackend/tests/KNSBackendTest.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "KNSBackendTest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +QTEST_MAIN( KNSBackendTest ) + +KNSBackendTest::KNSBackendTest(QObject* parent) + : QObject(parent) + , m_r(nullptr) +{ + QStandardPaths::setTestModeEnabled(true); + ResourcesModel* model = new ResourcesModel(QFINDTESTDATA("knscorrect-backend.desktop"), this); + Q_ASSERT(!model->backends().isEmpty()); + m_backend = model->backends().at(0); + + if (!m_backend->isValid()) { + qWarning() << "couldn't run the test"; + exit(0); + } + + QSignalSpy s(model, SIGNAL(allInitialized())); + Q_ASSERT(s.wait(50000)); + connect(m_backend->reviewsBackend(), &AbstractReviewsBackend::reviewsReady, this, &KNSBackendTest::reviewsArrived); +} + +void KNSBackendTest::wrongBackend() +{ + DiscoverBackendsFactory f; + AbstractResourcesBackend* b = f.backendForFile(QFINDTESTDATA("knswrong-backend.desktop"), QStringLiteral("knswrong-backend")); + QVERIFY(!b->isValid()); +} + +void KNSBackendTest::testRetrieval() +{ + ResourcesModel* model = ResourcesModel::global(); + QVector resources = m_backend->allResources(); + QVERIFY(!resources.isEmpty()); + QCOMPARE(resources.count(), model->rowCount()); + QVERIFY(m_backend->backendUpdater()); + QCOMPARE(m_backend->updatesCount(), m_backend->backendUpdater()->toUpdate().count()); + + foreach(AbstractResource* res, resources) { + QVERIFY(!res->name().isEmpty()); + QVERIFY(!res->categories().isEmpty()); + QVERIFY(!res->origin().isEmpty()); + QVERIFY(!res->icon().isNull()); + QVERIFY(!res->comment().isEmpty()); +// QVERIFY(!res->longDescription().isEmpty()); +// QVERIFY(!res->license().isEmpty()); + QVERIFY(res->homepage().isValid() && !res->homepage().isEmpty()); + QVERIFY(res->state() > AbstractResource::Broken); + QVERIFY(res->addonsInformation().isEmpty()); + QVERIFY(res->thumbnailUrl().isValid() || res->thumbnailUrl().isEmpty()); + QVERIFY(res->screenshotUrl().isValid() || res->screenshotUrl().isEmpty()); + + QSignalSpy spy(res, &AbstractResource::screenshotsFetched); + res->fetchScreenshots(); + QVERIFY(spy.count() || spy.wait()); + + QSignalSpy spy1(res, &AbstractResource::changelogFetched); + res->fetchChangelog(); + QVERIFY(spy1.count() || spy1.wait()); + } +} + +void KNSBackendTest::testReviews() +{ + QVector resources = m_backend->allResources(); + AbstractReviewsBackend* rev = m_backend->reviewsBackend(); + QVERIFY(!rev->hasCredentials()); + foreach(AbstractResource* res, resources) { + Rating* r = rev->ratingForApplication(res); + QVERIFY(r); + QCOMPARE(r->packageName(), res->packageName()); + QVERIFY(r->rating()>0 && r->rating()<=10); + } + + auto res = resources.first(); + QSignalSpy spy(rev, &AbstractReviewsBackend::reviewsReady); + rev->fetchReviews(res); + QVERIFY(spy.count() || spy.wait()); +} + +void KNSBackendTest::reviewsArrived(AbstractResource* r, const QList< Review* >& revs) +{ + m_r = r; + m_revs = revs; +} diff --git a/libdiscover/backends/KNSBackend/tests/KNSBackendTest.h b/libdiscover/backends/KNSBackend/tests/KNSBackendTest.h new file mode 100644 index 0000000..a3b1860 --- /dev/null +++ b/libdiscover/backends/KNSBackend/tests/KNSBackendTest.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef KNSBACKENDTEST_H +#define KNSBACKENDTEST_H + +#include + +class AbstractResourcesBackend; +class AbstractResource; +class Review; + +class KNSBackendTest : public QObject +{ + Q_OBJECT + public: + explicit KNSBackendTest(QObject* parent = nullptr); + + private Q_SLOTS: + void wrongBackend(); + void testRetrieval(); + void testReviews(); + + public Q_SLOTS: + void reviewsArrived(AbstractResource *r, const QList& revs); + + private: + AbstractResourcesBackend* m_backend; + AbstractResource* m_r; + QList m_revs; +}; + +#endif // KNSBACKENDTEST_H diff --git a/libdiscover/backends/KNSBackend/tests/knscorrect-backend.desktop b/libdiscover/backends/KNSBackend/tests/knscorrect-backend.desktop new file mode 100644 index 0000000..bcb65e7 --- /dev/null +++ b/libdiscover/backends/KNSBackend/tests/knscorrect-backend.desktop @@ -0,0 +1,42 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Icon=plasma +Name=Correct +Name[ca]=Correcte +Name[ca@valencia]=Correcte +Name[cs]=Správně +Name[da]=Korrekt +Name[de]=Richtig +Name[el]=Σωστό +Name[en_GB]=Correct +Name[es]=Correcto +Name[et]=Õige +Name[fi]=Oikea +Name[fr]=Correct +Name[gl]=Correcto +Name[it]=Corretto +Name[ko]=올바름 +Name[nb]=Riktig +Name[nl]=Juist +Name[nn]=Rett +Name[pl]=Poprawny +Name[pt]=Certo +Name[pt_BR]=Certo +Name[ru]=Верно +Name[sk]=Správne +Name[sl]=Popravi +Name[sr]=Тачно +Name[sr@ijekavian]=Тачно +Name[sr@ijekavianlatin]=Tačno +Name[sr@latin]=Tačno +Name[sv]=Riktig +Name[uk]=Правильно +Name[x-test]=xxCorrectxx +Name[zh_CN]=改正 +Name[zh_TW]=正確 + +X-KDE-Library=kns-backend +X-KDE-PluginInfo-Name=knscorrect-backend +X-KDE-PluginInfo-License=GPL +X-Muon-Arguments=testplasmoids.knsrc diff --git a/libdiscover/backends/KNSBackend/tests/knswrong-backend.desktop b/libdiscover/backends/KNSBackend/tests/knswrong-backend.desktop new file mode 100644 index 0000000..7690c96 --- /dev/null +++ b/libdiscover/backends/KNSBackend/tests/knswrong-backend.desktop @@ -0,0 +1,42 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Icon=plasma +Name=Wrong +Name[ca]=Erroni +Name[ca@valencia]=Erroni +Name[cs]=Špatně +Name[da]=Forkert +Name[de]=Falsch +Name[el]=Λάθος +Name[en_GB]=Wrong +Name[es]=Erróneo +Name[et]=Vale +Name[fi]=Väärä +Name[fr]=Incorrect +Name[gl]=Incorrecto +Name[it]=Errato +Name[ko]=잘못됨 +Name[nb]=Feil +Name[nl]=Verkeerd +Name[nn]=Feil +Name[pl]=Niepoprawny +Name[pt]=Errado +Name[pt_BR]=Errado +Name[ru]=Неверно +Name[sk]=Zlé +Name[sl]=Wrong +Name[sr]=Погрешно +Name[sr@ijekavian]=Погрешно +Name[sr@ijekavianlatin]=Pogrešno +Name[sr@latin]=Pogrešno +Name[sv]=Felaktig +Name[uk]=Неправильно +Name[x-test]=xxWrongxx +Name[zh_CN]=错误 +Name[zh_TW]=錯誤 + +X-KDE-Library=kns-backend +X-KDE-PluginInfo-Name=knswrong-backend +X-KDE-PluginInfo-License=GPL +X-Muon-Arguments=wrong.knsrc diff --git a/libdiscover/backends/KNSBackend/tests/testplasmoids.knsrc b/libdiscover/backends/KNSBackend/tests/testplasmoids.knsrc new file mode 100644 index 0000000..19293b5 --- /dev/null +++ b/libdiscover/backends/KNSBackend/tests/testplasmoids.knsrc @@ -0,0 +1,6 @@ +[KNewStuff3] +ProvidersUrl=http://download.kde.org/ocs/providers.xml +Categories=Plasma 5 Plasmoid +StandardResource=tmp +InstallationCommand=plasmapkg2 -i %f +UninstallCommand=plasmapkg2 -r %f diff --git a/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp new file mode 100644 index 0000000..9c30dc6 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp @@ -0,0 +1,274 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "AppPackageKitResource.h" +#ifdef NEWAPPSTREAM +#include +#include +#include +#else +#include +#include +#endif +// #include +#include +#include +#include +#include +#include + +AppPackageKitResource::AppPackageKitResource(const Appstream::Component& data, PackageKitBackend* parent) + : PackageKitResource(data.packageNames().at(0), QString(), parent) + , m_appdata(data) +{ + Q_ASSERT(data.isValid()); +} + +QString AppPackageKitResource::name() +{ + return m_appdata.name(); +} + +QString AppPackageKitResource::longDescription() +{ + const auto desc = m_appdata.description(); + if (!desc.isEmpty()) + return desc; + + return PackageKitResource::longDescription(); +} + +QVariant AppPackageKitResource::icon() const +{ + QIcon ret; +#ifdef NEWAPPSTREAM + const auto icons = m_appdata.icons(); + if (icons.isEmpty()) { + ret = QIcon::fromTheme(QStringLiteral("package-x-generic")); + } else foreach(const AppStream::Icon &icon, icons) { + QStringList stock; + switch(icon.kind()) { + case AppStream::Icon::KindLocal: + ret.addFile(icon.url().toLocalFile(), icon.size()); + break; + case AppStream::Icon::KindCached: + ret.addFile(icon.url().toLocalFile(), icon.size()); + break; + case AppStream::Icon::KindStock: + stock += icon.name(); + break; + default: + break; + } + if (ret.isNull() && !stock.isEmpty()) { + ret = QIcon::fromTheme(stock.first()); + } + } +#else + const auto icons = m_appdata.iconUrls(); + if (icons.isEmpty()) + return m_appdata.name(); + else { + for (auto it = icons.constBegin(), itEnd = icons.constEnd(); it!=itEnd; ++it) { + if (it->isLocalFile()) + ret.addFile(it->toLocalFile(), it.key()); + } + } + + if (ret.isNull()) { + ret = QIcon::fromTheme(QStringLiteral("package-x-generic")); + } +#endif + return ret; +} + +QString AppPackageKitResource::license() +{ + const auto license = m_appdata.projectLicense(); + return license.isEmpty() ? PackageKitResource::license() : license; +} + +QStringList AppPackageKitResource::mimetypes() const +{ + return findProvides(Appstream::Provides::KindMimetype); +} + +QStringList AppPackageKitResource::categories() +{ + auto cats = m_appdata.categories(); + if (m_appdata.kind() != Appstream::Component::KindAddon) + cats.append(QStringLiteral("Application")); + return cats; +} + +QString AppPackageKitResource::comment() +{ + const auto summary = m_appdata.summary(); + if (!summary.isEmpty()) + return summary; + + return PackageKitResource::comment(); +} + +QString AppPackageKitResource::appstreamId() const +{ + return m_appdata.id(); +} + +QUrl AppPackageKitResource::homepage() +{ +#ifdef NEWAPPSTREAM + return m_appdata.url(Appstream::Component::UrlKindHomepage); +#else + return m_appdata.urls().value(Appstream::Component::UrlKindHomepage); +#endif +} + +bool AppPackageKitResource::isTechnical() const +{ + return false; +} + +QStringList AppPackageKitResource::executables() const +{ + return findProvides(Appstream::Provides::KindBinary); +} + +void AppPackageKitResource::invokeApplication() const +{ + QStringList exes = executables(); + if(!exes.isEmpty()) + QProcess::startDetached(exes.first()); +} + +static QUrl imageOfKind(const QList& images, Appstream::Image::Kind kind) +{ + QUrl ret; + Q_FOREACH (const Appstream::Image &i, images) { + if (i.kind() == kind) { + ret = i.url(); + break; + } + } + return ret; +} + +static QUrl screenshot(const Appstream::Component& comp, Appstream::Image::Kind kind) +{ + QUrl ret; + Q_FOREACH (const Appstream::Screenshot &s, comp.screenshots()) { + ret = imageOfKind(s.images(), kind); + if (s.isDefault() && !ret.isEmpty()) + break; + } + return ret; +} + +QUrl AppPackageKitResource::screenshotUrl() +{ +#ifdef NEWAPPSTREAM + return screenshot(m_appdata, Appstream::Image::KindSource); +#else + return screenshot(m_appdata, Appstream::Image::Plain); +#endif +} + +QUrl AppPackageKitResource::thumbnailUrl() +{ +#ifdef NEWAPPSTREAM + return screenshot(m_appdata, Appstream::Image::KindThumbnail); +#else + return screenshot(m_appdata, Appstream::Image::Thumbnail); +#endif +} + +void AppPackageKitResource::fetchScreenshots() +{ + QList thumbnails, screenshots; + + Q_FOREACH (const Appstream::Screenshot &s, m_appdata.screenshots()) { +#ifdef NEWAPPSTREAM + const QUrl thumbnail = imageOfKind(s.images(), Appstream::Image::KindThumbnail); + const QUrl plain = imageOfKind(s.images(), Appstream::Image::KindSource); +#else + const QUrl thumbnail = imageOfKind(s.images(), Appstream::Image::Thumbnail); + const QUrl plain = imageOfKind(s.images(), Appstream::Image::Plain); +#endif + if (plain.isEmpty()) + qWarning() << "invalid screenshot for" << name(); + + screenshots << plain; + thumbnails << (thumbnail.isEmpty() ? plain : thumbnail); + } + + Q_EMIT screenshotsFetched(thumbnails, screenshots); +} + +bool AppPackageKitResource::canExecute() const +{ + return !executables().isEmpty(); +} + +QStringList AppPackageKitResource::findProvides(Appstream::Provides::Kind kind) const +{ +#ifdef NEWAPPSTREAM + return m_appdata.provided(kind).items(); +#else + QStringList ret; + Q_FOREACH (Appstream::Provides p, m_appdata.provides()) + if (p.kind() == kind) + ret += p.value(); + return ret; +#endif +} + +QStringList AppPackageKitResource::allPackageNames() const +{ + return m_appdata.packageNames(); +} + +QList AppPackageKitResource::addonsInformation() +{ + const PackageKitBackend* p = static_cast(parent()); + const QVector res = p->extendedBy(m_appdata.id()); + + QList ret; + Q_FOREACH (AppPackageKitResource* r, res) { + ret += PackageState(r->appstreamId(), r->name(), r->comment(), r->isInstalled()); + } + return ret; +} + +QStringList AppPackageKitResource::extends() const +{ + return m_appdata.extends(); +} + +void AppPackageKitResource::fetchChangelog() +{ + PackageKitResource::fetchChangelog(); + //TODO: uncomment when the API is publicly released +// QString changelog; +// for(const auto& rel: m_appdata.releases()) { +// changelog += QStringLiteral("

") + rel.version() + QStringLiteral("

"); +// changelog += QStringLiteral("

") + rel.description() + QStringLiteral("

"); +// } +// emit changelogFetched(changelog); +} diff --git a/libdiscover/backends/PackageKitBackend/AppPackageKitResource.h b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.h new file mode 100644 index 0000000..08d133d --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef APPPACKAGEKITRESOURCE_H +#define APPPACKAGEKITRESOURCE_H + +#include "PackageKitResource.h" +#include "PackageKitBackend.h" + +class AppPackageKitResource : public PackageKitResource +{ + Q_OBJECT + public: + explicit AppPackageKitResource(const Appstream::Component& data, PackageKitBackend* parent); + + QString appstreamId() const override; + + bool isTechnical() const override; + QString name() override; + QVariant icon() const override; + QStringList mimetypes() const override; + QStringList categories() override; + QString longDescription() override; + QUrl homepage() override; + bool canExecute() const override; + QStringList executables() const override; + void invokeApplication() const override; + QString comment() override; + QString license() override; + QUrl screenshotUrl() override; + QUrl thumbnailUrl() override; + QStringList allPackageNames() const override; + QList addonsInformation() override; + QStringList extends() const override; + void fetchScreenshots() override; + void fetchChangelog() override; + + private: + QStringList findProvides(Appstream::Provides::Kind kind) const; + + const Appstream::Component m_appdata; +}; + +#endif // APPPACKAGEKITRESOURCE_H diff --git a/libdiscover/backends/PackageKitBackend/AppstreamReviews.cpp b/libdiscover/backends/PackageKitBackend/AppstreamReviews.cpp new file mode 100644 index 0000000..2f5bd02 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/AppstreamReviews.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright © 2016 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "AppstreamReviews.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AppPackageKitResource.h" + +Q_GLOBAL_STATIC(QUrl, ratingsCache) + +AppstreamReviews::AppstreamReviews(AbstractResourcesBackend* parent) + : AbstractReviewsBackend(parent) + , m_fetching(true) +{ + const QUrl ratingsUrl(QStringLiteral("http://appstream.kubuntu.co.uk/appstream-ubuntu-popcon-results.gz")); + const QString dir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + QDir().mkpath(dir); + *ratingsCache = QUrl::fromLocalFile(dir+QLatin1String("/appstream-popcon.gz")); + + KIO::FileCopyJob *getJob = KIO::file_copy(ratingsUrl, *ratingsCache, -1, + KIO::Overwrite | KIO::HideProgressInfo); + connect(getJob, &KIO::FileCopyJob::result, this, &AppstreamReviews::ratingsFetched); + + if (QFile::exists(ratingsCache->toLocalFile())) + readRatings(); +} + +void AppstreamReviews::ratingsFetched(KJob* job) +{ + m_fetching = false; + if (job->error()) { + qWarning() << "error fetching popcon" << job->errorString(); + } else { + readRatings(); + } +} + +void AppstreamReviews::readRatings() +{ + QScopedPointer dev(new KCompressionDevice(ratingsCache->toLocalFile(), KCompressionDevice::GZip)); + if (!dev->open(QIODevice::ReadOnly)) { + qWarning() << "couldn't open popcon file" << dev->errorString(); + } else { + foreach(Rating* res, m_ratings) { + res->deleteLater(); + } + m_ratings = PopConParser::parsePopcon(this, dev.data()); + Q_EMIT ratingsReady(); + } +} + +Rating * AppstreamReviews::ratingForApplication(AbstractResource* app) const +{ + if (app->isTechnical()) + return nullptr; + auto appk = qobject_cast(app); + if (!appk) + return nullptr; +// qDebug() << "fuuuuuu" << appk->appstreamId() << m_ratings.value(appk->appstreamId()); + return m_ratings.value(appk->appstreamId()); +} + +bool AppstreamReviews::isFetching() const +{ + return m_fetching; +} diff --git a/libdiscover/backends/PackageKitBackend/AppstreamReviews.h b/libdiscover/backends/PackageKitBackend/AppstreamReviews.h new file mode 100644 index 0000000..c383bed --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/AppstreamReviews.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright © 2016 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef APPSTREAMREVIEWS_H +#define APPSTREAMREVIEWS_H + +#include +#include + +class KJob; +class AbstractResourcesBackend; + +class AppstreamReviews : public AbstractReviewsBackend +{ + Q_OBJECT +public: + AppstreamReviews(AbstractResourcesBackend* parent); + + Rating *ratingForApplication(AbstractResource *app) const override; + + QString userName() const override{ return {}; } + bool hasCredentials() const override { return false; } + void login() override {} + void registerAndLogin() override {} + void logout() override {} + void submitUsefulness(Review* /*r*/, bool /*useful*/) override {} + void submitReview(AbstractResource* /*app*/, const QString& /*summary*/, const QString& /*review_text*/, const QString& /*rating*/) override {} + void deleteReview(Review* /*r*/) override {} + + void flagReview(Review* /*r*/, const QString& /*reason*/, const QString &/*text*/) override {} + void fetchReviews(AbstractResource* /*app*/, int /*page*/) override {} + bool isReviewable() const override { return false; } + bool isFetching() const override; + +Q_SIGNALS: + void ratingsReady(); + +private: + void readRatings(); + void ratingsFetched(KJob* job); + + QHash m_ratings; + bool m_fetching; +}; + +#endif // APPSTREAMREVIEWS_H diff --git a/libdiscover/backends/PackageKitBackend/CMakeLists.txt b/libdiscover/backends/PackageKitBackend/CMakeLists.txt new file mode 100644 index 0000000..bb39561 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/CMakeLists.txt @@ -0,0 +1,36 @@ +find_package(KF5KIO REQUIRED) +find_package(KF5Archive REQUIRED) + +add_subdirectory(runservice) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-paths.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-paths.h) + +add_library(packagekit-backend MODULE PackageKitBackend.cpp + PackageKitResource.cpp + AppPackageKitResource.cpp + PKTransaction.cpp + PackageKitUpdater.cpp + PackageKitMessages.cpp + PackageKitSourcesBackend.cpp + AppstreamReviews.cpp +) + +set(AppstreamTarget "AppstreamQt") +if (AppStreamQt_FOUND) + target_compile_definitions(packagekit-backend PRIVATE -DNEWAPPSTREAM=0) + set(AppstreamTarget "AppStreamQt") +endif() +target_link_libraries(packagekit-backend PRIVATE Discover::Common Qt5::Core PK::packagekitqt5 KF5::ConfigGui KF5::Service KF5::KIOWidgets KF5::Archive ${AppstreamTarget}) + +install(TARGETS packagekit-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover) +install(FILES packagekit-backend.desktop DESTINATION ${DATA_INSTALL_DIR}/libdiscover/backends) + +#notifier +add_library(DiscoverPackageKitNotifier MODULE PackageKitNotifier.cpp) +target_link_libraries(DiscoverPackageKitNotifier PRIVATE PK::packagekitqt5 Discover::Notifiers) +set_target_properties(DiscoverPackageKitNotifier PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/plasma-discover) + +install(TARGETS DiscoverPackageKitNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier) + +install(FILES packagekit-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories) +add_subdirectory(categoryimages) diff --git a/libdiscover/backends/PackageKitBackend/PKTransaction.cpp b/libdiscover/backends/PackageKitBackend/PKTransaction.cpp new file mode 100644 index 0000000..1428c28 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PKTransaction.cpp @@ -0,0 +1,229 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "PKTransaction.h" +#include "PackageKitBackend.h" +#include "PackageKitResource.h" +#include "PackageKitMessages.h" +#include +#include +#include +#include +#include +#include +#include +#include + +PKTransaction::PKTransaction(const QVector& apps, Transaction::Role role) + : Transaction(apps.first(), apps.first(), role) + , m_apps(apps) +{ + Q_ASSERT(!apps.contains(nullptr)); + foreach(auto r, apps) { + PackageKitResource* res = qobject_cast(r); + m_pkgnames.unite(res->allPackageNames().toSet()); + } +} + +static QStringList packageIds(const QVector& res, std::function func) +{ + QStringList ret; + foreach(auto r, res) { + ret += func(qobject_cast(r)); + } + ret.removeDuplicates(); + return ret; +} + +void PKTransaction::start() +{ + trigger(PackageKit::Transaction::TransactionFlagSimulate); +} + +void PKTransaction::trigger(PackageKit::Transaction::TransactionFlags flags) +{ + if (m_trans) + m_trans->deleteLater(); + m_newPackageStates.clear(); + + switch (role()) { + case Transaction::ChangeAddonsRole: + case Transaction::InstallRole: + m_trans = PackageKit::Daemon::installPackages(packageIds(m_apps, [](PackageKitResource* r){return r->availablePackageId(); }), flags); + break; + case Transaction::RemoveRole: + //see bug #315063 + m_trans = PackageKit::Daemon::removePackages(packageIds(m_apps, [](PackageKitResource* r){return r->installedPackageId(); }), true /*allowDeps*/, false, flags); + break; + }; + Q_ASSERT(m_trans); + +// connect(m_trans.data(), &PackageKit::Transaction::statusChanged, this, [this]() { qDebug() << "state..." << m_trans->status(); }); + connect(m_trans.data(), &PackageKit::Transaction::package, this, &PKTransaction::packageResolved); + connect(m_trans.data(), &PackageKit::Transaction::finished, this, &PKTransaction::cleanup); + connect(m_trans.data(), &PackageKit::Transaction::errorCode, this, &PKTransaction::errorFound); + connect(m_trans.data(), &PackageKit::Transaction::mediaChangeRequired, this, &PKTransaction::mediaChange); + connect(m_trans.data(), &PackageKit::Transaction::requireRestart, this, &PKTransaction::requireRestart); + connect(m_trans.data(), &PackageKit::Transaction::itemProgress, this, &PKTransaction::progressChanged); + connect(m_trans.data(), &PackageKit::Transaction::eulaRequired, this, &PKTransaction::eulaRequired); + connect(m_trans.data(), &PackageKit::Transaction::allowCancelChanged, this, &PKTransaction::cancellableChanged); + + setCancellable(m_trans->allowCancel()); +} + +void PKTransaction::progressChanged(const QString &id, PackageKit::Transaction::Status status, uint percentage) +{ + Q_UNUSED(percentage); + PackageKitResource * res = qobject_cast(resource()); + if (!res->allPackageNames().contains(PackageKit::Daemon::packageName(id))) + return; + + if (status == PackageKit::Transaction::StatusDownload) + setStatus(Transaction::DownloadingStatus); + else + setStatus(Transaction::CommittingStatus); +} + +void PKTransaction::cancellableChanged() +{ + setCancellable(m_trans->allowCancel()); +} + +void PKTransaction::cancel() +{ + if (!m_trans) { + const auto backend = qobject_cast(resource()->backend()); + backend->transactionCanceled(this); + } else if (m_trans->allowCancel()) { + m_trans->cancel(); + } else { + qWarning() << "trying to cancel a non-cancellable transaction: " << resource()->name(); + } +} + +void PKTransaction::cleanup(PackageKit::Transaction::Exit exit, uint runtime) +{ + Q_UNUSED(runtime) + const bool cancel = exit == PackageKit::Transaction::ExitEulaRequired || exit == PackageKit::Transaction::ExitCancelled; + const bool simulate = m_trans->transactionFlags() & PackageKit::Transaction::TransactionFlagSimulate; + + disconnect(m_trans, nullptr, this, nullptr); + m_trans = nullptr; + + const auto backend = qobject_cast(resource()->backend()); + + if (!cancel && simulate) { + auto packagesToRemove = m_newPackageStates.value(PackageKit::Transaction::InfoRemoving); + QMutableListIterator i(packagesToRemove); + QSet removedResources; + while (i.hasNext()) { + const auto pkgname = PackageKit::Daemon::packageName(i.next()); + removedResources.unite(backend->searchPackageName(pkgname).toSet()); + + if (m_pkgnames.contains(pkgname)) { + i.remove(); + } + } + removedResources.subtract(m_apps.toList().toSet()); + + QString msg = PackageKitResource::joinPackages(packagesToRemove); + if (!removedResources.isEmpty()) { + QStringList removedResourcesStr; + removedResourcesStr.reserve(removedResources.size()); + foreach(AbstractResource* res, removedResources) + removedResourcesStr.append(res->name()); + msg += QLatin1Char('\n'); + msg += removedResourcesStr.join(QStringLiteral(", ")); + } + + if (!msg.isEmpty()) { + Q_EMIT proceedRequest(PackageKitMessages::statusMessage(PackageKit::Transaction::StatusRemove), msg); + } else { + proceed(); + } + return; + } + + this->submitResolve(); + setStatus(Transaction::DoneStatus); + if (cancel) + backend->transactionCanceled(this); + else + backend->removeTransaction(this); +} + +void PKTransaction::proceed() +{ + trigger(PackageKit::Transaction::TransactionFlagOnlyTrusted); +} + +void PKTransaction::packageResolved(PackageKit::Transaction::Info info, const QString& packageId) +{ + m_newPackageStates[info].append(packageId); +} + +void PKTransaction::submitResolve() +{ + QStringList needResolving; + const auto pkgids = m_newPackageStates.value(PackageKit::Transaction::InfoFinished); + foreach(const auto pkgid, pkgids) { + needResolving += PackageKit::Daemon::packageName(pkgid); + } + const auto backend = qobject_cast(resource()->backend()); + + backend->clearPackages(needResolving); + backend->resolvePackages(needResolving); +} + +PackageKit::Transaction* PKTransaction::transaction() +{ + return m_trans; +} + +void PKTransaction::eulaRequired(const QString& eulaID, const QString& packageID, const QString& vendor, const QString& licenseAgreement) +{ + int ret = QMessageBox::question(nullptr, i18n("Accept EULA"), i18n("The package %1 and its vendor %2 require that you accept their license:\n %3", + PackageKit::Daemon::packageName(packageID), vendor, licenseAgreement)); + if (ret == QMessageBox::Yes) { + PackageKit::Transaction* t = PackageKit::Daemon::acceptEula(eulaID); + connect(t, &PackageKit::Transaction::finished, this, &PKTransaction::start); + } else { + cleanup(PackageKit::Transaction::ExitCancelled, 0); + } +} + +void PKTransaction::errorFound(PackageKit::Transaction::Error err, const QString& error) +{ + if (err == PackageKit::Transaction::ErrorNoLicenseAgreement) + return; + qWarning() << "PackageKit error:" << err << PackageKitMessages::errorMessage(err) << error; + Q_EMIT passiveMessage(PackageKitMessages::errorMessage(err)); +} + +void PKTransaction::mediaChange(PackageKit::Transaction::MediaType media, const QString& type, const QString& text) +{ + Q_UNUSED(media) + Q_EMIT passiveMessage(i18n("Media Change of type '%1' is requested.\n%2", type, text)); +} + +void PKTransaction::requireRestart(PackageKit::Transaction::Restart restart, const QString& pkgid) +{ + Q_EMIT passiveMessage(PackageKitMessages::restartMessage(restart, pkgid)); +} diff --git a/libdiscover/backends/PackageKitBackend/PKTransaction.h b/libdiscover/backends/PackageKitBackend/PKTransaction.h new file mode 100644 index 0000000..195a75a --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PKTransaction.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * Copyright © 2013 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef PKTRANSACTION_H +#define PKTRANSACTION_H + +#include +#include +#include +#include + +class PKTransaction : public Transaction +{ + Q_OBJECT + public: + explicit PKTransaction(const QVector& app, Transaction::Role role); + PackageKit::Transaction* transaction(); + + void cancel() override; + void proceed() override; + + public Q_SLOTS: + void start(); + + private: + void cleanup(PackageKit::Transaction::Exit, uint); + void errorFound(PackageKit::Transaction::Error err, const QString& error); + void mediaChange(PackageKit::Transaction::MediaType media, const QString& type, const QString& text); + void requireRestart(PackageKit::Transaction::Restart restart, const QString& p); + void progressChanged(const QString&, PackageKit::Transaction::Status, uint); + void eulaRequired(const QString &eulaID, const QString &packageID, const QString &vendor, const QString &licenseAgreement); + void cancellableChanged(); + void packageResolved(PackageKit::Transaction::Info info, const QString& packageId); + void submitResolve(); + + void trigger(PackageKit::Transaction::TransactionFlags flags); + QPointer m_trans; + const QVector m_apps; + QSet m_pkgnames; + + QMap m_newPackageStates; +}; + +#endif // PKTRANSACTION_H diff --git a/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp b/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp new file mode 100644 index 0000000..3421cd1 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp @@ -0,0 +1,561 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "PackageKitBackend.h" +#include "PackageKitSourcesBackend.h" +#include "PackageKitResource.h" +#include "PackageKitUpdater.h" +#include "AppPackageKitResource.h" +#include "PKTransaction.h" +#include "AppstreamReviews.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "utils.h" +#include "config-paths.h" + +MUON_BACKEND_PLUGIN(PackageKitBackend) + +static QString locateService(const QString &filename) +{ + return QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("applications/")+filename); +} + +PackageKitBackend::PackageKitBackend(QObject* parent) + : AbstractResourcesBackend(parent) + , m_updater(new PackageKitUpdater(this)) + , m_refresher(nullptr) + , m_isFetching(0) + , m_reviews(new AppstreamReviews(this)) +{ +#ifdef NEWAPPSTREAM + bool b = m_appdata.load(); +#else + bool b = m_appdata.open(); +#endif + if (!b) { + qWarning() << "Could not open the AppStream metadata pool"; + + auto msg = new QAction(i18n("Got it"), this); + msg->setWhatsThis(i18n("Please make sure that Appstream is properly set up on your system")); + msg->setPriority(QAction::HighPriority); + connect(msg, &QAction::triggered, msg, [msg](){ msg->setVisible(false); }); + m_messageActions << msg; + } + reloadPackageList(); + + QTimer* t = new QTimer(this); + connect(t, &QTimer::timeout, this, &PackageKitBackend::refreshDatabase); + t->setInterval(60 * 60 * 1000); + t->setSingleShot(false); + t->start(); + + m_delayedDetailsFetch.setSingleShot(true); + m_delayedDetailsFetch.setInterval(0); + connect(&m_delayedDetailsFetch, &QTimer::timeout, this, &PackageKitBackend::performDetailsFetch); + + QAction* updateAction = new QAction(this); + updateAction->setIcon(QIcon::fromTheme(QStringLiteral("system-software-update"))); + updateAction->setText(i18nc("@action Checks the Internet for updates", "Check for Updates")); + updateAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R)); + connect(this, &PackageKitBackend::fetchingChanged, updateAction, [updateAction, this](){ + updateAction->setEnabled(!isFetching()); + }); + connect(updateAction, &QAction::triggered, this, &PackageKitBackend::refreshDatabase); + m_messageActions += updateAction; + + const auto service = locateService(QStringLiteral("software-properties-kde.desktop")); + if (!service.isEmpty()) + m_messageActions += createActionForService(service); + + connect(PackageKit::Daemon::global(), &PackageKit::Daemon::updatesChanged, this, &PackageKitBackend::fetchUpdates); + connect(PackageKit::Daemon::global(), &PackageKit::Daemon::isRunningChanged, this, &PackageKitBackend::checkDaemonRunning); + connect(m_reviews, &AppstreamReviews::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady); + + SourcesModel::global()->addSourcesBackend(new PackageKitSourcesBackend(this)); +} + +PackageKitBackend::~PackageKitBackend() +{ +} + +QAction* PackageKitBackend::createActionForService(const QString &servicePath) +{ + QAction* action = new QAction(this); + KDesktopFile parser(servicePath); + action->setIcon(QIcon::fromTheme(parser.readIcon())); + action->setText(parser.readName()); + connect(action, &QAction::triggered, action, [servicePath, this](){ + bool b = QProcess::startDetached(QStringLiteral(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/discover/runservice"), {servicePath}); + if (!b) + qWarning() << "Could not start" << servicePath; + }); + return action; +} + +bool PackageKitBackend::isFetching() const +{ + return m_isFetching; +} + +void PackageKitBackend::acquireFetching(bool f) +{ + if (f) + m_isFetching++; + else + m_isFetching--; + + if ((!f && m_isFetching==0) || (f && m_isFetching==1)) { + emit fetchingChanged(); + } + Q_ASSERT(m_isFetching>=0); +} + +void PackageKitBackend::reloadPackageList() +{ + acquireFetching(true); + if (m_refresher) { + disconnect(m_refresher.data(), &PackageKit::Transaction::finished, this, &PackageKitBackend::reloadPackageList); + } + +#ifdef NEWAPPSTREAM + const auto components = m_appdata.components(); +#else + const auto components = m_appdata.allComponents(); +#endif + QStringList neededPackages; + neededPackages.reserve(components.size()); + foreach(const Appstream::Component& component, components) { + if (component.packageNames().isEmpty()) { + qDebug() << "no packages for" << component.name(); + continue; + } + neededPackages += component.packageNames(); + + const auto res = new AppPackageKitResource(component, this); + m_packages.packages[component.id()] = res; + foreach (const QString& pkg, component.packageNames()) { + m_packages.packageToApp[pkg] += component.id(); + } + + foreach (const QString& pkg, component.extends()) { + m_packages.extendedBy[pkg] += res; + } + } + acquireFetching(false); + neededPackages.removeDuplicates(); + + qDebug() << "needed..." << neededPackages.count(); + resolvePackages(neededPackages); +} + +class TransactionSet : public QObject +{ + Q_OBJECT + public: + TransactionSet(const QVector &transactions) + : m_transactions(transactions) + { + foreach(PackageKit::Transaction* t, transactions) { + connect(t, &PackageKit::Transaction::finished, this, &TransactionSet::transactionFinished); + } + } + + void transactionFinished(PackageKit::Transaction::Exit exit) { + PackageKit::Transaction* t = qobject_cast(sender()); + if (exit != PackageKit::Transaction::ExitSuccess) { + qWarning() << "failed" << exit << t; + } + + m_transactions.removeAll(t); + if (m_transactions.isEmpty()) { + Q_EMIT allFinished(); + } + } + + Q_SIGNALS: + void allFinished(); + + private: + QVector m_transactions; + +}; + +void PackageKitBackend::clearPackages(const QStringList& packageNames) +{ + const auto resources = resourcesByPackageNames>(packageNames); + for(auto res: resources) { + qobject_cast(res)->clearPackageIds(); + } +} + +void PackageKitBackend::resolvePackages(const QStringList &packageNames) +{ + PackageKit::Transaction * tArch = PackageKit::Daemon::resolve(packageNames, PackageKit::Transaction::FilterArch); + connect(tArch, &PackageKit::Transaction::package, this, &PackageKitBackend::addPackageArch); + connect(tArch, &PackageKit::Transaction::errorCode, this, &PackageKitBackend::transactionError); + + PackageKit::Transaction * tNotArch = PackageKit::Daemon::resolve(packageNames, PackageKit::Transaction::FilterNotArch); + connect(tNotArch, &PackageKit::Transaction::package, this, &PackageKitBackend::addPackageNotArch); + connect(tNotArch, &PackageKit::Transaction::errorCode, this, &PackageKitBackend::transactionError); + + TransactionSet* merge = new TransactionSet({tArch, tNotArch}); + connect(merge, &TransactionSet::allFinished, this, &PackageKitBackend::getPackagesFinished); + fetchUpdates(); +} + +void PackageKitBackend::fetchUpdates() +{ + PackageKit::Transaction * tUpdates = PackageKit::Daemon::getUpdates(); + connect(tUpdates, &PackageKit::Transaction::finished, this, &PackageKitBackend::getUpdatesFinished); + connect(tUpdates, &PackageKit::Transaction::package, this, &PackageKitBackend::addPackageToUpdate); + connect(tUpdates, &PackageKit::Transaction::errorCode, this, &PackageKitBackend::transactionError); + m_updatesPackageId.clear(); + + m_updater->setProgressing(true); +} + +void PackageKitBackend::addPackageArch(PackageKit::Transaction::Info info, const QString& packageId, const QString& summary) +{ + addPackage(info, packageId, summary, true); +} + +void PackageKitBackend::addPackageNotArch(PackageKit::Transaction::Info info, const QString& packageId, const QString& summary) +{ + addPackage(info, packageId, summary, false); +} + +void PackageKitBackend::addPackage(PackageKit::Transaction::Info info, const QString &packageId, const QString &summary, bool arch) +{ + const QString packageName = PackageKit::Daemon::packageName(packageId); + QSet r = resourcesByPackageName(packageName); + if (r.isEmpty()) { + auto pk = new PackageKitResource(packageName, summary, this); + r = { pk }; + m_packagesToAdd.insert(pk); + } + foreach(auto res, r) + static_cast(res)->addPackageId(info, packageId, arch); +} + +void PackageKitBackend::getPackagesFinished() +{ + for(auto it = m_packages.packages.cbegin(); it != m_packages.packages.cend(); ++it) { + auto pkr = qobject_cast(it.value()); + if (pkr->packages().isEmpty()) { + qWarning() << "Failed to find package for" << it.key(); + m_packagesToDelete += pkr; + } + } + includePackagesToAdd(); +} + +void PackageKitBackend::includePackagesToAdd() +{ + if (m_packagesToAdd.isEmpty() && m_packagesToDelete.isEmpty()) + return; + + acquireFetching(true); + foreach(PackageKitResource* res, m_packagesToAdd) { + m_packages.packages[res->packageName()] = res; + } + foreach(PackageKitResource* res, m_packagesToDelete) { + const auto pkgs = m_packages.packageToApp.value(res->packageName(), {res->packageName()}); + foreach(const auto &pkg, pkgs) { + m_packages.packages.take(pkg)->deleteLater(); + } + } + m_packagesToAdd.clear(); + m_packagesToDelete.clear(); + acquireFetching(false); +} + +void PackageKitBackend::transactionError(PackageKit::Transaction::Error, const QString& message) +{ + qWarning() << "Transaction error: " << message << sender(); +} + +void PackageKitBackend::packageDetails(const PackageKit::Details& details) +{ + const QSet resources = resourcesByPackageName(PackageKit::Daemon::packageName(details.packageId())); + if (resources.isEmpty()) + qWarning() << "couldn't find package for" << details.packageId(); + + foreach(AbstractResource* res, resources) { + qobject_cast(res)->setDetails(details); + } +} + +QSet PackageKitBackend::resourcesByPackageName(const QString& name) const +{ + const QStringList names = m_packages.packageToApp.value(name, QStringList(name)); + QSet ret; + ret.reserve(names.size()); + foreach(const QString& name, names) { + AbstractResource* res = m_packages.packages.value(name); + if (res) + ret += res; + } + return ret; +} + +template +T PackageKitBackend::resourcesByPackageNames(const QStringList &pkgnames) const +{ + T ret; + ret.reserve(pkgnames.size()); + for(const QString &name : pkgnames) { + const QStringList names = m_packages.packageToApp.value(name, QStringList(name)); + foreach(const QString& name, names) { + AbstractResource* res = m_packages.packages.value(name); + if (res) + ret += res; + } + } + return ret; +} + +void PackageKitBackend::refreshDatabase() +{ + if (!m_refresher) { + acquireFetching(true); + m_refresher = PackageKit::Daemon::refreshCache(false); + connect(m_refresher.data(), &PackageKit::Transaction::finished, this, [this]() { + reloadPackageList(); + acquireFetching(false); + delete m_refresher; + }); + } else { + qWarning() << "already resetting"; + } +} + +QVector PackageKitBackend::allResources() const +{ + return containerValues>(m_packages.packages); +} + +AbstractResource* PackageKitBackend::resourceByPackageName(const QString& name) const +{ + const QStringList ids = m_packages.packageToApp.value(name, QStringList(name)); + return ids.isEmpty() ? nullptr : m_packages.packages[ids.first()]; +} + +QList PackageKitBackend::searchPackageName(const QString& searchText) +{ +#ifdef NEWAPPSTREAM + const QList components = m_appdata.search(searchText); +#else + const QList components = m_appdata.findComponentsByString(searchText, {}); +#endif + const QStringList ids = kTransform(components, [](const Appstream::Component& comp) { return comp.id(); }); + + return resourcesByPackageNames>(ids); +} + +int PackageKitBackend::updatesCount() const +{ + return m_updatesPackageId.count(); +} + +void PackageKitBackend::transactionCanceled(Transaction* t) +{ + qDebug() << "Cancel transaction:" << t->resource()->packageName() << "with" << m_transactions.size() << "transactions running"; + int count = m_transactions.removeAll(t); + Q_ASSERT(count==1); + Q_UNUSED(count) + TransactionModel::global()->cancelTransaction(t); +} + +void PackageKitBackend::removeTransaction(Transaction* t) +{ + qDebug() << "Remove transaction:" << t->resource()->packageName() << "with" << m_transactions.size() << "transactions running"; + int count = m_transactions.removeAll(t); + Q_ASSERT(count==1); + Q_UNUSED(count) + TransactionModel::global()->removeTransaction(t); +} + +void PackageKitBackend::addTransaction(PKTransaction* t) +{ + m_transactions.append(t); + TransactionModel::global()->addTransaction(t); + t->start(); +} + +void PackageKitBackend::installApplication(AbstractResource* app, const AddonList& addons) +{ + if(!addons.addonsToInstall().isEmpty()) + { + QVector appsToInstall; + + if(!app->isInstalled()) + appsToInstall << app; + + foreach(const QString& toInstall, addons.addonsToInstall()) { + appsToInstall += m_packages.packages.value(toInstall); + Q_ASSERT(appsToInstall.last()); + } + addTransaction(new PKTransaction(appsToInstall, Transaction::ChangeAddonsRole)); + } + + if (!addons.addonsToRemove().isEmpty()) { + QVector appsToRemove; + foreach(const QString& toRemove, addons.addonsToRemove()) { + appsToRemove += m_packages.packages.value(toRemove); + } + addTransaction(new PKTransaction(appsToRemove, Transaction::RemoveRole)); + } +} + +void PackageKitBackend::installApplication(AbstractResource* app) +{ + addTransaction(new PKTransaction({app}, Transaction::InstallRole)); +} + +void PackageKitBackend::removeApplication(AbstractResource* app) +{ + Q_ASSERT(!isFetching()); + addTransaction(new PKTransaction({app}, Transaction::RemoveRole)); +} + +QSet PackageKitBackend::upgradeablePackages() const +{ + QSet ret; + ret.reserve(m_updatesPackageId.size()); + Q_FOREACH (const QString& pkgid, m_updatesPackageId) { + const QString pkgname = PackageKit::Daemon::packageName(pkgid); + const auto pkgs = resourcesByPackageName(pkgname); + if (pkgs.isEmpty()) { + qWarning() << "couldn't find resource for" << pkgid; + } + ret.unite(pkgs); + } + return ret; +} + +void PackageKitBackend::addPackageToUpdate(PackageKit::Transaction::Info info, const QString& packageId, const QString& summary) +{ + if (info != PackageKit::Transaction::InfoBlocked) { + m_updatesPackageId += packageId; + addPackage(info, packageId, summary, true); + } +} + +void PackageKitBackend::getUpdatesFinished(PackageKit::Transaction::Exit, uint) +{ + if (!m_updatesPackageId.isEmpty()) { + PackageKit::Transaction* transaction = PackageKit::Daemon::getDetails(m_updatesPackageId.toList()); + connect(transaction, &PackageKit::Transaction::details, this, &PackageKitBackend::packageDetails); + connect(transaction, &PackageKit::Transaction::errorCode, this, &PackageKitBackend::transactionError); + connect(transaction, &PackageKit::Transaction::finished, this, &PackageKitBackend::getUpdatesDetailsFinished); + } + + m_updater->setProgressing(false); + + includePackagesToAdd(); + emit updatesCountChanged(); +} + +void PackageKitBackend::getUpdatesDetailsFinished(PackageKit::Transaction::Exit exit, uint) +{ + if (exit != PackageKit::Transaction::ExitSuccess) { + qWarning() << "Couldn't figure out the updates on PackageKit backend" << exit; + } +} + +bool PackageKitBackend::isPackageNameUpgradeable(const PackageKitResource* res) const +{ + return !upgradeablePackageId(res).isEmpty(); +} + +QString PackageKitBackend::upgradeablePackageId(const PackageKitResource* res) const +{ + QString name = res->packageName(); + foreach (const QString& pkgid, m_updatesPackageId) { + if (PackageKit::Daemon::packageName(pkgid) == name) + return pkgid; + } + return QString(); +} + +void PackageKitBackend::fetchDetails(const QString& pkgid) +{ + if (!m_delayedDetailsFetch.isActive()) { + m_delayedDetailsFetch.start(); + } + + m_packageNamesToFetchDetails += pkgid; +} + +void PackageKitBackend::performDetailsFetch() +{ + Q_ASSERT(!m_packageNamesToFetchDetails.isEmpty()); + PackageKit::Transaction* transaction = PackageKit::Daemon::getDetails(m_packageNamesToFetchDetails.toList()); + connect(transaction, &PackageKit::Transaction::details, this, &PackageKitBackend::packageDetails); + connect(transaction, &PackageKit::Transaction::errorCode, this, &PackageKitBackend::transactionError); +} + +void PackageKitBackend::checkDaemonRunning() +{ + if (!PackageKit::Daemon::isRunning()) { + qWarning() << "PackageKit stopped running!"; + } +} + +AbstractBackendUpdater* PackageKitBackend::backendUpdater() const +{ + return m_updater; +} + +QList PackageKitBackend::messageActions() const +{ + return m_messageActions; +} + +QVector PackageKitBackend::extendedBy(const QString& id) const +{ + return m_packages.extendedBy[id]; +} + +AbstractReviewsBackend* PackageKitBackend::reviewsBackend() const +{ + return m_reviews; +} + +#include "PackageKitBackend.moc" diff --git a/libdiscover/backends/PackageKitBackend/PackageKitBackend.h b/libdiscover/backends/PackageKitBackend/PackageKitBackend.h new file mode 100644 index 0000000..6d10448 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitBackend.h @@ -0,0 +1,134 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef PACKAGEKITBACKEND_H +#define PACKAGEKITBACKEND_H + +#include "PackageKitResource.h" +#include +#include +#include +#include +#include +#include +#include + +#ifdef NEWAPPSTREAM +#include +#include +namespace AppStream { + typedef Provided Provides; + typedef Pool Database; +} +namespace Appstream = AppStream; +#else +#include +#endif + +class AppstreamReviews; +class AppPackageKitResource; +class PackageKitUpdater; +class PKTransaction; + +class DISCOVERCOMMON_EXPORT PackageKitBackend : public AbstractResourcesBackend +{ + Q_OBJECT + public: + explicit PackageKitBackend(QObject* parent = nullptr); + ~PackageKitBackend() override; + + AbstractBackendUpdater* backendUpdater() const override; + AbstractReviewsBackend* reviewsBackend() const override; + + QVector< AbstractResource* > allResources() const override; + AbstractResource* resourceByPackageName(const QString& name) const override; + QList searchPackageName(const QString& searchText) override; + int updatesCount() const override; + + void installApplication(AbstractResource* app) override; + void installApplication(AbstractResource* app, const AddonList& addons) override; + void removeApplication(AbstractResource* app) override; + bool isValid() const override { return true; } + QSet upgradeablePackages() const; + bool isFetching() const override; + QList messageActions() const override; + + bool isPackageNameUpgradeable(const PackageKitResource* res) const; + QString upgradeablePackageId(const PackageKitResource* res) const; + QVector extendedBy(const QString& id) const; + void fetchUpdates(); + + void clearPackages(const QStringList &packageNames); + void resolvePackages(const QStringList &packageNames); + void fetchDetails(const QString& pkgid); + + public Q_SLOTS: + void transactionCanceled(Transaction* t); + void removeTransaction(Transaction* t); + void reloadPackageList(); + void refreshDatabase(); + + private Q_SLOTS: + void getPackagesFinished(); + void addPackage(PackageKit::Transaction::Info info, const QString &packageId, const QString &summary, bool arch); + void addPackageArch(PackageKit::Transaction::Info info, const QString &packageId, const QString &summary); + void addPackageNotArch(PackageKit::Transaction::Info info, const QString &packageId, const QString &summary); + void packageDetails(const PackageKit::Details& details); + void transactionError(PackageKit::Transaction::Error, const QString& message); + void addPackageToUpdate(PackageKit::Transaction::Info, const QString& pkgid, const QString& summary); + void getUpdatesFinished(PackageKit::Transaction::Exit,uint); + void getUpdatesDetailsFinished(PackageKit::Transaction::Exit,uint); + + private: + QSet resourcesByPackageName(const QString& name) const; + template + T resourcesByPackageNames(const QStringList& names) const; + + void addTransaction(PKTransaction* trans); + void checkDaemonRunning(); + void acquireFetching(bool f); + void includePackagesToAdd(); + void performDetailsFetch(); + QAction* createActionForService(const QString &filename); + + Appstream::Database m_appdata; + QList m_transactions; + PackageKitUpdater* m_updater; + QPointer m_refresher; + int m_isFetching; + QSet m_updatesPackageId; + QSet m_packagesToAdd; + QSet m_packagesToDelete; + QList m_messageActions; + + struct Packages { + QHash packages; + QHash packageToApp; + QHash> extendedBy; + void clear() { *this = {}; } + }; + + QTimer m_delayedDetailsFetch; + QSet m_packageNamesToFetchDetails; + Packages m_packages; + AppstreamReviews* const m_reviews; +}; + +#endif // PACKAGEKITBACKEND_H diff --git a/libdiscover/backends/PackageKitBackend/PackageKitMessages.cpp b/libdiscover/backends/PackageKitBackend/PackageKitMessages.cpp new file mode 100644 index 0000000..ee82ef8 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitMessages.cpp @@ -0,0 +1,333 @@ +/*************************************************************************** + * Copyright © 2012-2014 Aleix Pol Gonzalez * + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "PackageKitMessages.h" +#include +#include +#include + +namespace PackageKitMessages +{ + +QString errorMessage(PackageKit::Transaction::Error error) +{ + switch(error) { + case PackageKit::Transaction::ErrorOom: + return i18n("Out of memory"); + case PackageKit::Transaction::ErrorNoNetwork: + return i18n("No network connection available"); + case PackageKit::Transaction::ErrorNotSupported: + return i18n("Operation not supported"); + case PackageKit::Transaction::ErrorInternalError: + return i18n("Internal error"); + case PackageKit::Transaction::ErrorGpgFailure: + return i18n("GPG failure"); + case PackageKit::Transaction::ErrorPackageIdInvalid: + return i18n("PackageID invalid"); + case PackageKit::Transaction::ErrorPackageNotInstalled: + return i18n("Package not installed"); + case PackageKit::Transaction::ErrorPackageNotFound: + return i18n("Package not found"); + case PackageKit::Transaction::ErrorPackageAlreadyInstalled: + return i18n("Package is already installed"); + case PackageKit::Transaction::ErrorPackageDownloadFailed: + return i18n("Package download failed"); + case PackageKit::Transaction::ErrorGroupNotFound: + return i18n("Package group not found"); + case PackageKit::Transaction::ErrorGroupListInvalid: + return i18n("Package group list invalid"); + case PackageKit::Transaction::ErrorDepResolutionFailed: + return i18n("Dependency resolution failed"); + case PackageKit::Transaction::ErrorFilterInvalid: + return i18n("Filter invalid"); + case PackageKit::Transaction::ErrorCreateThreadFailed: + return i18n("Failed while creating a thread"); + case PackageKit::Transaction::ErrorTransactionError: + return i18n("Transaction failure"); + case PackageKit::Transaction::ErrorTransactionCancelled: + return i18n("Transaction canceled"); + case PackageKit::Transaction::ErrorNoCache: + return i18n("No Cache available"); + case PackageKit::Transaction::ErrorRepoNotFound: + return i18n("Cannot find repository"); + case PackageKit::Transaction::ErrorCannotRemoveSystemPackage: + return i18n("Cannot remove system package"); + case PackageKit::Transaction::ErrorProcessKill: + return i18n("The PackageKit daemon has crashed"); + case PackageKit::Transaction::ErrorFailedInitialization: + return i18n("Initialization failure"); + case PackageKit::Transaction::ErrorFailedFinalise: + return i18n("Failed to finalize transaction"); + case PackageKit::Transaction::ErrorFailedConfigParsing: + return i18n("Config parsing failed"); + case PackageKit::Transaction::ErrorCannotCancel: + return i18n("Cannot cancel transaction"); + case PackageKit::Transaction::ErrorCannotGetLock: + return i18n("Cannot obtain lock"); + case PackageKit::Transaction::ErrorNoPackagesToUpdate: + return i18n("No packages to update"); + case PackageKit::Transaction::ErrorCannotWriteRepoConfig: + return i18n("Cannot write repo config"); + case PackageKit::Transaction::ErrorLocalInstallFailed: + return i18n("Local install failed"); + case PackageKit::Transaction::ErrorBadGpgSignature: + return i18n("Bad GPG signature found"); + case PackageKit::Transaction::ErrorMissingGpgSignature: + return i18n("No GPG signature found"); + case PackageKit::Transaction::ErrorCannotInstallSourcePackage: + return i18n("Cannot install source package"); + case PackageKit::Transaction::ErrorRepoConfigurationError: + return i18n("Repo configuration error"); + case PackageKit::Transaction::ErrorNoLicenseAgreement: + return i18n("No license agreement"); + case PackageKit::Transaction::ErrorFileConflicts: + return i18n("File conflicts found"); + case PackageKit::Transaction::ErrorPackageConflicts: + return i18n("Package conflict found"); + case PackageKit::Transaction::ErrorRepoNotAvailable: + return i18n("Repo not available"); + case PackageKit::Transaction::ErrorInvalidPackageFile: + return i18n("Invalid package file"); + case PackageKit::Transaction::ErrorPackageInstallBlocked: + return i18n("Package install blocked"); + case PackageKit::Transaction::ErrorPackageCorrupt: + return i18n("Corrupt package found"); + case PackageKit::Transaction::ErrorAllPackagesAlreadyInstalled: + return i18n("All packages already installed"); + case PackageKit::Transaction::ErrorFileNotFound: + return i18n("File not found"); + case PackageKit::Transaction::ErrorNoMoreMirrorsToTry: + return i18n("No more mirrors available"); + case PackageKit::Transaction::ErrorNoDistroUpgradeData: + return i18n("No distro upgrade data"); + case PackageKit::Transaction::ErrorIncompatibleArchitecture: + return i18n("Incompatible architecture"); + case PackageKit::Transaction::ErrorNoSpaceOnDevice: + return i18n("No space on device left"); + case PackageKit::Transaction::ErrorMediaChangeRequired: + return i18n("A media change is required"); + case PackageKit::Transaction::ErrorNotAuthorized: + return i18n("You have no authorization to execute this operation"); + case PackageKit::Transaction::ErrorUpdateNotFound: + return i18n("Update not found"); + case PackageKit::Transaction::ErrorCannotInstallRepoUnsigned: + return i18n("Cannot install from unsigned repo"); + case PackageKit::Transaction::ErrorCannotUpdateRepoUnsigned: + return i18n("Cannot update from unsigned repo"); + case PackageKit::Transaction::ErrorCannotGetFilelist: + return i18n("Cannot get file list"); + case PackageKit::Transaction::ErrorCannotGetRequires: + return i18n("Cannot get requires"); + case PackageKit::Transaction::ErrorCannotDisableRepository: + return i18n("Cannot disable repository"); + case PackageKit::Transaction::ErrorRestrictedDownload: + return i18n("Restricted download detected"); + case PackageKit::Transaction::ErrorPackageFailedToConfigure: + return i18n("Package failed to configure"); + case PackageKit::Transaction::ErrorPackageFailedToBuild: + return i18n("Package failed to build"); + case PackageKit::Transaction::ErrorPackageFailedToInstall: + return i18n("Package failed to install"); + case PackageKit::Transaction::ErrorPackageFailedToRemove: + return i18n("Package failed to remove"); + case PackageKit::Transaction::ErrorUpdateFailedDueToRunningProcess: + return i18n("Update failed due to running process"); + case PackageKit::Transaction::ErrorPackageDatabaseChanged: + return i18n("The package database changed"); + case PackageKit::Transaction::ErrorProvideTypeNotSupported: + return i18n("The provided type is not supported"); + case PackageKit::Transaction::ErrorInstallRootInvalid: + return i18n("Install root is invalid"); + case PackageKit::Transaction::ErrorCannotFetchSources: + return i18n("Cannot fetch sources"); + case PackageKit::Transaction::ErrorCancelledPriority: + return i18n("Canceled priority"); + case PackageKit::Transaction::ErrorUnfinishedTransaction: + return i18n("Unfinished transaction"); + case PackageKit::Transaction::ErrorLockRequired: + return i18n("Lock required"); + case PackageKit::Transaction::ErrorUnknown: + default: { + int idx = PackageKit::Transaction::staticMetaObject.indexOfEnumerator("Error"); + QMetaEnum metaenum = PackageKit::Transaction::staticMetaObject.enumerator(idx); + return i18n("Unknown error %1.", QString::fromLatin1(metaenum.valueToKey(error))); + } + } +} + +QString restartMessage(PackageKit::Transaction::Restart restart, const QString& pkgid) +{ + switch (restart) { + case PackageKit::Transaction::RestartApplication: + return i18n("'%1' was changed and suggests to be restarted.", PackageKit::Daemon::packageName(pkgid)); + case PackageKit::Transaction::RestartSession: + return i18n("A change by '%1' suggests your session to be restarted.", PackageKit::Daemon::packageName(pkgid)); + case PackageKit::Transaction::RestartSecuritySession: + return i18n("'%1' was updated for security reasons, a restart of the session is recommended.", PackageKit::Daemon::packageName(pkgid)); + case PackageKit::Transaction::RestartSecuritySystem: + return i18n("'%1' was updated for security reasons, a restart of the system is recommended.", PackageKit::Daemon::packageName(pkgid)); + case PackageKit::Transaction::RestartSystem: + case PackageKit::Transaction::RestartUnknown: + case PackageKit::Transaction::RestartNone: + default: + return i18n("A change by '%1' suggests your system to be rebooted.", PackageKit::Daemon::packageName(pkgid)); + } +} + +QString restartMessage(PackageKit::Transaction::Restart restart) +{ + switch (restart) { + case PackageKit::Transaction::RestartApplication: + return i18n("The application will have to be restarted."); + case PackageKit::Transaction::RestartSession: + return i18n("The session will have to be restarted"); + case PackageKit::Transaction::RestartSystem: + return i18n("The system will have to be rebooted."); + case PackageKit::Transaction::RestartSecuritySession: + return i18n("For security, the session will have to be restarted."); + case PackageKit::Transaction::RestartSecuritySystem: + return i18n("For security, the system will have to be restarted."); + case PackageKit::Transaction::RestartUnknown: + case PackageKit::Transaction::RestartNone: + default: + return QString(); + } +} + +QString statusMessage(PackageKit::Transaction::Status status) +{ + switch (status) { + case PackageKit::Transaction::StatusWait: + return i18n("Waiting..."); + case PackageKit::Transaction::StatusRefreshCache: + return i18n("Refreshing Cache..."); + case PackageKit::Transaction::StatusSetup: + return i18n("Setup..."); + case PackageKit::Transaction::StatusRunning: + return i18n("Processing..."); + case PackageKit::Transaction::StatusRemove: + return i18n("Remove..."); + case PackageKit::Transaction::StatusDownload: + return i18n("Downloading..."); + case PackageKit::Transaction::StatusInstall: + return i18n("Installing..."); + case PackageKit::Transaction::StatusUpdate: + return i18n("Updating..."); + case PackageKit::Transaction::StatusCleanup: + return i18n("Cleaning up..."); +// case PackageKit::Transaction::StatusObsolete: + case PackageKit::Transaction::StatusDepResolve: + return i18n("Resolving dependencies..."); + case PackageKit::Transaction::StatusSigCheck: + return i18n("Checking signatures..."); + case PackageKit::Transaction::StatusTestCommit: + return i18n("Test committing..."); + case PackageKit::Transaction::StatusCommit: + return i18n("Committing..."); + //StatusRequest, + case PackageKit::Transaction::StatusFinished: + return i18n("Finished"); + case PackageKit::Transaction::StatusCancel: + return i18n("Canceled"); + case PackageKit::Transaction::StatusWaitingForLock: + return i18n("Waiting for lock..."); + case PackageKit::Transaction::StatusWaitingForAuth: + return i18n("Waiting for authorization..."); + //StatusScanProcessList, + //StatusCheckExecutableFiles, + //StatusCheckLibraries, + case PackageKit::Transaction::StatusCopyFiles: + return i18n("Copying files..."); + case PackageKit::Transaction::StatusUnknown: + default: + return i18n("Unknown Status"); + } +} + +QString statusDetail(PackageKit::Transaction::Status status) +{ + switch (status) { + case PackageKit::Transaction::StatusWait: + return i18n("We are waiting for something."); + case PackageKit::Transaction::StatusSetup: + return i18n("Setting up transaction..."); + case PackageKit::Transaction::StatusRunning: + return i18n("The transaction is currently working..."); + case PackageKit::Transaction::StatusRemove: + return i18n("The transaction is currently removing packages..."); + case PackageKit::Transaction::StatusDownload: + return i18n("The transaction is currently downloading packages..."); + case PackageKit::Transaction::StatusInstall: + return i18n("The transactions is currently installing packages..."); + case PackageKit::Transaction::StatusUpdate: + return i18n("The transaction is currently updating packages..."); + case PackageKit::Transaction::StatusCleanup: + return i18n("The transaction is currently cleaning up..."); + //case PackageKit::Transaction::StatusObsolete, + case PackageKit::Transaction::StatusDepResolve: + return i18n("The transaction is currently resolving the dependencies of the packages it will install..."); + case PackageKit::Transaction::StatusSigCheck: + return i18n("The transaction is currently checking the signatures of the packages..."); + case PackageKit::Transaction::StatusTestCommit: + return i18n("The transaction is currently testing the commit of this set of packages..."); + case PackageKit::Transaction::StatusCommit: + return i18n("The transaction is currently committing its set of packages..."); + //StatusRequest, + case PackageKit::Transaction::StatusFinished: + return i18n("The transaction has finished!"); + case PackageKit::Transaction::StatusCancel: + return i18n("The transaction was canceled"); + case PackageKit::Transaction::StatusWaitingForLock: + return i18n("The transaction is currently waiting for the lock..."); + case PackageKit::Transaction::StatusWaitingForAuth: + return i18n("Waiting for the user to authorize the transaction..."); + //StatusScanProcessList, + //StatusCheckExecutableFiles, + //StatusCheckLibraries, + case PackageKit::Transaction::StatusCopyFiles: + return i18n("The transaction is currently copying files..."); + case PackageKit::Transaction::StatusRefreshCache: + return i18n("Currently refreshing the repository cache..."); + case PackageKit::Transaction::StatusUnknown: + default: { + int idx = PackageKit::Transaction::staticMetaObject.indexOfEnumerator("Status"); + QMetaEnum metaenum = PackageKit::Transaction::staticMetaObject.enumerator(idx); + return i18n("Unknown status %1.", QString::fromLatin1(metaenum.valueToKey(status))); + } + } +} + +QString updateStateMessage(PackageKit::Transaction::UpdateState state) +{ + switch(state) { + case PackageKit::Transaction::UpdateStateUnknown: + return QString(); + case PackageKit::Transaction::UpdateStateStable: + return i18nc("update state", "Stable"); + case PackageKit::Transaction::UpdateStateUnstable: + return i18nc("update state", "Unstable"); + case PackageKit::Transaction::UpdateStateTesting: + return i18nc("update state", "Testing"); + } + return QString(); +} + +} diff --git a/libdiscover/backends/PackageKitBackend/PackageKitMessages.h b/libdiscover/backends/PackageKitBackend/PackageKitMessages.h new file mode 100644 index 0000000..66400f9 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitMessages.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright © 2012-2014 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef PACKAGEKITMESSAGES_H +#define PACKAGEKITMESSAGES_H + +#include + +namespace PackageKitMessages +{ + QString errorMessage(PackageKit::Transaction::Error error); + QString restartMessage(PackageKit::Transaction::Restart restart, const QString& p); + QString restartMessage(PackageKit::Transaction::Restart restart); + QString statusMessage(PackageKit::Transaction::Status status); + QString statusDetail(PackageKit::Transaction::Status status); + QString updateStateMessage(PackageKit::Transaction::UpdateState state); +} + +#endif // PACKAGEKITMESSAGES_H diff --git a/libdiscover/backends/PackageKitBackend/PackageKitNotifier.cpp b/libdiscover/backends/PackageKitBackend/PackageKitNotifier.cpp new file mode 100644 index 0000000..8b6d9d9 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitNotifier.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * Copyright © 2015 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "PackageKitNotifier.h" + +#include +#include + +PackageKitNotifier::PackageKitNotifier(QObject* parent) + : BackendNotifierModule(parent) + , m_update(NoUpdate) + , m_securityUpdates(0) + , m_normalUpdates(0) +{ +if (PackageKit::Daemon::global()->isRunning()) { + recheckSystemUpdateNeeded(); + } + connect(PackageKit::Daemon::global(), &PackageKit::Daemon::networkStateChanged, this, &PackageKitNotifier::recheckSystemUpdateNeeded); + connect(PackageKit::Daemon::global(), &PackageKit::Daemon::updatesChanged, this, &PackageKitNotifier::recheckSystemUpdateNeeded); + connect(PackageKit::Daemon::global(), &PackageKit::Daemon::isRunningChanged, this, &PackageKitNotifier::recheckSystemUpdateNeeded); +} + +PackageKitNotifier::~PackageKitNotifier() +{ +} + +void PackageKitNotifier::recheckSystemUpdateNeeded() +{ + if (PackageKit::Daemon::global()->isRunning()) { + PackageKit::Transaction * trans = PackageKit::Daemon::getUpdates(); + trans->setProperty("normalUpdates", 0); + trans->setProperty("securityUpdates", 0); + trans->setProperty("update", NoUpdate); + connect(trans, &PackageKit::Transaction::package, this, &PackageKitNotifier::package); + connect(trans, &PackageKit::Transaction::finished, this, &PackageKitNotifier::finished); + } +} + +void PackageKitNotifier::package(PackageKit::Transaction::Info info, const QString &/*packageID*/, const QString &/*summary*/) +{ + PackageKit::Transaction * trans = qobject_cast(sender()); + + switch (info) { + case PackageKit::Transaction::InfoBlocked: + break; //skip, we ignore blocked updates + case PackageKit::Transaction::InfoSecurity: + trans->setProperty("update", qMax(Security, trans->property("update").toInt())); + trans->setProperty("securityUpdates", trans->property("securityUpdates").toInt()+1); + break; + default: + trans->setProperty("update", qMax(Normal, trans->property("update").toInt())); + trans->setProperty("normalUpdates", trans->property("normalUpdates").toInt()+1); + break; + } +} + +void PackageKitNotifier::finished(PackageKit::Transaction::Exit /*exit*/, uint) +{ + const PackageKit::Transaction * trans = qobject_cast(sender()); + + const uint normalUpdates = trans->property("normalUpdates").toInt(); + const uint securityUpdates = trans->property("securityUpdates").toInt(); + const Update update = Update(trans->property("update").toInt()); + + const bool changed = update != m_update || normalUpdates != m_normalUpdates || securityUpdates != m_securityUpdates; + + m_normalUpdates = normalUpdates; + m_securityUpdates = securityUpdates; + m_update = update; + + if (changed) { + Q_EMIT foundUpdates(); + } +} + +bool PackageKitNotifier::isSystemUpToDate() const +{ + return m_update == NoUpdate; +} + +uint PackageKitNotifier::securityUpdatesCount() +{ + return m_securityUpdates; +} + +uint PackageKitNotifier::updatesCount() +{ + return m_normalUpdates; +} + diff --git a/libdiscover/backends/PackageKitBackend/PackageKitNotifier.h b/libdiscover/backends/PackageKitBackend/PackageKitNotifier.h new file mode 100644 index 0000000..9718c70 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitNotifier.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#ifndef PACKAGEKITNOTIFIER_H +#define PACKAGEKITNOTIFIER_H + +#include +#include +#include + +class QTimer; + +class PackageKitNotifier : public BackendNotifierModule +{ +Q_OBJECT +Q_PLUGIN_METADATA(IID "org.kde.discover.BackendNotifierModule") +Q_INTERFACES(BackendNotifierModule) +public: + enum Update { + NoUpdate, + Security, + Normal + }; + Q_ENUM(Update) + explicit PackageKitNotifier(QObject* parent = nullptr); + ~PackageKitNotifier() override; + + bool isSystemUpToDate() const final; + uint securityUpdatesCount() final; + uint updatesCount() final; + void recheckSystemUpdateNeeded() final; + +private Q_SLOTS: + void package(PackageKit::Transaction::Info info, const QString &packageID, const QString &summary); + void finished(PackageKit::Transaction::Exit exit, uint); + +private: + Update m_update; + uint m_securityUpdates; + uint m_normalUpdates; +}; + +#endif diff --git a/libdiscover/backends/PackageKitBackend/PackageKitResource.cpp b/libdiscover/backends/PackageKitBackend/PackageKitResource.cpp new file mode 100644 index 0000000..2d91761 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitResource.cpp @@ -0,0 +1,255 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "PackageKitResource.h" +#include "PackageKitBackend.h" +#include "PackageKitMessages.h" +#include +#include +#include +#include + +PackageKitResource::PackageKitResource(QString packageName, QString summary, PackageKitBackend* parent) + : AbstractResource(parent) + , m_summary(std::move(summary)) + , m_name(std::move(packageName)) +{ + setObjectName(m_name); +} + +QString PackageKitResource::name() +{ + return m_name; +} + +QString PackageKitResource::packageName() const +{ + return m_name; +} + +QStringList PackageKitResource::allPackageNames() const +{ + return { m_name }; +} + +QString PackageKitResource::availablePackageId() const +{ + //First we check if it's upgradeable and use this version to display + const QString pkgid = backend()->upgradeablePackageId(this); + if (!pkgid.isEmpty()) + return pkgid; + + QMap::const_iterator it = m_packages.constFind(PackageKit::Transaction::InfoAvailable); + if (it != m_packages.constEnd()) + return it->last(); + return installedPackageId(); +} + +QString PackageKitResource::installedPackageId() const +{ + const auto installed = m_packages[PackageKit::Transaction::InfoInstalled]; + return installed.isEmpty() ? QString() : installed.last(); +} + +QString PackageKitResource::comment() +{ + return m_summary; +} + +QString PackageKitResource::longDescription() +{ + fetchDetails(); + return m_details.description(); +} + +QUrl PackageKitResource::homepage() +{ + fetchDetails(); + return QUrl(m_details.url()); +} + +QVariant PackageKitResource::icon() const +{ + return QStringLiteral("applications-other"); +} + +QString PackageKitResource::license() +{ + fetchDetails(); + return m_details.license().isEmpty() ? i18n("Unknown") : m_details.license(); +} + +QList PackageKitResource::addonsInformation() +{ + return QList(); +} + +QString PackageKitResource::availableVersion() const +{ + return PackageKit::Daemon::packageVersion(availablePackageId()); +} + +QString PackageKitResource::installedVersion() const +{ + return PackageKit::Daemon::packageVersion(installedPackageId()); +} + +int PackageKitResource::size() +{ + fetchDetails(); + return m_details.size(); +} + +QString PackageKitResource::origin() const +{ + auto pkgid = availablePackageId(); + return PackageKit::Daemon::packageData(pkgid); +} + +QString PackageKitResource::section() +{ + return QString(); +} + +QUrl PackageKitResource::screenshotUrl() +{ + return {}; +} + +QUrl PackageKitResource::thumbnailUrl() +{ + return {}; +} + +AbstractResource::State PackageKitResource::state() +{ + if (backend()->isPackageNameUpgradeable(this)) + return Upgradeable; + else if(m_packages.contains(PackageKit::Transaction::InfoInstalled)) + return Installed; + else if(m_packages.contains(PackageKit::Transaction::InfoAvailable)) + return None; + else + return Broken; +} + +void PackageKitResource::addPackageId(PackageKit::Transaction::Info info, const QString &packageId, bool arch) +{ + if (arch) + m_packages[info].append(packageId); + else + m_packages[info].prepend(packageId); + emit stateChanged(); +} + +QStringList PackageKitResource::categories() +{ + return { QStringLiteral("Unknown") }; +} + +bool PackageKitResource::isTechnical() const +{ + return true;//!m_availablePackageId.startsWith("flash"); +} + +void PackageKitResource::fetchDetails() +{ + const QString pkgid = availablePackageId(); + if (!m_details.isEmpty() || pkgid.isEmpty()) + return; + m_details.insert(QStringLiteral("fetching"), true);//we add an entry so it's not re-fetched. + + backend()->fetchDetails(pkgid); +} + +void PackageKitResource::failedFetchingDetails(PackageKit::Transaction::Error, const QString& msg) +{ + qWarning() << "error fetching details" << msg; +} + +void PackageKitResource::setDetails(const PackageKit::Details & details) +{ + const bool ourDetails = details.packageId() == availablePackageId(); + if (!ourDetails) + return; + + if (m_details != details) { + m_details = details; + emit stateChanged(); + + if (!backend()->isFetching()) + backend()->resourcesChanged(this, {"size", "homepage", "license"}); + } +} + +void PackageKitResource::fetchChangelog() +{ + PackageKit::Transaction* t = PackageKit::Daemon::getUpdateDetail(availablePackageId()); + connect(t, &PackageKit::Transaction::updateDetail, this, &PackageKitResource::updateDetail); + connect(t, &PackageKit::Transaction::errorCode, this, [this](PackageKit::Transaction::Error err, const QString & error) { qWarning() << "error fetching updates:" << err << error; emit changelogFetched(QString()); }); +} + +static void addIfNotEmpty(const QString& title, const QString& content, QString& where) +{ + if (!content.isEmpty()) + where += QStringLiteral("

") + title + QStringLiteral(" ") + content + QStringLiteral("

"); +} + +QString PackageKitResource::joinPackages(const QStringList& pkgids) +{ + QStringList ret; + foreach(const QString& pkgid, pkgids) { + ret += i18nc("package-name (version)", "%1 (%2)", PackageKit::Daemon::packageName(pkgid), PackageKit::Daemon::packageVersion(pkgid)); + } + return ret.join(i18nc("comma separating package names", ", ")); +} + +static QStringList urlToLinks(const QStringList& urls) +{ + QStringList ret; + foreach(const QString& in, urls) + ret += QStringLiteral("%1").arg(in); + return ret; +} + +void PackageKitResource::updateDetail(const QString& /*packageID*/, const QStringList& updates, const QStringList& obsoletes, const QStringList& vendorUrls, + const QStringList& /*bugzillaUrls*/, const QStringList& /*cveUrls*/, PackageKit::Transaction::Restart restart, const QString& updateText, + const QString& changelog, PackageKit::Transaction::UpdateState state, const QDateTime& /*issued*/, const QDateTime& /*updated*/) +{ + QString info; + addIfNotEmpty(i18n("Reason:"), updateText, info); + addIfNotEmpty(i18n("Obsoletes:"), joinPackages(obsoletes), info); + addIfNotEmpty(i18n("Updates:"), joinPackages(updates), info); + addIfNotEmpty(i18n("Change Log:"), changelog, info); + addIfNotEmpty(i18n("Update State:"), PackageKitMessages::updateStateMessage(state), info); + addIfNotEmpty(i18n("Restart:"), PackageKitMessages::restartMessage(restart), info); + + if (!vendorUrls.isEmpty()) + addIfNotEmpty(i18n("Vendor:"), urlToLinks(vendorUrls).join(QStringLiteral(", ")), info); + + emit changelogFetched(info); +} + +PackageKitBackend* PackageKitResource::backend() const +{ + return qobject_cast(parent()); +} + diff --git a/libdiscover/backends/PackageKitBackend/PackageKitResource.h b/libdiscover/backends/PackageKitBackend/PackageKitResource.h new file mode 100644 index 0000000..c3d96d4 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitResource.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright © 2012 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef PACKAGEKITRESOURCE_H +#define PACKAGEKITRESOURCE_H + +#include +#include +#include + +class PackageKitBackend; + +class PackageKitResource : public AbstractResource +{ + Q_OBJECT + public: + explicit PackageKitResource(QString packageName, QString summary, PackageKitBackend* parent); + QString packageName() const override; + QString name() override; + QString comment() override; + QString longDescription() override; + QUrl homepage() override; + QVariant icon() const override; + QStringList categories() override; + QString license() override; + QString origin() const override; + QString section() override; + bool isTechnical() const override; + int size() override; + void fetchChangelog() override; + + QList addonsInformation() override; + State state() override; + + QUrl screenshotUrl() override; + QUrl thumbnailUrl() override; + + QString installedVersion() const override; + QString availableVersion() const override; + virtual QStringList allPackageNames() const; + QString installedPackageId() const; + QString availablePackageId() const; + + void clearPackageIds() { m_packages.clear(); } + + QMap packages() const { return m_packages; } + + PackageKitBackend* backend() const; + + static QString joinPackages(const QStringList& pkgids); + + public Q_SLOTS: + void addPackageId(PackageKit::Transaction::Info info, const QString &packageId, bool arch); + void setDetails(const PackageKit::Details& details); + + void updateDetail(const QString &packageID, + const QStringList &updates, + const QStringList &obsoletes, + const QStringList &vendorUrls, + const QStringList &bugzillaUrls, + const QStringList &cveUrls, + PackageKit::Transaction::Restart restart, + const QString &updateText, + const QString &changelog, + PackageKit::Transaction::UpdateState state, + const QDateTime &issued, + const QDateTime &updated); + + private Q_SLOTS: + void failedFetchingDetails(PackageKit::Transaction::Error, const QString& msg); + + private: + /** fetches details individually, it's better if done in batch, like for updates */ + void fetchDetails(); + + QMap m_packages; + const QString m_summary; + const QString m_name; + PackageKit::Details m_details; +}; + +#endif // PACKAGEKITRESOURCE_H diff --git a/libdiscover/backends/PackageKitBackend/PackageKitSourcesBackend.cpp b/libdiscover/backends/PackageKitBackend/PackageKitSourcesBackend.cpp new file mode 100644 index 0000000..945d51e --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitSourcesBackend.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + * Copyright © 2016 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#include "PackageKitSourcesBackend.h" +#include +#include +#include +#include +#include + +class PKSourcesModel : public QStandardItemModel +{ +public: + PKSourcesModel(PackageKitSourcesBackend* backend) + : QStandardItemModel(backend) + , m_backend(backend) {} + + QHash roleNames() const override + { + auto roles = QStandardItemModel::roleNames(); + roles[Qt::CheckStateRole] = "checked"; + return roles; + } + + bool setData(const QModelIndex & index, const QVariant & value, int role) override { + auto item = itemFromIndex(index); + if (!item) + return false; + + switch(role) { + case Qt::CheckStateRole: { + auto transaction = PackageKit::Daemon::global()->repoEnable(item->text(), value.toInt() == Qt::Checked); + connect(transaction, &PackageKit::Transaction::errorCode, m_backend, &PackageKitSourcesBackend::transactionError); + return true; + } + } + item->setData(value, role); + return true; + } + +private: + PackageKitSourcesBackend* m_backend; +}; + +PackageKitSourcesBackend::PackageKitSourcesBackend(QObject* parent) + : AbstractSourcesBackend(parent) + , m_sources(new PKSourcesModel(this)) +{ + connect(PackageKit::Daemon::global(), &PackageKit::Daemon::repoListChanged, this, &PackageKitSourcesBackend::resetSources); + resetSources(); +} + +QString PackageKitSourcesBackend::name() const +{ + return i18n("Software Management"); +} + +QString PackageKitSourcesBackend::idDescription() +{ + return i18n("Repository description:"); +} + +QStandardItem* PackageKitSourcesBackend::findItemForId(const QString &id) const +{ + for(int i=0, c=m_sources->rowCount(); iitem(i); + if (it->text() == id) + return it; + } + return nullptr; +} + +void PackageKitSourcesBackend::addRepositoryDetails(const QString &id, const QString &description, bool enabled) +{ + bool add = false; + QStandardItem* item = findItemForId(id); + + if (!item) { + item = new QStandardItem; + item->setText(id); + add = true; + } + item->setData(description, Qt::ToolTipRole); + item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked); + + if (add) + m_sources->appendRow(item); +} + +QAbstractItemModel * PackageKitSourcesBackend::sources() +{ + return m_sources; +} + +bool PackageKitSourcesBackend::addSource(const QString& /*id*/) +{ + return false; +} + +bool PackageKitSourcesBackend::removeSource(const QString& id) +{ + auto transaction = PackageKit::Daemon::global()->repoRemove(id, false); + connect(transaction, &PackageKit::Transaction::errorCode, this, &PackageKitSourcesBackend::transactionError); + return false; +} + +QList PackageKitSourcesBackend::actions() const +{ + return {}; +} + +void PackageKitSourcesBackend::resetSources() +{ + m_sources->clear(); + auto transaction = PackageKit::Daemon::global()->getRepoList(); + connect(transaction, &PackageKit::Transaction::repoDetail, this, &PackageKitSourcesBackend::addRepositoryDetails); + connect(transaction, &PackageKit::Transaction::errorCode, this, &PackageKitSourcesBackend::transactionError); +} + +void PackageKitSourcesBackend::transactionError(PackageKit::Transaction::Error error, const QString& message) +{ + Q_EMIT passiveMessage(message); + qWarning() << "Transaction error: " << error << message << sender(); +} diff --git a/libdiscover/backends/PackageKitBackend/PackageKitSourcesBackend.h b/libdiscover/backends/PackageKitBackend/PackageKitSourcesBackend.h new file mode 100644 index 0000000..1da6763 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitSourcesBackend.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright © 2016 Aleix Pol Gonzalez * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef PACKAGEKITSOURCESBACKEND_H +#define PACKAGEKITSOURCESBACKEND_H + +#include +#include + +class QStandardItem; +class PKSourcesModel; + +class PackageKitSourcesBackend : public AbstractSourcesBackend +{ + Q_OBJECT + public: + PackageKitSourcesBackend(QObject* parent); + + QString name() const; + QString idDescription(); + + bool addSource(const QString& id); + bool removeSource(const QString& id); + + QAbstractItemModel* sources(); + QList actions() const; + + void transactionError(PackageKit::Transaction::Error, const QString& message); + + private: + void resetSources(); + void addRepositoryDetails(const QString &id, const QString &description, bool enabled); + QStandardItem* findItemForId(const QString &id) const; + + PKSourcesModel* m_sources; +}; + +#endif // PACKAGEKITSOURCESBACKEND_H diff --git a/libdiscover/backends/PackageKitBackend/PackageKitUpdater.cpp b/libdiscover/backends/PackageKitBackend/PackageKitUpdater.cpp new file mode 100644 index 0000000..71901e7 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitUpdater.cpp @@ -0,0 +1,360 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#include "PackageKitUpdater.h" +#include "PackageKitMessages.h" + +#include +#include +#include +#include +#include + +#include +#include + +PackageKitUpdater::PackageKitUpdater(PackageKitBackend * parent) + : AbstractBackendUpdater(parent), + m_transaction(nullptr), + m_backend(parent), + m_isCancelable(false), + m_isProgressing(false), + m_speed(0), + m_remainingTime(0), + m_percentage(0), + m_lastUpdate() +{ + fetchLastUpdateTime(); +} + +PackageKitUpdater::~PackageKitUpdater() +{ + delete m_transaction; +} + +void PackageKitUpdater::prepare() +{ + Q_ASSERT(!m_transaction); + m_toUpgrade = m_backend->upgradeablePackages(); + m_allUpgradeable = m_toUpgrade; +} + +void PackageKitUpdater::setupTransaction(PackageKit::Transaction::TransactionFlags flags) +{ + m_packagesRemoved.clear(); + m_transaction = PackageKit::Daemon::updatePackages(involvedPackages(m_toUpgrade).toList(), flags); + m_isCancelable = m_transaction->allowCancel(); + + connect(m_transaction.data(), &PackageKit::Transaction::finished, this, &PackageKitUpdater::finished); + connect(m_transaction.data(), &PackageKit::Transaction::package, this, &PackageKitUpdater::packageResolved); + connect(m_transaction.data(), &PackageKit::Transaction::errorCode, this, &PackageKitUpdater::errorFound); + connect(m_transaction.data(), &PackageKit::Transaction::message, this, &PackageKitUpdater::printMessage); + connect(m_transaction.data(), &PackageKit::Transaction::mediaChangeRequired, this, &PackageKitUpdater::mediaChange); + connect(m_transaction.data(), &PackageKit::Transaction::requireRestart, this, &PackageKitUpdater::requireRestart); + connect(m_transaction.data(), &PackageKit::Transaction::eulaRequired, this, &PackageKitUpdater::eulaRequired); + connect(m_transaction.data(), &PackageKit::Transaction::statusChanged, this, &PackageKitUpdater::statusChanged); + connect(m_transaction.data(), &PackageKit::Transaction::speedChanged, this, &PackageKitUpdater::speedChanged); + connect(m_transaction.data(), &PackageKit::Transaction::allowCancelChanged, this, &PackageKitUpdater::cancellableChanged); + connect(m_transaction.data(), &PackageKit::Transaction::remainingTimeChanged, this, &PackageKitUpdater::remainingTimeChanged); + connect(m_transaction.data(), &PackageKit::Transaction::percentageChanged, this, &PackageKitUpdater::percentageChanged); + connect(m_transaction.data(), &PackageKit::Transaction::itemProgress, this, &PackageKitUpdater::itemProgress); +} + +QSet PackageKitUpdater::packagesForPackageId(const QSet& pkgids) const +{ + QSet packages; + packages.reserve(pkgids.size()); + foreach(const QString& pkgid, pkgids) { + packages += PackageKit::Daemon::packageName(pkgid); + } + + QSet ret; + foreach (AbstractResource * res, m_allUpgradeable) { + PackageKitResource* pres = qobject_cast(res); + if (packages.contains(pres->allPackageNames().toSet())) { + ret.insert(res); + } + } + + return ret; +} + +QSet PackageKitUpdater::involvedPackages(const QSet& packages) const +{ + QSet packageIds; + packageIds.reserve(packages.size()); + foreach (AbstractResource * res, packages) { + PackageKitResource * app = qobject_cast(res); + QString pkgid = m_backend->upgradeablePackageId(app); + packageIds.insert(pkgid); + } + return packageIds; +} + +void PackageKitUpdater::start() +{ + Q_ASSERT(!isProgressing()); + + setupTransaction(PackageKit::Transaction::TransactionFlagSimulate); + setProgressing(true); +} + +void PackageKitUpdater::finished(PackageKit::Transaction::Exit exit, uint /*time*/) +{ +// qDebug() << "update finished!" << exit << time; + if (exit == PackageKit::Transaction::ExitEulaRequired) + return; + const bool cancel = exit == PackageKit::Transaction::ExitCancelled; + const bool simulate = m_transaction->transactionFlags() & PackageKit::Transaction::TransactionFlagSimulate; + + disconnect(m_transaction, nullptr, this, nullptr); + m_transaction = nullptr; + + if (!cancel && simulate) { + int ret = m_packagesRemoved.isEmpty() ? QMessageBox::Yes : QMessageBox::question(nullptr, PackageKitMessages::statusMessage(PackageKit::Transaction::StatusRemove), PackageKitResource::joinPackages(m_packagesRemoved), QMessageBox::Yes, QMessageBox::No); + if (ret == QMessageBox::Yes) { + setupTransaction(PackageKit::Transaction::TransactionFlagOnlyTrusted); + return; + } + } + + setProgressing(false); + m_backend->refreshDatabase(); + fetchLastUpdateTime(); +} + +void PackageKitUpdater::cancellableChanged() +{ + if (m_isCancelable != m_transaction->allowCancel()) { + m_isCancelable = m_transaction->allowCancel(); + emit cancelableChanged(m_isCancelable); + } +} + +void PackageKitUpdater::percentageChanged() +{ + if (m_percentage != m_transaction->percentage()) { + m_percentage = m_transaction->percentage(); + emit progressChanged(m_percentage); + } +} + +void PackageKitUpdater::remainingTimeChanged() +{ + if (m_remainingTime != m_transaction->remainingTime()) { + m_remainingTime = m_transaction->remainingTime(); + emit remainingTimeChanged(); + } +} + +void PackageKitUpdater::speedChanged() +{ + if (m_speed != m_transaction->speed()) { + m_speed = m_transaction->speed(); + emit downloadSpeedChanged(m_speed); + } +} + +void PackageKitUpdater::statusChanged() +{ + if (m_status != m_transaction->status()) { + m_status = m_transaction->status(); + m_statusMessage = PackageKitMessages::statusMessage(m_status); + m_statusDetail = PackageKitMessages::statusDetail(m_status); + + emit statusMessageChanged(m_statusMessage); + emit statusDetailChanged(m_statusDetail); + } +} + +bool PackageKitUpdater::hasUpdates() const +{ + return m_backend->updatesCount() > 0; +} + +qreal PackageKitUpdater::progress() const +{ + return m_percentage; +} + +/** proposed ETA in milliseconds */ +long unsigned int PackageKitUpdater::remainingTime() const +{ + return m_remainingTime; +} + +void PackageKitUpdater::removeResources(const QList& apps) +{ + QSet pkgs = involvedPackages(apps.toSet()); + m_toUpgrade.subtract(packagesForPackageId(pkgs)); +} + +void PackageKitUpdater::addResources(const QList& apps) +{ + QSet pkgs = involvedPackages(apps.toSet()); + m_toUpgrade.unite(packagesForPackageId(pkgs)); +} + +QList PackageKitUpdater::toUpdate() const +{ + return m_toUpgrade.toList(); +} + +bool PackageKitUpdater::isMarked(AbstractResource* res) const +{ + return m_toUpgrade.contains(res); +} + +QDateTime PackageKitUpdater::lastUpdate() const +{ + return m_lastUpdate; +} + +bool PackageKitUpdater::isCancelable() const +{ + return m_isCancelable; +} + +bool PackageKitUpdater::isProgressing() const +{ + return m_isProgressing; +} + +QString PackageKitUpdater::statusMessage() const +{ + return m_statusMessage; +} + +QString PackageKitUpdater::statusDetail() const +{ + return m_statusDetail; +} + +quint64 PackageKitUpdater::downloadSpeed() const +{ + return m_speed; +} + +void PackageKitUpdater::cancel() +{ + m_transaction->cancel(); +} + +void PackageKitUpdater::errorFound(PackageKit::Transaction::Error err, const QString& error) +{ + Q_UNUSED(error); + if (err == PackageKit::Transaction::ErrorNoLicenseAgreement) + return; + Q_EMIT passiveMessage(QStringLiteral("%1\n%2").arg(PackageKitMessages::errorMessage(err), error)); + qWarning() << "Error happened" << err << error; +} + +void PackageKitUpdater::printMessage(PackageKit::Transaction::Message type, const QString &message) +{ + qDebug() << "message" << type << message; +} + +void PackageKitUpdater::mediaChange(PackageKit::Transaction::MediaType media, const QString& type, const QString& text) +{ + Q_UNUSED(media) + Q_EMIT passiveMessage(i18n("Media Change of type '%1' is requested.\n%2", type, text)); +} + +void PackageKitUpdater::requireRestart(PackageKit::Transaction::Restart restart, const QString& pkgid) +{ + Q_EMIT passiveMessage(PackageKitMessages::restartMessage(restart, pkgid)); +} + +void PackageKitUpdater::eulaRequired(const QString& eulaID, const QString& packageID, const QString& vendor, const QString& licenseAgreement) +{ + QString packageName = PackageKit::Daemon::packageName(packageID); + int ret = QMessageBox::question(nullptr, i18n("%1 requires user to accept its license", packageName), i18n("The package %1 and its vendor %2 require that you accept their license:\n %3", + packageName, vendor, licenseAgreement), QMessageBox::Yes, QMessageBox::No); + if (ret == QMessageBox::Yes) { + PackageKit::Transaction* t = PackageKit::Daemon::acceptEula(eulaID); + connect(t, &PackageKit::Transaction::finished, this, &PackageKitUpdater::start); + } else { + finished(PackageKit::Transaction::ExitCancelled, 0); + } +} + +void PackageKitUpdater::setProgressing(bool progressing) +{ + if (m_isProgressing != progressing) { + m_isProgressing = progressing; + emit progressingChanged(m_isProgressing); + } +} + +void PackageKitUpdater::fetchLastUpdateTime() +{ + QDBusPendingReply transaction = PackageKit::Daemon::global()->getTimeSinceAction(PackageKit::Transaction::RoleGetUpdates); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(transaction, this); + connect(watcher, &QDBusPendingCallWatcher::finished, this, &PackageKitUpdater::lastUpdateTimeReceived); +} + +void PackageKitUpdater::lastUpdateTimeReceived(QDBusPendingCallWatcher* w) +{ + QDBusPendingReply reply = w->reply(); + if (reply.isError()) { + qWarning() << "Error when fetching the last update time" << reply.error(); + } else { + m_lastUpdate = QDateTime::currentDateTime().addSecs(-int(reply.value())); + } + w->deleteLater(); +} + +void PackageKitUpdater::itemProgress(const QString& itemID, PackageKit::Transaction::Status /*status*/, uint percentage) +{ + auto res = packagesForPackageId({itemID}); + + foreach(auto r, res) { + Q_EMIT resourceProgressed(r, percentage); + } +} + +void PackageKitUpdater::fetchChangelog() const +{ + QStringList pkgids; + foreach(AbstractResource* res, m_allUpgradeable) { + pkgids += static_cast(res)->availablePackageId(); + } + Q_ASSERT(!pkgids.isEmpty()); + + PackageKit::Transaction* t = PackageKit::Daemon::getUpdatesDetails(pkgids); + connect(t, &PackageKit::Transaction::updateDetail, this, &PackageKitUpdater::updateDetail); + connect(t, &PackageKit::Transaction::errorCode, this, &PackageKitUpdater::errorFound); +} + +void PackageKitUpdater::updateDetail(const QString& packageID, const QStringList& updates, const QStringList& obsoletes, const QStringList& vendorUrls, + const QStringList& bugzillaUrls, const QStringList& cveUrls, PackageKit::Transaction::Restart restart, const QString& updateText, + const QString& changelog, PackageKit::Transaction::UpdateState state, const QDateTime& issued, const QDateTime& updated) +{ + auto res = packagesForPackageId({packageID}); + foreach(auto r, res) { + static_cast(r)->updateDetail(packageID, updates, obsoletes, vendorUrls, bugzillaUrls, + cveUrls, restart, updateText, changelog, state, issued, updated); + } +} + +void PackageKitUpdater::packageResolved(PackageKit::Transaction::Info info, const QString& packageId) +{ + if (info == PackageKit::Transaction::InfoRemoving) + m_packagesRemoved << packageId; +} diff --git a/libdiscover/backends/PackageKitBackend/PackageKitUpdater.h b/libdiscover/backends/PackageKitBackend/PackageKitUpdater.h new file mode 100644 index 0000000..507210a --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/PackageKitUpdater.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * Copyright © 2013 Lukas Appelhans * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License or (at your option) version 3 or any later version * + * accepted by the membership of KDE e.V. (or its successor approved * + * by the membership of KDE e.V.), which shall act as a proxy * + * defined in Section 14 of version 3 of the license. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ +#ifndef PACKAGEKITUPDATER_H +#define PACKAGEKITUPDATER_H + +#include +#include "PackageKitBackend.h" +#include + +class PackageKitUpdater : public AbstractBackendUpdater +{ + Q_OBJECT + public: + PackageKitUpdater(PackageKitBackend * parent = nullptr); + ~PackageKitUpdater() override; + + void prepare() override; + + bool hasUpdates() const override; + qreal progress() const override; + + void setProgressing(bool progressing); + + /** proposed ETA in milliseconds */ + long unsigned int remainingTime() const override; + + void removeResources(const QList& apps) override; + void addResources(const QList& apps) override; + QList toUpdate() const override; + bool isMarked(AbstractResource* res) const override; + QDateTime lastUpdate() const override; + bool isCancelable() const override; + bool isProgressing() const override; + void fetchChangelog() const override; + + QString statusMessage() const override; + QString statusDetail() const override; + quint64 downloadSpeed() const override; + + public Q_SLOTS: + ///must be implemented if ever isCancelable is true + void cancel() override; + void start() override; + + private Q_SLOTS: + void errorFound(PackageKit::Transaction::Error err, const QString& error); + void mediaChange(PackageKit::Transaction::MediaType media, const QString& type, const QString& text); + void requireRestart(PackageKit::Transaction::Restart restart, const QString& p); + void eulaRequired(const QString &eulaID, const QString &packageID, const QString &vendor, const QString &licenseAgreement); + void finished(PackageKit::Transaction::Exit exit, uint); + void statusChanged(); + void speedChanged(); + void cancellableChanged(); + void remainingTimeChanged(); + void percentageChanged(); + void printMessage(PackageKit::Transaction::Message type, const QString &message); + void updateDetail(const QString& packageID, const QStringList& updates, const QStringList& obsoletes, const QStringList& vendorUrls, + const QStringList& bugzillaUrls, const QStringList& cveUrls, PackageKit::Transaction::Restart restart, const QString& updateText, + const QString& changelog, PackageKit::Transaction::UpdateState state, const QDateTime& issued, const QDateTime& updated); + void packageResolved(PackageKit::Transaction::Info info, const QString& packageId); + + private: + void itemProgress(const QString &itemID, PackageKit::Transaction::Status status, uint percentage); + void fetchLastUpdateTime(); + void lastUpdateTimeReceived(QDBusPendingCallWatcher* w); + void setupTransaction(PackageKit::Transaction::TransactionFlags flags); + QSet involvedPackages(const QSet& packages) const; + QSet packagesForPackageId(const QSet& packages) const; + + QPointer m_transaction; + PackageKitBackend * const m_backend; + QSet m_toUpgrade; + QSet m_allUpgradeable; + bool m_isCancelable; + bool m_isProgressing; + PackageKit::Transaction::Status m_status; + QString m_statusMessage; + QString m_statusDetail; + quint64 m_speed; + long unsigned int m_remainingTime; + uint m_percentage; + QDateTime m_lastUpdate; + QStringList m_packagesRemoved; +}; + + +#endif diff --git a/libdiscover/backends/PackageKitBackend/categoryimages/CMakeLists.txt b/libdiscover/backends/PackageKitBackend/categoryimages/CMakeLists.txt new file mode 100644 index 0000000..aa72a70 --- /dev/null +++ b/libdiscover/backends/PackageKitBackend/categoryimages/CMakeLists.txt @@ -0,0 +1,18 @@ +install( FILES + educationcrop.jpg + fontcrop.jpg + gamecrop.jpg + graphiccrop.jpg +# multimedia2.jpg + multimediacrop.jpg +# music.jpe + officecrop.jpg + sciencecrop.jpg + accesscropped.jpg + toolcrop.jpg + accesscropped.jpg + accessoriescrop.jpg + applicationcrop.jpg + internetcrop.jpg + settingscrop.jpg + DESTINATION ${KDE_INSTALL_FULL_DATAROOTDIR}/discover/pkcategories) diff --git a/libdiscover/backends/PackageKitBackend/categoryimages/accesscropped.jpg b/libdiscover/backends/PackageKitBackend/categoryimages/accesscropped.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dacf9eb0f49d4dd3d04fe561870fdcabaefdec59 GIT binary patch literal 804054 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

My6i^KF)_J@X;ABE8>xy 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 literal 0 HcmV?d00001 diff --git a/discover/icons/updatescrop.jpg b/discover/icons/updatescrop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7d4ceb646e794c4b6d0515691bf5dbbdae28cffe GIT binary patch literal 271389 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Ⓢu{SbBud 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