Philipp Hörist pushed to branch master at gajim / gajim
Commits: 77a4f36c by Daniel Brötzmann at 2019-11-17T13:15:29Z Rework InputDialog
- - - - - 4fd4bda0 by Daniel Brötzmann at 2019-11-17T13:15:34Z Add mnemonics to default button types
- - - - - cba9931e by Daniel Brötzmann at 2019-11-17T13:15:34Z Remove usage of ResourceConflictDialog
- - - - - 9c86fa37 by Daniel Brötzmann at 2019-11-17T13:15:34Z Remove obsolete ResourceConflictDialog
- - - - -
6 changed files:
- − gajim/data/gui/input_dialog.ui - − gajim/data/gui/input_text_dialog.ui - gajim/dialogs.py - gajim/gtk/dialogs.py - gajim/gui_interface.py - gajim/roster_window.py
Changes:
===================================== gajim/data/gui/input_dialog.ui deleted ===================================== @@ -1,133 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> -<interface> - <requires lib="gtk+" version="3.12"/> - <object class="GtkDialog" id="input_dialog"> - <property name="can_focus">False</property> - <property name="border_width">12</property> - <property name="type_hint">dialog</property> - <signal name="delete-event" handler="on_input_dialog_delete_event" swapped="no"/> - <signal name="destroy" handler="on_input_dialog_destroy" swapped="no"/> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox10"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area9"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="cancelbutton"> - <property name="label">gtk-cancel</property> - <property name="use_action_appearance">False</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="okbutton"> - <property name="label">gtk-ok</property> - <property name="use_action_appearance">False</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">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkBox" id="vbox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="valign">end</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child> - <object class="GtkBox" id="hbox2960"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">12</property> - <child> - <object class="GtkImage" id="image507"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-dialog-question</property> - <property name="icon_size">6</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="use_markup">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="input_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="activates_default">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-6">cancelbutton</action-widget> - <action-widget response="-5">okbutton</action-widget> - </action-widgets> - </object> -</interface>
===================================== gajim/data/gui/input_text_dialog.ui deleted ===================================== @@ -1,141 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> -<interface> - <requires lib="gtk+" version="3.12"/> - <object class="GtkDialog" id="input_dialog"> - <property name="can_focus">False</property> - <property name="border_width">6</property> - <property name="default_width">400</property> - <property name="type_hint">dialog</property> - <signal name="destroy" handler="on_input_dialog_destroy" swapped="no"/> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox10"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area9"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="cancelbutton"> - <property name="label">gtk-cancel</property> - <property name="use_action_appearance">False</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="okbutton"> - <property name="label">gtk-ok</property> - <property name="use_action_appearance">False</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">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkBox" id="vbox76"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="border_width">6</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkBox" id="hbox2960"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">12</property> - <child> - <object class="GtkImage" id="image507"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-dialog-question</property> - <property name="icon_size">6</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="use_markup">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="vscrollbar_policy">never</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkTextView" id="input_textview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="wrap_mode">word</property> - </object> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-6">cancelbutton</action-widget> - <action-widget response="-5">okbutton</action-widget> - </action-widgets> - </object> -</interface>
===================================== gajim/dialogs.py ===================================== @@ -670,13 +670,13 @@ class ChangeStatusMessageDialog(TimeoutDialog): status_message_to_save_as_preset = self.message_buffer.get_text( start_iter, finish_iter, True)
- def on_ok(msg_name): + def _on_save_preset(msg_name): msg_text = status_message_to_save_as_preset msg_text_1l = helpers.to_one_line(msg_text) if not msg_name: # msg_name was '' msg_name = msg_text_1l
- def _on_ok2(): + def _on_overwrite_preset(): self.preset_messages_dict[msg_name] = [ msg_text, self.pep_dict.get('activity'), self.pep_dict.get('subactivity'), @@ -694,6 +694,7 @@ class ChangeStatusMessageDialog(TimeoutDialog): self.pep_dict.get('mood')) app.config.set_per('statusmsg', msg_name, 'mood_text', self.pep_dict.get('mood_text')) + if msg_name in self.preset_messages_dict: NewConfirmationDialog( _('Overwrite'), @@ -703,17 +704,26 @@ class ChangeStatusMessageDialog(TimeoutDialog): [DialogButton.make('Cancel'), DialogButton.make('Remove', text=_('_Overwrite'), - callback=_on_ok2)], + callback=_on_overwrite_preset)], transient_for=self.dialog).show() return + app.config.add_per('statusmsg', msg_name) - _on_ok2() + _on_overwrite_preset() iter_ = self.message_liststore.append((msg_name,)) - # select in combobox the one we just saved + # Select the one we just saved in combobox self.message_combobox.set_active_iter(iter_) - InputDialog(_('Save as Preset Status Message'), - _('Please type a name for this status message'), is_modal=False, - ok_handler=on_ok) + + InputDialog( + _('Status Preset'), + _('Save status as preset'), + _('Please assign a name to this status message preset'), + [DialogButton.make('Cancel'), + DialogButton.make('Accept', + text=_('_Save'), + callback=_on_save_preset)], + input_str=_('New Status'), + transient_for=self.dialog).show()
def on_activity_button_clicked(self, widget): self.countdown_enabled = False @@ -997,18 +1007,6 @@ class TransformChatToMUC: self.window.destroy()
-class ResourceConflictDialog(TimeoutDialog, InputDialog): - def __init__(self, title, text, resource, ok_handler): - TimeoutDialog.__init__(self, 15) - InputDialog.__init__(self, title, text, input_str=resource, - is_modal=False, ok_handler=ok_handler) - self.title_text = title - self.run_timeout() - - def on_timeout(self): - self.on_okbutton_clicked(None) - - class VoIPCallReceivedDialog: instances = {} # type: Dict[Tuple[str, str], VoIPCallReceivedDialog] def __init__(self, account, contact_jid, sid, content_types):
===================================== gajim/gtk/dialogs.py ===================================== @@ -45,26 +45,26 @@ class DialogButton(namedtuple('DialogButton', ('response text callback args ' if type_ is not None: if type_ == 'OK': default_kwargs['response'] = Gtk.ResponseType.OK - default_kwargs['text'] = 'OK' + default_kwargs['text'] = _('_OK')
elif type_ == 'Cancel': default_kwargs['response'] = Gtk.ResponseType.CANCEL - default_kwargs['text'] = _('Cancel') + default_kwargs['text'] = _('_Cancel')
elif type_ == 'Accept': default_kwargs['response'] = Gtk.ResponseType.ACCEPT - default_kwargs['text'] = _('Accept') + default_kwargs['text'] = _('_Accept') default_kwargs['is_default'] = True default_kwargs['action'] = ButtonAction.SUGGESTED
elif type_ == 'Delete': default_kwargs['response'] = Gtk.ResponseType.REJECT - default_kwargs['text'] = _('Delete') + default_kwargs['text'] = _('_Delete') default_kwargs['action'] = ButtonAction.DESTRUCTIVE
elif type_ == 'Remove': default_kwargs['response'] = Gtk.ResponseType.REJECT - default_kwargs['text'] = _('Remove') + default_kwargs['text'] = _('_Remove') default_kwargs['action'] = ButtonAction.DESTRUCTIVE else: raise ValueError('Unknown button type: %s ' % type_) @@ -276,151 +276,6 @@ class ConfirmationDialogDoubleRadio(ConfirmationDialog): return [is_checked_1, is_checked_2]
-class CommonInputDialog: - """ - Common Class for Input dialogs - """ - - def __init__(self, title, label_str, is_modal, ok_handler, cancel_handler, - transient_for=None): - self.dialog = self.xml.get_object('input_dialog') - label = self.xml.get_object('label') - self.dialog.set_title(title) - label.set_markup(label_str) - self.cancel_handler = cancel_handler - self.vbox = self.xml.get_object('vbox') - if transient_for is None: - transient_for = app.app.get_active_window() - self.dialog.set_transient_for(transient_for) - - self.ok_handler = ok_handler - okbutton = self.xml.get_object('okbutton') - okbutton.connect('clicked', self.on_okbutton_clicked) - cancelbutton = self.xml.get_object('cancelbutton') - cancelbutton.connect('clicked', self.on_cancelbutton_clicked) - self.xml.connect_signals(self) - self.dialog.show_all() - - def on_input_dialog_destroy(self, widget): - if self.cancel_handler: - self.cancel_handler() - - def on_okbutton_clicked(self, widget): - user_input = self.get_text() - if user_input: - user_input = user_input - self.cancel_handler = None - self.dialog.destroy() - if isinstance(self.ok_handler, tuple): - self.ok_handler[0](user_input, *self.ok_handler[1:]) - else: - self.ok_handler(user_input) - - def on_cancelbutton_clicked(self, widget): - self.dialog.destroy() - - def destroy(self): - self.dialog.destroy() - - -class InputDialog(CommonInputDialog): - """ - Class for Input dialog - """ - - def __init__(self, title, label_str, input_str=None, is_modal=True, - ok_handler=None, cancel_handler=None, transient_for=None): - self.xml = get_builder('input_dialog.ui') - CommonInputDialog.__init__(self, title, label_str, is_modal, - ok_handler, cancel_handler, - transient_for=transient_for) - self.input_entry = self.xml.get_object('input_entry') - if input_str: - self.set_entry(input_str) - - def on_input_dialog_delete_event(self, widget, event): - ''' - may be implemented by subclasses - ''' - - def set_entry(self, value): - self.input_entry.set_text(value) - self.input_entry.select_region(0, -1) # select all - - def get_text(self): - return self.input_entry.get_text() - - -class InputDialogCheck(InputDialog): - """ - Class for Input dialog - """ - - def __init__(self, title, label_str, checktext='', input_str=None, - is_modal=True, ok_handler=None, cancel_handler=None, - transient_for=None): - self.xml = get_builder('input_dialog.ui') - InputDialog.__init__(self, title, label_str, input_str=input_str, - is_modal=is_modal, ok_handler=ok_handler, - cancel_handler=cancel_handler, - transient_for=transient_for) - self.input_entry = self.xml.get_object('input_entry') - if input_str: - self.input_entry.set_text(input_str) - self.input_entry.select_region(0, -1) # select all - - if checktext: - self.checkbutton = Gtk.CheckButton.new_with_mnemonic(checktext) - self.vbox.pack_start(self.checkbutton, False, True, 0) - self.checkbutton.show() - - def on_okbutton_clicked(self, widget): - user_input = self.get_text() - if user_input: - user_input = user_input - self.cancel_handler = None - self.dialog.destroy() - if isinstance(self.ok_handler, tuple): - self.ok_handler[0](user_input, self.is_checked(), *self.ok_handler[1:]) - else: - self.ok_handler(user_input, self.is_checked()) - - def get_text(self): - return self.input_entry.get_text() - - def is_checked(self): - """ - Get active state of the checkbutton - """ - try: - return self.checkbutton.get_active() - except Exception: - # There is no checkbutton - return False - - -class InputTextDialog(CommonInputDialog): - """ - Class for multilines Input dialog (more place than InputDialog) - """ - - def __init__(self, title, label_str, input_str=None, is_modal=True, - ok_handler=None, cancel_handler=None, transient_for=None): - self.xml = get_builder('input_text_dialog.ui') - CommonInputDialog.__init__(self, title, label_str, is_modal, - ok_handler, cancel_handler, - transient_for=transient_for) - self.input_buffer = self.xml.get_object('input_textview').get_buffer() - if input_str: - self.input_buffer.set_text(input_str) - start_iter, end_iter = self.input_buffer.get_bounds() - self.input_buffer.select_range(start_iter, end_iter) # select all - - def get_text(self): - start_iter, end_iter = self.input_buffer.get_bounds() - return self.input_buffer.get_text(start_iter, end_iter, True) - - class CertificateDialog(Gtk.ApplicationWindow): def __init__(self, transient_for, account, cert): Gtk.ApplicationWindow.__init__(self) @@ -748,6 +603,35 @@ class NewConfirmationCheckDialog(NewConfirmationDialog): super()._on_response(_dialog, response)
+class InputDialog(NewConfirmationDialog): + def __init__(self, title, text, sec_text, buttons, input_str=None, + transient_for=None, modal=True): + NewConfirmationDialog.__init__(self, + title, + text, + sec_text, + buttons, + transient_for=transient_for, + modal=modal) + + self._entry = Gtk.Entry() + self._entry.set_activates_default(True) + self._entry.set_margin_start(50) + self._entry.set_margin_end(50) + + if input_str: + self._entry.set_text(input_str) + self._entry.select_region(0, -1) # select all + + self.get_content_area().add(self._entry) + + def _on_response(self, _dialog, response): + button = self._buttons.get(response) + if button is not None: + button.args.insert(0, self._entry.get_text()) + super()._on_response(_dialog, response) + + class ShortcutsWindow: def __init__(self): transient = app.app.get_active_window()
===================================== gajim/gui_interface.py ===================================== @@ -91,12 +91,12 @@ from gajim.common import optparser
from gajim.gtk.avatar import AvatarStorage from gajim.gtk.notification import Notification +from gajim.gtk.dialogs import DialogButton from gajim.gtk.dialogs import ErrorDialog from gajim.gtk.dialogs import WarningDialog from gajim.gtk.dialogs import InformationDialog from gajim.gtk.dialogs import NewConfirmationDialog from gajim.gtk.dialogs import NewConfirmationCheckDialog -from gajim.gtk.dialogs import DialogButton from gajim.gtk.dialogs import InputDialog from gajim.gtk.dialogs import PassphraseDialog from gajim.gtk.dialogs import InvitationReceivedDialog @@ -878,19 +878,27 @@ class Interface: app.contacts.define_metacontacts(obj.conn.name, obj.meta_list)
def handle_event_zc_name_conflict(self, obj): - def on_ok(new_name): + def _on_ok(new_name): app.config.set_per('accounts', obj.conn.name, 'name', new_name) show = obj.conn.old_show status = obj.conn.status obj.conn.username = new_name obj.conn.change_status(show, status) - def on_cancel(): + + def _on_cancel(*args): obj.conn.change_status('offline', '')
- InputDialog(_('Username Conflict'), - _('Please type a new username for your local account'), - input_str=obj.alt_name, is_modal=True, ok_handler=on_ok, - cancel_handler=on_cancel, transient_for=self.roster.window) + InputDialog( + _('Username Conflict'), + _('Username Conflict'), + _('Please enter a new username for your local account'), + [DialogButton.make('Cancel', + callback=_on_cancel), + DialogButton.make('Accept', + text=_('_OK'), + callback=_on_ok)], + input_str=obj.alt_name, + transient_for=self.roster.window).show()
def handle_event_resource_conflict(self, obj): # ('RESOURCE_CONFLICT', account, ()) @@ -899,7 +907,7 @@ class Interface: conn = obj.conn self.roster.send_status(account, 'offline', conn.status)
- def on_ok(new_resource): + def _set_resource(new_resource): app.config.set_per('accounts', account, 'resource', new_resource) self.roster.send_status(account, conn.old_show, conn.status)
@@ -907,14 +915,21 @@ class Interface: if proposed_resource.startswith('gajim.'): # Dont notify the user about resource change if he didn't set # a custom resource - on_ok('gajim.$rand') + _set_resource('gajim.$rand') return
proposed_resource += app.config.get('gc_proposed_nick_char') - dialogs.ResourceConflictDialog(_('Resource Conflict'), + + InputDialog( + _('Resource Conflict'), + _('Resource Conflict'), _('You are already connected to this account with the same ' - 'resource. Please type a new one'), resource=proposed_resource, - ok_handler=on_ok) + 'resource. Please enter a different one.'), + [DialogButton.make('Cancel'), + DialogButton.make('Accept', + text=_('_Connect'), + callback=_set_resource)], + input_str=proposed_resource).show()
def handle_event_jingleft_cancel(self, obj): ft = self.instances['file_transfers']
===================================== gajim/roster_window.py ===================================== @@ -2893,31 +2893,30 @@ class RosterWindow: del app.interface.instances[acct]['privacy_list_block']
def on_rename(self, widget, row_type, jid, account): - # this function is called either by F2 or by Rename menuitem + # This function is called either by F2 or by Rename menuitem if 'rename' in app.interface.instances: app.interface.instances['rename'].dialog.present() return
- # account is offline, don't allow to rename + # Account is offline, don't allow to rename if not app.account_is_connected(account): return if row_type in ('contact', 'agent'): - # it's jid + # It's jid title = _('Rename Contact') - message = _('Enter a new nickname for contact %s') % jid + text = _('Rename contact %s?') % jid + sec_text = _('Please enter a new nickname') old_text = app.contacts.get_contact_with_highest_priority(account, - jid).name + jid).name elif row_type == 'group': if jid in helpers.special_groups + (_('General'),): return old_text = jid title = _('Rename Group') - message = _('Enter a new name for group %s') % \ - GLib.markup_escape_text(jid) + text = _('Rename group %s?') % GLib.markup_escape_text(jid) + sec_text = _('Please enter a new name')
- def on_renamed(new_text, account, row_type, jid, old_text): - if 'rename' in app.interface.instances: - del app.interface.instances['rename'] + def _on_renamed(new_text, account, row_type, jid, old_text): if row_type in ('contact', 'agent'): if old_text == new_text: return @@ -2936,16 +2935,23 @@ class RosterWindow: win.redraw_tab(ctrl) win.show_title() elif row_type == 'group': - # in Column.JID column, we hold the group name (which is not escaped) + # In Column.JID column, we hold the group name (which is not escaped) self.rename_group(old_text, new_text, account)
- def on_canceled(): - if 'rename' in app.interface.instances: - del app.interface.instances['rename'] - - app.interface.instances['rename'] = InputDialog(title, - message, old_text, False, (on_renamed, account, row_type, jid, - old_text), on_canceled, transient_for=self.window) + InputDialog( + title, + text, + sec_text, + [DialogButton.make('Cancel'), + DialogButton.make('Accept', + text=_('_Rename'), + callback=_on_renamed, + args=[account, + row_type, + jid, + old_text])], + input_str=old_text, + transient_for=self.window).show()
def on_remove_group_item_activated(self, widget, group, account): def _on_ok(is_checked):
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/6329dfd072484dbb43d0684388a4837feb...