[gnome-control-center/wip/feborges/new-printers-panel: 21/21] printers: redesign the Printer Jobs Dialog
- From: Felipe Borges <felipeborges src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/feborges/new-printers-panel: 21/21] printers: redesign the Printer Jobs Dialog
- Date: Wed, 30 Sep 2015 11:30:31 +0000 (UTC)
commit 390d90ee0031b4494677d64f3217a8828df59f71
Author: Felipe Borges <feborges redhat com>
Date: Tue Sep 8 16:55:38 2015 +0200
printers: redesign the Printer Jobs Dialog
Update the Printer Jobs Dialog to match the current designs at
https://wiki.gnome.org/Design/SystemSettings/Printers
https://bugzilla.gnome.org/show_bug.cgi?id=755626
panels/printers/Makefile.am | 2 +
panels/printers/jobs-dialog.ui | 145 +++++-------
panels/printers/pp-job.c | 133 +++++++++++
panels/printers/pp-job.h | 38 +++
panels/printers/pp-jobs-dialog.c | 471 ++++++++++++++------------------------
panels/printers/pp-utils.c | 29 ++-
panels/printers/pp-utils.h | 8 +-
7 files changed, 423 insertions(+), 403 deletions(-)
---
diff --git a/panels/printers/Makefile.am b/panels/printers/Makefile.am
index c386486..7fb2c17 100644
--- a/panels/printers/Makefile.am
+++ b/panels/printers/Makefile.am
@@ -37,6 +37,8 @@ libprinters_la_SOURCES = \
pp-ppd-selection-dialog.h \
pp-options-dialog.c \
pp-options-dialog.h \
+ pp-job.c \
+ pp-job.h \
pp-jobs-dialog.c \
pp-jobs-dialog.h \
pp-authentication-dialog.c \
diff --git a/panels/printers/jobs-dialog.ui b/panels/printers/jobs-dialog.ui
index 6ac05a3..c47381d 100644
--- a/panels/printers/jobs-dialog.ui
+++ b/panels/printers/jobs-dialog.ui
@@ -3,143 +3,110 @@
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkDialog" id="jobs-dialog">
- <property name="width_request">500</property>
- <property name="height_request">350</property>
+ <property name="width_request">600</property>
+ <property name="height_request">500</property>
<property name="can_focus">False</property>
- <property name="border_width">5</property>
- <property name="title" translatable="yes" comments="Translators: This dialog contains list of active
print jobs of the selected printer">Active Jobs</property>
+ <property name="border_width">0</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
- <child internal-child="vbox">
- <object class="GtkBox" id="main-vbox">
+ <property name="use-header-bar">1</property>
+ <child internal-child="headerbar">
+ <object class="GtkHeaderBar" id="dialog-header-bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">vertical</property>
- <property name="spacing">10</property>
- <child internal-child="action_area">
- <object class="GtkButtonBox" id="dialog-action-area1">
+ <property name="show_close_button">True</property>
+ <child>
+ <object class="GtkButton" id="jobs-clear-all-button">
+ <property name="label" translatable="yes">Clear All</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="jobs-close-button">
- <property name="label" translatable="yes">Close</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="valign">center</property>
+ <style>
+ <class name="destructive-action"/>
+ </style>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
</child>
+ </object>
+ </child>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="border_width">0</property>
<child>
- <object class="GtkBox" id="box2">
+ <object class="GtkStack" id="stack">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
- <property name="orientation">vertical</property>
<child>
- <object class="GtkScrolledWindow" id="queue-scrolledwindow">
+ <object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="shadow_type">in</property>
+ <property name="vexpand">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="shadow_type">none</property>
<child>
- <object class="GtkTreeView" id="job-treeview">
+ <object class="GtkListBox" id="jobs-listbox">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <child internal-child="selection">
- <object class="GtkTreeSelection" id="treeview-selection"/>
+ <property name="can-focus">True</property>
+ <property name="halign">fill</property>
+ <property name="valign">fill</property>
+ <property name="selection-mode">none</property>
+ <child>
+ <placeholder/>
</child>
</object>
</child>
</object>
<packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <property name="name">list-jobs-page</property>
</packing>
</child>
<child>
- <object class="GtkToolbar" id="queue-toolbar">
+ <object class="GtkBox" id="no-jobs-dialog">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="icon_size">1</property>
+ <property name="spacing">10</property>
+ <property name="orientation">vertical</property>
+ <property name="valign">center</property>
<child>
- <object class="GtkToolButton" id="job-release-button">
+ <object class="GtkImage" id="no-printer-image">
<property name="visible">True</property>
- <property name="sensitive">False</property>
<property name="can_focus">False</property>
- <property name="label" translatable="yes">Resume Printing</property>
- <property name="use_underline">True</property>
- <property name="icon_name">media-playback-start-symbolic</property>
+ <property name="valign">start</property>
+ <property name="pixel_size">64</property>
+ <property name="icon_name">printer-symbolic</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
</object>
<packing>
<property name="expand">False</property>
- <property name="homogeneous">True</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkToolButton" id="job-hold-button">
+ <object class="GtkLabel" id="no-printer-label">
<property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Pause Printing</property>
- <property name="use_underline">True</property>
- <property name="icon_name">media-playback-pause-symbolic</property>
+ <property name="label" translatable="yes">No Active Printer Jobs</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
</object>
<packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkToolButton" id="job-cancel-button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Cancel Print Job</property>
- <property name="use_underline">True</property>
- <property name="icon_name">media-playback-stop-symbolic</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
+ <property name="position">1</property>
</packing>
</child>
- <style>
- <class name="inline-toolbar"/>
- </style>
</object>
<packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
+ <property name="name">no-jobs-page</property>
</packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
</child>
</object>
</child>
- <action-widgets>
- <action-widget response="0">jobs-close-button</action-widget>
- </action-widgets>
</object>
</interface>
diff --git a/panels/printers/pp-job.c b/panels/printers/pp-job.c
new file mode 100644
index 0000000..cdb8f07
--- /dev/null
+++ b/panels/printers/pp-job.c
@@ -0,0 +1,133 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2015 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Felipe Borges <feborges redhat com>
+ */
+
+#include "pp-job.h"
+
+typedef struct
+{
+ GObject parent;
+
+ gint id;
+ gchar *title;
+ gint state;
+} PpJobPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (PpJob, pp_job, G_TYPE_OBJECT)
+
+enum
+{
+ PROP_0,
+ PROP_ID,
+ PROP_TITLE,
+ PROP_STATE,
+ LAST_PROPERTY
+};
+
+static GParamSpec *properties[LAST_PROPERTY];
+
+static void
+pp_job_init (PpJob *obj)
+{
+}
+
+static void
+job_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PpJobPrivate *priv;
+
+ priv = pp_job_get_instance_private (PP_JOB (object));
+
+ switch (property_id)
+ {
+ case PROP_ID:
+ g_value_set_int (value, priv->id);
+ break;
+ case PROP_TITLE:
+ g_value_set_string (value, priv->title);
+ break;
+ case PROP_STATE:
+ g_value_set_int (value, priv->state);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+job_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PpJobPrivate *priv;
+
+ priv = pp_job_get_instance_private (PP_JOB (object));
+
+ switch (property_id)
+ {
+ case PROP_ID:
+ priv->id = g_value_get_int (value);
+ break;
+ case PROP_TITLE:
+ g_free (priv->title);
+ priv->title = g_value_dup_string (value);
+ break;
+ case PROP_STATE:
+ priv->state = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+job_finalize (GObject *object)
+{
+ PpJobPrivate *priv;
+
+ priv = pp_job_get_instance_private (PP_JOB (object));
+
+ g_free (priv->title);
+
+ G_OBJECT_CLASS (pp_job_parent_class)->finalize (object);
+}
+
+static void
+pp_job_class_init (PpJobClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->get_property = job_get_property;
+ object_class->set_property = job_set_property;
+ object_class->finalize = job_finalize;
+
+ properties[PROP_ID] = g_param_spec_int ("id", "id", "id",
+ 0, G_MAXINT, 0, G_PARAM_READWRITE);
+ properties[PROP_TITLE] = g_param_spec_string ("title", "title", "title",
+ NULL, G_PARAM_READWRITE);
+ properties[PROP_STATE] = g_param_spec_int ("state", "state", "state",
+ 0, G_MAXINT, 0, G_PARAM_READWRITE);
+ g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
+}
diff --git a/panels/printers/pp-job.h b/panels/printers/pp-job.h
new file mode 100644
index 0000000..e42ccf8
--- /dev/null
+++ b/panels/printers/pp-job.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2015 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Felipe Borges <feborges redhat com>
+ */
+
+#ifndef __PP_JOB_H__
+#define __PP_JOB_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define PP_TYPE_JOB (pp_job_get_type ())
+G_DECLARE_FINAL_TYPE (PpJob, pp_job, PP, JOB, GObject)
+
+struct _PpJob
+{
+ GObject parent_instance;
+};
+
+G_END_DECLS
+
+#endif
diff --git a/panels/printers/pp-jobs-dialog.c b/panels/printers/pp-jobs-dialog.c
index 2d8682e..4c3e9b5 100644
--- a/panels/printers/pp-jobs-dialog.c
+++ b/panels/printers/pp-jobs-dialog.c
@@ -31,8 +31,10 @@
#include <cups/cups.h>
+#include "shell/list-box-helper.h"
#include "pp-jobs-dialog.h"
#include "pp-utils.h"
+#include "pp-job.h"
#define EMPTY_TEXT "\xe2\x80\x94"
@@ -46,6 +48,7 @@ struct _PpJobsDialog {
GtkWidget *parent;
GtkWidget *dialog;
+ GtkListBox *listbox;
UserResponseCallback user_callback;
gpointer user_data;
@@ -54,318 +57,189 @@ struct _PpJobsDialog {
cups_job_t *jobs;
gint num_jobs;
- gint current_job_id;
gint ref_count;
};
-enum
+static void
+job_stop_cb (GtkButton *button,
+ gint job_id)
{
- JOB_ID_COLUMN,
- JOB_TITLE_COLUMN,
- JOB_STATE_COLUMN,
- JOB_CREATION_TIME_COLUMN,
- JOB_N_COLUMNS
-};
+ job_cancel_purge_async (job_id,
+ FALSE,
+ NULL,
+ NULL);
+}
static void
-update_jobs_list_cb (cups_job_t *jobs,
- gint num_of_jobs,
- gpointer user_data)
+job_pause_cb (GtkButton *button,
+ gpointer user_data)
{
- GtkTreeSelection *selection;
- PpJobsDialog *dialog = (PpJobsDialog *) user_data;
- GtkListStore *store;
- GtkTreeView *treeview;
- GtkTreeIter select_iter;
- GtkTreeIter iter;
- GSettings *settings;
- gboolean select_iter_set = FALSE;
- gint i;
- gint select_index = 0;
-
- treeview = (GtkTreeView*)
- gtk_builder_get_object (dialog->builder, "job-treeview");
+ PpJob *job = (PpJob *)user_data;
+ gint job_id;
+ gint job_state;
+
+ g_object_get (job,
+ "id", &job_id,
+ "state", &job_state,
+ NULL);
+
+ job_set_hold_until_async (job_id,
+ job_state == IPP_JOB_HELD ? "no-hold" : "indefinite",
+ NULL,
+ NULL);
+
+ gtk_button_set_image (button,
+ gtk_image_new_from_icon_name (job_state == IPP_JOB_HELD ?
+ "media-playback-pause-symbolic" :
"media-playback-start-symbolic",
+ GTK_ICON_SIZE_SMALL_TOOLBAR));
+}
- if (dialog->num_jobs > 0)
- cupsFreeJobs (dialog->num_jobs, dialog->jobs);
+static GtkWidget *
+create_listbox_row (gpointer item,
+ gpointer user_data)
+{
+ PpJob *job = (PpJob *)item;
+ GtkWidget *box;
+ GtkWidget *widget;
+ gchar *state_string;
+ gint *job_id;
+ gint job_state = NULL;
+
+ g_object_get (job,
+ "id", &job_id,
+ "state", &job_state,
+ NULL);
+
+ switch (job_state)
+ {
+ case IPP_JOB_PENDING:
+ /* Translators: Job's state (job is waiting to be printed) */
+ state_string = g_strdup (C_("print job", "Pending"));
+ break;
+ case IPP_JOB_HELD:
+ /* Translators: Job's state (job is held for printing) */
+ state_string = g_strdup (C_("print job", "Paused"));
+ break;
+ case IPP_JOB_PROCESSING:
+ /* Translators: Job's state (job is currently printing) */
+ state_string = g_strdup (C_("print job", "Processing"));
+ break;
+ case IPP_JOB_STOPPED:
+ /* Translators: Job's state (job has been stopped) */
+ state_string = g_strdup (C_("print job", "Stopped"));
+ break;
+ case IPP_JOB_CANCELED:
+ /* Translators: Job's state (job has been canceled) */
+ state_string = g_strdup (C_("print job", "Canceled"));
+ break;
+ case IPP_JOB_ABORTED:
+ /* Translators: Job's state (job has aborted due to error) */
+ state_string = g_strdup (C_("print job", "Aborted"));
+ break;
+ case IPP_JOB_COMPLETED:
+ /* Translators: Job's state (job has completed successfully) */
+ state_string = g_strdup (C_("print job", "Completed"));
+ break;
+ }
- dialog->num_jobs = num_of_jobs;
- dialog->jobs = jobs;
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ g_object_set (box, "margin", 6, NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 2);
- store = gtk_list_store_new (JOB_N_COLUMNS,
- G_TYPE_INT,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING);
+ widget = gtk_label_new ("");
+ g_object_bind_property (job, "title", widget, "label", G_BINDING_SYNC_CREATE);
+ gtk_widget_set_halign (widget, GTK_ALIGN_START);
+ gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 10);
- if (dialog->current_job_id >= 0)
- {
- for (i = 0; i < dialog->num_jobs; i++)
- {
- select_index = i;
- if (dialog->jobs[i].id >= dialog->current_job_id)
- break;
- }
- }
+ widget = gtk_label_new (state_string);
+ gtk_widget_set_halign (widget, GTK_ALIGN_END);
+ gtk_widget_set_margin_end (widget, 64);
+ gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 10);
- for (i = 0; i < dialog->num_jobs; i++)
- {
- GDesktopClockFormat value;
- GDateTime *time;
- struct tm *ts;
- gchar *time_string;
- gchar *state = NULL;
-
- ts = localtime (&(dialog->jobs[i].creation_time));
- time = g_date_time_new_local (ts->tm_year + 1900,
- ts->tm_mon + 1,
- ts->tm_mday,
- ts->tm_hour,
- ts->tm_min,
- ts->tm_sec);
-
- settings = g_settings_new (CLOCK_SCHEMA);
- value = g_settings_get_enum (settings, CLOCK_FORMAT_KEY);
-
- if (value == G_DESKTOP_CLOCK_FORMAT_24H)
- time_string = g_date_time_format (time, "%k:%M");
- else
- time_string = g_date_time_format (time, "%l:%M %p");
-
- g_date_time_unref (time);
-
- switch (dialog->jobs[i].state)
- {
- case IPP_JOB_PENDING:
- /* Translators: Job's state (job is waiting to be printed) */
- state = g_strdup (C_("print job", "Pending"));
- break;
- case IPP_JOB_HELD:
- /* Translators: Job's state (job is held for printing) */
- state = g_strdup (C_("print job", "Held"));
- break;
- case IPP_JOB_PROCESSING:
- /* Translators: Job's state (job is currently printing) */
- state = g_strdup (C_("print job", "Processing"));
- break;
- case IPP_JOB_STOPPED:
- /* Translators: Job's state (job has been stopped) */
- state = g_strdup (C_("print job", "Stopped"));
- break;
- case IPP_JOB_CANCELED:
- /* Translators: Job's state (job has been canceled) */
- state = g_strdup (C_("print job", "Canceled"));
- break;
- case IPP_JOB_ABORTED:
- /* Translators: Job's state (job has aborted due to error) */
- state = g_strdup (C_("print job", "Aborted"));
- break;
- case IPP_JOB_COMPLETED:
- /* Translators: Job's state (job has completed successfully) */
- state = g_strdup (C_("print job", "Completed"));
- break;
- }
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- JOB_ID_COLUMN, dialog->jobs[i].id,
- JOB_TITLE_COLUMN, dialog->jobs[i].title,
- JOB_STATE_COLUMN, state,
- JOB_CREATION_TIME_COLUMN, time_string,
- -1);
-
- if (i == select_index)
- {
- select_iter = iter;
- select_iter_set = TRUE;
- dialog->current_job_id = dialog->jobs[i].id;
- }
-
- g_free (time_string);
- g_free (state);
- }
+ widget = gtk_button_new_from_icon_name (job_state == IPP_JOB_HELD ? "media-playback-start-symbolic" :
"media-playback-pause-symbolic",
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+ g_signal_connect (widget, "clicked", G_CALLBACK (job_pause_cb), item);
+ gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 4);
- gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
+ widget = gtk_button_new_from_icon_name ("edit-delete-symbolic",
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+ g_signal_connect (widget, "clicked", G_CALLBACK (job_stop_cb), job_id);
+ gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 4);
- if (select_iter_set &&
- (selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview))))
- {
- gtk_tree_selection_select_iter (selection, &select_iter);
- }
+ gtk_widget_show_all (box);
- g_object_unref (store);
- dialog->ref_count--;
+ return box;
}
static void
-update_jobs_list (PpJobsDialog *dialog)
-{
- if (dialog->printer_name)
- {
- dialog->ref_count++;
- cups_get_jobs_async (dialog->printer_name,
- TRUE,
- CUPS_WHICHJOBS_ACTIVE,
- update_jobs_list_cb,
- dialog);
- }
-}
-
-static void
-job_selection_changed_cb (GtkTreeSelection *selection,
- gpointer user_data)
+update_jobs_list_cb (cups_job_t *jobs,
+ gint num_of_jobs,
+ gpointer user_data)
{
- PpJobsDialog *dialog = (PpJobsDialog *) user_data;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GtkWidget *widget;
- gboolean release_button_sensitive = FALSE;
- gboolean hold_button_sensitive = FALSE;
- gboolean cancel_button_sensitive = FALSE;
- gint id = -1;
+ PpJobsDialog *dialog = user_data;
+ GListStore *store;
gint i;
+ GtkStack *stack;
+ GtkWidget *clear_all_button;
+
+ store = g_list_store_new (pp_job_get_type ());
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ stack = (GtkStack*) gtk_builder_get_object (GTK_BUILDER (dialog->builder), "stack");
+ clear_all_button = (GtkWidget*) gtk_builder_get_object (GTK_BUILDER (dialog->builder),
"jobs-clear-all-button");
+ if (num_of_jobs > 0)
{
- gtk_tree_model_get (model, &iter,
- JOB_ID_COLUMN, &id,
- -1);
+ gtk_widget_set_sensitive (clear_all_button, TRUE);
+ gtk_stack_set_visible_child_name (GTK_STACK (stack), "list-jobs-page");
}
else
{
- id = -1;
+ gtk_widget_set_sensitive (clear_all_button, FALSE);
+ gtk_stack_set_visible_child_name (GTK_STACK (stack), "no-jobs-page");
}
- dialog->current_job_id = id;
+ if (dialog->num_jobs > 0)
+ cupsFreeJobs (dialog->num_jobs, dialog->jobs);
- if (dialog->current_job_id >= 0 &&
- dialog->jobs != NULL)
- {
- for (i = 0; i < dialog->num_jobs; i++)
- {
- if (dialog->jobs[i].id == dialog->current_job_id)
- {
- ipp_jstate_t job_state = dialog->jobs[i].state;
-
- release_button_sensitive = job_state == IPP_JOB_HELD;
- hold_button_sensitive = job_state == IPP_JOB_PENDING;
- cancel_button_sensitive = job_state < IPP_JOB_CANCELED;
-
- break;
- }
- }
- }
+ dialog->num_jobs = num_of_jobs;
+ dialog->jobs = jobs;
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-release-button");
- gtk_widget_set_sensitive (widget, release_button_sensitive);
+ for (i = 0; i < dialog->num_jobs; i++)
+ {
+ gchar *state = NULL;
+ PpJob *job;
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-hold-button");
- gtk_widget_set_sensitive (widget, hold_button_sensitive);
+ job = g_object_new (pp_job_get_type (),
+ "id", dialog->jobs[i].id,
+ "title", dialog->jobs[i].title,
+ "state", dialog->jobs[i].state,
+ NULL);
+ g_list_store_append (store, job);
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-cancel-button");
- gtk_widget_set_sensitive (widget, cancel_button_sensitive);
-}
+ g_object_unref (job);
+ g_free (state);
+ }
-static void
-populate_jobs_list (PpJobsDialog *dialog)
-{
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- GtkCellRenderer *title_renderer;
- GtkTreeView *treeview;
-
- treeview = (GtkTreeView*)
- gtk_builder_get_object (dialog->builder, "job-treeview");
-
- renderer = gtk_cell_renderer_text_new ();
- title_renderer = gtk_cell_renderer_text_new ();
-
- /* Translators: Name of column showing titles of print jobs */
- column = gtk_tree_view_column_new_with_attributes (_("Job Title"), title_renderer,
- "text", JOB_TITLE_COLUMN, NULL);
- g_object_set (G_OBJECT (title_renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- gtk_tree_view_column_set_fixed_width (column, 180);
- gtk_tree_view_column_set_min_width (column, 180);
- gtk_tree_view_column_set_max_width (column, 180);
- gtk_tree_view_append_column (treeview, column);
-
- /* Translators: Name of column showing statuses of print jobs */
- column = gtk_tree_view_column_new_with_attributes (_("Job State"), renderer,
- "text", JOB_STATE_COLUMN, NULL);
- gtk_tree_view_column_set_expand (column, TRUE);
- gtk_tree_view_append_column (treeview, column);
-
- /* Translators: Name of column showing times of creation of print jobs */
- column = gtk_tree_view_column_new_with_attributes (_("Time"), renderer,
- "text", JOB_CREATION_TIME_COLUMN, NULL);
- gtk_tree_view_column_set_expand (column, TRUE);
- gtk_tree_view_append_column (treeview, column);
-
- g_signal_connect (gtk_tree_view_get_selection (treeview),
- "changed", G_CALLBACK (job_selection_changed_cb), dialog);
+ gtk_list_box_bind_model (dialog->listbox, G_LIST_MODEL (store),
+ create_listbox_row, NULL, NULL);
- update_jobs_list (dialog);
-}
+ gtk_container_add (GTK_CONTAINER (dialog->listbox), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
-static void
-job_process_cb_cb (gpointer user_data)
-{
+ dialog->ref_count--;
}
static void
-job_process_cb (GtkButton *button,
- gpointer user_data)
+update_jobs_list (PpJobsDialog *dialog)
{
- PpJobsDialog *dialog = (PpJobsDialog *) user_data;
- GtkWidget *widget;
-
- if (dialog->current_job_id >= 0)
+ if (dialog->printer_name)
{
- if ((GtkButton*) gtk_builder_get_object (dialog->builder,
- "job-cancel-button") ==
- button)
- {
- job_cancel_purge_async (dialog->current_job_id,
- FALSE,
- NULL,
- job_process_cb_cb,
- dialog);
- }
- else if ((GtkButton*) gtk_builder_get_object (dialog->builder,
- "job-hold-button") ==
- button)
- {
- job_set_hold_until_async (dialog->current_job_id,
- "indefinite",
- NULL,
- job_process_cb_cb,
- dialog);
- }
- else
- {
- job_set_hold_until_async (dialog->current_job_id,
- "no-hold",
- NULL,
- job_process_cb_cb,
- dialog);
- }
- }
-
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-release-button");
- gtk_widget_set_sensitive (widget, FALSE);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-hold-button");
- gtk_widget_set_sensitive (widget, FALSE);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-cancel-button");
- gtk_widget_set_sensitive (widget, FALSE);
+ dialog->ref_count++;
+ cups_get_jobs_async (dialog->printer_name,
+ TRUE,
+ CUPS_WHICHJOBS_ACTIVE,
+ update_jobs_list_cb,
+ dialog);
+ }
}
static void
@@ -382,15 +256,27 @@ jobs_dialog_response_cb (GtkDialog *dialog,
jobs_dialog->user_data);
}
+static void
+on_clear_all_button_clicked (GtkButton *button,
+ gpointer user_data)
+{
+ PpJobsDialog *dialog = user_data;
+
+ job_cancel_purge_all (dialog->jobs,
+ dialog->num_jobs,
+ FALSE,
+ NULL,
+ NULL);
+}
+
PpJobsDialog *
pp_jobs_dialog_new (GtkWindow *parent,
UserResponseCallback user_callback,
gpointer user_data,
gchar *printer_name)
{
- GtkStyleContext *context;
PpJobsDialog *dialog;
- GtkWidget *widget;
+ GtkButton *clear_all_button;
GError *error = NULL;
gchar *objects[] = { "jobs-dialog", NULL };
guint builder_result;
@@ -416,43 +302,26 @@ pp_jobs_dialog_new (GtkWindow *parent,
dialog->user_callback = user_callback;
dialog->user_data = user_data;
dialog->printer_name = g_strdup (printer_name);
- dialog->current_job_id = -1;
dialog->ref_count = 0;
/* connect signals */
g_signal_connect (dialog->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
g_signal_connect (dialog->dialog, "response", G_CALLBACK (jobs_dialog_response_cb), dialog);
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-cancel-button");
- g_signal_connect (widget, "clicked", G_CALLBACK (job_process_cb), dialog);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-hold-button");
- g_signal_connect (widget, "clicked", G_CALLBACK (job_process_cb), dialog);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "job-release-button");
- g_signal_connect (widget, "clicked", G_CALLBACK (job_process_cb), dialog);
-
+ clear_all_button = (GtkButton *) gtk_builder_get_object (dialog->builder, "jobs-clear-all-button");
+ g_signal_connect (clear_all_button, "clicked", G_CALLBACK (on_clear_all_button_clicked), dialog);
- /* Set junctions */
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "queue-scrolledwindow");
- context = gtk_widget_get_style_context (widget);
- gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
-
- widget = (GtkWidget*)
- gtk_builder_get_object (dialog->builder, "queue-toolbar");
- context = gtk_widget_get_style_context (widget);
- gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
-
-
- title = g_strdup_printf (_("%s Active Jobs"), printer_name);
+ /* Translators: This is the printer name to which we are showing the active jobs */
+ title = g_strdup_printf (C_("Printer jobs dialog title", "%s - Active Jobs"), printer_name);
gtk_window_set_title (GTK_WINDOW (dialog->dialog), title);
g_free (title);
- populate_jobs_list (dialog);
+ dialog->listbox = (GtkListBox*)
+ gtk_builder_get_object (dialog->builder, "jobs-listbox");
+ gtk_list_box_set_header_func (dialog->listbox,
+ cc_list_box_update_header_func, NULL, NULL);
+
+ update_jobs_list (dialog);
gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog), GTK_WINDOW (parent));
gtk_window_present (GTK_WINDOW (dialog->dialog));
diff --git a/panels/printers/pp-utils.c b/panels/printers/pp-utils.c
index 899bcf3..f9314eb 100644
--- a/panels/printers/pp-utils.c
+++ b/panels/printers/pp-utils.c
@@ -3856,18 +3856,33 @@ job_cancel_purge_async_dbus_cb (GObject *source_object,
g_error_free (error);
}
- data->callback (data->user_data);
-
if (data->cancellable)
g_object_unref (data->cancellable);
g_free (data);
}
void
+job_cancel_purge_all (cups_job_t *jobs,
+ gint num_of_jobs,
+ gboolean job_purge,
+ GCancellable *cancellable,
+ gpointer user_data)
+{
+ gint i;
+
+ for (i = 0; i < num_of_jobs; i++)
+ {
+ job_cancel_purge_async (jobs[i].id,
+ job_purge,
+ cancellable,
+ user_data);
+ }
+}
+
+void
job_cancel_purge_async (gint job_id,
gboolean job_purge,
GCancellable *cancellable,
- JCPCallback callback,
gpointer user_data)
{
GDBusConnection *bus;
@@ -3879,14 +3894,12 @@ job_cancel_purge_async (gint job_id,
{
g_warning ("Failed to get session bus: %s", error->message);
g_error_free (error);
- callback (user_data);
return;
}
data = g_new0 (JCPData, 1);
if (cancellable)
data->cancellable = g_object_ref (cancellable);
- data->callback = callback;
data->user_data = user_data;
g_dbus_connection_call (bus,
@@ -3908,7 +3921,6 @@ job_cancel_purge_async (gint job_id,
typedef struct
{
GCancellable *cancellable;
- JSHUCallback callback;
gpointer user_data;
} JSHUData;
@@ -3937,8 +3949,6 @@ job_set_hold_until_async_dbus_cb (GObject *source_object,
g_error_free (error);
}
- data->callback (data->user_data);
-
if (data->cancellable)
g_object_unref (data->cancellable);
g_free (data);
@@ -3948,7 +3958,6 @@ void
job_set_hold_until_async (gint job_id,
const gchar *job_hold_until,
GCancellable *cancellable,
- JSHUCallback callback,
gpointer user_data)
{
GDBusConnection *bus;
@@ -3960,14 +3969,12 @@ job_set_hold_until_async (gint job_id,
{
g_warning ("Failed to get session bus: %s", error->message);
g_error_free (error);
- callback (user_data);
return;
}
data = g_new0 (JSHUData, 1);
if (cancellable)
data->cancellable = g_object_ref (cancellable);
- data->callback = callback;
data->user_data = user_data;
g_dbus_connection_call (bus,
diff --git a/panels/printers/pp-utils.h b/panels/printers/pp-utils.h
index 9b39b6d..0b0fdd5 100644
--- a/panels/printers/pp-utils.h
+++ b/panels/printers/pp-utils.h
@@ -264,15 +264,19 @@ typedef void (*JCPCallback) (gpointer user_data);
void job_cancel_purge_async (gint job_id,
gboolean job_purge,
GCancellable *cancellable,
- JCPCallback callback,
gpointer user_data);
+void job_cancel_purge_all (cups_job_t *jobs,
+ gint num_of_jobs,
+ gboolean job_purge,
+ GCancellable *cancellable,
+ gpointer user_data);
+
typedef void (*JSHUCallback) (gpointer user_data);
void job_set_hold_until_async (gint job_id,
const gchar *job_hold_until,
GCancellable *cancellable,
- JSHUCallback callback,
gpointer user_data);
void pp_devices_list_free (PpDevicesList *result);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]