Skip to content

Instantly share code, notes, and snippets.

@Zren
Created July 17, 2020 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Zren/8b84ffbb540e7e1bda788dcfca11c074 to your computer and use it in GitHub Desktop.
Save Zren/8b84ffbb540e7e1bda788dcfca11c074 to your computer and use it in GitHub Desktop.
import QtQuick 2.0
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.1
import org.kde.plasma.core 2.0 as PlasmaCore
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.draganddrop 2.0 as DragAndDrop
import org.kde.plasma.private.kicker 0.1 as Kicker
Item {
id: appsModel
property alias rootModel: rootModel
property alias appsCategorically: appsCategorically
property alias appsAlphabetically: appsAlphabetically
QtObject {
id: dummyAppletInterface
property var configuration: { return {} }
// This is to avoid a crash when plasmoid doesn't exist.
// https://github.com/KDE/plasma-desktop/blob/master/applets/kicker/plugin/appsmodel.cpp#L542
// Another crash happens when we fetch an app's actionList, but there's no workarounds.
// https://github.com/KDE/plasma-desktop/blob/6e1ca08eb9b431994e97571678dbc9b918284629/applets/kicker/plugin/appentry.cpp#L179
// https://github.com/KDE/plasma-desktop/blob/fc24edd139dd8e75a58b9f6b560a3752ad9452be/applets/kicker/plugin/actionlist.cpp#L139
// https://github.com/KDE/plasma-desktop/blob/6965f2a434b8e9a72170b7806026ebbf8a5473df/applets/kicker/plugin/containmentinterface.cpp#L51
}
property bool useDummyAppletInterface: true
Kicker.RootModel {
id: rootModel
appNameFormat: 0 // plasmoid.configuration.appNameFormat
property bool alphabetical: true
flat: false // isDash ? true : plasmoid.configuration.limitDepth
showSeparators: false // !isDash
appletInterface: typeof plasmoid !== "undefined" ? plasmoid : dummyAppletInterface
// showAllSubtree: true //isDash (KDE 5.8 and below)
showAllApps: false //isDash (KDE 5.9+)
showRecentApps: false //plasmoid.configuration.showRecentApps
showRecentDocs: false //plasmoid.configuration.showRecentDocs
showRecentContacts: false //plasmoid.configuration.showRecentContacts
autoPopulate: false // (KDE 5.9+) defaulted to true
// paginate: false // (KDE 5.9+)
property bool loaded: false
onRefreshed: {
loaded = true
var path = [0,0,0]
// console.log(path, getAppByPath(path).display)
}
Component.onCompleted: {
refresh()
}
}
function getAppByPath(path) {
var parentModel = rootModel
var app = {}
for (var depth = 0; depth < path.length; depth++) {
var depthIndex = path[depth].index
if (depth == path.length - 1) {
var modelIndex = parentModel.index(depthIndex, 0)
var app = {}
app.favoriteId = parentModel.data(modelIndex, Qt.UserRole + 3)
app.display = parentModel.data(modelIndex, Qt.DisplayRole)
app.decoration = parentModel.data(modelIndex, Qt.DecorationRole)
app.description = parentModel.data(modelIndex, Qt.UserRole + 1)
app.group = parentModel.data(modelIndex, Qt.UserRole + 2)
app.url = parentModel.data(modelIndex, Qt.UserRole + 10)
return app
} else {
var childModel = parentModel.modelForRow(depthIndex)
parentModel = childModel
console.log(path, depth, childModel, childModel.description)
}
}
return null
}
function getObjByPath(path) {
var parentModel = rootModel
var app = {}
console.log('getObjByPath', getPathIndexArr(path), getPathNameArr(path))
console.log('path.count', path.count)
for (var depth = 0; depth < path.count; depth++) {
var depthIndex = path.get(depth).index
console.log('getObjByPath', getPathIndexArr(path), depth, depthIndex)
if (depth == path.count - 1) {
console.log('depth == path.count - 1', parentModel, depthIndex)
var output = {}
output.parentModel = parentModel
output.index = depthIndex
console.log('output.parentModel', output.parentModel)
console.log('output.index', output.index)
return output
} else {
var childModel = parentModel.modelForRow(depthIndex)
console.log('parentModel = childModel', parentModel, childModel)
parentModel = childModel
}
}
return null
}
function hasActionList(path) {
var obj = getObjByPath(path)
console.log('hasActionList.obj', obj)
console.log('hasActionList.obj.index', obj.index)
var HasActionListRole = Qt.UserRole + 8
var modelIndex = obj.parentModel.index(obj.index, 0)
// var hasActionList = obj.parentModel.data(modelIndex, HasActionListRole)
console.log('hasActionList', hasActionList)
return hasActionList
}
function getActionList(path) {
console.log('getActionList.path', path)
console.log('getActionList.path', getPathIndexArr(path))
console.log('getActionList.path', getPathNameArr(path))
var obj = getObjByPath(path)
console.log('getActionList.obj.parentModel', obj.parentModel)
console.log('getActionList.obj.index', obj.index)
var ActionListRole = Qt.UserRole + 9
var modelIndex = obj.parentModel.index(obj.index, 0)
console.log('getActionList.modelIndex', modelIndex)
var actionList = obj.parentModel.data(modelIndex, ActionListRole)
console.log('getActionList.actionList', actionList)
actionList.forEach(function(actionItem) {
console.log('getActionList', actionList, actionItem)
actionItem.onClicked = function() {
appsModel.triggerIndexAction(path, actionItem.actionId, actionItem.actionArgument)
}
})
return actionList
}
signal itemTriggered()
function triggerPath(path) {
triggerPathAction(path, "", null)
}
function triggerPathAction(path, actionId, actionArgument) {
console.log('triggerPathAction', getPathIndexArr(path), actionId, actionArgument)
var obj = getObjByPath(path)
obj.parentModel.trigger(obj.index, actionId, actionArgument)
itemTriggered()
}
function startsWith(a, b) {
return a.substr(0, b.length) === b
}
function iterApps(parentModel, parentPath, callback) {
for (var i = 0; i < parentModel.count; i++) {
var childModel = parentModel.modelForRow(i)
var modelIndex = parentModel.index(i, 0)
var item = {}
item.display = parentModel.data(modelIndex, Qt.DisplayRole)
item.decoration = parentModel.data(modelIndex, Qt.DecorationRole)
// item.favoriteId = parentModel.data(modelIndex, Qt.UserRole + 3)
// item.description = parentModel.data(modelIndex, Qt.UserRole + 1)
// item.group = parentModel.data(modelIndex, Qt.UserRole + 2)
// item.url = parentModel.data(modelIndex, Qt.UserRole + 10)
var path = parentPath.concat([
{
index: i,
name: item.display,
}
])
if (childModel) {
iterApps(childModel, path, callback)
} else {
callback(path, item, parentModel)
}
}
}
function getPathIndexArr(path) {
var pathArr = []
for (var i = 0; i < path.length; i++) {
pathArr.push(path[i].index)
}
for (var i = 0; i < path.count; i++) {
pathArr.push(path.get(i).index)
}
return pathArr
}
function getPathNameArr(path) {
var pathArr = []
for (var i = 0; i < path.length; i++) {
pathArr.push(path[i].name)
}
for (var i = 0; i < path.count; i++) {
pathArr.push(path.get(i).name)
}
return pathArr
}
function pathStr(path) {
return getPathNameArr(path).join(' / ')
}
function logItem(path, item) {
// var pathStr = ''
// for (var i = 0; i < path.length; i++) {
// if (i > 0) {
// pathStr += '/'
// }
// pathStr +=
// }
console.log(pathStr(path))
}
function test() {
// iterApps(rootModel, [], logItem)
// var itemList = []
// iterApps(rootModel, [], function(path, item) {
// itemList.push({
// name: item.display,
// path: path,
// item: item,
// })
// })
// itemList.sort(function(a, b){
// return
// })
}
Connections {
target: rootModel
onRefreshed: {
appsModel.test()
}
}
Connections {
target: rootModel
onRefreshed: appsCategorically.update()
}
ListModel {
id: appsCategorically
function update() {
clear()
iterApps(rootModel, [], function(path, item, parentModel) {
if (startsWith(parentModel.toString(), 'AppsModel')) {
var firstChar = item.display ? item.display.substr(0, 1) : '?'
if ('0' <= firstChar && firstChar <= '9') {
firstChar = '0-9'
} else {
firstChar = firstChar.toUpperCase()
}
appsCategorically.append({
path: path,
item: item,
name: item.display,
category: pathStr(path.slice(0, path.length - 1)),
firstChar: firstChar,
})
}
})
// for (var i = 0; i < appsAlphabetically.count; i++) {
// var item = appsAlphabetically.get(i)
// console.log(pathStr(item.path))
// }
}
}
PlasmaCore.SortFilterModel {
id: appsAlphabetically
sourceModel: appsCategorically
sortRole: 'name'
sortCaseSensitivity: Qt.CaseInsensitive
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment