Invite dialog fully functional, with dnd removed

Tue, 23 Apr 2019 17:20:19 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Tue, 23 Apr 2019 17:20:19 -0500
changeset 39577
0dd1d673bbef
parent 39576
9da340b66f6d
child 39578
03e375280534

Invite dialog fully functional, with dnd removed

pidgin/gtkconv.c file | annotate | diff | comparison | revisions
pidgin/meson.build file | annotate | diff | comparison | revisions
pidgin/pidgininvitedialog.c file | annotate | diff | comparison | revisions
pidgin/pidgininvitedialog.h file | annotate | diff | comparison | revisions
pidgin/resources/Conversations/invite_dialog.ui file | annotate | diff | comparison | revisions
pidgin/resources/pidgin.gresource.xml file | annotate | diff | comparison | revisions
--- a/pidgin/gtkconv.c	Tue Apr 23 16:04:12 2019 -0500
+++ b/pidgin/gtkconv.c	Tue Apr 23 17:20:19 2019 -0500
@@ -67,6 +67,7 @@
 #include "gtkutils.h"
 #include "gtkwebview.h"
 #include "pidgingdkpixbuf.h"
+#include "pidgininvitedialog.h"
 #include "pidginstock.h"
 #include "pidgintooltip.h"
 
@@ -161,16 +162,6 @@
 
 static GtkTargetList *webkit_dnd_targets = NULL;
 
-typedef struct {
-	GtkWidget *window;
-
-	GtkWidget *entry;
-	GtkWidget *message;
-
-	PurpleChatConversation *chat;
-
-} InviteBuddyInfo;
-
 static GtkWidget *invite_dialog = NULL;
 static GtkWidget *warn_close_dialog = NULL;
 
@@ -805,245 +796,44 @@
 }
 
 static void
-do_invite(GtkWidget *w, int resp, InviteBuddyInfo *info)
-{
-	const char *buddy, *message;
-	PurpleChatConversation *chat;
-
-	chat = info->chat;
-
-	if (resp == GTK_RESPONSE_OK) {
-		buddy   = gtk_entry_get_text(GTK_ENTRY(info->entry));
-		message = gtk_entry_get_text(GTK_ENTRY(info->message));
-
-		if (!g_ascii_strcasecmp(buddy, ""))
+do_invite(GtkWidget *w, int resp, PurpleChatConversation *chat)
+{
+	const gchar *contact, *message;
+
+	if (resp == GTK_RESPONSE_ACCEPT) {
+		contact = pidgin_invite_dialog_get_contact(PIDGIN_INVITE_DIALOG(w));
+		if (!g_ascii_strcasecmp(contact, ""))
 			return;
 
+		message = pidgin_invite_dialog_get_message(PIDGIN_INVITE_DIALOG(w));
+
 		purple_serv_chat_invite(purple_conversation_get_connection(PURPLE_CONVERSATION(chat)),
 						 purple_chat_conversation_get_id(chat),
-						 message, buddy);
-	}
-
-	gtk_widget_destroy(invite_dialog);
-	invite_dialog = NULL;
-
-	g_free(info);
-}
-
-static void
-invite_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
-				GtkSelectionData *sd, guint dnd_info, guint t, gpointer data)
-{
-	InviteBuddyInfo *info = (InviteBuddyInfo *)data;
-	const char *convprotocol;
-	gboolean success = TRUE;
-
-	convprotocol = purple_account_get_protocol_id(
-			purple_conversation_get_account(PURPLE_CONVERSATION(info->chat)));
-
-	if (dnd_info == PIDGIN_DRAG_BLIST_NODE)
-	{
-		PurpleBlistNode *node = NULL;
-		PurpleBuddy *buddy;
-		const guchar *data = gtk_selection_data_get_data(sd);
-
-		memcpy(&node, data, sizeof(node));
-
-		if (PURPLE_IS_CONTACT(node))
-			buddy = purple_contact_get_priority_buddy((PurpleContact *)node);
-		else if (PURPLE_IS_BUDDY(node))
-			buddy = (PurpleBuddy *)node;
-		else
-			return;
-
-		if (!purple_strequal(convprotocol, purple_account_get_protocol_id(purple_buddy_get_account(buddy))))
-		{
-			purple_notify_error(PIDGIN_CONVERSATION(PURPLE_CONVERSATION(info->chat)),
-				NULL, _("That buddy is not on the same protocol"
-				" as this chat."), NULL,
-				purple_request_cpar_from_conversation(PURPLE_CONVERSATION(info->chat)));
-			success = FALSE;
-		}
-		else
-			gtk_entry_set_text(GTK_ENTRY(info->entry), purple_buddy_get_name(buddy));
-
-		gtk_drag_finish(dc, success,
-		                gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
-	}
-	else if (dnd_info == PIDGIN_DRAG_IM_CONTACT)
-	{
-		char *protocol = NULL;
-		char *username = NULL;
-		PurpleAccount *account;
-
-		if (pidgin_parse_x_im_contact((const char *) data, FALSE, &account,
-										&protocol, &username, NULL))
-		{
-			if (account == NULL)
-			{
-				purple_notify_error(PIDGIN_CONVERSATION(PURPLE_CONVERSATION(info->chat)), NULL,
-					_("You are not currently signed on with an account that "
-					  "can invite that buddy."), NULL, NULL);
-			}
-			else if (!purple_strequal(convprotocol, purple_account_get_protocol_id(account)))
-			{
-				purple_notify_error(
-					PIDGIN_CONVERSATION(PURPLE_CONVERSATION(info->chat)), NULL,
-					_("That buddy is not on the same "
-					"protocol as this chat."), NULL,
-					purple_request_cpar_from_account(
-						account));
-				success = FALSE;
-			}
-			else
-			{
-				gtk_entry_set_text(GTK_ENTRY(info->entry), username);
-			}
-		}
-
-		g_free(username);
-		g_free(protocol);
-
-		gtk_drag_finish(dc, success,
-		                gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
-	}
+						 message, contact);
+	}
+
+	g_clear_pointer(&invite_dialog, gtk_widget_destroy);
 }
 
 static void
 invite_cb(GtkWidget *widget, PidginConversation *gtkconv)
 {
 	PurpleChatConversation *chat = PURPLE_CHAT_CONVERSATION(gtkconv->active_conv);
-	InviteBuddyInfo *info = NULL;
 
 	if (invite_dialog == NULL) {
-		PidginConvWindow *gtkwin;
-		GtkWidget *label;
-		GtkWidget *vbox, *hbox;
-		GtkWidget *grid;
-		GtkWidget *img;
-
-		img = gtk_image_new_from_icon_name("dialog-question",
-				GTK_ICON_SIZE_DIALOG);
-
-		info = g_new0(InviteBuddyInfo, 1);
-		info->chat = chat;
-
-		gtkwin    = pidgin_conv_get_window(gtkconv);
-
-		/* Create the new dialog. */
-		invite_dialog = gtk_dialog_new_with_buttons(
-			_("Invite Buddy Into Chat Room"),
-			GTK_WINDOW(gtkwin->window), 0,
-			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-			PIDGIN_STOCK_INVITE, GTK_RESPONSE_OK, NULL);
-
-		gtk_dialog_set_default_response(GTK_DIALOG(invite_dialog),
-		                                GTK_RESPONSE_OK);
-		gtk_container_set_border_width(GTK_CONTAINER(invite_dialog), PIDGIN_HIG_BOX_SPACE);
-		gtk_window_set_resizable(GTK_WINDOW(invite_dialog), FALSE);
-
-		info->window = GTK_WIDGET(invite_dialog);
-
-		/* Setup the outside spacing. */
-		vbox = gtk_dialog_get_content_area(GTK_DIALOG(invite_dialog));
-
-		gtk_box_set_spacing(GTK_BOX(vbox), PIDGIN_HIG_BORDER);
-		gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BOX_SPACE);
-
-		/* Setup the inner hbox and put the dialog's icon in it. */
-		hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PIDGIN_HIG_BORDER);
-		gtk_container_add(GTK_CONTAINER(vbox), hbox);
-		gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
-		gtk_widget_set_halign(img, GTK_ALIGN_START);
-		gtk_widget_set_valign(img, GTK_ALIGN_START);
-
-		/* Setup the right vbox. */
-		vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-		gtk_container_add(GTK_CONTAINER(hbox), vbox);
-
-		/* Put our happy label in it. */
-		label = gtk_label_new(_("Please enter the name of the user you wish "
-								"to invite, along with an optional invite "
-								"message."));
-		gtk_widget_set_size_request(label, 350, -1);
-		gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
-		gtk_label_set_xalign(GTK_LABEL(label), 0);
-		gtk_label_set_yalign(GTK_LABEL(label), 0);
-		gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-
-		/* hbox for the grid, and to give it some spacing on the left. */
-		hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PIDGIN_HIG_BOX_SPACE);
-		gtk_container_add(GTK_CONTAINER(vbox), hbox);
-
-		/* Setup the grid we're going to use to lay stuff out. */
-		grid = gtk_grid_new();
-		gtk_grid_set_row_spacing(GTK_GRID(grid), PIDGIN_HIG_BOX_SPACE);
-		gtk_grid_set_column_spacing(GTK_GRID(grid), PIDGIN_HIG_BOX_SPACE);
-		gtk_container_set_border_width(GTK_CONTAINER(grid), PIDGIN_HIG_BORDER);
-		gtk_box_pack_start(GTK_BOX(vbox), grid, FALSE, FALSE, 0);
-
-		/* Now the Buddy label */
-		label = gtk_label_new(NULL);
-		gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Buddy:"));
-		gtk_widget_set_hexpand(label, TRUE);
-		gtk_widget_set_vexpand(label, TRUE);
-		gtk_label_set_xalign(GTK_LABEL(label), 0);
-		gtk_label_set_yalign(GTK_LABEL(label), 0);
-		gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
-
-		/* Now the Buddy drop-down entry field. */
-		info->entry = gtk_entry_new();
+		invite_dialog = pidgin_invite_dialog_new();
+
+		/*
 		pidgin_setup_screenname_autocomplete(info->entry, NULL, chat_invite_filter,
 				purple_conversation_get_account(PURPLE_CONVERSATION(chat)));
-		gtk_widget_set_hexpand(info->entry, TRUE);
-		gtk_widget_set_vexpand(info->entry, TRUE);
-		gtk_grid_attach(GTK_GRID(grid), info->entry, 1, 0, 1, 1);
-		gtk_label_set_mnemonic_widget(GTK_LABEL(label), info->entry);
-
-		/* Now the label for "Message" */
-		label = gtk_label_new(NULL);
-		gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Message:"));
-		gtk_widget_set_hexpand(label, TRUE);
-		gtk_widget_set_vexpand(label, TRUE);
-		gtk_label_set_xalign(GTK_LABEL(label), 0);
-		gtk_label_set_yalign(GTK_LABEL(label), 0);
-		gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);
-
-		/* And finally, the Message entry field. */
-		info->message = gtk_entry_new();
-		gtk_entry_set_activates_default(GTK_ENTRY(info->message), TRUE);
-		gtk_widget_set_hexpand(info->message, TRUE);
-		gtk_widget_set_vexpand(info->message, TRUE);
-		gtk_grid_attach(GTK_GRID(grid), info->message, 1, 1, 1, 1);
-		gtk_label_set_mnemonic_widget(GTK_LABEL(label), info->message);
+		*/
 
 		/* Connect the signals. */
 		g_signal_connect(G_OBJECT(invite_dialog), "response",
-						 G_CALLBACK(do_invite), info);
-		/* Setup drag-and-drop */
-		gtk_drag_dest_set(info->window,
-						  GTK_DEST_DEFAULT_MOTION |
-						  GTK_DEST_DEFAULT_DROP,
-						  dnd_targets,
-						  sizeof(dnd_targets) / sizeof(GtkTargetEntry),
-						  GDK_ACTION_COPY);
-		gtk_drag_dest_set(info->entry,
-						  GTK_DEST_DEFAULT_MOTION |
-						  GTK_DEST_DEFAULT_DROP,
-						  dnd_targets,
-						  sizeof(dnd_targets) / sizeof(GtkTargetEntry),
-						  GDK_ACTION_COPY);
-
-		g_signal_connect(G_OBJECT(info->window), "drag_data_received",
-						 G_CALLBACK(invite_dnd_recv), info);
-		g_signal_connect(G_OBJECT(info->entry), "drag_data_received",
-						 G_CALLBACK(invite_dnd_recv), info);
+						 G_CALLBACK(do_invite), chat);
 	}
 
 	gtk_widget_show_all(invite_dialog);
-
-	if (info != NULL)
-		gtk_widget_grab_focus(info->entry);
 }
 
 static void
--- a/pidgin/meson.build	Tue Apr 23 16:04:12 2019 -0500
+++ b/pidgin/meson.build	Tue Apr 23 17:20:19 2019 -0500
@@ -45,6 +45,7 @@
 	'pidgindebug.c',
 	'pidgindebugplugininfo.c',
 	'pidgingdkpixbuf.c',
+	'pidgininvitedialog.c',
 	'pidgintalkatu.c',
 	'pidgintooltip.c',
 ]
@@ -98,6 +99,7 @@
 	'pidgindebugplugininfo.h',
 	'pidgingdkpixbuf.h',
 	'pidginicon.h',
+	'pidgininvitedialog.h',
 	'pidgintalkatu.h',
 	'pidgintooltip.h',
 	'pidgin.h',
--- a/pidgin/pidgininvitedialog.c	Tue Apr 23 16:04:12 2019 -0500
+++ b/pidgin/pidgininvitedialog.c	Tue Apr 23 17:20:19 2019 -0500
@@ -24,8 +24,8 @@
 };
 
 typedef struct {
-	gchar *contact;
-	gchar *message;
+	GtkWidget *contact;
+	GtkWidget *message;
 } PidginInviteDialogPrivate;
 
 enum {
@@ -119,6 +119,17 @@
 		"/im/pidgin/Pidgin/Conversations/invite_dialog.ui"
 	);
 
+	gtk_widget_class_bind_template_child_private(
+		widget_class,
+		PidginInviteDialog,
+		contact
+	);
+	gtk_widget_class_bind_template_child_private(
+		widget_class,
+		PidginInviteDialog,
+		message
+	);
+
 	properties[PROP_CONTACT] = g_param_spec_string(
 		"contact",
 		"contact",
@@ -139,6 +150,11 @@
 /******************************************************************************
  * Public API
  *****************************************************************************/
+GtkWidget *
+pidgin_invite_dialog_new(void) {
+	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_INVITE_DIALOG, NULL));
+}
+
 const gchar *
 pidgin_invite_dialog_get_contact(PidginInviteDialog *dialog) {
 	PidginInviteDialogPrivate *priv = NULL;
@@ -147,7 +163,7 @@
 
 	priv = pidgin_invite_dialog_get_instance_private(dialog);
 
-	return priv->contact;
+	return gtk_entry_get_text(GTK_ENTRY(priv->contact));
 }
 
 void
@@ -160,13 +176,11 @@
 
 	priv = pidgin_invite_dialog_get_instance_private(dialog);
 
-	g_clear_pointer(&priv->contact, g_free);
+	if(contact != NULL) {
+		gtk_entry_set_text(GTK_ENTRY(priv->contact), contact);
 
-	if(contact != NULL) {
-		priv->contact = g_strdup(contact);
+		g_object_notify_by_pspec(G_OBJECT(dialog), properties[PROP_CONTACT]);
 	}
-
-	g_object_notify_by_pspec(G_OBJECT(dialog), properties[PROP_CONTACT]);
 }
 
 const gchar *
@@ -177,7 +191,7 @@
 
 	priv = pidgin_invite_dialog_get_instance_private(dialog);
 
-	return priv->message;
+	return gtk_entry_get_text(GTK_ENTRY(priv->message));
 }
 
 void
@@ -190,12 +204,10 @@
 
 	priv = pidgin_invite_dialog_get_instance_private(dialog);
 
-	g_clear_pointer(&priv->message, g_free);
+	if(message != NULL) {
+		gtk_entry_set_text(GTK_ENTRY(priv->message), message);
 
-	if(message != NULL) {
-		priv->message = g_strdup(message);
+		g_object_notify_by_pspec(G_OBJECT(dialog), properties[PROP_MESSAGE]);
 	}
-
-	g_object_notify_by_pspec(G_OBJECT(dialog), properties[PROP_MESSAGE]);
 }
 
--- a/pidgin/pidgininvitedialog.h	Tue Apr 23 16:04:12 2019 -0500
+++ b/pidgin/pidgininvitedialog.h	Tue Apr 23 17:20:19 2019 -0500
@@ -1,5 +1,5 @@
-#ifndef PIDGIN_ABOUT_H
-#define PIDGIN_ABOUT_H
+#ifndef PIDGIN_INVITE_DIALOG_H
+#define PIDGIN_INVITE_DIALOG_H
 
 /**
  * SECTION:pidgininvitedialog
@@ -13,17 +13,18 @@
 G_BEGIN_DECLS
 
 #define PIDGIN_TYPE_INVITE_DIALOG  pidgin_invite_dialog_get_type()
+
 G_DECLARE_FINAL_TYPE(PidginInviteDialog, pidgin_invite_dialog, PIDGIN,
 		INVITE_DIALOG, GtkDialog)
 
-GtkWidget *pidgin_invite_dialog_new();
+GtkWidget *pidgin_invite_dialog_new(void);
 
 void pidgin_invite_dialog_set_contact(PidginInviteDialog *dialog, const gchar *contact);
 const gchar *pidgin_invite_dialog_get_contact(PidginInviteDialog *dialog);
 
 void pidgin_invite_dialog_set_message(PidginInviteDialog *dialog, const gchar *message);
-const gchar * pidgin_invite_dialog_get_message(PidginInviteDialog *dialog);
+const gchar *pidgin_invite_dialog_get_message(PidginInviteDialog *dialog);
 
 G_END_DECLS
 
-#endif /* PIDGIN_INVITE_H */
+#endif /* PIDGIN_INVITE_DIALOG_H */
--- a/pidgin/resources/Conversations/invite_dialog.ui	Tue Apr 23 16:04:12 2019 -0500
+++ b/pidgin/resources/Conversations/invite_dialog.ui	Tue Apr 23 17:20:19 2019 -0500
@@ -38,6 +38,8 @@
                 <property name="label" translatable="yes">Invite</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
                 <property name="receives_default">True</property>
               </object>
               <packing>
@@ -101,6 +103,8 @@
               <object class="GtkEntry" id="contact">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="has_focus">True</property>
+                <property name="activates_default">True</property>
               </object>
               <packing>
                 <property name="left_attach">1</property>
@@ -111,6 +115,7 @@
               <object class="GtkEntry" id="message">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="activates_default">True</property>
               </object>
               <packing>
                 <property name="left_attach">1</property>
--- a/pidgin/resources/pidgin.gresource.xml	Tue Apr 23 16:04:12 2019 -0500
+++ b/pidgin/resources/pidgin.gresource.xml	Tue Apr 23 17:20:19 2019 -0500
@@ -5,6 +5,7 @@
     <file compressed="true">About/about.ui</file>
     <file compressed="true">About/about.md</file>
     <file compressed="true">About/credits.json</file>
+    <file compressed="true">Conversations/invite_dialog.ui</file>
     <file compressed="true">Debug/debug.ui</file>
     <file compressed="true">Debug/filter-popover.ui</file>
     <file compressed="true">Debug/plugininfo.ui</file>

mercurial