[gnome-control-center] printers: Add adjust printer task priority button
- From: Marek Kašík <mkasik src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] printers: Add adjust printer task priority button
- Date: Wed, 10 Nov 2021 15:35:59 +0000 (UTC)
commit 51760441b3291d62757d63b335fde48675fb07c9
Author: zhuyaliang <15132211195 163 com>
Date: Thu Dec 24 13:20:24 2020 +0800
printers: Add adjust printer task priority button
Add a new button to the 'PpJobRow',This button can adjust the priority of tasks in the print queue to
the highest
panels/printers/cc-printers-panel.c | 3 +-
panels/printers/pp-job-row.c | 37 +++++++++++++-
panels/printers/pp-job-row.h | 4 +-
panels/printers/pp-job-row.ui | 18 +++++++
panels/printers/pp-job.c | 98 +++++++++++++++++++++++++++++++++++--
panels/printers/pp-job.h | 21 ++++++++
panels/printers/pp-jobs-dialog.c | 76 ++++++++++++++++++++++++++--
panels/printers/pp-printer.c | 3 +-
8 files changed, 248 insertions(+), 12 deletions(-)
---
diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index 880d5a4a0..9269eec96 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -45,6 +45,7 @@
#include "cc-permission-infobar.h"
#include "cc-util.h"
+#define JOB_DEFAULT_PRIORITY 50
#define RENEW_INTERVAL 500
#define SUBSCRIPTION_DURATION 600
@@ -457,7 +458,7 @@ on_cups_notification (GDBusConnection *connection,
{
g_autoptr(PpJob) job = NULL;
- job = pp_job_new (job_id, NULL, 0, NULL);
+ job = pp_job_new (job_id, NULL, 0, JOB_DEFAULT_PRIORITY, NULL);
pp_job_get_attributes_async (job,
requested_attrs,
cc_panel_get_cancellable (CC_PANEL (self)),
diff --git a/panels/printers/pp-job-row.c b/panels/printers/pp-job-row.c
index 7caa8319b..a165ab1de 100644
--- a/panels/printers/pp-job-row.c
+++ b/panels/printers/pp-job-row.c
@@ -30,6 +30,7 @@ struct _PpJobRow
GtkButton *pause_button;
GtkImage *pause_image;
+ GtkButton *priority_button;
GtkLabel *state_label;
GtkLabel *title_label;
@@ -38,6 +39,13 @@ struct _PpJobRow
G_DEFINE_TYPE (PpJobRow, pp_job_row, GTK_TYPE_LIST_BOX_ROW)
+enum {
+ PRIORITY_CHANGED,
+ LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
static void
pause_cb (PpJobRow *self)
{
@@ -54,6 +62,12 @@ stop_cb (PpJobRow *self)
pp_job_cancel_purge_async (self->job, FALSE);
}
+static void
+priority_cb (PpJobRow *self)
+{
+ g_signal_emit_by_name (self, "priority-changed");
+}
+
static void
pp_job_row_dispose (GObject *object)
{
@@ -76,11 +90,21 @@ pp_job_row_class_init (PpJobRowClass *klass)
gtk_widget_class_bind_template_child (widget_class, PpJobRow, pause_button);
gtk_widget_class_bind_template_child (widget_class, PpJobRow, pause_image);
+ gtk_widget_class_bind_template_child (widget_class, PpJobRow, priority_button);
gtk_widget_class_bind_template_child (widget_class, PpJobRow, state_label);
gtk_widget_class_bind_template_child (widget_class, PpJobRow, title_label);
gtk_widget_class_bind_template_callback (widget_class, pause_cb);
gtk_widget_class_bind_template_callback (widget_class, stop_cb);
+ gtk_widget_class_bind_template_callback (widget_class, priority_cb);
+
+ signals[PRIORITY_CHANGED] =
+ g_signal_new ("priority-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
}
static void
@@ -89,10 +113,17 @@ pp_job_row_init (PpJobRow *self)
gtk_widget_init_template (GTK_WIDGET (self));
}
+PpJob *
+pp_job_row_get_job (PpJobRow *self)
+{
+ return self->job;
+}
+
PpJobRow *
pp_job_row_new (PpJob *job)
{
PpJobRow *self;
+ gboolean status;
g_autofree gchar *state_string = NULL;
self = g_object_new (PP_TYPE_JOB_ROW, NULL);
@@ -138,10 +169,14 @@ pp_job_row_new (PpJob *job)
state_string = g_strdup (C_("print job", "Completed"));
break;
}
-
gtk_label_set_text (self->title_label, pp_job_get_title (job));
gtk_label_set_markup (self->state_label, state_string);
gtk_widget_set_sensitive (GTK_WIDGET (self->pause_button), pp_job_get_auth_info_required (job) == NULL);
+ status = pp_job_priority_get_sensitive (job);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->priority_button), status);
+ if (status)
+ /* Translators: Clicking this button prioritizes printing of this print job */
+ gtk_widget_set_tooltip_text (GTK_WIDGET (self->priority_button), _("Move this job to the top of the
queue"));
gtk_image_set_from_icon_name (self->pause_image,
pp_job_get_state (self->job) == IPP_JOB_HELD ?
"media-playback-start-symbolic" :
"media-playback-pause-symbolic",
diff --git a/panels/printers/pp-job-row.h b/panels/printers/pp-job-row.h
index 9e8b6df79..088d7ffdc 100644
--- a/panels/printers/pp-job-row.h
+++ b/panels/printers/pp-job-row.h
@@ -29,6 +29,8 @@ G_BEGIN_DECLS
#define PP_TYPE_JOB_ROW (pp_job_row_get_type())
G_DECLARE_FINAL_TYPE (PpJobRow, pp_job_row, PP, JOB_ROW, GtkListBoxRow)
-PpJobRow* pp_job_row_new (PpJob *job);
+PpJobRow* pp_job_row_new (PpJob *job);
+
+PpJob* pp_job_row_get_job (PpJobRow *self);
G_END_DECLS
diff --git a/panels/printers/pp-job-row.ui b/panels/printers/pp-job-row.ui
index 50674871e..aa7746ca9 100644
--- a/panels/printers/pp-job-row.ui
+++ b/panels/printers/pp-job-row.ui
@@ -26,6 +26,24 @@
<property name="margin-end">74</property>
</object>
</child>
+ <child>
+ <object class="GtkButton" id="priority_button">
+ <property name="visible">True</property>
+ <property name="margin-left">4</property>
+ <property name="margin-right">4</property>
+ <signal name="clicked" handler="priority_cb" object="PpJobRow" swapped="yes" />
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon-size">2</property>
+ <property name="icon-name">go-top-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
<child>
<object class="GtkButton" id="pause_button">
<property name="visible">True</property>
diff --git a/panels/printers/pp-job.c b/panels/printers/pp-job.c
index 9351ac773..68ceb6be1 100644
--- a/panels/printers/pp-job.c
+++ b/panels/printers/pp-job.c
@@ -47,9 +47,12 @@ struct _PpJob
{
GObject parent_instance;
- gint id;
- gchar *title;
- gint state;
+ gint id;
+ gchar *title;
+ gint state;
+ gint priority;
+ gboolean sensitive;
+
GStrv auth_info_required;
};
@@ -68,13 +71,15 @@ pp_job_cancel_purge_async_dbus_cb (GObject *source_object,
}
PpJob *
-pp_job_new (gint id, const gchar *title, gint state, GStrv auth_info_required)
+pp_job_new (gint id, const gchar *title, gint state, gint priority, GStrv auth_info_required)
{
PpJob *job = g_object_new (pp_job_get_type (), NULL);
job->id = id;
job->title = g_strdup (title);
job->state = state;
+ job->priority = priority;
+ job->sensitive = FALSE;
job->auth_info_required = g_strdupv (auth_info_required);
return job;
@@ -94,6 +99,34 @@ pp_job_get_state (PpJob *self)
return self->state;
}
+void
+pp_job_priority_set_sensitive (PpJob *self,
+ gboolean sensitive)
+{
+ self->sensitive = sensitive;
+}
+
+gboolean
+pp_job_priority_get_sensitive (PpJob *self)
+{
+ g_return_val_if_fail (PP_IS_JOB (self), FALSE);
+ return self->sensitive;
+}
+
+gint
+pp_job_get_priority (PpJob *self)
+{
+ g_return_val_if_fail (PP_IS_JOB (self), -1);
+ return self->priority;
+}
+
+void
+pp_job_set_priority (PpJob *self,
+ gint priority)
+{
+ self->priority = priority;
+}
+
GStrv
pp_job_get_auth_info_required (PpJob *self)
{
@@ -393,3 +426,60 @@ pp_job_authenticate_finish (PpJob *self,
return g_task_propagate_boolean (G_TASK (result), error);
}
+
+static void
+pp_job_set_priority_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ PpJob *self = source_object;
+ gint priority = GPOINTER_TO_INT (task_data);
+ ipp_t *request;
+ gboolean result = TRUE;
+ g_autofree gchar *uri = NULL;
+
+ request = ippNewRequest (IPP_SET_JOB_ATTRIBUTES);
+ uri = g_strdup_printf ("ipp://localhost/jobs/%d", self->id);
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "job-uri", NULL, uri);
+ ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser ());
+
+ ippAddInteger (request, IPP_TAG_JOB, IPP_TAG_INTEGER,
+ "job-priority", priority);
+
+ ippDelete (cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/"));
+
+ if (cupsLastError () > IPP_OK_CONFLICT)
+ {
+ g_warning ("Failed to set job priority: %s", cupsLastErrorString ());
+ result = FALSE;
+ }
+
+ g_task_return_boolean (task, result);
+}
+
+void
+pp_job_set_priority_async (PpJob *self,
+ gint priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_task_data (task, GINT_TO_POINTER (priority), NULL);
+ g_task_run_in_thread (task, pp_job_set_priority_thread);
+}
+
+gboolean
+pp_job_set_priority_finish (PpJob *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
diff --git a/panels/printers/pp-job.h b/panels/printers/pp-job.h
index e99abdf05..b5d734855 100644
--- a/panels/printers/pp-job.h
+++ b/panels/printers/pp-job.h
@@ -32,12 +32,23 @@ G_DECLARE_FINAL_TYPE (PpJob, pp_job, PP, JOB, GObject)
PpJob *pp_job_new (gint id,
const gchar *title,
gint state,
+ gint priority,
GStrv auth_info_required);
const gchar *pp_job_get_title (PpJob *job);
gint pp_job_get_state (PpJob *job);
+gboolean pp_job_priority_get_sensitive (PpJob *job);
+
+void pp_job_priority_set_sensitive (PpJob *job,
+ gboolean sensitive);
+
+gint pp_job_get_priority (PpJob *job);
+
+void pp_job_set_priority (PpJob *job,
+ gint priority);
+
GStrv pp_job_get_auth_info_required (PpJob *job);
void pp_job_set_hold_until_async (PpJob *job,
@@ -66,4 +77,14 @@ gboolean pp_job_authenticate_finish (PpJob *job,
GAsyncResult *result,
GError **error);
+void pp_job_set_priority_async (PpJob *job,
+ gint priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean pp_job_set_priority_finish (PpJob *job,
+ GAsyncResult *result,
+ GError **error);
+
G_END_DECLS
diff --git a/panels/printers/pp-jobs-dialog.c b/panels/printers/pp-jobs-dialog.c
index c47741fd3..6a921df33 100644
--- a/panels/printers/pp-jobs-dialog.c
+++ b/panels/printers/pp-jobs-dialog.c
@@ -70,6 +70,7 @@ struct _PpJobsDialog {
gchar **actual_auth_info_required;
gboolean jobs_filled;
gboolean pop_up_authentication_popup;
+ gint max_priority;
GCancellable *get_jobs_cancellable;
};
@@ -175,11 +176,54 @@ authenticate_popover_update (PpJobsDialog *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->authenticate_button), FALSE);
}
+static void
+pp_job_update_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PpJobsDialog *self = user_data;
+ gboolean result;
+ g_autoptr(GError) error = NULL;
+ PpJob *job = PP_JOB (source_object);
+
+ result = pp_job_set_priority_finish (job, res, &error);
+ if (result)
+ {
+ pp_jobs_dialog_update (self);
+ }
+ else if (error != NULL)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ {
+ g_warning ("Could not set job priority: %s", error->message);
+ }
+ }
+}
+
+static void
+on_priority_changed (PpJobRow *job_row,
+ PpJobsDialog *self)
+{
+ PpJob *job;
+
+ job = pp_job_row_get_job (job_row);
+ pp_job_set_priority_async (job, ++self->max_priority, NULL, pp_job_update_cb, self);
+}
+
static GtkWidget *
create_listbox_row (gpointer item,
gpointer user_data)
{
- return GTK_WIDGET (pp_job_row_new (PP_JOB (item)));
+ PpJobRow *job_row;
+
+ job_row = pp_job_row_new (PP_JOB (item));
+
+ g_signal_connect (job_row,
+ "priority-changed",
+ G_CALLBACK (on_priority_changed),
+ user_data);
+
+ return GTK_WIDGET (job_row);
}
static void
@@ -200,7 +244,11 @@ update_jobs_list_cb (GObject *source_object,
g_autoptr(GPtrArray) jobs;
PpJob *job;
gint num_of_auth_jobs = 0;
+ gint job_priority;
+ guint state;
guint i;
+ gint current_max_value = 1;
+ gint first_unprocessed_job = -1;
g_list_store_remove_all (self->store);
@@ -226,9 +274,31 @@ update_jobs_list_cb (GObject *source_object,
gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->no_jobs_page));
}
+ for (i = 0; i < jobs->len; i++)
+ {
+ job = PP_JOB (g_ptr_array_index (jobs, i));
+ state = pp_job_get_state (job);
+
+ if (state == IPP_JOB_PENDING || state == IPP_JOB_HELD)
+ {
+ if (first_unprocessed_job == -1)
+ {
+ first_unprocessed_job = i;
+ break;
+ }
+ }
+ }
+
for (i = 0; i < jobs->len; i++)
{
job = PP_JOB (g_ptr_array_index (jobs, i));
+ job_priority = pp_job_get_priority (job);
+ pp_job_priority_set_sensitive (job, (pp_job_get_state (job) == IPP_JOB_PENDING ||
+ pp_job_get_state (job) == IPP_JOB_HELD) &&
+ i > first_unprocessed_job);
+
+ if (job_priority >= current_max_value && job_priority != 100)
+ current_max_value = job_priority;
g_list_store_append (self->store, g_object_ref (job));
@@ -240,7 +310,7 @@ update_jobs_list_cb (GObject *source_object,
self->actual_auth_info_required = g_strdupv (pp_job_get_auth_info_required (job));
}
}
-
+ self->max_priority = current_max_value;
if (num_of_auth_jobs > 0)
{
g_autofree gchar *text = NULL;
@@ -409,7 +479,7 @@ pp_jobs_dialog_new (const gchar *printer_name)
cc_list_box_update_header_func, NULL, NULL);
self->store = g_list_store_new (pp_job_get_type ());
gtk_list_box_bind_model (self->jobs_listbox, G_LIST_MODEL (self->store),
- create_listbox_row, NULL, NULL);
+ create_listbox_row, self, NULL);
update_jobs_list (self);
diff --git a/panels/printers/pp-printer.c b/panels/printers/pp-printer.c
index 67720a82b..76d0bfc32 100644
--- a/panels/printers/pp-printer.c
+++ b/panels/printers/pp-printer.c
@@ -304,8 +304,7 @@ get_jobs_thread (GTask *task,
}
}
- job = pp_job_new (jobs[i].id, jobs[i].title, jobs[i].state, auth_info_is_required ? auth_info_required
: NULL);
-
+ job = pp_job_new (jobs[i].id, jobs[i].title, jobs[i].state, jobs[i].priority, auth_info_is_required ?
auth_info_required : NULL);
g_ptr_array_add (array, job);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]