/* * Copyright (c) 2003 Benedikt Meurer (benedikt.meurer@unix-ag.uni-siegen.de) * 2004-2006 Jean-François Wauthy (pollux@xfce.org) * * 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 Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif /* !HAVE_CONFIG_H */ #ifdef HAVE_STRING_H #include #endif #include #include #include #include #include #include #include #define PRINTER_LIST_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ PRINTER_LIST_WINDOW_TYPE, PrinterListWindowPrivate)) #define STATUS_IDLE_FORMAT "%s" #define STATUS_PROCESSING_FORMAT "%s" #define STATUS_STOPPED_FORMAT "%s" #define STATUS_UNKNOWN_FORMAT "%s" struct _PrinterListWindowPrivate { PrintingSystem *ps; GtkIconTheme *icontheme; GtkUIManager *ui_manager; GtkWidget *treeview; guint timeout_id; }; /* prototypes */ static void printer_list_window_class_init (PrinterListWindowClass * klass); static void printer_list_window_init (PrinterListWindow * obj); static void load_printer_list_in_treeview (PrinterListWindow * win); static void icon_theme_changed_cb (GtkIconTheme * icon_theme, PrinterListWindow * win); static void tree_view_row_activated_cb (GtkWidget * widget, GtkTreePath * path, GtkTreeViewColumn * col, PrinterListWindow * win); static gboolean update_jobs_and_states (PrinterListWindow * win); static void action_quit_cb (GtkAction * action, PrinterListWindow * win); static void action_about_cb (GtkAction * action, PrinterListWindow * win); /* globals */ static GtkWindowClass *parent_class = NULL; static GtkActionEntry action_entries[] = { {"printer-menu", NULL, N_("Printer"), NULL,}, {"quit", GTK_STOCK_QUIT, N_("Quit"), NULL, N_("Quit xfprint4-manager"), G_CALLBACK (action_quit_cb),}, {"about-menu", NULL, N_("About"), NULL,}, {"about", GTK_STOCK_ABOUT, N_("About xfprint4-manager"), NULL, N_("Display informations about xfprint4-manager"), G_CALLBACK (action_about_cb),}, }; /*********/ /* class */ /*********/ GType printer_list_window_get_type () { static GType type = 0; if (type == 0) { static const GTypeInfo our_info = { sizeof (PrinterListWindowClass), NULL, NULL, (GClassInitFunc) printer_list_window_class_init, NULL, NULL, sizeof (PrinterListWindow), 0, (GInstanceInitFunc) printer_list_window_init, }; type = g_type_register_static (GTK_TYPE_WINDOW, "PrinterListWindow", &our_info, 0); } return type; } static void printer_list_window_init (PrinterListWindow * win) { PrinterListWindowPrivate *priv; GError *error = NULL; GtkActionGroup *action_group; GtkAccelGroup *accel_group; GtkTreeSelection *selection; GtkWidget *menubar; GtkWidget *scrollwin; GtkWidget *vbox; GtkListStore *store; GtkCellRenderer *cell; GtkTreeViewColumn *column; priv = win->priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); priv->icontheme = gtk_icon_theme_get_default (); g_signal_connect (G_OBJECT (priv->icontheme), "changed", G_CALLBACK (icon_theme_changed_cb), win); gtk_window_set_icon_name (GTK_WINDOW (win), "printer"); gtk_window_set_default_size (GTK_WINDOW (win), 450, 250); gtk_window_set_title (GTK_WINDOW (win), _("Printer manager")); /* ui manager */ action_group = gtk_action_group_new ("printer-list-default"); gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); gtk_action_group_add_actions (action_group, action_entries, G_N_ELEMENTS (action_entries), GTK_WIDGET (win)); priv->ui_manager = gtk_ui_manager_new (); gtk_ui_manager_insert_action_group (priv->ui_manager, action_group, 0); if (gtk_ui_manager_add_ui_from_string (priv->ui_manager, "" "" " " " " " " " " " " " " " " " " "" "", -1, &error) == 0) { g_warning ("Unable to build the user interface correctly : %s", error->message); g_error_free (error); } gtk_ui_manager_ensure_update (priv->ui_manager); accel_group = gtk_ui_manager_get_accel_group (priv->ui_manager); gtk_window_add_accel_group (GTK_WINDOW (win), accel_group); /* contents */ vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (win), vbox); /* menubar */ menubar = gtk_ui_manager_get_widget (priv->ui_manager, "/main-menu"); if (G_LIKELY (menubar != NULL)) { gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0); gtk_widget_show (menubar); } /* the printer list store */ store = gtk_list_store_new (PRINTERS_N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); /* The printer list view */ scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (vbox), scrollwin, TRUE, TRUE, 0); priv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); gtk_container_add (GTK_CONTAINER (scrollwin), priv->treeview); /* configure the tree selection for the printer list */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); cell = gtk_cell_renderer_pixbuf_new (); column = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (column, cell, FALSE); gtk_tree_view_column_set_attributes (column, cell, "pixbuf", PRINTERS_ICON_COLUMN, NULL); g_object_set (cell, "xalign", 0.0, "ypad", 0, NULL); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, TRUE); gtk_tree_view_column_set_attributes (column, cell, "markup", PRINTERS_ALIAS_COLUMN, NULL); g_object_set (cell, "ypad", 0, "yalign", 0.5, NULL); gtk_tree_view_column_set_title (column, _("Alias name")); gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->treeview), PRINTERS_STATE_COLUMN, _("State"), gtk_cell_renderer_text_new (), "markup", PRINTERS_STATE_COLUMN, NULL); /* the view now holds a reference of the store */ g_object_unref (G_OBJECT (store)); gtk_widget_show_all (vbox); /* Select nothing in the list */ gtk_tree_selection_unselect_all (selection); } static void printer_list_window_finalize (GObject * object) { PrinterListWindow *cobj; PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (object); cobj = PRINTER_LIST_WINDOW (object); if (priv->timeout_id > 0) g_source_remove (priv->timeout_id); G_OBJECT_CLASS (parent_class)->finalize (object); } static void printer_list_window_class_init (PrinterListWindowClass * klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (klass, sizeof (PrinterListWindowPrivate)); parent_class = g_type_class_peek_parent (klass); object_class->finalize = printer_list_window_finalize; } /* actions */ static void action_quit_cb (GtkAction * action, PrinterListWindow * win) { gtk_widget_destroy (GTK_WIDGET (win)); gtk_main_quit (); } static void action_about_cb (GtkAction * action, PrinterListWindow * win) { XfceAboutInfo *info; PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); GtkWidget *dialog; GdkPixbuf *icon; info = xfce_about_info_new ("xfprint-manager", VERSION, _("Xfprint printers manager"), XFCE_COPYRIGHT_TEXT ("2003-2006", "Xfce4 Team"), XFCE_LICENSE_GPL); xfce_about_info_set_homepage (info, "http://www.xfce.org/"); /* Credits */ xfce_about_info_add_credit (info, "Benedikt Meurer", "benny@xfce.org", _("Former maintainer")); xfce_about_info_add_credit (info, "Jean-Francois Wauthy", "pollux@xfce.org", _("Maintainer")); icon = gtk_icon_theme_load_icon (priv->icontheme, "printer", 48, 0, NULL); dialog = xfce_about_dialog_new_with_values (GTK_WINDOW (win), info, icon); gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400); xfce_about_info_free (info); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_object_unref (icon); } static void load_printer_list_in_treeview (PrinterListWindow * win) { PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); GtkListStore *store; GtkTreeIter iter; GList *printers = NULL, *printer_el = NULL; Printer *printer = NULL; GtkTreeSelection *selection; gchar *default_printer; store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview))); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); printer = printing_system_get_default_printer (priv->ps); if (printer) default_printer = g_strdup (printer->name); else default_printer = g_strdup (""); printers = printer_el = printing_system_get_printers (priv->ps); while (printer_el) { GdkPixbuf *icon = NULL; gint num_jobs = 0; gchar *num_jobs_str = NULL; gint state; gchar *state_str = NULL; gint x, y; if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &x, &y)) x = 48; printer = printer_el->data; if (g_strrstr (printer->name, "/")) { /* instance ? */ printer_el = g_list_next (printer_el); continue; } if (printer->type == PRINTER_TYPE_CLASS) icon = gtk_icon_theme_load_icon (priv->icontheme, "printer-class", x, 0, NULL); if (!icon || printer->type == PRINTER_TYPE_PRINTER) icon = gtk_icon_theme_load_icon (priv->icontheme, "printer", x, 0, NULL); num_jobs = printing_system_get_jobs_count (priv->ps, printer->name); num_jobs_str = g_strdup_printf ("%d", num_jobs); state = printing_system_get_printer_state (priv->ps, printer->name); switch (state) { case PRINTER_STATE_UNKNOWN: state_str = g_strdup_printf (STATUS_UNKNOWN_FORMAT, _("Unknown")); break; case PRINTER_STATE_IDLE: state_str = g_strdup_printf (STATUS_IDLE_FORMAT, _("Idle")); break; case PRINTER_STATE_PROCESSING: state_str = g_strdup_printf (STATUS_PROCESSING_FORMAT, _("Processing")); break; case PRINTER_STATE_STOPPED: state_str = g_strdup_printf (STATUS_STOPPED_FORMAT, _("Stopped")); } gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, PRINTERS_ICON_COLUMN, icon, PRINTERS_ALIAS_COLUMN, printer->alias, PRINTERS_NAME_COLUMN, printer->name, PRINTERS_JOBS_COLUMN, num_jobs_str, PRINTERS_STATE_COLUMN, state_str, -1); g_free (num_jobs_str); g_free (state_str); if (strcmp (default_printer, printer->name) == 0) gtk_tree_selection_select_iter (selection, &iter); if (icon) g_object_unref (G_OBJECT (icon)); printer_el = g_list_next (printer_el); } printers_free (printers); g_free (default_printer); } /**********************/ /* Icontheme callback */ /**********************/ static gboolean icon_theme_update_foreach_func (GtkTreeModel * model, GtkTreePath * path, GtkTreeIter * iter, PrinterListWindow * win) { PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); GdkPixbuf *icon = NULL; gchar *name = NULL; Printer *printer = NULL; gtk_tree_model_get (model, iter, PRINTERS_ICON_COLUMN, &icon, PRINTERS_NAME_COLUMN, &name, -1); if (model) { gtk_list_store_clear (GTK_LIST_STORE (model)); load_printer_list_in_treeview (win); } if (icon) g_object_unref (icon); // FIXME //printer = printer_lookup_byname (printers_list, name); if (printer->type == PRINTER_TYPE_CLASS) icon = gtk_icon_theme_load_icon (priv->icontheme, "printer-class", 48, 0, NULL); if (!icon || printer->type == PRINTER_TYPE_PRINTER) icon = gtk_icon_theme_load_icon (priv->icontheme, "printer", 48, 0, NULL); gtk_list_store_set (GTK_LIST_STORE (model), iter, PRINTERS_ICON_COLUMN, icon, -1); g_object_unref (icon); g_free (name); return FALSE; } /***********************/ /* Mainwindow callback */ /***********************/ /* Callbacks */ static void icon_theme_changed_cb (GtkIconTheme * icon_theme, PrinterListWindow * win) { GtkTreeModel *model; PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); if (model) gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) & icon_theme_update_foreach_func, win); } /**********************/ /* Treeview callbacks */ /**********************/ static void tree_view_row_activated_cb (GtkWidget * widget, GtkTreePath * path, GtkTreeViewColumn * col, PrinterListWindow * win) { gchar *printer = NULL; printer = printer_list_window_get_selected_printer (win); if (printer) { PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); GtkWidget *dialog; dialog = printer_queue_window_new (priv->ps, printer); gtk_widget_show (dialog); } g_free (printer); } /**************************/ /* Update jobs and states */ /**************************/ static gboolean update_jobs_and_states (PrinterListWindow * win) { PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); GtkTreeModel *model; //TODO memoriser selection model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); if (model) { gtk_list_store_clear (GTK_LIST_STORE (model)); load_printer_list_in_treeview (win); return TRUE; } return FALSE; } /********************/ /* public functions */ /********************/ gchar * printer_list_window_get_selected_printer (PrinterListWindow * win) { PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *printer = NULL; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); if (selection && gtk_tree_selection_get_selected (selection, &model, &iter)) gtk_tree_model_get (model, &iter, PRINTERS_NAME_COLUMN, &printer, -1); return printer; } GtkUIManager * printer_list_window_get_ui_manager (PrinterListWindow * win) { return PRINTER_LIST_WINDOW_GET_PRIVATE (win)->ui_manager; } void printer_list_window_hide_column (PrinterListWindow * win, PrinterListWindowColumn column) { PrinterListWindowPrivate *priv = PRINTER_LIST_WINDOW_GET_PRIVATE (win); GtkTreeViewColumn *tree_column; tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (priv->treeview), column); gtk_tree_view_column_set_visible (tree_column, FALSE); } GtkWidget * printer_list_window_new (PrintingSystem * ps) { GObject *obj; PrinterListWindowPrivate *priv; obj = g_object_new (PRINTER_LIST_WINDOW_TYPE, NULL); priv = PRINTER_LIST_WINDOW_GET_PRIVATE (obj); if (ps) { priv->ps = ps; /* load the printer list in the treeview */ load_printer_list_in_treeview (PRINTER_LIST_WINDOW (obj)); g_signal_connect (G_OBJECT (priv->treeview), "row-activated", G_CALLBACK (tree_view_row_activated_cb), obj); /* Refresh job list every 3 sec */ priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 3000, (GSourceFunc) update_jobs_and_states, PRINTER_LIST_WINDOW (obj), NULL); /* customize the dialog for the printing system */ printing_system_customize_printer_list_window (ps, PRINTER_LIST_WINDOW (obj)); } else { gtk_widget_set_sensitive (priv->treeview, FALSE); } return GTK_WIDGET (obj); }