* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
#include <string.h>
#include "gtkmountoperationprivate.h"
-#include "gtkalignment.h"
#include "gtkbox.h"
+#include "gtkdbusgenerated.h"
#include "gtkentry.h"
-#include "gtkhbox.h"
+#include "gtkbox.h"
#include "gtkintl.h"
#include "gtklabel.h"
-#include "gtkvbox.h"
#include "gtkmessagedialog.h"
-#include "gtkmisc.h"
#include "gtkmountoperation.h"
#include "gtkprivate.h"
#include "gtkradiobutton.h"
#include "gtkstock.h"
-#include "gtktable.h"
+#include "gtkgrid.h"
#include "gtkwindow.h"
#include "gtktreeview.h"
#include "gtktreeselection.h"
#include "gtkimagemenuitem.h"
#include "gtkmain.h"
+#include <glib/gprintf.h>
+
/**
* SECTION:filesystem
* @short_description: Functions for working with GIO
GtkDialog *dialog;
GdkScreen *screen;
+ /* bus proxy */
+ _GtkMountOperationHandler *handler;
+ GCancellable *cancellable;
+ gboolean handler_showing;
+
/* for the ask-password dialog */
GtkWidget *entry_container;
GtkWidget *username_entry;
static void
gtk_mount_operation_init (GtkMountOperation *operation)
{
+ gchar *name_owner;
+
operation->priv = G_TYPE_INSTANCE_GET_PRIVATE (operation,
GTK_TYPE_MOUNT_OPERATION,
GtkMountOperationPrivate);
+
+ operation->priv->handler =
+ _gtk_mount_operation_handler_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ "org.gtk.MountOperationHandler",
+ "/org/gtk/MountOperationHandler",
+ NULL, NULL);
+ name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (operation->priv->handler));
+ if (!name_owner)
+ g_clear_object (&operation->priv->handler);
+ g_free (name_owner);
}
static void
if (priv->screen)
g_object_unref (priv->screen);
+ if (priv->handler)
+ g_object_unref (priv->handler);
+
G_OBJECT_CLASS (gtk_mount_operation_parent_class)->finalize (object);
}
break;
case PROP_IS_SHOWING:
- g_value_set_boolean (value, priv->dialog != NULL);
+ g_value_set_boolean (value, priv->dialog != NULL || priv->handler_showing);
break;
case PROP_SCREEN:
}
}
+static void
+gtk_mount_operation_proxy_finish (GtkMountOperation *op,
+ GMountOperationResult result)
+{
+ _gtk_mount_operation_handler_call_close (op->priv->handler, NULL, NULL, NULL);
+
+ op->priv->handler_showing = FALSE;
+ g_object_notify (G_OBJECT (op), "is-showing");
+
+ g_mount_operation_reply (G_MOUNT_OPERATION (op), result);
+
+ /* drop the reference acquired when calling the proxy method */
+ g_object_unref (op);
+}
+
static void
remember_button_toggled (GtkToggleButton *button,
GtkMountOperation *operation)
GtkWidget *label;
label = gtk_label_new_with_mnemonic (label_text);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
+ gtk_widget_set_hexpand (label, TRUE);
entry = gtk_entry_new ();
if (value)
gtk_entry_set_text (GTK_ENTRY (entry), value);
- gtk_table_attach (GTK_TABLE (table), label,
- 0, 1, row, row + 1,
- GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- gtk_table_attach_defaults (GTK_TABLE (table), entry,
- 1, 2, row, row + 1);
+ gtk_grid_attach (GTK_GRID (table), label, 0, row, 1, 1);
+ gtk_grid_attach (GTK_GRID (table), entry, 1, row, 1, 1);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
g_signal_connect (entry, "changed",
}
static void
-gtk_mount_operation_ask_password (GMountOperation *mount_op,
- const char *message,
- const char *default_user,
- const char *default_domain,
- GAskPasswordFlags flags)
+gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
+ const gchar *message,
+ const gchar *default_user,
+ const gchar *default_domain)
{
- GtkMountOperation *operation;
GtkMountOperationPrivate *priv;
GtkWidget *widget;
GtkDialog *dialog;
GtkWindow *window;
- GtkWidget *entry_container;
GtkWidget *hbox, *main_vbox, *vbox, *icon;
GtkWidget *table;
GtkWidget *message_label;
guint rows;
const gchar *secondary;
- operation = GTK_MOUNT_OPERATION (mount_op);
priv = operation->priv;
- priv->ask_flags = flags;
-
widget = gtk_dialog_new ();
dialog = GTK_DIALOG (widget);
window = GTK_WINDOW (widget);
icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
GTK_ICON_SIZE_DIALOG);
- gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0.0);
+ gtk_widget_set_halign (icon, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign (icon, GTK_ALIGN_START);
gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 18);
message_label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (message_label), s);
- gtk_misc_set_alignment (GTK_MISC (message_label), 0.0, 0.5);
+ gtk_widget_set_halign (message_label, GTK_ALIGN_START);
+ gtk_widget_set_valign (message_label, GTK_ALIGN_CENTER);
gtk_label_set_line_wrap (GTK_LABEL (message_label), TRUE);
gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (message_label),
FALSE, TRUE, 0);
else
{
message_label = gtk_label_new (message);
- gtk_misc_set_alignment (GTK_MISC (message_label), 0.0, 0.5);
+ gtk_widget_set_halign (message_label, GTK_ALIGN_START);
+ gtk_widget_set_valign (message_label, GTK_ALIGN_CENTER);
gtk_label_set_line_wrap (GTK_LABEL (message_label), TRUE);
gtk_box_pack_start (GTK_BOX (main_vbox), GTK_WIDGET (message_label),
FALSE, FALSE, 0);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
- can_anonymous = flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED;
+ can_anonymous = priv->ask_flags & G_ASK_PASSWORD_ANONYMOUS_SUPPORTED;
priv->anonymous_toggle = NULL;
if (can_anonymous)
rows = 0;
- if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_PASSWORD)
rows++;
- if (flags & G_ASK_PASSWORD_NEED_USERNAME)
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_USERNAME)
rows++;
- if (flags &G_ASK_PASSWORD_NEED_DOMAIN)
+ if (priv->ask_flags &G_ASK_PASSWORD_NEED_DOMAIN)
rows++;
/* The table that holds the entries */
- entry_container = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+ table = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (table), 6);
+ gtk_grid_set_column_spacing (GTK_GRID (table), 6);
- gtk_alignment_set_padding (GTK_ALIGNMENT (entry_container),
- 0, 0, can_anonymous ? 12 : 0, 0);
-
- gtk_box_pack_start (GTK_BOX (vbox), entry_container,
- FALSE, FALSE, 0);
- priv->entry_container = entry_container;
+ if (can_anonymous)
+ gtk_widget_set_margin_left (table, 12);
- table = gtk_table_new (rows, 2, FALSE);
- gtk_table_set_col_spacings (GTK_TABLE (table), 12);
- gtk_table_set_row_spacings (GTK_TABLE (table), 6);
- gtk_container_add (GTK_CONTAINER (entry_container), table);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ priv->entry_container = table;
rows = 0;
priv->username_entry = NULL;
- if (flags & G_ASK_PASSWORD_NEED_USERNAME)
+
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_USERNAME)
priv->username_entry = table_add_entry (table, rows++, _("_Username:"),
default_user, operation);
priv->domain_entry = NULL;
- if (flags & G_ASK_PASSWORD_NEED_DOMAIN)
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_DOMAIN)
priv->domain_entry = table_add_entry (table, rows++, _("_Domain:"),
default_domain, operation);
priv->password_entry = NULL;
- if (flags & G_ASK_PASSWORD_NEED_PASSWORD)
+ if (priv->ask_flags & G_ASK_PASSWORD_NEED_PASSWORD)
{
priv->password_entry = table_add_entry (table, rows++, _("_Password:"),
NULL, operation);
gtk_entry_set_visibility (GTK_ENTRY (priv->password_entry), FALSE);
}
- if (flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
+ if (priv->ask_flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
{
GtkWidget *choice;
GtkWidget *remember_box;
gtk_box_pack_start (GTK_BOX (vbox), remember_box,
FALSE, FALSE, 0);
- password_save = g_mount_operation_get_password_save (mount_op);
+ password_save = g_mount_operation_get_password_save (G_MOUNT_OPERATION (operation));
choice = gtk_radio_button_new_with_mnemonic (NULL, _("Forget password _immediately"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
g_object_ref (operation);
}
+static void
+call_password_proxy_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ _GtkMountOperationHandler *proxy = _GTK_MOUNT_OPERATION_HANDLER (source);
+ GMountOperation *op = user_data;
+ GMountOperationResult result;
+ GVariant *result_details;
+ GVariantIter iter;
+ const gchar *key;
+ GVariant *value;
+ GError *error = NULL;
+
+ if (!_gtk_mount_operation_handler_call_ask_password_finish (proxy,
+ &result,
+ &result_details,
+ res,
+ &error))
+ {
+ result = G_MOUNT_OPERATION_ABORTED;
+ g_warning ("Shell mount operation error: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ g_variant_iter_init (&iter, result_details);
+ while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
+ {
+ if (strcmp (key, "password") == 0)
+ g_mount_operation_set_password (op, g_variant_get_string (value, NULL));
+ else if (strcmp (key, "password_save") == 0)
+ g_mount_operation_set_password_save (op, g_variant_get_uint32 (value));
+ }
+
+ out:
+ gtk_mount_operation_proxy_finish (GTK_MOUNT_OPERATION (op), result);
+}
+
+static void
+gtk_mount_operation_ask_password_do_proxy (GtkMountOperation *operation,
+ const char *message,
+ const char *default_user,
+ const char *default_domain)
+{
+ gchar id[255];
+ g_sprintf(id, "GtkMountOperation%p", operation);
+
+ operation->priv->handler_showing = TRUE;
+ g_object_notify (G_OBJECT (operation), "is-showing");
+
+ /* keep a ref to the operation while the handler is showing */
+ g_object_ref (operation);
+
+ _gtk_mount_operation_handler_call_ask_password (operation->priv->handler, id,
+ message, "drive-harddisk",
+ default_user, default_domain,
+ operation->priv->ask_flags, NULL,
+ call_password_proxy_cb, operation);
+}
+
+static void
+gtk_mount_operation_ask_password (GMountOperation *mount_op,
+ const char *message,
+ const char *default_user,
+ const char *default_domain,
+ GAskPasswordFlags flags)
+{
+ GtkMountOperation *operation;
+ GtkMountOperationPrivate *priv;
+ gboolean use_gtk;
+
+ operation = GTK_MOUNT_OPERATION (mount_op);
+ priv = operation->priv;
+ priv->ask_flags = flags;
+
+ use_gtk = (operation->priv->handler == NULL) ||
+ (priv->ask_flags & G_ASK_PASSWORD_NEED_DOMAIN) ||
+ (priv->ask_flags & G_ASK_PASSWORD_NEED_USERNAME);
+
+ if (use_gtk)
+ gtk_mount_operation_ask_password_do_gtk (operation, message, default_user, default_domain);
+ else
+ gtk_mount_operation_ask_password_do_proxy (operation, message, default_user, default_domain);
+}
+
static void
question_dialog_button_clicked (GtkDialog *dialog,
gint button_number,
}
static void
-gtk_mount_operation_ask_question (GMountOperation *op,
- const char *message,
- const char *choices[])
+gtk_mount_operation_ask_question_do_gtk (GtkMountOperation *op,
+ const char *message,
+ const char *choices[])
{
GtkMountOperationPrivate *priv;
GtkWidget *dialog;
g_return_if_fail (message != NULL);
g_return_if_fail (choices != NULL);
- priv = GTK_MOUNT_OPERATION (op)->priv;
+ priv = op->priv;
primary = strstr (message, "\n");
if (primary)
g_object_ref (op);
}
+static void
+call_question_proxy_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ _GtkMountOperationHandler *proxy = _GTK_MOUNT_OPERATION_HANDLER (source);
+ GMountOperation *op = user_data;
+ GMountOperationResult result;
+ GVariant *result_details;
+ GVariantIter iter;
+ const gchar *key;
+ GVariant *value;
+ GError *error = NULL;
+
+ if (!_gtk_mount_operation_handler_call_ask_question_finish (proxy,
+ &result,
+ &result_details,
+ res,
+ &error))
+ {
+ result = G_MOUNT_OPERATION_ABORTED;
+ g_warning ("Shell mount operation error: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ g_variant_iter_init (&iter, result_details);
+ while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
+ {
+ if (strcmp (key, "choice") == 0)
+ g_mount_operation_set_choice (op, g_variant_get_int32 (value));
+ }
+
+ out:
+ gtk_mount_operation_proxy_finish (GTK_MOUNT_OPERATION (op), result);
+}
+
+static void
+gtk_mount_operation_ask_question_do_proxy (GtkMountOperation *operation,
+ const char *message,
+ const char *choices[])
+{
+ gchar id[255];
+ g_sprintf(id, "GtkMountOperation%p", operation);
+
+ operation->priv->handler_showing = TRUE;
+ g_object_notify (G_OBJECT (operation), "is-showing");
+
+ /* keep a ref to the operation while the handler is showing */
+ g_object_ref (operation);
+
+ _gtk_mount_operation_handler_call_ask_question (operation->priv->handler, id,
+ message, "drive-harddisk",
+ choices, NULL,
+ call_question_proxy_cb, operation);
+}
+
+static void
+gtk_mount_operation_ask_question (GMountOperation *op,
+ const char *message,
+ const char *choices[])
+{
+ GtkMountOperation *operation;
+ gboolean use_gtk;
+
+ operation = GTK_MOUNT_OPERATION (op);
+ use_gtk = (operation->priv->handler == NULL);
+
+ if (use_gtk)
+ gtk_mount_operation_ask_question_do_gtk (operation, message, choices);
+ else
+ gtk_mount_operation_ask_question_do_proxy (operation, message, choices);
+}
+
static void
show_processes_button_clicked (GtkDialog *dialog,
gint button_number,
ret = FALSE;
- /* Ignore double-clicks and triple-clicks */
- if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
+ if (gdk_event_triggers_context_menu ((GdkEvent *) event))
{
ret = do_popup_menu_for_process_tree_view (widget, event, op);
}
}
static GtkWidget *
-create_show_processes_dialog (GMountOperation *op,
+create_show_processes_dialog (GtkMountOperation *op,
const char *message,
const char *choices[])
{
GtkListStore *list_store;
gchar *s;
- priv = GTK_MOUNT_OPERATION (op)->priv;
+ priv = op->priv;
primary = strstr (message, "\n");
if (primary)
}
static void
-gtk_mount_operation_show_processes (GMountOperation *op,
- const char *message,
- GArray *processes,
- const char *choices[])
+call_processes_proxy_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ _GtkMountOperationHandler *proxy = _GTK_MOUNT_OPERATION_HANDLER (source);
+ GMountOperation *op = user_data;
+ GMountOperationResult result;
+ GVariant *result_details;
+ GVariantIter iter;
+ const gchar *key;
+ GVariant *value;
+ GError *error = NULL;
+
+ if (!_gtk_mount_operation_handler_call_show_processes_finish (proxy,
+ &result,
+ &result_details,
+ res,
+ &error))
+ {
+ result = G_MOUNT_OPERATION_ABORTED;
+ g_warning ("Shell mount operation error: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* If the request was unhandled it means we called the method again;
+ * in this case, just return and wait for the next response.
+ */
+ if (result == G_MOUNT_OPERATION_UNHANDLED)
+ return;
+
+ g_variant_iter_init (&iter, result_details);
+ while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
+ {
+ if (strcmp (key, "choice") == 0)
+ g_mount_operation_set_choice (op, g_variant_get_int32 (value));
+ }
+
+ out:
+ gtk_mount_operation_proxy_finish (GTK_MOUNT_OPERATION (op), result);
+}
+
+static void
+gtk_mount_operation_show_processes_do_proxy (GtkMountOperation *operation,
+ const char *message,
+ GArray *processes,
+ const char *choices[])
+{
+ gchar id[255];
+ g_sprintf(id, "GtkMountOperation%p", operation);
+
+ operation->priv->handler_showing = TRUE;
+ g_object_notify (G_OBJECT (operation), "is-showing");
+
+ /* keep a ref to the operation while the handler is showing */
+ g_object_ref (operation);
+
+ _gtk_mount_operation_handler_call_show_processes (operation->priv->handler, id,
+ message, "drive-harddisk",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_INT32,
+ processes->data, processes->len,
+ sizeof (GPid)),
+ choices, NULL,
+ call_processes_proxy_cb, operation);
+}
+
+static void
+gtk_mount_operation_show_processes_do_gtk (GtkMountOperation *op,
+ const char *message,
+ GArray *processes,
+ const char *choices[])
{
GtkMountOperationPrivate *priv;
GtkWidget *dialog = NULL;
g_return_if_fail (processes != NULL);
g_return_if_fail (choices != NULL);
- priv = GTK_MOUNT_OPERATION (op)->priv;
+ priv = op->priv;
if (priv->process_list_store == NULL)
{
/* otherwise, we're showing the dialog, assume messages+choices hasn't changed */
- update_process_list_store (GTK_MOUNT_OPERATION (op),
+ update_process_list_store (op,
priv->process_list_store,
processes);
}
}
+
+static void
+gtk_mount_operation_show_processes (GMountOperation *op,
+ const char *message,
+ GArray *processes,
+ const char *choices[])
+{
+
+ GtkMountOperation *operation;
+ gboolean use_gtk;
+
+ operation = GTK_MOUNT_OPERATION (op);
+ use_gtk = (operation->priv->handler == NULL);
+
+ if (use_gtk)
+ gtk_mount_operation_show_processes_do_gtk (operation, message, processes, choices);
+ else
+ gtk_mount_operation_show_processes_do_proxy (operation, message, processes, choices);
+}
+
static void
gtk_mount_operation_aborted (GMountOperation *op)
{
g_object_notify (G_OBJECT (op), "is-showing");
g_object_unref (op);
}
+
+ if (priv->handler != NULL)
+ {
+ _gtk_mount_operation_handler_call_close (priv->handler, NULL, NULL, NULL);
+
+ priv->handler_showing = FALSE;
+ g_object_notify (G_OBJECT (op), "is-showing");
+ }
}
/**