/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright 2012 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 .
*
* Author: Marek Kasik
*/
#include "config.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "pp-options-dialog.h"
#include "pp-maintenance-command.h"
#include "pp-ppd-option-widget.h"
#include "pp-ipp-option-widget.h"
#include "pp-utils.h"
#include "pp-printer.h"
struct _PpOptionsDialog {
GtkBuilder *builder;
GtkWidget *parent;
GtkWidget *dialog;
UserResponseCallback user_callback;
gpointer user_data;
gchar *printer_name;
gchar *ppd_filename;
gboolean ppd_filename_set;
cups_dest_t *destination;
gboolean destination_set;
GHashTable *ipp_attributes;
gboolean ipp_attributes_set;
gboolean populating_dialog;
GtkResponseType response;
gboolean sensitive;
};
static void pp_options_dialog_hide (PpOptionsDialog *dialog);
enum
{
CATEGORY_IDS_COLUMN = 0,
CATEGORY_NAMES_COLUMN
};
/* These lists come from Gtk+ */
static const struct {
const char *keyword;
const char *translation;
} ppd_option_translations[] = {
{ "Duplex", N_("Two Sided") },
{ "MediaType", N_("Paper Type") },
{ "InputSlot", N_("Paper Source") },
{ "OutputBin", N_("Output Tray") },
{ "Resolution", N_("Resolution") },
{ "PreFilter", N_("GhostScript pre-filtering") },
};
/* keep sorted when changing */
static const char *page_setup_option_whitelist[] = {
"InputSlot",
"MediaType",
"OutputBin",
"PageSize",
};
/* keep sorted when changing */
static const char *color_option_whitelist[] = {
"BRColorEnhancement",
"BRColorMatching",
"BRColorMatching",
"BRColorMode",
"BRGammaValue",
"BRImprovedGray",
"BlackSubstitution",
"ColorModel",
"HPCMYKInks",
"HPCSGraphics",
"HPCSImages",
"HPCSText",
"HPColorSmart",
"RPSBlackMode",
"RPSBlackOverPrint",
"Rcmyksimulation",
};
/* keep sorted when changing */
static const char *color_group_whitelist[] = {
"Color",
"Color1",
"Color2",
"ColorBalance",
"ColorPage",
"ColorSettings1",
"ColorSettings2",
"ColorSettings3",
"ColorSettings4",
"EPColorSettings",
"FPColorWise1",
"FPColorWise2",
"FPColorWise3",
"FPColorWise4",
"FPColorWise5",
"HPCMYKInksPanel",
"HPColorOptions",
"HPColorOptionsPanel",
"HPColorQualityOptionsPanel",
"ManualColor",
};
/* keep sorted when changing */
static const char *image_quality_option_whitelist[] = {
"BRDocument",
"BRHalfTonePattern",
"BRNormalPrt",
"BRPrintQuality",
"BitsPerPixel",
"Darkness",
"Dithering",
"EconoMode",
"Economode",
"HPEconoMode",
"HPEdgeControl",
"HPGraphicsHalftone",
"HPHalftone",
"HPImagingOptions",
"HPLJDensity",
"HPPhotoHalftone",
"HPPrintQualityOptions",
"HPResolutionOptions",
"OutputMode",
"REt",
"RPSBitsPerPixel",
"RPSDitherType",
"Resolution",
"ScreenLock",
"Smoothing",
"TonerSaveMode",
"UCRGCRForImage",
};
/* keep sorted when changing */
static const char *image_quality_group_whitelist[] = {
"EPQualitySettings",
"FPImageQuality1",
"FPImageQuality2",
"FPImageQuality3",
"ImageQualityPage",
"Quality",
};
/* keep sorted when changing */
static const char * finishing_option_whitelist[] = {
"BindColor",
"BindEdge",
"BindType",
"BindWhen",
"Booklet",
"FoldType",
"FoldWhen",
"HPStaplerOptions",
"Jog",
"Slipsheet",
"Sorter",
"StapleLocation",
"StapleOrientation",
"StapleWhen",
"StapleX",
"StapleY",
};
/* keep sorted when changing */
static const char *job_group_whitelist[] = {
"JobHandling",
"JobLog",
};
/* keep sorted when changing */
static const char *finishing_group_whitelist[] = {
"Booklet",
"BookletCover",
"BookletModeOptions",
"FPFinishing1",
"FPFinishing2",
"FPFinishing3",
"FPFinishing4",
"Finishing",
"FinishingOptions",
"FinishingPage",
"HPBookletPanel",
"HPFinishing",
"HPFinishingOptions",
"HPFinishingPanel",
};
/* keep sorted when changing */
static const char *installable_options_group_whitelist[] = {
"InstallableOptions",
};
/* keep sorted when changing */
static const char *page_setup_group_whitelist[] = {
"HPMarginAndLayout",
"OutputControl",
"PaperHandling",
"Paper",
"Source",
};
/* keep sorted when changing */
static const char *ppd_option_blacklist[] = {
"Collate",
"Copies",
"Duplex",
"HPManualDuplexOrientation",
"HPManualDuplexSwitch",
"OutputOrder",
"PageRegion"
};
static int
strptr_cmp (const void *a,
const void *b)
{
char **aa = (char **)a;
char **bb = (char **)b;
return strcmp (*aa, *bb);
}
static gboolean
string_in_table (gchar *str,
const gchar *table[],
gint table_len)
{
return bsearch (&str, table, table_len, sizeof (char *), (void *)strptr_cmp) != NULL;
}
#define STRING_IN_TABLE(_str, _table) (string_in_table (_str, _table, G_N_ELEMENTS (_table)))
static gchar *
ppd_option_name_translate (ppd_option_t *option)
{
gint i;
for (i = 0; i < G_N_ELEMENTS (ppd_option_translations); i++)
{
if (g_strcmp0 (ppd_option_translations[i].keyword, option->keyword) == 0)
return g_strdup (_(ppd_option_translations[i].translation));
}
return g_strdup (option->text);
}
static gint
grid_get_height (GtkWidget *grid)
{
GList *children;
GList *child;
gint height = 0;
gint top_attach = 0;
gint max = 0;
children = gtk_container_get_children (GTK_CONTAINER (grid));
for (child = children; child; child = g_list_next (child))
{
gtk_container_child_get (GTK_CONTAINER (grid), child->data,
"top-attach", &top_attach,
"height", &height,
NULL);
if (height + top_attach > max)
max = height + top_attach;
}
g_list_free (children);
return max;
}
static gboolean
grid_is_empty (GtkWidget *grid)
{
GList *children;
children = gtk_container_get_children (GTK_CONTAINER (grid));
if (children)
{
g_list_free (children);
return FALSE;
}
else
{
return TRUE;
}
}
static GtkWidget *
ipp_option_add (IPPAttribute *attr_supported,
IPPAttribute *attr_default,
const gchar *option_name,
const gchar *option_display_name,
const gchar *printer_name,
GtkWidget *grid,
gboolean sensitive)
{
GtkStyleContext *context;
GtkWidget *widget;
GtkWidget *label;
gint position;
widget = (GtkWidget *) pp_ipp_option_widget_new (attr_supported,
attr_default,
option_name,
printer_name);
if (widget)
{
gtk_widget_set_sensitive (widget, sensitive);
position = grid_get_height (grid);
label = gtk_label_new (option_display_name);
context = gtk_widget_get_style_context (label);
gtk_style_context_add_class (context, "dim-label");
gtk_widget_set_halign (label, GTK_ALIGN_END);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start (label, 10);
gtk_grid_attach (GTK_GRID (grid), label, 0, position, 1, 1);
gtk_widget_set_margin_start (widget, 20);
gtk_grid_attach (GTK_GRID (grid), widget, 1, position, 1, 1);
}
return widget;
}
static GtkWidget *
ppd_option_add (ppd_option_t option,
const gchar *printer_name,
GtkWidget *grid,
gboolean sensitive)
{
GtkStyleContext *context;
GtkWidget *widget;
GtkWidget *label;
gint position;
widget = (GtkWidget *) pp_ppd_option_widget_new (&option, printer_name);
if (widget)
{
gtk_widget_set_sensitive (widget, sensitive);
position = grid_get_height (grid);
label = gtk_label_new (ppd_option_name_translate (&option));
context = gtk_widget_get_style_context (label);
gtk_style_context_add_class (context, "dim-label");
gtk_widget_set_halign (label, GTK_ALIGN_END);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start (label, 10);
gtk_grid_attach (GTK_GRID (grid), label, 0, position, 1, 1);
gtk_widget_set_margin_start (widget, 20);
gtk_grid_attach (GTK_GRID (grid), widget, 1, position, 1, 1);
}
return widget;
}
static GtkWidget *
tab_grid_new ()
{
GtkWidget *grid;
grid = gtk_grid_new ();
gtk_container_set_border_width (GTK_CONTAINER (grid), 20);
gtk_grid_set_row_spacing (GTK_GRID (grid), 15);
return grid;
}
static void
tab_add (const gchar *tab_name,
GtkWidget *options_notebook,
GtkTreeView *treeview,
GtkWidget *grid)
{
GtkListStore *store;
GtkTreeIter iter;
GtkWidget *scrolled_window;
gboolean unref_store = FALSE;
gint id;
if (!grid_is_empty (grid))
{
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (scrolled_window), grid);
id = gtk_notebook_append_page (GTK_NOTEBOOK (options_notebook),
scrolled_window,
NULL);
if (id >= 0)
{
store = GTK_LIST_STORE (gtk_tree_view_get_model (treeview));
if (!store)
{
store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING);
unref_store = TRUE;
}
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
CATEGORY_IDS_COLUMN, id,
CATEGORY_NAMES_COLUMN, tab_name,
-1);
if (unref_store)
{
gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
g_object_unref (store);
}
}
}
else
{
g_object_ref_sink (grid);
g_object_unref (grid);
}
}
static void
category_selection_changed_cb (GtkTreeSelection *selection,
gpointer user_data)
{
PpOptionsDialog *dialog = (PpOptionsDialog *) user_data;
GtkTreeModel *model;
GtkTreeIter iter;
GtkWidget *options_notebook;
gint id = -1;
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
gtk_tree_model_get (model, &iter,
CATEGORY_IDS_COLUMN, &id,
-1);
}
if (id >= 0)
{
options_notebook = (GtkWidget*)
gtk_builder_get_object (dialog->builder, "options-notebook");
gtk_notebook_set_current_page (GTK_NOTEBOOK (options_notebook), id);
}
}
static void
populate_options_real (PpOptionsDialog *dialog)
{
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeView *treeview;
GtkTreeIter iter;
ppd_file_t *ppd_file;
GtkWidget *notebook;
GtkWidget *grid;
GtkWidget *general_tab_grid = tab_grid_new ();
GtkWidget *page_setup_tab_grid = tab_grid_new ();
GtkWidget *installable_options_tab_grid = tab_grid_new ();
GtkWidget *job_tab_grid = tab_grid_new ();
GtkWidget *image_quality_tab_grid = tab_grid_new ();
GtkWidget *color_tab_grid = tab_grid_new ();
GtkWidget *finishing_tab_grid = tab_grid_new ();
GtkWidget *advanced_tab_grid = tab_grid_new ();
GtkWidget *widget;
gint i, j;
widget = (GtkWidget*)
gtk_builder_get_object (dialog->builder, "options-spinner");
gtk_spinner_stop (GTK_SPINNER (widget));
widget = (GtkWidget*)
gtk_builder_get_object (dialog->builder, "stack");
gtk_stack_set_visible_child_name (GTK_STACK (widget), "main-box");
treeview = (GtkTreeView *)
gtk_builder_get_object (dialog->builder, "options-categories-treeview");
notebook = (GtkWidget *)
gtk_builder_get_object (dialog->builder, "options-notebook");
if (dialog->ipp_attributes)
{
/* Add number-up option to Page Setup tab */
ipp_option_add (g_hash_table_lookup (dialog->ipp_attributes,
"number-up-supported"),
g_hash_table_lookup (dialog->ipp_attributes,
"number-up-default"),
"number-up",
/* Translators: This option sets number of pages printed on one sheet */
_("Pages per side"),
dialog->printer_name,
page_setup_tab_grid,
dialog->sensitive);
/* Add sides option to Page Setup tab */
ipp_option_add (g_hash_table_lookup (dialog->ipp_attributes,
"sides-supported"),
g_hash_table_lookup (dialog->ipp_attributes,
"sides-default"),
"sides",
/* Translators: This option sets whether to print on both sides of paper */
_("Two-sided"),
dialog->printer_name,
page_setup_tab_grid,
dialog->sensitive);
/* Add orientation-requested option to Page Setup tab */
ipp_option_add (g_hash_table_lookup (dialog->ipp_attributes,
"orientation-requested-supported"),
g_hash_table_lookup (dialog->ipp_attributes,
"orientation-requested-default"),
"orientation-requested",
/* Translators: This option sets orientation of print (portrait, landscape...) */
_("Orientation"),
dialog->printer_name,
page_setup_tab_grid,
dialog->sensitive);
}
if (dialog->destination && dialog->ppd_filename)
{
ppd_file = ppdOpenFile (dialog->ppd_filename);
ppdLocalize (ppd_file);
if (ppd_file)
{
ppdMarkDefaults (ppd_file);
cupsMarkOptions (ppd_file,
dialog->destination->num_options,
dialog->destination->options);
for (i = 0; i < ppd_file->num_groups; i++)
{
for (j = 0; j < ppd_file->groups[i].num_options; j++)
{
grid = NULL;
if (STRING_IN_TABLE (ppd_file->groups[i].name,
color_group_whitelist))
grid = color_tab_grid;
else if (STRING_IN_TABLE (ppd_file->groups[i].name,
image_quality_group_whitelist))
grid = image_quality_tab_grid;
else if (STRING_IN_TABLE (ppd_file->groups[i].name,
job_group_whitelist))
grid = job_tab_grid;
else if (STRING_IN_TABLE (ppd_file->groups[i].name,
finishing_group_whitelist))
grid = finishing_tab_grid;
else if (STRING_IN_TABLE (ppd_file->groups[i].name,
installable_options_group_whitelist))
grid = installable_options_tab_grid;
else if (STRING_IN_TABLE (ppd_file->groups[i].name,
page_setup_group_whitelist))
grid = page_setup_tab_grid;
if (!STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
ppd_option_blacklist))
{
if (!grid && STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
color_option_whitelist))
grid = color_tab_grid;
else if (!grid && STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
image_quality_option_whitelist))
grid = image_quality_tab_grid;
else if (!grid && STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
finishing_option_whitelist))
grid = finishing_tab_grid;
else if (!grid && STRING_IN_TABLE (ppd_file->groups[i].options[j].keyword,
page_setup_option_whitelist))
grid = page_setup_tab_grid;
if (!grid)
grid = advanced_tab_grid;
ppd_option_add (ppd_file->groups[i].options[j],
dialog->printer_name,
grid,
dialog->sensitive);
}
}
}
ppdClose (ppd_file);
}
}
dialog->ppd_filename_set = FALSE;
if (dialog->ppd_filename)
{
g_unlink (dialog->ppd_filename);
g_free (dialog->ppd_filename);
dialog->ppd_filename = NULL;
}
dialog->destination_set = FALSE;
if (dialog->destination)
{
cupsFreeDests (1, dialog->destination);
dialog->destination = NULL;
}
dialog->ipp_attributes_set = FALSE;
if (dialog->ipp_attributes)
{
g_hash_table_unref (dialog->ipp_attributes);
dialog->ipp_attributes = NULL;
}
/* Translators: "General" tab contains general printer options */
tab_add (C_("Printer Option Group", "General"), notebook, treeview, general_tab_grid);
/* Translators: "Page Setup" tab contains settings related to pages (page size, paper source, etc.) */
tab_add (C_("Printer Option Group", "Page Setup"), notebook, treeview, page_setup_tab_grid);
/* Translators: "Installable Options" tab contains settings of presence of installed options (amount of RAM, duplex unit, etc.) */
tab_add (C_("Printer Option Group", "Installable Options"), notebook, treeview, installable_options_tab_grid);
/* Translators: "Job" tab contains settings for jobs */
tab_add (C_("Printer Option Group", "Job"), notebook, treeview, job_tab_grid);
/* Translators: "Image Quality" tab contains settings for quality of output print (e.g. resolution) */
tab_add (C_("Printer Option Group", "Image Quality"), notebook, treeview, image_quality_tab_grid);
/* Translators: "Color" tab contains color settings (e.g. color printing) */
tab_add (C_("Printer Option Group", "Color"), notebook, treeview, color_tab_grid);
/* Translators: "Finishing" tab contains finishing settings (e.g. booklet printing) */
tab_add (C_("Printer Option Group", "Finishing"), notebook, treeview, finishing_tab_grid);
/* Translators: "Advanced" tab contains all others settings */
tab_add (C_("Printer Option Group", "Advanced"), notebook, treeview, advanced_tab_grid);
gtk_widget_show_all (GTK_WIDGET (notebook));
/* Select the first option group */
if ((selection = gtk_tree_view_get_selection (treeview)) != NULL)
{
g_signal_connect (selection,
"changed",
G_CALLBACK (category_selection_changed_cb), dialog);
if ((model = gtk_tree_view_get_model (treeview)) != NULL &&
gtk_tree_model_get_iter_first (model, &iter))
gtk_tree_selection_select_iter (selection, &iter);
}
dialog->populating_dialog = FALSE;
if (dialog->response != GTK_RESPONSE_NONE)
{
dialog->user_callback (GTK_DIALOG (dialog->dialog), dialog->response, dialog->user_data);
}
}
static void
printer_get_ppd_cb (const gchar *ppd_filename,
gpointer user_data)
{
PpOptionsDialog *dialog = (PpOptionsDialog *) user_data;
if (dialog->ppd_filename)
{
g_unlink (dialog->ppd_filename);
g_free (dialog->ppd_filename);
}
dialog->ppd_filename = g_strdup (ppd_filename);
dialog->ppd_filename_set = TRUE;
if (dialog->destination_set &&
dialog->ipp_attributes_set)
{
populate_options_real (dialog);
}
}
static void
get_named_dest_cb (cups_dest_t *dest,
gpointer user_data)
{
PpOptionsDialog *dialog = (PpOptionsDialog *) user_data;
if (dialog->destination)
cupsFreeDests (1, dialog->destination);
dialog->destination = dest;
dialog->destination_set = TRUE;
if (dialog->ppd_filename_set &&
dialog->ipp_attributes_set)
{
populate_options_real (dialog);
}
}
static void
get_ipp_attributes_cb (GHashTable *table,
gpointer user_data)
{
PpOptionsDialog *dialog = (PpOptionsDialog *) user_data;
if (dialog->ipp_attributes)
g_hash_table_unref (dialog->ipp_attributes);
dialog->ipp_attributes = table;
dialog->ipp_attributes_set = TRUE;
if (dialog->ppd_filename_set &&
dialog->destination_set)
{
populate_options_real (dialog);
}
}
static void
populate_options (PpOptionsDialog *dialog)
{
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeView *treeview;
GtkWidget *widget;
/*
* Options which we need to obtain through an IPP request
* to be able to fill the options dialog.
* *-supported - possible values of the option
* *-default - actual value of the option
*/
const gchar *attributes[] =
{ "number-up-supported",
"number-up-default",
"sides-supported",
"sides-default",
"orientation-requested-supported",
"orientation-requested-default",
NULL};
widget = (GtkWidget*)
gtk_builder_get_object (dialog->builder, "stack");
gtk_stack_set_visible_child_name (GTK_STACK (widget), "progress-box");
treeview = (GtkTreeView *)
gtk_builder_get_object (dialog->builder, "options-categories-treeview");
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Categories", renderer,
"text", CATEGORY_NAMES_COLUMN, NULL);
gtk_tree_view_column_set_expand (column, TRUE);
gtk_tree_view_append_column (treeview, column);
widget = (GtkWidget*)
gtk_builder_get_object (dialog->builder, "options-spinner");
gtk_spinner_start (GTK_SPINNER (widget));
printer_get_ppd_async (dialog->printer_name,
NULL,
0,
printer_get_ppd_cb,
dialog);
get_named_dest_async (dialog->printer_name,
get_named_dest_cb,
dialog);
get_ipp_attributes_async (dialog->printer_name,
(gchar **) attributes,
get_ipp_attributes_cb,
dialog);
}
static void
pp_maintenance_command_execute_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
PpMaintenanceCommand *command = (PpMaintenanceCommand *) source_object;
pp_maintenance_command_execute_finish (command, res, NULL);
g_object_unref (command);
}
static gchar *
get_testprint_filename (const gchar *datadir)
{
const gchar *testprint[] = { "/data/testprint",
"/data/testprint.ps",
NULL };
gchar *filename = NULL;
gint i;
for (i = 0; testprint[i] != NULL; i++)
{
filename = g_strconcat (datadir, testprint[i], NULL);
if (g_access (filename, R_OK) == 0)
break;
g_clear_pointer (&filename, g_free);
}
return filename;
}
static void
print_test_page_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
pp_printer_print_file_finish (PP_PRINTER (source_object),
result, NULL);
g_object_unref (source_object);
}
static void
test_page_cb (GtkButton *button,
gpointer user_data)
{
PpOptionsDialog *dialog = (PpOptionsDialog*) user_data;
gint i;
if (dialog->printer_name)
{
const gchar *const dirs[] = { "/usr/share/cups",
"/usr/local/share/cups",
NULL };
const gchar *datadir = NULL;
gchar *filename = NULL;
datadir = getenv ("CUPS_DATADIR");
if (datadir != NULL)
{
filename = get_testprint_filename (datadir);
}
else
{
for (i = 0; dirs[i] != NULL && filename == NULL; i++)
filename = get_testprint_filename (dirs[i]);
}
if (filename != NULL)
{
PpPrinter *printer;
printer = pp_printer_new (dialog->printer_name);
pp_printer_print_file_async (printer,
filename,
/* Translators: Name of job which makes printer to print test page */
_("Test Page"),
NULL,
print_test_page_cb,
NULL);
g_free (filename);
}
else
{
PpMaintenanceCommand *command;
command = pp_maintenance_command_new (dialog->printer_name,
"PrintSelfTestPage",
NULL,
/* Translators: Name of job which makes printer to print test page */
_("Test page"));
pp_maintenance_command_execute_async (command, NULL, pp_maintenance_command_execute_cb, NULL);
}
}
}
static void
options_dialog_response_cb (GtkDialog *_dialog,
gint response_id,
gpointer user_data)
{
PpOptionsDialog *dialog = (PpOptionsDialog*) user_data;
pp_options_dialog_hide (dialog);
dialog->response = response_id;
if (!dialog->populating_dialog)
dialog->user_callback (GTK_DIALOG (dialog->dialog), response_id, dialog->user_data);
}
PpOptionsDialog *
pp_options_dialog_new (GtkWindow *parent,
UserResponseCallback user_callback,
gpointer user_data,
gchar *printer_name,
gboolean sensitive)
{
PpOptionsDialog *dialog;
GtkWidget *test_page_button;
GError *error = NULL;
gchar *objects[] = { "options-dialog", NULL };
guint builder_result;
dialog = g_new0 (PpOptionsDialog, 1);
dialog->builder = gtk_builder_new ();
dialog->parent = GTK_WIDGET (parent);
builder_result = gtk_builder_add_objects_from_resource (dialog->builder,
"/org/gnome/control-center/printers/options-dialog.ui",
objects, &error);
if (builder_result == 0)
{
g_warning ("Could not load ui: %s", error->message);
g_error_free (error);
return NULL;
}
dialog->dialog = (GtkWidget *) gtk_builder_get_object (dialog->builder, "options-dialog");
gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog), GTK_WINDOW (parent));
dialog->user_callback = user_callback;
dialog->user_data = user_data;
dialog->printer_name = g_strdup (printer_name);
dialog->ppd_filename = NULL;
dialog->ppd_filename_set = FALSE;
dialog->destination = NULL;
dialog->destination_set = FALSE;
dialog->ipp_attributes = NULL;
dialog->ipp_attributes_set = FALSE;
dialog->response = GTK_RESPONSE_NONE;
dialog->sensitive = sensitive;
/* connect signals */
g_signal_connect (dialog->dialog, "response", G_CALLBACK (options_dialog_response_cb), dialog);
test_page_button = (GtkWidget*) gtk_builder_get_object (dialog->builder, "print-test-page");
g_signal_connect (test_page_button, "clicked", G_CALLBACK (test_page_cb), dialog);
gtk_window_set_title (GTK_WINDOW (dialog->dialog), printer_name);
gtk_widget_show_all (GTK_WIDGET (dialog->dialog));
dialog->populating_dialog = TRUE;
populate_options (dialog);
return dialog;
}
void
pp_options_dialog_set_callback (PpOptionsDialog *dialog,
UserResponseCallback user_callback,
gpointer user_data)
{
if (dialog != NULL)
{
dialog->user_callback = user_callback;
dialog->user_data = user_data;
}
}
void
pp_options_dialog_free (PpOptionsDialog *dialog)
{
gtk_widget_destroy (GTK_WIDGET (dialog->dialog));
dialog->dialog = NULL;
g_object_unref (dialog->builder);
dialog->builder = NULL;
g_free (dialog->printer_name);
dialog->printer_name = NULL;
if (dialog->ppd_filename)
{
g_unlink (dialog->ppd_filename);
g_free (dialog->ppd_filename);
dialog->ppd_filename = NULL;
}
if (dialog->destination)
{
cupsFreeDests (1, dialog->destination);
dialog->destination = NULL;
}
if (dialog->ipp_attributes)
{
g_hash_table_unref (dialog->ipp_attributes);
dialog->ipp_attributes = NULL;
}
g_free (dialog);
}
static void
pp_options_dialog_hide (PpOptionsDialog *dialog)
{
gtk_widget_hide (GTK_WIDGET (dialog->dialog));
}