From 21aa352a344948d076f0fc033aa021312c28cdcb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20H=C3=B6rist?= <philipp@hoerist.com>
Date: Tue, 26 Mar 2019 20:14:53 +0100
Subject: [PATCH] Refactor NewConfirmationDialog

---
 gajim/common/const.py |  3 ---
 gajim/gtk/dialogs.py  | 54 +++++++++++++++++++++++++++++++++++--------
 gajim/gtk/themes.py   | 24 +++++++++----------
 3 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/gajim/common/const.py b/gajim/common/const.py
index d9d030408c..8f6b4ca231 100644
--- a/gajim/common/const.py
+++ b/gajim/common/const.py
@@ -6,9 +6,6 @@ from gajim.common.i18n import _
 Option = namedtuple('Option', 'kind label type value name callback data desc enabledif props')
 Option.__new__.__defaults__ = (None,) * len(Option._fields)  # type: ignore
 
-DialogButton = namedtuple('DialogButton', 'text callback action')
-DialogButton.__new__.__defaults__ = (None, None)  # type: ignore
-
 EncryptionData = namedtuple('EncryptionData', 'additional_data')
 EncryptionData.__new__.__defaults__ = (None,)  # type: ignore
 
diff --git a/gajim/gtk/dialogs.py b/gajim/gtk/dialogs.py
index ce23839509..d2cac935ca 100644
--- a/gajim/gtk/dialogs.py
+++ b/gajim/gtk/dialogs.py
@@ -12,6 +12,8 @@
 # You should have received a copy of the GNU General Public License
 # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
 
+from collections import namedtuple
+
 from gi.repository import Gtk
 
 from gajim.common import app
@@ -22,6 +24,36 @@ from gajim.gtk.util import get_builder
 from gajim.gtk.util import load_icon
 
 
+class DialogButton(namedtuple('DialogButton', ('response text callback args '
+                                               'kwargs action is_default'))):
+    @classmethod
+    def make(cls, type_=None, **kwargs):
+        # Defaults
+        default_kwargs = {
+            'response': None,
+            'text': None,
+            'callback': None,
+            'args': [],
+            'kwargs': {},
+            'action': None,
+            'is_default': False
+        }
+
+        if type_ is not None:
+            if type_ == 'OK':
+                default_kwargs['response'] = Gtk.ResponseType.OK
+                default_kwargs['text'] = 'OK'
+
+            elif type_ == 'Cancel':
+                default_kwargs['response'] = Gtk.ResponseType.CANCEL
+                default_kwargs['text'] = _('Cancel')
+            else:
+                raise ValueError('Unknown button type: %s ' % type_)
+
+        default_kwargs.update(kwargs)
+        return cls(**default_kwargs)
+
+
 class HigDialog(Gtk.MessageDialog):
     def __init__(self, parent, type_, buttons, pritext, sectext,
     on_response_ok=None, on_response_cancel=None, on_response_yes=None,
@@ -952,18 +984,22 @@ class ChangePasswordDialog(Gtk.Dialog):
 
 
 class NewConfirmationDialog(Gtk.MessageDialog):
-    def __init__(self, text, sec_text, buttons, transient_for=None):
+    def __init__(self, title, text, sec_text, buttons, transient_for=None):
         Gtk.MessageDialog.__init__(self,
+                                   title=title,
+                                   text=text,
                                    transient_for=transient_for,
-                                   message_type=Gtk.MessageType.QUESTION,
-                                   text=text)
+                                   message_type=Gtk.MessageType.QUESTION)
 
-        self._buttons = buttons
+        self._buttons = {}
 
-        for response, button in buttons.items():
-            self.add_button(button.text, response)
+        for button in buttons:
+            self._buttons[button.response] = button
+            self.add_button(button.text, button.response)
+            if button.is_default:
+                self.set_default_response(button.response)
             if button.action is not None:
-                widget = self.get_widget_for_response(response)
+                widget = self.get_widget_for_response(button.response)
                 widget.get_style_context().add_class(button.action.value)
 
         self.format_secondary_markup(sec_text)
@@ -972,7 +1008,7 @@ class NewConfirmationDialog(Gtk.MessageDialog):
 
         self.run()
 
-    def _on_response(self, dialog, response):
+    def _on_response(self, _dialog, response):
         if response == Gtk.ResponseType.DELETE_EVENT:
             # Look if DELETE_EVENT is mapped to another response
             response = self._buttons.get(response, None)
@@ -986,7 +1022,7 @@ class NewConfirmationDialog(Gtk.MessageDialog):
             return
 
         if button.callback is not None:
-            button.callback()
+            button.callback(*button.args, **button.kwargs)
         self.destroy()
 
 
diff --git a/gajim/gtk/themes.py b/gajim/gtk/themes.py
index d325f148bf..bb0eb9deb0 100644
--- a/gajim/gtk/themes.py
+++ b/gajim/gtk/themes.py
@@ -24,10 +24,10 @@ from gajim.common import app
 from gajim.common.nec import NetworkEvent
 from gajim.common.i18n import _
 from gajim.common.const import StyleAttr
-from gajim.common.const import DialogButton
 from gajim.common.const import ButtonAction
 
 from gajim.gtk.dialogs import ErrorDialog
+from gajim.gtk.dialogs import DialogButton
 from gajim.gtk.dialogs import NewConfirmationDialog
 from gajim.gtk.util import get_builder
 
@@ -320,17 +320,17 @@ class Themes(Gtk.ApplicationWindow):
                 self._add_option_button.set_sensitive(False)
                 self._clear_options()
 
-        buttons = {
-            Gtk.ResponseType.CANCEL: DialogButton('Keep Theme'),
-            Gtk.ResponseType.OK: DialogButton('Delete',
-                                              _remove_theme,
-                                              ButtonAction.DESTRUCTIVE),
-        }
-
-        NewConfirmationDialog('Delete Theme',
-                              'Do you want to permanently delete this theme?',
-                              buttons,
-                              transient_for=self)
+        NewConfirmationDialog(
+            _('Delete'),
+            _('Delete Theme'),
+            _('Do you want to permanently '
+              'delete this theme?'),
+            [DialogButton.make('Cancel'),
+             DialogButton.make('OK',
+                               text=_('Delete'),
+                               callback=_remove_theme,
+                               action=ButtonAction.DESTRUCTIVE)],
+            transient_for=self)
 
     @staticmethod
     def _on_destroy(*args):
-- 
GitLab