Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
5f84dffc
by Philipp Hörist at 2019-04-20T15:43:54Z
8 changed files:
- gajim/chat_control.py
- gajim/common/app.py
- gajim/common/config.py
- gajim/common/helpers.py
- gajim/common/modules/chatstates.py
- gajim/data/gui/preferences_window.ui
- gajim/gtk/preferences.py
- gajim/gui_menu_builder.py
Changes:
| ... | ... | @@ -289,6 +289,16 @@ class ChatControl(ChatControlBase): |
| 289 | 289 |
self.video_action.connect('change-state', self._on_video)
|
| 290 | 290 |
self.parent_win.window.add_action(self.video_action)
|
| 291 | 291 |
|
| 292 |
+ chatstate = app.config.get_per(
|
|
| 293 |
+ 'contacts', self.contact.jid, 'send_chatstate', 'composing_only')
|
|
| 294 |
+ |
|
| 295 |
+ act = Gio.SimpleAction.new_stateful(
|
|
| 296 |
+ 'send-chatstate-' + self.control_id,
|
|
| 297 |
+ GLib.VariantType.new("s"),
|
|
| 298 |
+ GLib.Variant("s", chatstate))
|
|
| 299 |
+ act.connect('change-state', self._on_send_chatstate)
|
|
| 300 |
+ self.parent_win.window.add_action(act)
|
|
| 301 |
+ |
|
| 292 | 302 |
def update_actions(self):
|
| 293 | 303 |
win = self.parent_win.window
|
| 294 | 304 |
online = app.account_is_connected(self.account)
|
| ... | ... | @@ -376,6 +386,11 @@ class ChatControl(ChatControlBase): |
| 376 | 386 |
state = param.get_boolean()
|
| 377 | 387 |
self.on_jingle_button_toggled(state, 'video')
|
| 378 | 388 |
|
| 389 |
+ def _on_send_chatstate(self, action, param):
|
|
| 390 |
+ action.set_state(param)
|
|
| 391 |
+ app.config.set_per('contacts', self.contact.jid,
|
|
| 392 |
+ 'send_chatstate', param.get_string())
|
|
| 393 |
+ |
|
| 379 | 394 |
def subscribe_events(self):
|
| 380 | 395 |
"""
|
| 381 | 396 |
Register listeners to the events class
|
| ... | ... | @@ -156,6 +156,7 @@ gajim_common_features = [ |
| 156 | 156 |
nbxmpp.NS_DATA,
|
| 157 | 157 |
nbxmpp.NS_ENCRYPTED,
|
| 158 | 158 |
nbxmpp.NS_PING,
|
| 159 |
+ nbxmpp.NS_CHATSTATES,
|
|
| 159 | 160 |
nbxmpp.NS_TIME_REVISED,
|
| 160 | 161 |
nbxmpp.NS_VERSION,
|
| 161 | 162 |
nbxmpp.NS_ROSTERX,
|
| ... | ... | @@ -183,7 +183,6 @@ class Config: |
| 183 | 183 |
'always_english_wikipedia': [opt_bool, False],
|
| 184 | 184 |
'always_english_wiktionary': [opt_bool, True],
|
| 185 | 185 |
'remote_control': [opt_bool, False, _('If checked, Gajim can be controlled remotely using gajim-remote.'), True],
|
| 186 |
- 'outgoing_chat_state_notifications': [opt_str, 'all', _('Sent chat state notifications. Can be one of all, composing_only, disabled.')],
|
|
| 187 | 186 |
'autodetect_browser_mailer': [opt_bool, True, '', True],
|
| 188 | 187 |
'print_ichat_every_foo_minutes': [opt_int, 5, _('When not printing time for every message (print_time==sometimes), print it every x minutes.')],
|
| 189 | 188 |
'confirm_close_muc': [opt_bool, True, _('Ask before closing a group chat tab/window.')],
|
| ... | ... | @@ -421,9 +420,9 @@ class Config: |
| 421 | 420 |
'bosh_http_pipelining': [opt_bool, False],
|
| 422 | 421 |
'bosh_wait_for_restart_response': [opt_bool, False],
|
| 423 | 422 |
}, {}),
|
| 424 |
- |
|
| 425 | 423 |
'contacts': ({
|
| 426 | 424 |
'speller_language': [opt_str, '', _('Language for which misspelled words will be checked')],
|
| 425 |
+ 'send_chatstate': [opt_str, 'composing_only', _('Chat state notifications that are sent to contacts. Possible values: all, composing_only, disabled')],
|
|
| 427 | 426 |
}, {}),
|
| 428 | 427 |
'encryption': ({
|
| 429 | 428 |
'encryption': [opt_str, '', _('The currently active encryption for that contact')],
|
| ... | ... | @@ -1127,8 +1127,6 @@ def update_optional_features(account=None): |
| 1127 | 1127 |
features.append(nbxmpp.NS_NICK + '+notify')
|
| 1128 | 1128 |
if app.config.get_per('accounts', account_, 'subscribe_location'):
|
| 1129 | 1129 |
features.append(nbxmpp.NS_LOCATION + '+notify')
|
| 1130 |
- if app.config.get('outgoing_chat_state_notifactions') != 'disabled':
|
|
| 1131 |
- features.append(nbxmpp.NS_CHATSTATES)
|
|
| 1132 | 1130 |
if not app.config.get('ignore_incoming_xhtml'):
|
| 1133 | 1131 |
features.append(nbxmpp.NS_XHTML_IM)
|
| 1134 | 1132 |
if app.config.get_per('accounts', account_, 'answer_receipts'):
|
| ... | ... | @@ -358,7 +358,8 @@ class Chatstate(BaseModule): |
| 358 | 358 |
if contact.is_groupchat():
|
| 359 | 359 |
return app.config.get_per(
|
| 360 | 360 |
'rooms', contact.jid, 'send_chatstate', 'composing_only')
|
| 361 |
- return app.config.get('outgoing_chat_state_notifications')
|
|
| 361 |
+ return app.config.get_per(
|
|
| 362 |
+ 'contacts', contact.jid, 'send_chatstate', 'composing_only')
|
|
| 362 | 363 |
|
| 363 | 364 |
def remove_delay_timeout(self, contact):
|
| 364 | 365 |
timeout = self._delay_timeout_ids.get(contact.jid)
|
| ... | ... | @@ -42,23 +42,6 @@ |
| 42 | 42 |
<column type="gboolean"/>
|
| 43 | 43 |
</columns>
|
| 44 | 44 |
</object>
|
| 45 |
- <object class="GtkListStore" id="display_chat_state_notifications_liststore">
|
|
| 46 |
- <columns>
|
|
| 47 |
- <!-- column-name item -->
|
|
| 48 |
- <column type="gchararray"/>
|
|
| 49 |
- </columns>
|
|
| 50 |
- <data>
|
|
| 51 |
- <row>
|
|
| 52 |
- <col id="0" translatable="yes">All chat states</col>
|
|
| 53 |
- </row>
|
|
| 54 |
- <row>
|
|
| 55 |
- <col id="0" translatable="yes">Composing only</col>
|
|
| 56 |
- </row>
|
|
| 57 |
- <row>
|
|
| 58 |
- <col id="0" translatable="yes">Disabled</col>
|
|
| 59 |
- </row>
|
|
| 60 |
- </data>
|
|
| 61 |
- </object>
|
|
| 62 | 45 |
<object class="GtkListStore" id="on_event_received_liststore">
|
| 63 | 46 |
<columns>
|
| 64 | 47 |
<!-- column-name item -->
|
| ... | ... | @@ -127,23 +110,6 @@ |
| 127 | 110 |
</row>
|
| 128 | 111 |
</data>
|
| 129 | 112 |
</object>
|
| 130 |
- <object class="GtkListStore" id="send_chatstate_notifications_liststore">
|
|
| 131 |
- <columns>
|
|
| 132 |
- <!-- column-name item -->
|
|
| 133 |
- <column type="gchararray"/>
|
|
| 134 |
- </columns>
|
|
| 135 |
- <data>
|
|
| 136 |
- <row>
|
|
| 137 |
- <col id="0" translatable="yes">All chat states</col>
|
|
| 138 |
- </row>
|
|
| 139 |
- <row>
|
|
| 140 |
- <col id="0" translatable="yes">Composing only</col>
|
|
| 141 |
- </row>
|
|
| 142 |
- <row>
|
|
| 143 |
- <col id="0" translatable="yes">Disabled</col>
|
|
| 144 |
- </row>
|
|
| 145 |
- </data>
|
|
| 146 |
- </object>
|
|
| 147 | 113 |
<object class="GtkListStore" id="show_roster_on_startup_liststore">
|
| 148 | 114 |
<columns>
|
| 149 | 115 |
<!-- column-name item -->
|
| ... | ... | @@ -756,7 +722,6 @@ |
| 756 | 722 |
<property name="label" translatable="yes">Default Sync Threshold</property>
|
| 757 | 723 |
<property name="use_underline">True</property>
|
| 758 | 724 |
<property name="justify">right</property>
|
| 759 |
- <property name="mnemonic_widget">outgoing_chat_states_combobox</property>
|
|
| 760 | 725 |
<style>
|
| 761 | 726 |
<class name="dim-label"/>
|
| 762 | 727 |
</style>
|
| ... | ... | @@ -1754,107 +1719,6 @@ $T will be replaced by auto-not-available timeout.</property> |
| 1754 | 1719 |
<property name="position">3</property>
|
| 1755 | 1720 |
</packing>
|
| 1756 | 1721 |
</child>
|
| 1757 |
- <child>
|
|
| 1758 |
- <object class="GtkBox" id="privacy_tab">
|
|
| 1759 |
- <property name="visible">True</property>
|
|
| 1760 |
- <property name="can_focus">False</property>
|
|
| 1761 |
- <property name="border_width">18</property>
|
|
| 1762 |
- <property name="orientation">vertical</property>
|
|
| 1763 |
- <property name="spacing">6</property>
|
|
| 1764 |
- <child>
|
|
| 1765 |
- <object class="GtkFrame">
|
|
| 1766 |
- <property name="visible">True</property>
|
|
| 1767 |
- <property name="can_focus">False</property>
|
|
| 1768 |
- <property name="label_xalign">0</property>
|
|
| 1769 |
- <property name="shadow_type">none</property>
|
|
| 1770 |
- <child>
|
|
| 1771 |
- <object class="GtkBox">
|
|
| 1772 |
- <property name="visible">True</property>
|
|
| 1773 |
- <property name="can_focus">False</property>
|
|
| 1774 |
- <property name="margin_top">6</property>
|
|
| 1775 |
- <property name="orientation">vertical</property>
|
|
| 1776 |
- <property name="spacing">6</property>
|
|
| 1777 |
- <child>
|
|
| 1778 |
- <object class="GtkBox">
|
|
| 1779 |
- <property name="visible">True</property>
|
|
| 1780 |
- <property name="can_focus">False</property>
|
|
| 1781 |
- <property name="halign">start</property>
|
|
| 1782 |
- <property name="spacing">12</property>
|
|
| 1783 |
- <child>
|
|
| 1784 |
- <object class="GtkLabel">
|
|
| 1785 |
- <property name="visible">True</property>
|
|
| 1786 |
- <property name="can_focus">False</property>
|
|
| 1787 |
- <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>
|
|
| 1788 |
- <property name="halign">start</property>
|
|
| 1789 |
- <property name="label" translatable="yes">S_end chat state notifications</property>
|
|
| 1790 |
- <property name="use_underline">True</property>
|
|
| 1791 |
- <property name="justify">right</property>
|
|
| 1792 |
- <property name="mnemonic_widget">outgoing_chat_states_combobox</property>
|
|
| 1793 |
- <style>
|
|
| 1794 |
- <class name="dim-label"/>
|
|
| 1795 |
- </style>
|
|
| 1796 |
- </object>
|
|
| 1797 |
- <packing>
|
|
| 1798 |
- <property name="expand">False</property>
|
|
| 1799 |
- <property name="fill">True</property>
|
|
| 1800 |
- <property name="position">0</property>
|
|
| 1801 |
- </packing>
|
|
| 1802 |
- </child>
|
|
| 1803 |
- <child>
|
|
| 1804 |
- <object class="GtkComboBox" id="outgoing_chat_states_combobox">
|
|
| 1805 |
- <property name="width_request">200</property>
|
|
| 1806 |
- <property name="visible">True</property>
|
|
| 1807 |
- <property name="can_focus">False</property>
|
|
| 1808 |
- <property name="halign">start</property>
|
|
| 1809 |
- <property name="model">send_chatstate_notifications_liststore</property>
|
|
| 1810 |
- <signal name="changed" handler="on_outgoing_chat_states_combobox_changed" swapped="no"/>
|
|
| 1811 |
- <child>
|
|
| 1812 |
- <object class="GtkCellRendererText"/>
|
|
| 1813 |
- <attributes>
|
|
| 1814 |
- <attribute name="text">0</attribute>
|
|
| 1815 |
- </attributes>
|
|
| 1816 |
- </child>
|
|
| 1817 |
- </object>
|
|
| 1818 |
- <packing>
|
|
| 1819 |
- <property name="expand">False</property>
|
|
| 1820 |
- <property name="fill">True</property>
|
|
| 1821 |
- <property name="position">1</property>
|
|
| 1822 |
- </packing>
|
|
| 1823 |
- </child>
|
|
| 1824 |
- </object>
|
|
| 1825 |
- <packing>
|
|
| 1826 |
- <property name="expand">False</property>
|
|
| 1827 |
- <property name="fill">True</property>
|
|
| 1828 |
- <property name="position">0</property>
|
|
| 1829 |
- </packing>
|
|
| 1830 |
- </child>
|
|
| 1831 |
- </object>
|
|
| 1832 |
- </child>
|
|
| 1833 |
- <child type="label">
|
|
| 1834 |
- <object class="GtkLabel">
|
|
| 1835 |
- <property name="visible">True</property>
|
|
| 1836 |
- <property name="can_focus">False</property>
|
|
| 1837 |
- <property name="label" translatable="yes">Privacy</property>
|
|
| 1838 |
- <style>
|
|
| 1839 |
- <class name="bold"/>
|
|
| 1840 |
- <class name="margin-top6"/>
|
|
| 1841 |
- </style>
|
|
| 1842 |
- </object>
|
|
| 1843 |
- </child>
|
|
| 1844 |
- </object>
|
|
| 1845 |
- <packing>
|
|
| 1846 |
- <property name="expand">False</property>
|
|
| 1847 |
- <property name="fill">True</property>
|
|
| 1848 |
- <property name="position">0</property>
|
|
| 1849 |
- </packing>
|
|
| 1850 |
- </child>
|
|
| 1851 |
- </object>
|
|
| 1852 |
- <packing>
|
|
| 1853 |
- <property name="name">privacy</property>
|
|
| 1854 |
- <property name="title" translatable="yes">Privacy</property>
|
|
| 1855 |
- <property name="position">4</property>
|
|
| 1856 |
- </packing>
|
|
| 1857 |
- </child>
|
|
| 1858 | 1722 |
<child>
|
| 1859 | 1723 |
<object class="GtkBox" id="style_tab">
|
| 1860 | 1724 |
<property name="visible">True</property>
|
| ... | ... | @@ -2169,7 +2033,7 @@ $T will be replaced by auto-not-available timeout.</property> |
| 2169 | 2033 |
<packing>
|
| 2170 | 2034 |
<property name="name">style</property>
|
| 2171 | 2035 |
<property name="title" translatable="yes">Style</property>
|
| 2172 |
- <property name="position">5</property>
|
|
| 2036 |
+ <property name="position">4</property>
|
|
| 2173 | 2037 |
</packing>
|
| 2174 | 2038 |
</child>
|
| 2175 | 2039 |
<child>
|
| ... | ... | @@ -2479,7 +2343,7 @@ to discover one from the server. (Example: stun.iptel.org)</property> |
| 2479 | 2343 |
<packing>
|
| 2480 | 2344 |
<property name="name">audio_video</property>
|
| 2481 | 2345 |
<property name="title" translatable="yes">Audio/Video</property>
|
| 2482 |
- <property name="position">6</property>
|
|
| 2346 |
+ <property name="position">5</property>
|
|
| 2483 | 2347 |
</packing>
|
| 2484 | 2348 |
</child>
|
| 2485 | 2349 |
<child>
|
| ... | ... | @@ -2875,7 +2739,7 @@ to discover one from the server. (Example: stun.iptel.org)</property> |
| 2875 | 2739 |
<packing>
|
| 2876 | 2740 |
<property name="name">advanced</property>
|
| 2877 | 2741 |
<property name="title" translatable="yes">Advanced</property>
|
| 2878 |
- <property name="position">7</property>
|
|
| 2742 |
+ <property name="position">6</property>
|
|
| 2879 | 2743 |
</packing>
|
| 2880 | 2744 |
</child>
|
| 2881 | 2745 |
<style>
|
| ... | ... | @@ -281,16 +281,6 @@ class Preferences(Gtk.ApplicationWindow): |
| 281 | 281 |
buf = self._ui.msg_textview.get_buffer()
|
| 282 | 282 |
buf.connect('end-user-action', self.on_msg_textview_changed)
|
| 283 | 283 |
|
| 284 |
- ### Privacy tab ###
|
|
| 285 |
- # Outgoing chat state notifications
|
|
| 286 |
- st = app.config.get('outgoing_chat_state_notifications')
|
|
| 287 |
- if st == 'all':
|
|
| 288 |
- self._ui.outgoing_chat_states_combobox.set_active(0)
|
|
| 289 |
- elif st == 'composing_only':
|
|
| 290 |
- self._ui.outgoing_chat_states_combobox.set_active(1)
|
|
| 291 |
- else: # disabled
|
|
| 292 |
- self._ui.outgoing_chat_states_combobox.set_active(2)
|
|
| 293 |
- |
|
| 294 | 284 |
### Style tab ###
|
| 295 | 285 |
# Themes
|
| 296 | 286 |
self.changed_id = self._ui.theme_combobox.connect(
|
| ... | ... | @@ -858,20 +848,6 @@ class Preferences(Gtk.ApplicationWindow): |
| 858 | 848 |
widget.set_inconsistent(False)
|
| 859 | 849 |
self.on_per_account_checkbutton_toggled(widget, 'ignore_unknown_contacts')
|
| 860 | 850 |
|
| 861 |
- def on_outgoing_chat_states_combobox_changed(self, widget):
|
|
| 862 |
- active = widget.get_active()
|
|
| 863 |
- old_value = app.config.get('outgoing_chat_state_notifications')
|
|
| 864 |
- if active == 0: # all
|
|
| 865 |
- app.config.set('outgoing_chat_state_notifications', 'all')
|
|
| 866 |
- elif active == 1: # only composing
|
|
| 867 |
- app.config.set('outgoing_chat_state_notifications', 'composing_only')
|
|
| 868 |
- else: # disabled
|
|
| 869 |
- app.config.set('outgoing_chat_state_notifications', 'disabled')
|
|
| 870 |
- new_value = app.config.get('outgoing_chat_state_notifications')
|
|
| 871 |
- if 'disabled' in (old_value, new_value):
|
|
| 872 |
- # We changed from disabled to sth else or vice versa
|
|
| 873 |
- helpers.update_optional_features()
|
|
| 874 |
- |
|
| 875 | 851 |
### Style ###
|
| 876 | 852 |
@staticmethod
|
| 877 | 853 |
def on_theme_combobox_changed(combobox):
|
| ... | ... | @@ -609,6 +609,7 @@ def get_singlechat_menu(control_id, account, jid): |
| 609 | 609 |
('win.send-file-httpupload-', _('Upload File…')),
|
| 610 | 610 |
('win.send-file-jingle-', _('Send File Directly…')),
|
| 611 | 611 |
]),
|
| 612 |
+ (_('Send Chatstate'), ['chatstate']),
|
|
| 612 | 613 |
('win.invite-contacts-', _('Invite Contacts')),
|
| 613 | 614 |
('win.add-to-roster-', _('Add to Roster')),
|
| 614 | 615 |
('win.toggle-audio-', _('Audio Session')),
|
| ... | ... | @@ -617,6 +618,20 @@ def get_singlechat_menu(control_id, account, jid): |
| 617 | 618 |
('app.browse-history', _('History')),
|
| 618 | 619 |
]
|
| 619 | 620 |
|
| 621 |
+ def build_chatstate_menu():
|
|
| 622 |
+ menu = Gio.Menu()
|
|
| 623 |
+ entrys = [
|
|
| 624 |
+ (_('Disabled'), 'disabled'),
|
|
| 625 |
+ (_('Composing only'), 'composing_only'),
|
|
| 626 |
+ (_('All chat states'), 'all')
|
|
| 627 |
+ ]
|
|
| 628 |
+ |
|
| 629 |
+ for entry in entrys:
|
|
| 630 |
+ label, setting = entry
|
|
| 631 |
+ action = 'win.send-chatstate-%s::%s' % (control_id, setting)
|
|
| 632 |
+ menu.append(label, action)
|
|
| 633 |
+ return menu
|
|
| 634 |
+ |
|
| 620 | 635 |
def build_menu(preset):
|
| 621 | 636 |
menu = Gio.Menu()
|
| 622 | 637 |
for item in preset:
|
| ... | ... | @@ -634,8 +649,10 @@ def get_singlechat_menu(control_id, account, jid): |
| 634 | 649 |
menu.append(label, action_name + control_id)
|
| 635 | 650 |
else:
|
| 636 | 651 |
label, sub_menu = item
|
| 637 |
- # This is a submenu
|
|
| 638 |
- submenu = build_menu(sub_menu)
|
|
| 652 |
+ if 'chatstate' in sub_menu:
|
|
| 653 |
+ submenu = build_chatstate_menu()
|
|
| 654 |
+ else:
|
|
| 655 |
+ submenu = build_menu(sub_menu)
|
|
| 639 | 656 |
menu.append_submenu(label, submenu)
|
| 640 | 657 |
return menu
|
| 641 | 658 |
|