17import QtQuick.Controls as QQC2
20import org.kde.kcmutils as KCMUtils
21import org.kde.kirigami as Kirigami
22import org.kde.newstuff as NewStuff
24import "private" as Private
25import "private/entrygriddelegates" as EntryGridDelegates
36 property alias configFile: newStuffEngine.configFile
38 readonly
property alias engine: newStuffEngine
47 property alias showUploadAction: uploadAction.visible
57 function showEntryDetails(providerId, entryId) {
58 _showEntryDetailsThrottle.enabled =
true;
59 _showEntryDetailsThrottle.entry = newStuffEngine. __createEntry(providerId, entryId);
60 if (newStuffEngine.busyState === NewStuff.Engine.Initializing) {
61 _showEntryDetailsThrottle.queryWhenInitialized =
true;
63 _showEntryDetailsThrottle.requestDetails();
69 id: _showEntryDetailsThrottle
70 target: newStuffModel.engine
74 property bool queryWhenInitialized:
false
76 function requestDetails() {
77 newStuffEngine.updateEntryContents(entry);
78 queryWhenInitialized =
false;
81 function onBusyStateChanged() {
82 if (queryWhenInitialized && newStuffEngine.busyState !== NewStuff.Engine.Initializing) {
84 queryWhenInitialized =
false;
88 function onSignalEntryEvent(changedEntry, event) {
89 if (event === NewStuff.Engine.DetailsLoadedEvent && changedEntry === entry) {
91 pageStack.push(detailsPage, {
93 providerId: changedEntry.providerId,
101 id: _restoreSearchState
106 function onCurrentIndexChanged() {
107 if (pageStack.currentIndex === 0) {
108 newStuffEngine.restoreSearch();
109 _restoreSearchState.enabled =
false;
114 property string uninstallLabel:
i18ndc(
"knewstuff6",
"Request uninstallation of this item",
"Uninstall")
115 property
string useLabel: engine.useLabel
117 property
int viewMode:
Page.ViewMode.Tiles
127 Component.onCompleted: {
128 view.currentIndex = -1;
131 title: newStuffEngine.name
133 headerPaddingEnabled:
false
135 readonly
property bool riskyContent: newStuffEngine.contentWarningType === NewStuff.Engine.Executables
136 visible: !loadingOverlay.visible
138 position:
Kirigami.InlineMessage.Position.Header
140 ?
xi18nd(
"knewstuff6",
"Use caution when accessing user-created content shown here, as it may contain executable code that hasn't been tested by KDE or your distributor for safety, stability, or quality.")
141 :
i18nd(
"knewstuff6",
"User-created content shown here hasn't been tested by KDE or your distributor for functionality or quality.")
149 parent: root.QQC2.Overlay.overlay
152 Private.ErrorDisplayer {
153 engine: newStuffEngine
154 active: root.isCurrentPage
157 QQC2.ActionGroup { id: viewFilterActionGroup }
158 QQC2.ActionGroup { id: viewSortingActionGroup }
162 visible: newStuffEngine.needsLazyLoadSpinner
163 displayComponent: QQC2.BusyIndicator {
171 if (newStuffEngine.filter === 0) {
172 return i18nd(
"knewstuff6",
"Everything");
173 }
else if (newStuffEngine.filter === 1) {
174 return i18nd(
"knewstuff6",
"Installed");
175 }
else if (newStuffEngine.filter === 2) {
176 return i18nd(
"knewstuff6",
"Updateable");
183 if (newStuffEngine.filter === 0) {
184 return "package-available"
185 }
else if (newStuffEngine.filter === 1) {
186 return "package-installed-updated"
187 }
else if (newStuffEngine.filter === 2) {
188 return "package-installed-outdated"
195 icon.name:
"package-available"
196 text:
i18ndc(
"knewstuff6",
"List option which will set the filter to show everything",
"Show All Entries")
198 checked: newStuffEngine.filter === 0
199 onTriggered: source => {
200 newStuffEngine.filter = 0;
202 QQC2.ActionGroup.group: viewFilterActionGroup
206 icon.name:
"package-installed-updated"
207 text:
i18ndc(
"knewstuff6",
"List option which will set the filter so only installed items are shown",
"Show Only Installed Entries")
209 checked: newStuffEngine.filter === 1
210 onTriggered: source => {
211 newStuffEngine.filter = 1;
213 QQC2.ActionGroup.group: viewFilterActionGroup
217 icon.name:
"package-installed-outdated"
218 text:
i18ndc(
"knewstuff6",
"List option which will set the filter so only installed items with updates available are shown",
"Show Only Updateable Entries")
220 checked: newStuffEngine.filter === 2
221 onTriggered: source => {
222 newStuffEngine.filter = 2;
224 QQC2.ActionGroup.group: viewFilterActionGroup
230 if (newStuffEngine.sortOrder === 0) {
231 return i18nd(
"knewstuff6",
"Recent");
232 }
else if (newStuffEngine.sortOrder === 1) {
233 return i18nd(
"knewstuff6",
"Alphabetical");
234 }
else if (newStuffEngine.sortOrder === 2) {
235 return i18nd(
"knewstuff6",
"Rating");
236 }
else if (newStuffEngine.sortOrder === 3) {
237 return i18nd(
"knewstuff6",
"Downloads");
243 if (newStuffEngine.sortOrder === 0) {
244 return "change-date-symbolic";
245 }
else if (newStuffEngine.sortOrder === 1) {
247 }
else if (newStuffEngine.sortOrder === 2) {
249 }
else if (newStuffEngine.sortOrder === 3) {
256 icon.name:
"change-date-symbolic"
257 text:
i18ndc(
"knewstuff6",
"List option which will set the sort order to based on when items were most recently updated",
"Show Most Recent First")
259 checked: newStuffEngine.sortOrder === 0
260 onTriggered: source => {
261 newStuffEngine.sortOrder = 0;
263 QQC2.ActionGroup.group: viewSortingActionGroup
267 icon.name:
"sort-name"
268 text:
i18ndc(
"knewstuff6",
"List option which will set the sort order to be alphabetical based on the name",
"Sort Alphabetically By Name")
270 checked: newStuffEngine.sortOrder === 1
271 onTriggered: source => {
272 newStuffEngine.sortOrder = 1;
274 QQC2.ActionGroup.group: viewSortingActionGroup
279 text:
i18ndc(
"knewstuff6",
"List option which will set the sort order to based on user ratings",
"Show Highest Rated First")
281 checked: newStuffEngine.sortOrder === 2
282 onTriggered: source => {
283 newStuffEngine.sortOrder = 2;
285 QQC2.ActionGroup.group: viewSortingActionGroup
289 icon.name:
"download"
290 text:
i18ndc(
"knewstuff6",
"List option which will set the sort order to based on number of downloads",
"Show Most Downloaded First")
292 checked: newStuffEngine.sortOrder === 3
293 onTriggered: source => {
294 newStuffEngine.sortOrder = 3;
296 QQC2.ActionGroup.group: viewSortingActionGroup
303 text:
i18nd(
"knewstuff6",
"Upload…")
304 tooltip: i18nd("knewstuff6", "Learn how to add your own hot new stuff to this list")
305 icon.name: "upload-media"
306 visible: newStuffEngine.uploadEnabled
308 onTriggered: source => {
309 pageStack.push(uploadPage);
314 text:
i18nd(
"knewstuff6",
"Go to…")
316 id: searchModelActions
317 visible: children.length > 0
321 text:
i18nd(
"knewstuff6",
"Search…")
322 icon.name: "system-search"
323 displayHint:
Kirigami.DisplayHint.KeepVisible
328 enabled: engine.isValid
329 focusSequence:
"Ctrl+F"
330 placeholderText:
i18nd(
"knewstuff6",
"Search…")
331 text: newStuffEngine.searchTerm
334 newStuffEngine.searchTerm = searchField.text;
337 Component.onCompleted: {
338 if (!
Kirigami.InputMethod.willShowOnActive) {
347 id: searchPresetInstatiator
349 model: newStuffEngine.searchPresetModel
352 required
property int index
354 text: model.displayName
355 icon.name: model.iconName
357 onTriggered: source => {
358 const curIndex = newStuffEngine.searchPresetModel.index(index, 0);
359 newStuffEngine.searchPresetModel.loadSearch(curIndex);
363 onObjectAdded: (index, object) => {
364 searchModelActions.children.push(
object);
369 target: newStuffEngine.searchPresetModel
371 function onModelReset() {
372 searchModelActions.children = [];
377 spacing:
Kirigami.Units.smallSpacing
379 visible: visibleChildren.length > 0
380 height: visible ? implicitHeight : 0
383 visible: categoriesCombo.count > 2
384 text:
i18nd(
"knewstuff6",
"Category:")
390 Layout.fillWidth:
true
393 model: newStuffEngine.categories
394 textRole:
"displayName"
396 onCurrentIndexChanged: {
397 newStuffEngine.categoriesFilter = model.
data(model.index(currentIndex, 0), NewStuff.CategoriesModel.NameRole);
402 Layout.alignment:
Qt.AlignRight
404 text:
i18nd(
"knewstuff6",
"Contribute your own…")
405 icon.name: "upload-media"
406 visible: newStuffEngine.uploadEnabled && !uploadAction.visible
409 pageStack.push(uploadPage);
414 view.model: NewStuff.ItemsModel {
417 engine: newStuffEngine
420 NewStuff.DownloadItemsSheet {
421 id: downloadItemsSheet
423 parent: root.QQC2.Overlay.overlay
425 onItemPicked: (entry, downloadItemId) => {
426 newStuffModel.engine.install(entry, downloadItemId);
430 view.implicitCellWidth:
switch (root.viewMode) {
431 case Page.ViewMode.Preview:
432 return Kirigami.Units.gridUnit * 25;
434 case Page.ViewMode.Tiles:
435 case Page.ViewMode.Icons:
437 return Kirigami.Units.gridUnit * 30;
440 view.implicitCellHeight:
switch (root.viewMode) {
441 case Page.ViewMode.Preview:
442 return Kirigami.Units.gridUnit * 25;
444 case Page.ViewMode.Tiles:
445 case Page.ViewMode.Icons:
447 return Math.round(view.implicitCellWidth / 3);
450 view.delegate:
switch (root.viewMode) {
451 case Page.ViewMode.Preview:
452 return bigPreviewDelegate;
454 case Page.ViewMode.Tiles:
455 case Page.ViewMode.Icons:
461 id: bigPreviewDelegate
463 EntryGridDelegates.BigPreviewDelegate { }
469 EntryGridDelegates.TileDelegate {
470 useLabel: root.useLabel
471 uninstallLabel: root.uninstallLabel
478 NewStuff.EntryDetails { }
484 NewStuff.UploadPage {
485 engine: newStuffEngine
494 opacity: newStuffEngine.isLoading && !newStuffEngine.needsLazyLoadSpinner ? 1 : 0
495 Behavior on opacity {
497 duration:
Kirigami.Units.longDuration
505 color:
Kirigami.Theme.backgroundColor
509 anchors.centerIn: parent
510 text: newStuffEngine.busyMessage
KNSCore::EngineBase for interfacing with QML.
A component used to forward questions from KNewStuff's engine to the UI.
QString i18ndc(const char *domain, const char *context, const char *text, const TYPE &arg...)
QString xi18nd(const char *domain, const char *text, const TYPE &arg...)
QString i18nd(const char *domain, const char *text, const TYPE &arg...)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)