diff --git a/configure.ac b/configure.ac index 98ece7fb0..5bb94b1b5 100644 --- a/configure.ac +++ b/configure.ac @@ -76,13 +76,15 @@ GDKPIXBUF_REQUIRED_VERSION=2.23.0 POLKIT_REQUIRED_VERSION=0.97 GSD_REQUIRED_VERSION=2.91.94 NETWORK_MANAGER_REQUIRED_VERSION=0.8.992 +LIBNOTIFY_REQUIRED_VERSION=0.7.3 COMMON_MODULES="gtk+-3.0 >= $GTK_REQUIRED_VERSION glib-2.0 >= $GLIB_REQUIRED_VERSION gthread-2.0 gio-2.0 gio-unix-2.0 - gsettings-desktop-schemas >= $DESKTOP_SCHEMAS_REQUIRED_VERSION" + gsettings-desktop-schemas >= $DESKTOP_SCHEMAS_REQUIRED_VERSION + libnotify >= $LIBNOTIFY_REQUIRED_VERSION" PKG_CHECK_MODULES(LIBGNOME_CONTROL_CENTER, $COMMON_MODULES gconf-2.0) PKG_CHECK_MODULES(LIBLANGUAGE, $COMMON_MODULES gnome-desktop-3.0) diff --git a/panels/printers/new-printer-dialog.ui b/panels/printers/new-printer-dialog.ui index 98aa948b7..cbb947f70 100644 --- a/panels/printers/new-printer-dialog.ui +++ b/panels/printers/new-printer-dialog.ui @@ -81,6 +81,7 @@ True vertical + 10 True @@ -106,7 +107,8 @@ True - A_ddress + 0 + A_ddress: True address-entry @@ -176,7 +178,18 @@ - + + True + True + 6 + False + word + 10 + 10 + + + 2 + diff --git a/panels/printers/pp-new-printer-dialog.c b/panels/printers/pp-new-printer-dialog.c index 33d083e92..e3fbe9312 100644 --- a/panels/printers/pp-new-printer-dialog.c +++ b/panels/printers/pp-new-printer-dialog.c @@ -37,6 +37,7 @@ #include "pp-utils.h" #include +#include #ifdef GDK_WINDOWING_X11 #include @@ -48,6 +49,10 @@ #define PACKAGE_KIT_PATH "/org/freedesktop/PackageKit" #define PACKAGE_KIT_IFACE "org.freedesktop.PackageKit.Modify" +#define FIREWALLD_BUS "org.fedoraproject.FirewallD" +#define FIREWALLD_PATH "/org/fedoraproject/FirewallD" +#define FIREWALLD_IFACE "org.fedoraproject.FirewallD" + #define ALLOWED_CHARACTERS "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_/" static void pp_new_printer_dialog_hide (PpNewPrinterDialog *pp); @@ -57,7 +62,6 @@ enum { NOTEBOOK_LOCAL_PAGE = 0, NOTEBOOK_NETWORK_PAGE, - NOTEBOOK_HP_JETDIRECT_PAGE, NOTEBOOK_N_PAGES }; @@ -80,7 +84,6 @@ enum { DEVICE_TYPE_LOCAL = 0, DEVICE_TYPE_NETWORK, - DEVICE_TYPE_HP_JETDIRECT, DEVICE_TYPE_N }; @@ -115,8 +118,30 @@ struct _PpNewPrinterDialog { gpointer user_data; GCancellable *cancellable; + + gchar *warning; + gboolean show_warning; }; +static void +show_notification (gchar *primary_text, + gchar *secondary_text, + gchar *icon_name) +{ + if (primary_text) + { + NotifyNotification *notification; + notification = notify_notification_new (primary_text, + secondary_text, + icon_name); + notify_notification_set_app_name (notification, _("Printers")); + notify_notification_set_hint (notification, "transient", g_variant_new_boolean (TRUE)); + + notify_notification_show (notification, NULL); + g_object_unref (notification); + } +} + static void device_type_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data) @@ -144,7 +169,10 @@ device_type_selection_changed_cb (GtkTreeSelection *selection, widget = (GtkWidget*) gtk_builder_get_object (pp->builder, "device-type-notebook"); - gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), device_type); + if (pp->show_warning && device_type == DEVICE_TYPE_NETWORK) + gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 2); + else + gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), device_type); if (device_type == DEVICE_TYPE_LOCAL) treeview = (GtkWidget*) @@ -479,6 +507,13 @@ devices_get (PpNewPrinterDialog *pp) if (proxy) { + if (pp->show_warning) + { + widget = (GtkWidget*) + gtk_builder_get_object (pp->builder, "device-type-notebook"); + gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 2); + } + in_include = g_variant_builder_new (G_VARIANT_TYPE ("as")); in_exclude = g_variant_builder_new (G_VARIANT_TYPE ("as")); @@ -598,6 +633,180 @@ line_split (gchar *line) return result; } +static void +service_enable (gchar *service_name, + gint service_timeout) +{ + GDBusProxy *proxy; + GVariant *input = NULL; + GVariant *output = NULL; + GError *error = NULL; + gint result; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + FIREWALLD_BUS, + FIREWALLD_PATH, + FIREWALLD_IFACE, + NULL, + &error); + + if (proxy) + { + input = g_variant_new ("(si)", + service_name, + service_timeout); + + output = g_dbus_proxy_call_sync (proxy, + "enableService", + input, + G_DBUS_CALL_FLAGS_NONE, + 60000, + NULL, + &error); + + if (output && g_variant_n_children (output) == 1) + g_variant_get (output, "(i)", &result); + + if (output) + g_variant_unref (output); + g_variant_unref (input); + g_object_unref (proxy); + } +} + +static void +service_disable (gchar *service_name) +{ + GDBusProxy *proxy; + GVariant *input = NULL; + GVariant *output = NULL; + GError *error = NULL; + gint result; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + FIREWALLD_BUS, + FIREWALLD_PATH, + FIREWALLD_IFACE, + NULL, + &error); + + if (proxy) + { + input = g_variant_new ("(s)", service_name); + + output = g_dbus_proxy_call_sync (proxy, + "disableService", + input, + G_DBUS_CALL_FLAGS_NONE, + 60000, + NULL, + &error); + + if (output && g_variant_n_children (output) == 1) + g_variant_get (output, "(i)", &result); + + if (output) + g_variant_unref (output); + g_variant_unref (input); + g_object_unref (proxy); + } +} + +static gboolean +service_enabled (gchar *service_name) +{ + GDBusProxy *proxy; + GVariant *input = NULL; + GVariant *output = NULL; + GError *error = NULL; + gint query_result = 0; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + FIREWALLD_BUS, + FIREWALLD_PATH, + FIREWALLD_IFACE, + NULL, + &error); + + if (proxy) + { + input = g_variant_new ("(s)", + service_name); + + output = g_dbus_proxy_call_sync (proxy, + "queryService", + input, + G_DBUS_CALL_FLAGS_NONE, + 60000, + NULL, + &error); + + if (output && g_variant_n_children (output) == 1) + g_variant_get (output, "(i)", &query_result); + + if (output) + g_variant_unref (output); + g_variant_unref (input); + g_object_unref (proxy); + } + + if (query_result > 0) + return TRUE; + else + return FALSE; +} + +static gboolean +dbus_method_available (gchar *name, + gchar *path, + gchar *iface, + gchar *method) +{ + GDBusProxy *proxy; + GError *error = NULL; + GVariant *output = NULL; + gboolean result = FALSE; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + name, + path, + iface, + NULL, + NULL); + + if (proxy) + { + output = g_dbus_proxy_call_sync (proxy, + method, + NULL, + G_DBUS_CALL_FLAGS_NONE, + 60000, + NULL, + &error); + + if (error && + error->domain == G_DBUS_ERROR && + error->code == G_DBUS_ERROR_SERVICE_UNKNOWN) + result = FALSE; + else + result = TRUE; + + if (output) + g_variant_unref (output); + g_object_unref (proxy); + } + + return result; +} + static void search_address_cb (GtkToggleButton *togglebutton, gpointer user_data) @@ -825,10 +1034,14 @@ actualize_devices_list (PpNewPrinterDialog *pp) { GtkListStore *network_store; GtkListStore *local_store; + GtkTreeModel *model; GtkTreeView *network_treeview; GtkTreeView *local_treeview; GtkTreeIter iter; + GtkWidget *treeview; + GtkWidget *widget; gint i; + gint device_type = -1; network_treeview = (GtkTreeView*) gtk_builder_get_object (pp->builder, "network-devices-treeview"); @@ -855,6 +1068,7 @@ actualize_devices_list (PpNewPrinterDialog *pp) DEVICE_ID_COLUMN, i, DEVICE_NAME_COLUMN, pp->devices[i].display_name, -1); + pp->show_warning = FALSE; } else if (g_strcmp0 (pp->devices[i].device_class, "direct") == 0) { @@ -880,6 +1094,23 @@ actualize_devices_list (PpNewPrinterDialog *pp) gtk_tree_view_get_selection (GTK_TREE_VIEW (local_treeview)), &iter); + treeview = (GtkWidget*) + gtk_builder_get_object (pp->builder, "device-types-treeview"); + + if (gtk_tree_selection_get_selected ( + gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)), &model, &iter)) + gtk_tree_model_get (model, &iter, + DEVICE_TYPE_TYPE_COLUMN, &device_type, + -1); + + widget = (GtkWidget*) + gtk_builder_get_object (pp->builder, "device-type-notebook"); + + if (pp->show_warning && device_type == DEVICE_TYPE_NETWORK) + gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 2); + else + gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), device_type); + g_object_unref (network_store); g_object_unref (local_store); } @@ -889,6 +1120,9 @@ populate_devices_list (PpNewPrinterDialog *pp) { GtkTreeViewColumn *column; GtkCellRenderer *renderer; + GtkTextBuffer *text_buffer; + GtkTextView *warning_textview; + GtkTextIter text_iter; GtkWidget *network_treeview; GtkWidget *local_treeview; @@ -905,6 +1139,41 @@ populate_devices_list (PpNewPrinterDialog *pp) "changed", G_CALLBACK (device_selection_changed_cb), pp); actualize_devices_list (pp); + + if (dbus_method_available (FIREWALLD_BUS, + FIREWALLD_PATH, + FIREWALLD_IFACE, + "getServices")) + { + if (!service_enabled ("mdns")) + service_enable ("mdns", 300); + + if (!service_enabled ("ipp")) + service_enable ("ipp", 300); + + if (!service_enabled ("ipp-client")) + service_enable ("ipp-client", 300); + + if (!service_enabled ("samba-client")) + service_enable ("samba-client", 300); + } + else + { + pp->warning = g_strdup (_("FirewallD is not running. \ +Network printer detection needs services mdns, ipp, ipp-client \ +and samba-client enabled on firewall.")); + + warning_textview = (GtkTextView*) + gtk_builder_get_object (pp->builder, "warning-textview"); + text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (warning_textview)); + + gtk_text_buffer_set_text (text_buffer, "", 0); + gtk_text_buffer_get_iter_at_offset (text_buffer, &text_iter, 0); + gtk_text_buffer_insert (text_buffer, &text_iter, pp->warning, -1); + + pp->show_warning = TRUE; + } + devices_get (pp); renderer = gtk_cell_renderer_text_new (); @@ -1352,6 +1621,43 @@ new_printer_add_button_cb (GtkButton *button, } g_object_unref (proxy); } + + if (pp->devices[device_id].device_uri && + dbus_method_available (FIREWALLD_BUS, + FIREWALLD_PATH, + FIREWALLD_IFACE, + "getServices")) + { + if (g_str_has_prefix (pp->devices[device_id].device_uri, "dnssd:") || + g_str_has_prefix (pp->devices[device_id].device_uri, "mdns:")) + { + show_notification (_("Opening firewall for mDNS connections"), + NULL, + "dialog-information-symbolic"); + service_disable ("mdns"); + service_enable ("mdns", 0); + } + + if (g_strrstr (pp->devices[device_id].device_uri, "smb:") != NULL) + { + show_notification (_("Opening firewall for Samba connections"), + NULL, + "dialog-information-symbolic"); + service_disable ("samba-client"); + service_enable ("samba-client", 0); + } + + if (g_strrstr (pp->devices[device_id].device_uri, "ipp:") != NULL) + { + show_notification (_("Opening firewall for IPP connections"), + NULL, + "dialog-information-symbolic"); + service_disable ("ipp"); + service_enable ("ipp", 0); + service_disable ("ipp-client"); + service_enable ("ipp-client", 0); + } + } } } @@ -1407,6 +1713,8 @@ pp_new_printer_dialog_new (GtkWindow *parent, pp->user_data = user_data; pp->cancellable = NULL; + pp->warning = NULL; + pp->show_warning = FALSE; /* connect signals */ g_signal_connect (pp->dialog, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL); @@ -1459,6 +1767,8 @@ pp_new_printer_dialog_free (PpNewPrinterDialog *pp) g_object_unref (pp->cancellable); } + g_free (pp->warning); + g_free (pp); } diff --git a/shell/control-center.c b/shell/control-center.c index 2ba41fd7a..167ebb69a 100644 --- a/shell/control-center.c +++ b/shell/control-center.c @@ -28,6 +28,7 @@ #include #include +#include #include "cc-shell-log.h" @@ -181,6 +182,8 @@ main (int argc, char **argv) /* register a symbolic icon size for use in sidebar lists */ gtk_icon_size_register ("cc-sidebar-list", 24, 24); + notify_init ("gnome-control-center"); + shell = gnome_control_center_new (); /* enforce single instance of this application */