1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-29 07:52:50 -05:00

cups: sync with API changes

This commit is contained in:
bbedward
2025-11-05 16:15:11 -05:00
parent 3702f493f6
commit e75b47c21a
2 changed files with 181 additions and 138 deletions

View File

@@ -12,7 +12,7 @@ PluginComponent {
Ref { Ref {
service: CupsService service: CupsService
} }
ccWidgetIcon: CupsService.cupsAvailable && CupsService.getPrintersNum() > 0 ? "print" : "print_disabled" ccWidgetIcon: CupsService.cupsAvailable && CupsService.getPrintersNum() > 0 ? "print" : "print_disabled"
ccWidgetPrimaryText: I18n.tr("Printers") ccWidgetPrimaryText: I18n.tr("Printers")
ccWidgetSecondaryText: { ccWidgetSecondaryText: {
@@ -28,7 +28,9 @@ PluginComponent {
} }
ccWidgetIsActive: CupsService.cupsAvailable && CupsService.getTotalJobsNum() > 0 ccWidgetIsActive: CupsService.cupsAvailable && CupsService.getTotalJobsNum() > 0
onCcWidgetToggled: {} onCcWidgetToggled: {
}
ccDetailContent: Component { ccDetailContent: Component {
Rectangle { Rectangle {
@@ -66,7 +68,7 @@ PluginComponent {
Column { Column {
spacing: Theme.spacingS spacing: Theme.spacingS
StyledText { StyledText {
text: CupsService.getCurrentPrinterStatePrettyShort() text: CupsService.getCurrentPrinterStatePrettyShort()
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
@@ -74,10 +76,10 @@ PluginComponent {
font.weight: Font.Medium font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
Row { Row {
spacing: Theme.spacingM spacing: Theme.spacingM
Rectangle { Rectangle {
height: 24 height: 24
width: 80 width: 80
@@ -85,18 +87,18 @@ PluginComponent {
color: printerStatusToggle.containsMouse ? Theme.errorHover : Theme.surfaceLight color: printerStatusToggle.containsMouse ? Theme.errorHover : Theme.surfaceLight
visible: true visible: true
opacity: 1.0 opacity: 1.0
Row { Row {
anchors.centerIn: parent anchors.centerIn: parent
spacing: Theme.spacingXS spacing: Theme.spacingXS
DankIcon { DankIcon {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
name: CupsService.getCurrentPrinterState() === "stopped" ? "play_arrow" : "pause" name: CupsService.getCurrentPrinterState() === "stopped" ? "play_arrow" : "pause"
size: Theme.fontSizeSmall + 4 size: Theme.fontSizeSmall + 4
color: Theme.surfaceText color: Theme.surfaceText
} }
StyledText { StyledText {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: CupsService.getCurrentPrinterState() === "stopped" ? I18n.tr("Resume") : I18n.tr("Pause") text: CupsService.getCurrentPrinterState() === "stopped" ? I18n.tr("Resume") : I18n.tr("Pause")
@@ -105,7 +107,7 @@ PluginComponent {
font.weight: Font.Medium font.weight: Font.Medium
} }
} }
MouseArea { MouseArea {
id: printerStatusToggle id: printerStatusToggle
anchors.fill: parent anchors.fill: parent
@@ -122,7 +124,7 @@ PluginComponent {
} }
} }
} }
Rectangle { Rectangle {
height: 24 height: 24
width: 80 width: 80
@@ -130,18 +132,18 @@ PluginComponent {
color: clearJobsToggle.containsMouse ? Theme.errorHover : Theme.surfaceLight color: clearJobsToggle.containsMouse ? Theme.errorHover : Theme.surfaceLight
visible: true visible: true
opacity: 1.0 opacity: 1.0
Row { Row {
anchors.centerIn: parent anchors.centerIn: parent
spacing: Theme.spacingXS spacing: Theme.spacingXS
DankIcon { DankIcon {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
name: "delete_forever" name: "delete_forever"
size: Theme.fontSizeSmall + 4 size: Theme.fontSizeSmall + 4
color: Theme.surfaceText color: Theme.surfaceText
} }
StyledText { StyledText {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: I18n.tr("Jobs") text: I18n.tr("Jobs")
@@ -150,7 +152,7 @@ PluginComponent {
font.weight: Font.Medium font.weight: Font.Medium
} }
} }
MouseArea { MouseArea {
id: clearJobsToggle id: clearJobsToggle
anchors.fill: parent anchors.fill: parent
@@ -265,7 +267,7 @@ PluginComponent {
Layout.fillWidth: true Layout.fillWidth: true
} }
} }
DankActionButton { DankActionButton {
id: cancelJobButton id: cancelJobButton
anchors.right: parent.right anchors.right: parent.right
@@ -274,7 +276,7 @@ PluginComponent {
iconName: "delete" iconName: "delete"
buttonSize: 36 buttonSize: 36
onClicked: { onClicked: {
CupsService.cancelJob(modelData.id) CupsService.cancelJob(CupsService.getSelectedPrinter(), modelData.id)
} }
} }
} }

View File

@@ -1,6 +1,6 @@
pragma Singleton pragma Singleton
pragma ComponentBehavior: Bound pragma ComponentBehavior
import QtQuick import QtQuick
import Quickshell import Quickshell
@@ -9,13 +9,13 @@ import qs.Common
Singleton { Singleton {
id: root id: root
property int refCount: 0 property int refCount: 0
property var printerNames: [] property var printerNames: []
property var printers: [] property var printers: []
property string selectedPrinter: "" property string selectedPrinter: ""
property bool cupsAvailable: false property bool cupsAvailable: false
property bool stateInitialized: false property bool stateInitialized: false
@@ -38,21 +38,21 @@ Singleton {
} }
} }
} }
Connections { Connections {
target: DMSService target: DMSService
enabled: DMSService.isConnected enabled: DMSService.isConnected
function onCupsStateUpdate(data) { function onCupsStateUpdate(data) {
console.log("CupsService: Subscription update received") console.log("CupsService: Subscription update received")
updateState(data) getState()
} }
function onCapabilitiesChanged() { function onCapabilitiesChanged() {
checkDMSCapabilities() checkDMSCapabilities()
} }
} }
function checkDMSCapabilities() { function checkDMSCapabilities() {
if (!DMSService.isConnected) { if (!DMSService.isConnected) {
return return
@@ -71,17 +71,31 @@ Singleton {
} }
function getState() { function getState() {
if (!cupsAvailable) return if (!cupsAvailable)
return
DMSService.sendRequest("cups.getState", null, response => { DMSService.sendRequest("cups.getPrinters", null, response => {
if (response.result) { if (response.result) {
updateState(response.result) updatePrinters(response.result)
} fetchAllJobs()
}) }
})
} }
function updateState(state) { function updatePrinters(printersData) {
printerNames = Object.keys(state.printers) printerNames = printersData.map(p => p.name)
let printersObj = {}
for (var i = 0; i < printersData.length; i++) {
let printer = printersData[i]
printersObj[printer.name] = {
"state": printer.state,
"stateReason": printer.stateReason,
"jobs": []
}
}
printers = printersObj
if (printerNames.length > 0) { if (printerNames.length > 0) {
if (selectedPrinter.length > 0) { if (selectedPrinter.length > 0) {
if (!printerNames.includes(selectedPrinter)) { if (!printerNames.includes(selectedPrinter)) {
@@ -91,13 +105,32 @@ Singleton {
selectedPrinter = printerNames[0] selectedPrinter = printerNames[0]
} }
} }
printers = state.printers
} }
function fetchAllJobs() {
for (var i = 0; i < printerNames.length; i++) {
fetchJobsForPrinter(printerNames[i])
}
}
function fetchJobsForPrinter(printerName) {
const params = {
"printerName": printerName
}
DMSService.sendRequest("cups.getJobs", params, response => {
if (response.result && printers[printerName]) {
let updatedPrinters = Object.assign({}, printers)
updatedPrinters[printerName].jobs = response.result
printers = updatedPrinters
}
})
}
function getSelectedPrinter() { function getSelectedPrinter() {
return selectedPrinter return selectedPrinter
} }
function setSelectedPrinter(printerName) { function setSelectedPrinter(printerName) {
if (printerNames.length > 0) { if (printerNames.length > 0) {
if (printerNames.includes(printerName)) { if (printerNames.includes(printerName)) {
@@ -107,21 +140,24 @@ Singleton {
} }
} }
} }
function getPrintersNum() { function getPrintersNum() {
if (!cupsAvailable) return 0 if (!cupsAvailable)
return 0
return printerNames.length return printerNames.length
} }
function getPrintersNames() { function getPrintersNames() {
if (!cupsAvailable) return [] if (!cupsAvailable)
return []
return printerNames return printerNames
} }
function getTotalJobsNum() { function getTotalJobsNum() {
if (!cupsAvailable) return 0 if (!cupsAvailable)
return 0
var result = 0 var result = 0
for (var i = 0; i < printerNames.length; i++) { for (var i = 0; i < printerNames.length; i++) {
@@ -132,186 +168,191 @@ Singleton {
} }
return result return result
} }
function getCurrentPrinterState() { function getCurrentPrinterState() {
if (!cupsAvailable || !selectedPrinter) return "" if (!cupsAvailable || !selectedPrinter)
return ""
var printer = printers[selectedPrinter] var printer = printers[selectedPrinter]
return printer.state return printer.state
} }
function getCurrentPrinterStatePrettyShort() { function getCurrentPrinterStatePrettyShort() {
if (!cupsAvailable || !selectedPrinter) return "" if (!cupsAvailable || !selectedPrinter)
return ""
var printer = printers[selectedPrinter] var printer = printers[selectedPrinter]
return getPrinterStateTranslation(printer.state) + return getPrinterStateTranslation(printer.state) + " (" + getPrinterStateReasonTranslation(printer.stateReason) + ")"
" (" + getPrinterStateReasonTranslation(printer.stateReason) + ")"
} }
function getCurrentPrinterStatePretty() { function getCurrentPrinterStatePretty() {
if (!cupsAvailable || !selectedPrinter) return "" if (!cupsAvailable || !selectedPrinter)
return ""
var printer = printers[selectedPrinter] var printer = printers[selectedPrinter]
return getPrinterStateTranslation(printer.state) + return getPrinterStateTranslation(printer.state) + " (" + I18n.tr("Reason") + ": " + getPrinterStateReasonTranslation(printer.stateReason) + ")"
" (" + I18n.tr("Reason") + ": " + getPrinterStateReasonTranslation(printer.stateReason) + ")"
} }
function getCurrentPrinterJobs() { function getCurrentPrinterJobs() {
if (!cupsAvailable || !selectedPrinter) return [] if (!cupsAvailable || !selectedPrinter)
return []
return getJobs(selectedPrinter) return getJobs(selectedPrinter)
} }
function getJobs(printerName) { function getJobs(printerName) {
if (!cupsAvailable) return "" if (!cupsAvailable)
return ""
var printer = printers[printerName] var printer = printers[printerName]
return printer.jobs return printer.jobs
} }
function getJobsNum(printerName) { function getJobsNum(printerName) {
if (!cupsAvailable) return 0 if (!cupsAvailable)
return 0
var printer = printers[printerName] var printer = printers[printerName]
return printer.jobs.length return printer.jobs.length
} }
function pausePrinter(printerName) { function pausePrinter(printerName) {
if (!cupsAvailable) return if (!cupsAvailable)
return
const params = { const params = {
printerName: printerName "printerName": printerName
} }
DMSService.sendRequest("cups.pausePrinter", params, response => { DMSService.sendRequest("cups.pausePrinter", params, response => {
if (response.error) { if (response.error) {
ToastService.showError(I18n.tr("Failed to pause printer") + " - " + response.error) ToastService.showError(I18n.tr("Failed to pause printer") + " - " + response.error)
} }
}) })
} }
function resumePrinter(printerName) { function resumePrinter(printerName) {
if (!cupsAvailable) return if (!cupsAvailable)
return
const params = { const params = {
printerName: printerName "printerName": printerName
} }
DMSService.sendRequest("cups.resumePrinter", params, response => { DMSService.sendRequest("cups.resumePrinter", params, response => {
if (response.error) { if (response.error) {
ToastService.showError(I18n.tr("Failed to resume printer") + " - " + response.error) ToastService.showError(I18n.tr("Failed to resume printer") + " - " + response.error)
} }
}) })
} }
function cancelJob(jobid) { function cancelJob(printerName, jobID) {
if (!cupsAvailable) return if (!cupsAvailable)
return
const params = { const params = {
jobid: jobid "printerName": printerName,
"jobID": jobID
} }
DMSService.sendRequest("cups.cancelJob", params, response => { DMSService.sendRequest("cups.cancelJob", params, response => {
if (response.error) { if (response.error) {
ToastService.showError(I18n.tr("Failed to cancel selected job") + " - " + response.error) ToastService.showError(I18n.tr("Failed to cancel selected job") + " - " + response.error)
} } else {
}) fetchJobsForPrinter(printerName)
}
})
} }
function purgeJobs(printerName) { function purgeJobs(printerName) {
if (!cupsAvailable) return if (!cupsAvailable)
return
const params = { const params = {
printerName: printerName "printerName": printerName
} }
DMSService.sendRequest("cups.purgeJobs", params, response => { DMSService.sendRequest("cups.purgeJobs", params, response => {
if (response.error) { if (response.error) {
ToastService.showError(I18n.tr("Failed to cancel all jobs") + " - " + response.error) ToastService.showError(I18n.tr("Failed to cancel all jobs") + " - " + response.error)
} } else {
}) fetchJobsForPrinter(printerName)
}
})
} }
readonly property var states: ({ readonly property var states: ({
"idle": I18n.tr("Idle"), "idle": I18n.tr("Idle"),
"processing": I18n.tr("Processing"), "processing": I18n.tr("Processing"),
"stopped": I18n.tr("Stopped") "stopped": I18n.tr("Stopped")
}) })
readonly property var reasonsGeneral: ({ readonly property var reasonsGeneral: ({
"none": I18n.tr("None"), "none": I18n.tr("None"),
"other": I18n.tr("Other") "other": I18n.tr("Other")
}) })
readonly property var reasonsSupplies: ({ readonly property var reasonsSupplies: ({
"toner-low": I18n.tr("Toner Low"), "toner-low": I18n.tr("Toner Low"),
"toner-empty": I18n.tr("Toner Empty"), "toner-empty": I18n.tr("Toner Empty"),
"marker-supply-low": I18n.tr("Marker Supply Low"), "marker-supply-low": I18n.tr("Marker Supply Low"),
"marker-supply-empty": I18n.tr("Marker Supply Empty"), "marker-supply-empty": I18n.tr("Marker Supply Empty"),
"marker-waste-almost-full": I18n.tr("Marker Waste Almost Full"), "marker-waste-almost-full": I18n.tr("Marker Waste Almost Full"),
"marker-waste-full": I18n.tr("Marker Waste Full") "marker-waste-full": I18n.tr("Marker Waste Full")
}) })
readonly property var reasonsMedia: ({ readonly property var reasonsMedia: ({
"media-low": I18n.tr("Media Low"), "media-low": I18n.tr("Media Low"),
"media-empty": I18n.tr("Media Empty"), "media-empty": I18n.tr("Media Empty"),
"media-needed": I18n.tr("Media Needed"), "media-needed": I18n.tr("Media Needed"),
"media-jam": I18n.tr("Media Jam") "media-jam": I18n.tr("Media Jam")
}) })
readonly property var reasonsParts: ({ readonly property var reasonsParts: ({
"cover-open": I18n.tr("Cover Open"), "cover-open": I18n.tr("Cover Open"),
"door-open": I18n.tr("Door Open"), "door-open": I18n.tr("Door Open"),
"interlock-open": I18n.tr("Interlock Open"), "interlock-open": I18n.tr("Interlock Open"),
"output-tray-missing": I18n.tr("Output Tray Missing"), "output-tray-missing": I18n.tr("Output Tray Missing"),
"output-area-almost-full": I18n.tr("Output Area Almost Full"), "output-area-almost-full": I18n.tr("Output Area Almost Full"),
"output-area-full": I18n.tr("Output Area Full") "output-area-full": I18n.tr("Output Area Full")
}) })
readonly property var reasonsErrors: ({ readonly property var reasonsErrors: ({
"paused": I18n.tr("Paused"), "paused": I18n.tr("Paused"),
"shutdown": I18n.tr("Shutdown"), "shutdown": I18n.tr("Shutdown"),
"connecting-to-device": I18n.tr("Connecting to Device"), "connecting-to-device": I18n.tr("Connecting to Device"),
"timed-out": I18n.tr("Timed Out"), "timed-out": I18n.tr("Timed Out"),
"stopping": I18n.tr("Stopping"), "stopping": I18n.tr("Stopping"),
"stopped-partly": I18n.tr("Stopped Partly") "stopped-partly": I18n.tr("Stopped Partly")
}) })
readonly property var reasonsService: ({ readonly property var reasonsService: ({
"spool-area-full": I18n.tr("Spool Area Full"), "spool-area-full": I18n.tr("Spool Area Full"),
"cups-missing-filter-warning": I18n.tr("CUPS Missing Filter Warning"), "cups-missing-filter-warning": I18n.tr("CUPS Missing Filter Warning"),
"cups-insecure-filter-warning": I18n.tr("CUPS Insecure Filter Warning") "cups-insecure-filter-warning": I18n.tr("CUPS Insecure Filter Warning")
}) })
readonly property var reasonsConnectivity: ({ readonly property var reasonsConnectivity: ({
"offline-report": I18n.tr("Offline Report"), "offline-report": I18n.tr("Offline Report"),
"moving-to-paused": I18n.tr("Moving to Paused") "moving-to-paused": I18n.tr("Moving to Paused")
}) })
readonly property var severitySuffixes: ({ readonly property var severitySuffixes: ({
"-error": I18n.tr("Error"), "-error": I18n.tr("Error"),
"-warning": I18n.tr("Warning"), "-warning": I18n.tr("Warning"),
"-report": I18n.tr("Report") "-report": I18n.tr("Report")
}) })
function getPrinterStateTranslation(state) { function getPrinterStateTranslation(state) {
return states[state] || state return states[state] || state
} }
function getPrinterStateReasonTranslation(reason) { function getPrinterStateReasonTranslation(reason) {
let allReasons = Object.assign({}, let allReasons = Object.assign({}, reasonsGeneral, reasonsSupplies, reasonsMedia, reasonsParts, reasonsErrors, reasonsService, reasonsConnectivity)
reasonsGeneral,
reasonsSupplies,
reasonsMedia,
reasonsParts,
reasonsErrors,
reasonsService,
reasonsConnectivity
)
let basReason = reason let basReason = reason
let suffix = "" let suffix = ""
for (let s in severitySuffixes) { for (let s in severitySuffixes) {
if (reason.endsWith(s)) { if (reason.endsWith(s)) {
basReason = reason.slice(0, -s.length) basReason = reason.slice(0, -s.length)
@@ -319,7 +360,7 @@ Singleton {
break break
} }
} }
let translation = allReasons[basReason] || basReason let translation = allReasons[basReason] || basReason
return suffix ? translation + " (" + suffix + ")" : translation return suffix ? translation + " (" + suffix + ")" : translation
} }