From 5fbea471304eb90717126a75b7ccf1ef84d8e150 Mon Sep 17 00:00:00 2001
From: Yann Leboulanger <asterix@lagaule.org>
Date: Fri, 8 Aug 2008 15:19:08 +0000
Subject: [PATCH] warning dialogs when closing a chat window are non blocking

---
 src/chat_control.py      | 16 +++++++++++-----
 src/dialogs.py           |  5 +++--
 src/groupchat_control.py | 34 ++++++++++++++++++++++------------
 src/gtkgui_helpers.py    |  5 ++---
 src/message_control.py   |  8 +++++---
 src/message_window.py    | 39 ++++++++++++++++++++++++++++++---------
 src/roster_window.py     |  2 +-
 7 files changed, 74 insertions(+), 35 deletions(-)

diff --git a/src/chat_control.py b/src/chat_control.py
index ce9583e7b3..b31ec65fb1 100644
--- a/src/chat_control.py
+++ b/src/chat_control.py
@@ -2200,18 +2200,24 @@ def shutdown(self):
 		self.conv_textview.del_handlers()
 		self.msg_textview.destroy()
 
-	def allow_shutdown(self, method):
+	def allow_shutdown(self, method, on_yes, on_no, on_minimize):
 		if time.time() - gajim.last_message_time[self.account]\
 		[self.get_full_jid()] < 2:
 			# 2 seconds
+			def on_ok():
+				on_yes(self)
+
+			def on_cancel():
+				on_no(self)
+
 			dialog = dialogs.ConfirmationDialog(
 				# %s is being replaced in the code with JID
 				_('You just received a new message from "%s"') % self.contact.jid,
 				_('If you close this tab and you have history disabled, '\
-				'this message will be lost.'))
-			if dialog.get_response() != gtk.RESPONSE_OK:
-				return 'no' # stop the propagation of the event
-		return 'yes'
+				'this message will be lost.'), on_response_ok=on_ok,
+				on_response_cancel=on_cancel)
+			return
+		on_yes(self)
 
 	def handle_incoming_chatstate(self):
 		''' handle incoming chatstate that jid SENT TO us '''
diff --git a/src/dialogs.py b/src/dialogs.py
index 43e7a97b01..a140e4a7b9 100644
--- a/src/dialogs.py
+++ b/src/dialogs.py
@@ -1362,9 +1362,10 @@ def on_response_ok(self, widget):
 	def on_response_cancel(self, widget):
 		if self.user_response_cancel:
 			if isinstance(self.user_response_cancel, tuple):
-				self.user_response_cancel[0](*self.user_response_cancel[1:])
+				self.user_response_cancel[0](self.is_checked(),
+					*self.user_response_cancel[1:])
 			else:
-				self.user_response_cancel()
+				self.user_response_cancel(self.is_checked())
 		self.destroy()
 
 	def is_checked(self):
diff --git a/src/groupchat_control.py b/src/groupchat_control.py
index cf5b79fdc9..3f4628a55b 100644
--- a/src/groupchat_control.py
+++ b/src/groupchat_control.py
@@ -1667,37 +1667,47 @@ def shutdown(self, status='offline'):
 		# Remove unread events from systray
 		gajim.events.remove_events(self.account, self.room_jid)
 
-	def allow_shutdown(self, method):
+	def allow_shutdown(self, method, on_yes, on_no, on_minimize):
 		if self.contact.jid in gajim.config.get_per('accounts', self.account,
 		'minimized_gc').split(' '):
-			return 'minimize'
+			on_minimize(self)
+			return
 		if method == self.parent_win.CLOSE_ESC:
 			model, iter = self.list_treeview.get_selection().get_selected()
 			if iter:
 				self.list_treeview.get_selection().unselect_all()
-				return 'no'
-		retval = 'yes'
+				on_no(self)
+				return
 		includes = gajim.config.get('confirm_close_muc_rooms').split(' ')
 		excludes = gajim.config.get('noconfirm_close_muc_rooms').split(' ')
 		# whether to ask for comfirmation before closing muc
 		if (gajim.config.get('confirm_close_muc') or self.room_jid in includes) \
 		and gajim.gc_connected[self.account][self.room_jid] and self.room_jid not\
 		in excludes:
+
+			def on_ok(clicked):
+				if clicked:
+					# user does not want to be asked again
+					gajim.config.set('confirm_close_muc', False)
+				on_yes(self)
+
+			def on_cancel(clicked):
+				if clicked:
+					# user does not want to be asked again
+					gajim.config.set('confirm_close_muc', False)
+				on_no(self)
+
 			pritext = _('Are you sure you want to leave group chat "%s"?')\
 				% self.name
 			sectext = _('If you close this window, you will be disconnected '
 					'from this group chat.')
 
 			dialog = dialogs.ConfirmationDialogCheck(pritext, sectext,
-						_('Do _not ask me again'))
-
-			if dialog.get_response() != gtk.RESPONSE_OK:
-				retval = 'no'
-
-			if dialog.is_checked(): # user does not want to be asked again
-				gajim.config.set('confirm_close_muc', False)
+				_('Do _not ask me again'), on_response_ok=on_ok,
+				on_response_cancel=on_cancel)
+			return
 
-		return retval
+		on_yes(self)
 
 	def set_control_active(self, state):
 		self.conv_textview.allow_focus_out_line = True
diff --git a/src/gtkgui_helpers.py b/src/gtkgui_helpers.py
index 36f0899f36..a0a2e2d175 100644
--- a/src/gtkgui_helpers.py
+++ b/src/gtkgui_helpers.py
@@ -730,9 +730,8 @@ def set_gajim_as_xmpp_handler(is_checked=None):
 		sectext = _('Would you like to make Gajim the default Jabber client?')
 		checktext = _('Always check to see if Gajim is the default Jabber client '
 			'on startup')
-		def on_cancel():
-			gajim.config.set('check_if_gajim_is_default',
-				dlg.is_checked())
+		def on_cancel(checked):
+			gajim.config.set('check_if_gajim_is_default', checked)
 		dlg = dialogs.ConfirmationDialogCheck(pritext, sectext, checktext,
 			set_gajim_as_xmpp_handler, on_cancel)
 		if gajim.config.get('check_if_gajim_is_default'):
diff --git a/src/message_control.py b/src/message_control.py
index ed48828aeb..d8ddacf1c5 100644
--- a/src/message_control.py
+++ b/src/message_control.py
@@ -62,12 +62,14 @@ def set_control_active(self, state):
 		or inactive (state is False)'''
 		pass  # Derived classes MUST implement this method
 
-	def allow_shutdown(self, method):
+	def allow_shutdown(self, method, on_response_yes, on_response_no,
+	on_response_minimize):
 		'''Called to check is a control is allowed to shutdown.
 		If a control is not in a suitable shutdown state this method
-		should return 'no', else 'yes' or 'minimize' '''
+		should call on_response_no, else on_response_yes or
+		on_response_minimize '''
 		# NOTE: Derived classes MAY implement this
-		return 'yes'
+		on_response_yes(self)
 
 	def shutdown(self):
 		# NOTE: Derived classes MUST implement this
diff --git a/src/message_window.py b/src/message_window.py
index e7745042a3..50fbdc3211 100644
--- a/src/message_window.py
+++ b/src/message_window.py
@@ -65,6 +65,8 @@ def __init__(self, acct, type, parent_window=None, parent_paned=None):
 		# dict { handler id: widget}. Keeps callbacks, which
 		# lead to cylcular references
 		self.handlers = {}
+		# Don't show warning dialogs when we want to delete the window
+		self.dont_warn_on_delete = False
 
 		self.widget_name = 'message_window'
 		self.xml = gtkgui_helpers.get_glade('%s.glade' % self.widget_name)
@@ -182,18 +184,30 @@ def _on_window_focus(self, widget, event):
 				self.redraw_tab(ctrl)
 
 	def _on_window_delete(self, win, event):
+		if self.dont_warn_on_delete:
+			# Destroy the window
+			return False
+
+		def on_yes(ctrl):
+			if self.on_delete_ok == 1:
+				self.dont_warn_on_delete = True
+				win.destroy()
+			self.on_delete_ok -= 1
+
+		def on_no(ctrl):
+			return
+
+		def on_minimize(ctrl):
+			self.on_delete_ok -= 1
+			ctrl.minimize()
+
 		# Make sure all controls are okay with being deleted
 		ctrl_to_minimize = []
+		self.on_delete_ok = self.get_nb_controls()
 		for ctrl in self.controls():
-			allow_shutdown = ctrl.allow_shutdown(self.CLOSE_CLOSE_BUTTON)
-			if allow_shutdown == 'no':
-				return True # halt the delete
-			elif allow_shutdown == 'minimize':
-				ctrl_to_minimize.append(ctrl)
-		# If all are ok, minimize the one that need to be minimized
-		for ctrl in ctrl_to_minimize:
-			ctrl.minimize()
-		return False
+			ctrl.allow_shutdown(self.CLOSE_CLOSE_BUTTON, on_yes, on_no,
+				on_minimize)
+		return True # halt the delete for the moment
 
 	def _on_window_destroy(self, win):
 		for ctrl in self.controls():
@@ -607,6 +621,13 @@ def controls(self):
 			for ctrl in jid_dict.values():
 				yield ctrl
 
+	def get_nb_controls(self):
+		nb_ctrl = 0
+		for jid_dict in self._controls.values():
+			for ctrl in jid_dict.values():
+				nb_ctrl += 1
+		return nb_ctrl
+
 	def move_to_next_unread_tab(self, forward):
 		ind = self.notebook.get_current_page()
 		current = ind
diff --git a/src/roster_window.py b/src/roster_window.py
index 72f41d3fe2..24d6597e0f 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -3795,7 +3795,7 @@ def merge_contacts(is_checked=None):
 			'line. Generally it is used when the same person has several Jabber '
 			'accounts or transport accounts.')
 		dlg = dialogs.ConfirmationDialogCheck(pritext, sectext,
-			_('Do _not ask me again'), on_response_ok = merge_contacts)
+			_('Do _not ask me again'), on_response_ok=merge_contacts)
 		if not confirm_metacontacts: # First time we see this window
 			dlg.checkbutton.set_active(True)
 
-- 
GitLab