Add chatstate setting per contact
This commit is contained in:
parent
df13aa4b22
commit
5f84dffca6
|
@ -289,6 +289,16 @@ class ChatControl(ChatControlBase):
|
||||||
self.video_action.connect('change-state', self._on_video)
|
self.video_action.connect('change-state', self._on_video)
|
||||||
self.parent_win.window.add_action(self.video_action)
|
self.parent_win.window.add_action(self.video_action)
|
||||||
|
|
||||||
|
chatstate = app.config.get_per(
|
||||||
|
'contacts', self.contact.jid, 'send_chatstate', 'composing_only')
|
||||||
|
|
||||||
|
act = Gio.SimpleAction.new_stateful(
|
||||||
|
'send-chatstate-' + self.control_id,
|
||||||
|
GLib.VariantType.new("s"),
|
||||||
|
GLib.Variant("s", chatstate))
|
||||||
|
act.connect('change-state', self._on_send_chatstate)
|
||||||
|
self.parent_win.window.add_action(act)
|
||||||
|
|
||||||
def update_actions(self):
|
def update_actions(self):
|
||||||
win = self.parent_win.window
|
win = self.parent_win.window
|
||||||
online = app.account_is_connected(self.account)
|
online = app.account_is_connected(self.account)
|
||||||
|
@ -376,6 +386,11 @@ class ChatControl(ChatControlBase):
|
||||||
state = param.get_boolean()
|
state = param.get_boolean()
|
||||||
self.on_jingle_button_toggled(state, 'video')
|
self.on_jingle_button_toggled(state, 'video')
|
||||||
|
|
||||||
|
def _on_send_chatstate(self, action, param):
|
||||||
|
action.set_state(param)
|
||||||
|
app.config.set_per('contacts', self.contact.jid,
|
||||||
|
'send_chatstate', param.get_string())
|
||||||
|
|
||||||
def subscribe_events(self):
|
def subscribe_events(self):
|
||||||
"""
|
"""
|
||||||
Register listeners to the events class
|
Register listeners to the events class
|
||||||
|
|
|
@ -156,6 +156,7 @@ gajim_common_features = [
|
||||||
nbxmpp.NS_DATA,
|
nbxmpp.NS_DATA,
|
||||||
nbxmpp.NS_ENCRYPTED,
|
nbxmpp.NS_ENCRYPTED,
|
||||||
nbxmpp.NS_PING,
|
nbxmpp.NS_PING,
|
||||||
|
nbxmpp.NS_CHATSTATES,
|
||||||
nbxmpp.NS_TIME_REVISED,
|
nbxmpp.NS_TIME_REVISED,
|
||||||
nbxmpp.NS_VERSION,
|
nbxmpp.NS_VERSION,
|
||||||
nbxmpp.NS_ROSTERX,
|
nbxmpp.NS_ROSTERX,
|
||||||
|
|
|
@ -183,7 +183,6 @@ class Config:
|
||||||
'always_english_wikipedia': [opt_bool, False],
|
'always_english_wikipedia': [opt_bool, False],
|
||||||
'always_english_wiktionary': [opt_bool, True],
|
'always_english_wiktionary': [opt_bool, True],
|
||||||
'remote_control': [opt_bool, False, _('If checked, Gajim can be controlled remotely using gajim-remote.'), True],
|
'remote_control': [opt_bool, False, _('If checked, Gajim can be controlled remotely using gajim-remote.'), True],
|
||||||
'outgoing_chat_state_notifications': [opt_str, 'all', _('Sent chat state notifications. Can be one of all, composing_only, disabled.')],
|
|
||||||
'autodetect_browser_mailer': [opt_bool, True, '', True],
|
'autodetect_browser_mailer': [opt_bool, True, '', True],
|
||||||
'print_ichat_every_foo_minutes': [opt_int, 5, _('When not printing time for every message (print_time==sometimes), print it every x minutes.')],
|
'print_ichat_every_foo_minutes': [opt_int, 5, _('When not printing time for every message (print_time==sometimes), print it every x minutes.')],
|
||||||
'confirm_close_muc': [opt_bool, True, _('Ask before closing a group chat tab/window.')],
|
'confirm_close_muc': [opt_bool, True, _('Ask before closing a group chat tab/window.')],
|
||||||
|
@ -421,9 +420,9 @@ class Config:
|
||||||
'bosh_http_pipelining': [opt_bool, False],
|
'bosh_http_pipelining': [opt_bool, False],
|
||||||
'bosh_wait_for_restart_response': [opt_bool, False],
|
'bosh_wait_for_restart_response': [opt_bool, False],
|
||||||
}, {}),
|
}, {}),
|
||||||
|
|
||||||
'contacts': ({
|
'contacts': ({
|
||||||
'speller_language': [opt_str, '', _('Language for which misspelled words will be checked')],
|
'speller_language': [opt_str, '', _('Language for which misspelled words will be checked')],
|
||||||
|
'send_chatstate': [opt_str, 'composing_only', _('Chat state notifications that are sent to contacts. Possible values: all, composing_only, disabled')],
|
||||||
}, {}),
|
}, {}),
|
||||||
'encryption': ({
|
'encryption': ({
|
||||||
'encryption': [opt_str, '', _('The currently active encryption for that contact')],
|
'encryption': [opt_str, '', _('The currently active encryption for that contact')],
|
||||||
|
|
|
@ -1127,8 +1127,6 @@ def update_optional_features(account=None):
|
||||||
features.append(nbxmpp.NS_NICK + '+notify')
|
features.append(nbxmpp.NS_NICK + '+notify')
|
||||||
if app.config.get_per('accounts', account_, 'subscribe_location'):
|
if app.config.get_per('accounts', account_, 'subscribe_location'):
|
||||||
features.append(nbxmpp.NS_LOCATION + '+notify')
|
features.append(nbxmpp.NS_LOCATION + '+notify')
|
||||||
if app.config.get('outgoing_chat_state_notifactions') != 'disabled':
|
|
||||||
features.append(nbxmpp.NS_CHATSTATES)
|
|
||||||
if not app.config.get('ignore_incoming_xhtml'):
|
if not app.config.get('ignore_incoming_xhtml'):
|
||||||
features.append(nbxmpp.NS_XHTML_IM)
|
features.append(nbxmpp.NS_XHTML_IM)
|
||||||
if app.config.get_per('accounts', account_, 'answer_receipts'):
|
if app.config.get_per('accounts', account_, 'answer_receipts'):
|
||||||
|
|
|
@ -358,7 +358,8 @@ class Chatstate(BaseModule):
|
||||||
if contact.is_groupchat():
|
if contact.is_groupchat():
|
||||||
return app.config.get_per(
|
return app.config.get_per(
|
||||||
'rooms', contact.jid, 'send_chatstate', 'composing_only')
|
'rooms', contact.jid, 'send_chatstate', 'composing_only')
|
||||||
return app.config.get('outgoing_chat_state_notifications')
|
return app.config.get_per(
|
||||||
|
'contacts', contact.jid, 'send_chatstate', 'composing_only')
|
||||||
|
|
||||||
def remove_delay_timeout(self, contact):
|
def remove_delay_timeout(self, contact):
|
||||||
timeout = self._delay_timeout_ids.get(contact.jid)
|
timeout = self._delay_timeout_ids.get(contact.jid)
|
||||||
|
|
|
@ -42,23 +42,6 @@
|
||||||
<column type="gboolean"/>
|
<column type="gboolean"/>
|
||||||
</columns>
|
</columns>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkListStore" id="display_chat_state_notifications_liststore">
|
|
||||||
<columns>
|
|
||||||
<!-- column-name item -->
|
|
||||||
<column type="gchararray"/>
|
|
||||||
</columns>
|
|
||||||
<data>
|
|
||||||
<row>
|
|
||||||
<col id="0" translatable="yes">All chat states</col>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<col id="0" translatable="yes">Composing only</col>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<col id="0" translatable="yes">Disabled</col>
|
|
||||||
</row>
|
|
||||||
</data>
|
|
||||||
</object>
|
|
||||||
<object class="GtkListStore" id="on_event_received_liststore">
|
<object class="GtkListStore" id="on_event_received_liststore">
|
||||||
<columns>
|
<columns>
|
||||||
<!-- column-name item -->
|
<!-- column-name item -->
|
||||||
|
@ -127,23 +110,6 @@
|
||||||
</row>
|
</row>
|
||||||
</data>
|
</data>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkListStore" id="send_chatstate_notifications_liststore">
|
|
||||||
<columns>
|
|
||||||
<!-- column-name item -->
|
|
||||||
<column type="gchararray"/>
|
|
||||||
</columns>
|
|
||||||
<data>
|
|
||||||
<row>
|
|
||||||
<col id="0" translatable="yes">All chat states</col>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<col id="0" translatable="yes">Composing only</col>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<col id="0" translatable="yes">Disabled</col>
|
|
||||||
</row>
|
|
||||||
</data>
|
|
||||||
</object>
|
|
||||||
<object class="GtkListStore" id="show_roster_on_startup_liststore">
|
<object class="GtkListStore" id="show_roster_on_startup_liststore">
|
||||||
<columns>
|
<columns>
|
||||||
<!-- column-name item -->
|
<!-- column-name item -->
|
||||||
|
@ -756,7 +722,6 @@
|
||||||
<property name="label" translatable="yes">Default Sync Threshold</property>
|
<property name="label" translatable="yes">Default Sync Threshold</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="justify">right</property>
|
<property name="justify">right</property>
|
||||||
<property name="mnemonic_widget">outgoing_chat_states_combobox</property>
|
|
||||||
<style>
|
<style>
|
||||||
<class name="dim-label"/>
|
<class name="dim-label"/>
|
||||||
</style>
|
</style>
|
||||||
|
@ -1754,107 +1719,6 @@ $T will be replaced by auto-not-available timeout.</property>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkBox" id="privacy_tab">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="border_width">18</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="spacing">6</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkFrame">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label_xalign">0</property>
|
|
||||||
<property name="shadow_type">none</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="margin_top">6</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<property name="spacing">6</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
|
||||||
<property name="spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="tooltip_text" translatable="yes">Gajim can send and receive meta-information related to a conversation you may have with a contact. Here you can specify which chatstates you want to send to the other party.</property>
|
|
||||||
<property name="halign">start</property>
|
|
||||||
<property name="label" translatable="yes">S_end chat state notifications</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="justify">right</property>
|
|
||||||
<property name="mnemonic_widget">outgoing_chat_states_combobox</property>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkComboBox" id="outgoing_chat_states_combobox">
|
|
||||||
<property name="width_request">200</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="halign">start</property>
|
|
||||||
<property name="model">send_chatstate_notifications_liststore</property>
|
|
||||||
<signal name="changed" handler="on_outgoing_chat_states_combobox_changed" swapped="no"/>
|
|
||||||
<child>
|
|
||||||
<object class="GtkCellRendererText"/>
|
|
||||||
<attributes>
|
|
||||||
<attribute name="text">0</attribute>
|
|
||||||
</attributes>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</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>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child type="label">
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Privacy</property>
|
|
||||||
<style>
|
|
||||||
<class name="bold"/>
|
|
||||||
<class name="margin-top6"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="name">privacy</property>
|
|
||||||
<property name="title" translatable="yes">Privacy</property>
|
|
||||||
<property name="position">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="style_tab">
|
<object class="GtkBox" id="style_tab">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -2169,7 +2033,7 @@ $T will be replaced by auto-not-available timeout.</property>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="name">style</property>
|
<property name="name">style</property>
|
||||||
<property name="title" translatable="yes">Style</property>
|
<property name="title" translatable="yes">Style</property>
|
||||||
<property name="position">5</property>
|
<property name="position">4</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -2479,7 +2343,7 @@ to discover one from the server. (Example: stun.iptel.org)</property>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="name">audio_video</property>
|
<property name="name">audio_video</property>
|
||||||
<property name="title" translatable="yes">Audio/Video</property>
|
<property name="title" translatable="yes">Audio/Video</property>
|
||||||
<property name="position">6</property>
|
<property name="position">5</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -2875,7 +2739,7 @@ to discover one from the server. (Example: stun.iptel.org)</property>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="name">advanced</property>
|
<property name="name">advanced</property>
|
||||||
<property name="title" translatable="yes">Advanced</property>
|
<property name="title" translatable="yes">Advanced</property>
|
||||||
<property name="position">7</property>
|
<property name="position">6</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -281,16 +281,6 @@ class Preferences(Gtk.ApplicationWindow):
|
||||||
buf = self._ui.msg_textview.get_buffer()
|
buf = self._ui.msg_textview.get_buffer()
|
||||||
buf.connect('end-user-action', self.on_msg_textview_changed)
|
buf.connect('end-user-action', self.on_msg_textview_changed)
|
||||||
|
|
||||||
### Privacy tab ###
|
|
||||||
# Outgoing chat state notifications
|
|
||||||
st = app.config.get('outgoing_chat_state_notifications')
|
|
||||||
if st == 'all':
|
|
||||||
self._ui.outgoing_chat_states_combobox.set_active(0)
|
|
||||||
elif st == 'composing_only':
|
|
||||||
self._ui.outgoing_chat_states_combobox.set_active(1)
|
|
||||||
else: # disabled
|
|
||||||
self._ui.outgoing_chat_states_combobox.set_active(2)
|
|
||||||
|
|
||||||
### Style tab ###
|
### Style tab ###
|
||||||
# Themes
|
# Themes
|
||||||
self.changed_id = self._ui.theme_combobox.connect(
|
self.changed_id = self._ui.theme_combobox.connect(
|
||||||
|
@ -858,20 +848,6 @@ class Preferences(Gtk.ApplicationWindow):
|
||||||
widget.set_inconsistent(False)
|
widget.set_inconsistent(False)
|
||||||
self.on_per_account_checkbutton_toggled(widget, 'ignore_unknown_contacts')
|
self.on_per_account_checkbutton_toggled(widget, 'ignore_unknown_contacts')
|
||||||
|
|
||||||
def on_outgoing_chat_states_combobox_changed(self, widget):
|
|
||||||
active = widget.get_active()
|
|
||||||
old_value = app.config.get('outgoing_chat_state_notifications')
|
|
||||||
if active == 0: # all
|
|
||||||
app.config.set('outgoing_chat_state_notifications', 'all')
|
|
||||||
elif active == 1: # only composing
|
|
||||||
app.config.set('outgoing_chat_state_notifications', 'composing_only')
|
|
||||||
else: # disabled
|
|
||||||
app.config.set('outgoing_chat_state_notifications', 'disabled')
|
|
||||||
new_value = app.config.get('outgoing_chat_state_notifications')
|
|
||||||
if 'disabled' in (old_value, new_value):
|
|
||||||
# We changed from disabled to sth else or vice versa
|
|
||||||
helpers.update_optional_features()
|
|
||||||
|
|
||||||
### Style ###
|
### Style ###
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def on_theme_combobox_changed(combobox):
|
def on_theme_combobox_changed(combobox):
|
||||||
|
|
|
@ -609,6 +609,7 @@ def get_singlechat_menu(control_id, account, jid):
|
||||||
('win.send-file-httpupload-', _('Upload File…')),
|
('win.send-file-httpupload-', _('Upload File…')),
|
||||||
('win.send-file-jingle-', _('Send File Directly…')),
|
('win.send-file-jingle-', _('Send File Directly…')),
|
||||||
]),
|
]),
|
||||||
|
(_('Send Chatstate'), ['chatstate']),
|
||||||
('win.invite-contacts-', _('Invite Contacts')),
|
('win.invite-contacts-', _('Invite Contacts')),
|
||||||
('win.add-to-roster-', _('Add to Roster')),
|
('win.add-to-roster-', _('Add to Roster')),
|
||||||
('win.toggle-audio-', _('Audio Session')),
|
('win.toggle-audio-', _('Audio Session')),
|
||||||
|
@ -617,6 +618,20 @@ def get_singlechat_menu(control_id, account, jid):
|
||||||
('app.browse-history', _('History')),
|
('app.browse-history', _('History')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def build_chatstate_menu():
|
||||||
|
menu = Gio.Menu()
|
||||||
|
entrys = [
|
||||||
|
(_('Disabled'), 'disabled'),
|
||||||
|
(_('Composing only'), 'composing_only'),
|
||||||
|
(_('All chat states'), 'all')
|
||||||
|
]
|
||||||
|
|
||||||
|
for entry in entrys:
|
||||||
|
label, setting = entry
|
||||||
|
action = 'win.send-chatstate-%s::%s' % (control_id, setting)
|
||||||
|
menu.append(label, action)
|
||||||
|
return menu
|
||||||
|
|
||||||
def build_menu(preset):
|
def build_menu(preset):
|
||||||
menu = Gio.Menu()
|
menu = Gio.Menu()
|
||||||
for item in preset:
|
for item in preset:
|
||||||
|
@ -634,8 +649,10 @@ def get_singlechat_menu(control_id, account, jid):
|
||||||
menu.append(label, action_name + control_id)
|
menu.append(label, action_name + control_id)
|
||||||
else:
|
else:
|
||||||
label, sub_menu = item
|
label, sub_menu = item
|
||||||
# This is a submenu
|
if 'chatstate' in sub_menu:
|
||||||
submenu = build_menu(sub_menu)
|
submenu = build_chatstate_menu()
|
||||||
|
else:
|
||||||
|
submenu = build_menu(sub_menu)
|
||||||
menu.append_submenu(label, submenu)
|
menu.append_submenu(label, submenu)
|
||||||
return menu
|
return menu
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue