[gnome-control-center] printers: Add adjust printer task priority button



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]