]> cgit.babelmonkeys.de Git - jubjub.git/blobdiff - src/gui/gtk/JubGtkRosterUI.m
Close subscription dialogs, when answered on another client
[jubjub.git] / src / gui / gtk / JubGtkRosterUI.m
index 667760b0734cff566e6f9ed3a23791cc6340159b..e7e36f723a86fa53a1ca67ca533e3dbcd12e9abd 100644 (file)
@@ -63,6 +63,14 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
        return TRUE;
 }
 
+static void dialog_response_callback(GtkDialog *dialog, gint response_id,
+    gpointer user_data)
+{
+       void (^block)(gint) = user_data;
+       block(response_id);
+       [block release];
+}
+
 @implementation JubGtkRosterUI
 - initWithClient: (JubChatClient*)client
 {
@@ -75,6 +83,9 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
                _groupMap = [[OFMapTable alloc]
                    initWithKeyFunctions: keyFunctions
                          valueFunctions: rowRefFunctions];
+               _subDialogMap = [[OFMapTable alloc]
+                   initWithKeyFunctions: keyFunctions
+                   valueFunctions: gObjectFunctions];
                _contactMap = [[OFMutableDictionary alloc] init];
                _client = [client retain];
 
@@ -125,6 +136,7 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
 {
        [_client.avatarManager setDelegate: nil];
        [_client.contactManager removeDelegate: self];
+       [_subDialogMap release];
        [_groupMap release];
        [_contactMap release];
        [_client release];
@@ -134,6 +146,19 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
        [super dealloc];
 }
 
+- (void)Jub_closeSubscribeDialogForRosterItem: (XMPPRosterItem*)rosterItem
+{
+       // Close subscripton dialogs, answered on another client
+       GtkDialog *dialog;
+       OFString *subscription = rosterItem.subscription;
+       OFString *bareJID = [rosterItem.JID bareJID];
+
+       if (([subscription isEqual: @"from"] ||
+            [subscription isEqual: @"both"]) &&
+           (dialog = [_subDialogMap valueForKey: bareJID]) != NULL)
+               gtk_dialog_response(dialog, GTK_RESPONSE_NONE);
+}
+
 /* Roster Delegate methods */
 - (void)Jub_addRosterItem: (XMPPRosterItem*)item
                    group: (OFString*)group
@@ -257,6 +282,8 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
                    Jub_addRosterItem:group:)
                                       withObject: rosterItem
                                       withObject: group];
+
+       [self Jub_closeSubscribeDialogForRosterItem: rosterItem];
 }
 
 - (void)contactManager: (XMPPContactManager*)manager
@@ -275,9 +302,52 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model,
                                       withObject: group];
 }
 
+-          (void)contactManager: (XMPPContactManager*)manager
+  didReceiveSubscriptionRequest: (XMPPPresence*)presence
+{
+       XMPPJID *JID = presence.from;
+       OFString *bareJID = [JID bareJID];
+       OFString *message = [OFString stringWithFormat: @"<b>%@</b> would like "
+           @"to subscribe to your presence.", bareJID];
+       g_idle_add_block(^{
+               GtkWidget *dialog, *content_area, *label;
+
+               if ([_subDialogMap valueForKey: JID] != NULL)
+                       return;
+
+               dialog = gtk_dialog_new_with_buttons("Subscription Request",
+                   GTK_WINDOW(_roster_window), GTK_DIALOG_DESTROY_WITH_PARENT,
+                   "Accept", GTK_RESPONSE_ACCEPT,
+                   "Deny", GTK_RESPONSE_REJECT, NULL);
+
+               content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+               label = gtk_label_new(NULL);
+               gtk_label_set_markup(GTK_LABEL(label), [message UTF8String]);
+               gtk_container_add(GTK_CONTAINER(content_area), label);
+
+               g_signal_connect(dialog, "response",
+                   G_CALLBACK(dialog_response_callback),
+                   [^(gint response_id) {
+                       if (response_id == GTK_RESPONSE_ACCEPT)
+                               [manager sendSubscribedToJID: JID];
+                       else if (response_id == GTK_RESPONSE_REJECT)
+                               [manager sendUnsubscribedToJID: JID];
+                       [_subDialogMap removeValueForKey: bareJID];
+                       gtk_widget_destroy(GTK_WIDGET(dialog));
+               } copy]);
+
+               [_subDialogMap setValue: dialog
+                                forKey: bareJID];
+
+               gtk_widget_show_all(dialog);
+       });
+}
+
 -           (void)contact: (XMPPContact*)contact
   willUpdateWithRosterItem: (XMPPRosterItem*)rosterItem;
 {
+       [self Jub_closeSubscribeDialogForRosterItem: rosterItem];
+
        // Remove contact from old set of groups
        XMPPRosterItem *oldItem = contact.rosterItem;
        OFArray *groups = oldItem.groups;