Philipp Hörist pushed to branch master at gajim / gajim
Commits: 30692536 by wurstsalat at 2020-08-12T16:55:44+02:00 StatusChange: Rework status change window
- - - - -
9 changed files:
- − gajim/data/gui/change_mood_dialog.ui - − gajim/data/gui/change_status_message_dialog.ui - gajim/data/gui/change_activity_dialog.ui → gajim/data/gui/status_change_window.ui - gajim/dialogs.py - gajim/gtk/const.py - gajim/gtk/dialogs.py - + gajim/gtk/status_change.py - gajim/gtk/status_selector.py - gajim/roster_window.py
Changes:
===================================== gajim/data/gui/change_mood_dialog.ui deleted ===================================== @@ -1,359 +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="change_mood_dialog"> - <property name="can_focus">False</property> - <property name="border_width">6</property> - <property name="default_width">270</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox5"> - <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_area"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="cancel_button"> - <property name="label">gtk-cancel</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> - <signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="ok_button"> - <property name="label">gtk-ok</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> - <signal name="clicked" handler="on_ok_button_clicked" swapped="no"/> - </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">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="grid1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="hexpand">True</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - <child> - <object class="GtkLabel" id="label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes"><b>Mood:</b></property> - <property name="use_markup">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes"><b>Message:</b></property> - <property name="use_markup">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="mood_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">None</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="description_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hexpand">True</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="mood_icons_table"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="hexpand">True</property> - <child> - <object class="GtkRadioButton" id="no_mood_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="relief">none</property> - <property name="xalign">0.5</property> - <property name="draw_indicator">False</property> - <child> - <object class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-cancel</property> - <property name="icon_size">1</property> - </object> - </child> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - <property name="width">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-6">cancel_button</action-widget> - <action-widget response="-5">ok_button</action-widget> - </action-widgets> - </object> -</interface>
===================================== gajim/data/gui/change_status_message_dialog.ui deleted ===================================== @@ -1,338 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.1 --> -<interface> - <requires lib="gtk+" version="3.18"/> - <object class="GtkDialog" id="change_status_message_dialog"> - <property name="can_focus">False</property> - <property name="border_width">18</property> - <property name="default_width">270</property> - <property name="default_height">330</property> - <property name="type_hint">dialog</property> - <signal name="key-press-event" handler="on_change_status_message_dialog_key_press_event" swapped="no"/> - <child> - <placeholder/> - </child> - <child internal-child="vbox"> - <object class="GtkBox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">12</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="margin_top">6</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="cancel_button"> - <property name="label">gtk-cancel</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">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="ok_button"> - <property name="label">gtk-ok</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> - <style> - <class name="suggested-action"/> - </style> - </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="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - <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> - <child> - <object class="GtkScrolledWindow"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkTextView" id="message_textview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="wrap_mode">word</property> - <property name="left_margin">6</property> - <property name="right_margin">6</property> - <property name="top_margin">6</property> - <property name="bottom_margin">6</property> - </object> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="save_as_preset_button"> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="tooltip_text" translatable="yes">Save this message as a preset</property> - <signal name="clicked" handler="on_save_as_preset_button_clicked" swapped="no"/> - <child> - <object class="GtkImage"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-save-as</property> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkGrid" id="under_table"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">center</property> - <property name="margin_top">6</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">Preset _messages</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">message_combobox</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="activity_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="margin_top">6</property> - <property name="label" translatable="yes">Ac_tivity</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">activity_button</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="mood_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="halign">end</property> - <property name="label" translatable="yes">M_ood</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">mood_button</property> - <style> - <class name="dim-label"/> - </style> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - <child> - <object class="GtkComboBox" id="message_combobox"> - <property name="width_request">200</property> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="hexpand">True</property> - <signal name="changed" handler="on_message_combobox_changed" swapped="no"/> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="activity_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="margin_top">6</property> - <signal name="clicked" handler="on_activity_button_clicked" swapped="no"/> - <child> - <object class="GtkBox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkImage" id="activity_image"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</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="activity_button_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="wrap">True</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="mood_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <signal name="clicked" handler="on_mood_button_clicked" swapped="no"/> - <child> - <object class="GtkBox"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> - <child> - <object class="GtkImage" id="mood_image"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</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="mood_button_label"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="wrap">True</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - </child> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</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">_Type your new status message</property> - <property name="use_underline">True</property> - <property name="justify">center</property> - <property name="mnemonic_widget">message_textview</property> - <style> - <class name="dim-label"/> - <class name="bold"/> - </style> - </object> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> - <action-widgets> - <action-widget response="-6">cancel_button</action-widget> - <action-widget response="-5">ok_button</action-widget> - </action-widgets> - </object> -</interface>
===================================== gajim/data/gui/change_activity_dialog.ui → gajim/data/gui/status_change_window.ui ===================================== @@ -1,98 +1,370 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> +<!-- Generated with glade 3.36.0 --> <interface> - <requires lib="gtk+" version="3.12"/> - <object class="GtkDialog" id="change_activity_dialog"> + <requires lib="gtk+" version="3.22"/> + <object class="GtkPopover" id="preset_popover"> <property name="can_focus">False</property> - <property name="border_width">6</property> - <property name="title" translatable="yes">Set Activity</property> - <property name="default_width">270</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox5"> + <child> + <placeholder/> + </child> + </object> + <object class="GtkStack" id="status_stack"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="transition_duration">150</property> + <child> + <object class="GtkBox"> <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 internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area"> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_bottom">12</property> + <property name="label" translatable="yes">Change Status</property> + <style> + <class name="large-header"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="layout_style">end</property> + <property name="halign">center</property> + <property name="spacing">12</property> <child> - <object class="GtkButton" id="cancel_button"> - <property name="label">gtk-cancel</property> + <object class="GtkMenuButton" id="preset_list_button"> <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> - <signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/> + <property name="focus_on_click">False</property> + <property name="receives_default">True</property> + <property name="popover">preset_popover</property> + <signal name="toggled" handler="_stop_timeout" swapped="no"/> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Status Presets…</property> + </object> + </child> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkButton" id="ok_button"> - <property name="label">gtk-ok</property> + <object class="GtkButton"> <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> - <signal name="clicked" handler="on_ok_button_clicked" swapped="no"/> + <property name="tooltip_text" translatable="yes">Save this message as a preset</property> + <signal name="clicked" handler="_on_save_as_preset_clicked" swapped="no"/> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">document-save-as-symbolic</property> + </object> + </child> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">1</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTextView" id="message_textview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="wrap_mode">word</property> + <property name="left_margin">6</property> + <property name="right_margin">6</property> + <property name="top_margin">6</property> + <property name="bottom_margin">6</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <property name="row_spacing">6</property> + <property name="column_spacing">12</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">Ac_tivity</property> + <property name="use_underline">True</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">M_ood</property> + <property name="use_underline">True</property> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="activity_page_button"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="clicked" handler="_on_activity_page_clicked" swapped="no"/> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkImage" id="activity_image"> + <property name="visible">True</property> + <property name="can_focus">False</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="activity_button_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="mood_page_button"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <signal name="clicked" handler="_on_mood_page_clicked" swapped="no"/> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkImage" id="mood_image"> + <property name="visible">True</property> + <property name="can_focus">False</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="mood_button_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="wrap">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkSwitch" id="activity_switch"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="valign">center</property> + <signal name="notify::active" handler="_on_activity_switch" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkSwitch" id="mood_switch"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="valign">center</property> + <signal name="notify::active" handler="_on_mood_switch" swapped="no"/> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">end</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="label" translatable="yes">_Change Status</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="margin_top">12</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="_change_status" swapped="no"/> + <style> + <class name="suggested-action"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">5</property> + </packing> + </child> + </object> + <packing> + <property name="name">status-page</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <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="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_bottom">12</property> + <property name="label" translatable="yes">Activity</property> + <style> + <class name="large-header"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkCheckButton" id="enable_checkbutton"> - <property name="label" translatable="yes">Set an activity</property> + <object class="GtkRadioButton" id="no_activity_button"> + <property name="label" translatable="yes">_No Activity</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> - <property name="xalign">0.5</property> + <property name="halign">center</property> + <property name="use_underline">True</property> + <property name="active">True</property> <property name="draw_indicator">True</property> - <signal name="toggled" handler="on_enable_checkbutton_toggled" swapped="no"/> + <signal name="toggled" handler="_on_no_activity_toggled" swapped="no"/> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> <child> - <object class="GtkNotebook" id="notebook"> + <object class="GtkNotebook" id="activity_notebook"> <property name="visible">True</property> - <property name="sensitive">False</property> <property name="can_focus">True</property> + <property name="scrollable">True</property> <child> - <object class="GtkBox" id="doing_chores_vbox"> + <object class="GtkBox" id="doing_chores_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> </child> <child type="tab"> <object class="GtkImage" id="doing_chores_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -100,10 +372,20 @@ </packing> </child> <child> - <object class="GtkBox" id="drinking_vbox"> + <object class="GtkBox" id="drinking_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">1</property> @@ -113,7 +395,6 @@ <object class="GtkImage" id="drinking_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -122,10 +403,20 @@ </packing> </child> <child> - <object class="GtkBox" id="eating_vbox"> + <object class="GtkBox" id="eating_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">2</property> @@ -135,7 +426,6 @@ <object class="GtkImage" id="eating_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -144,10 +434,20 @@ </packing> </child> <child> - <object class="GtkBox" id="exercising_vbox"> + <object class="GtkBox" id="exercising_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">3</property> @@ -157,7 +457,6 @@ <object class="GtkImage" id="exercising_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -166,10 +465,20 @@ </packing> </child> <child> - <object class="GtkBox" id="grooming_vbox"> + <object class="GtkBox" id="grooming_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">4</property> @@ -179,7 +488,6 @@ <object class="GtkImage" id="grooming_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -188,10 +496,20 @@ </packing> </child> <child> - <object class="GtkBox" id="having_appointment_vbox"> + <object class="GtkBox" id="having_appointment_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">5</property> @@ -201,7 +519,6 @@ <object class="GtkImage" id="having_appointment_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -210,10 +527,20 @@ </packing> </child> <child> - <object class="GtkBox" id="inactive_vbox"> + <object class="GtkBox" id="inactive_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">6</property> @@ -223,7 +550,6 @@ <object class="GtkImage" id="inactive_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -232,10 +558,20 @@ </packing> </child> <child> - <object class="GtkBox" id="relaxing_vbox"> + <object class="GtkBox" id="relaxing_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">7</property> @@ -245,7 +581,6 @@ <object class="GtkImage" id="relaxing_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -254,10 +589,20 @@ </packing> </child> <child> - <object class="GtkBox" id="talking_vbox"> + <object class="GtkBox" id="talking_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">8</property> @@ -267,7 +612,6 @@ <object class="GtkImage" id="talking_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -276,10 +620,20 @@ </packing> </child> <child> - <object class="GtkBox" id="traveling_vbox"> + <object class="GtkBox" id="traveling_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">9</property> @@ -289,7 +643,6 @@ <object class="GtkImage" id="traveling_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -298,10 +651,20 @@ </packing> </child> <child> - <object class="GtkBox" id="working_vbox"> + <object class="GtkBox" id="working_box"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="border_width">6</property> <property name="orientation">vertical</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> </object> <packing> <property name="position">10</property> @@ -311,7 +674,6 @@ <object class="GtkImage" id="working_image"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="stock">gtk-missing-image</property> <property name="icon_size">1</property> </object> <packing> @@ -320,53 +682,133 @@ </packing> </child> </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="label" translatable="yes">_Back</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="margin_top">12</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="_on_back_clicked" swapped="no"/> + <style> + <class name="suggested-action"/> + </style> + </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">3</property> </packing> </child> + </object> + <packing> + <property name="name">activity-page</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <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="GtkBox" id="hbox1"> + <object class="GtkLabel"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="margin_bottom">12</property> + <property name="label" translatable="yes">Mood</property> + <style> + <class name="large-header"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="mood_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <style> + <class name="bold"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkGrid" id="moods_grid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> <child> - <object class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes"><b>Message:</b> </property> - <property name="use_markup">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="description_entry"> + <object class="GtkRadioButton" id="no_mood_button"> <property name="visible">True</property> - <property name="sensitive">False</property> <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="relief">none</property> + <property name="active">True</property> + <property name="draw_indicator">False</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_size">1</property> + </object> + </child> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> + <property name="left_attach">0</property> + <property name="top_attach">0</property> </packing> </child> </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="label" translatable="yes">_Back</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="halign">center</property> + <property name="margin_top">12</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="_on_back_clicked" swapped="no"/> + <style> + <class name="suggested-action"/> + </style> + </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">4</property> + <property name="fill">True</property> + <property name="position">5</property> </packing> </child> </object> + <packing> + <property name="name">mood-page</property> + <property name="position">2</property> + </packing> </child> - <action-widgets> - <action-widget response="-6">cancel_button</action-widget> - <action-widget response="-5">ok_button</action-widget> - </action-widgets> </object> </interface>
===================================== gajim/dialogs.py ===================================== @@ -34,30 +34,19 @@ import logging
from gi.repository import Gtk from gi.repository import Gdk -from gi.repository import GLib
from gajim.common.i18n import _ -from gajim.common.const import ACTIVITIES -from gajim.common.const import MOODS
from gajim.common import app from gajim.common import helpers from gajim.common.exceptions import GajimGeneralException
-from gajim.gtk.dialogs import DialogButton -from gajim.gtk.dialogs import NewConfirmationDialog from gajim.gtk.dialogs import ErrorDialog -from gajim.gtk.dialogs import InputDialog from gajim.gtk.util import get_icon_name from gajim.gtk.util import get_builder -from gajim.gtk.util import get_activity_icon_name from gajim.gtk.util import get_app_window from gajim.gtk import gstreamer
-if app.is_installed('GSPELL'): - from gi.repository import Gspell # pylint: disable=ungrouped-imports - - log = logging.getLogger('gajim.dialogs')
@@ -216,533 +205,6 @@ class EditGroupsDialog: column.add_attribute(renderer, 'inconsistent', 2)
-class ChangeActivityDialog: - PAGELIST = [ - 'doing_chores', 'drinking', 'eating', 'exercising', 'grooming', - 'having_appointment', 'inactive', 'relaxing', 'talking', 'traveling', - 'working'] - - def __init__(self, on_response, activity_=None, subactivity_=None, text=''): - self.on_response = on_response - self.activity = activity_ - self.subactivity = subactivity_ - self.text = text - self.xml = get_builder('change_activity_dialog.ui') - self.window = self.xml.get_object('change_activity_dialog') - self.window.set_transient_for(app.interface.roster.window) - - self.checkbutton = self.xml.get_object('enable_checkbutton') - self.notebook = self.xml.get_object('notebook') - self.entry = self.xml.get_object('description_entry') - - rbtns = {} - group = None - - for category in ACTIVITIES: - icon_name = get_activity_icon_name(category) - item = self.xml.get_object(category + '_image') - item.set_from_icon_name(icon_name, Gtk.IconSize.MENU) - item.set_tooltip_text(ACTIVITIES[category]['category']) - - vbox = self.xml.get_object(category + '_vbox') - vbox.set_border_width(5) - - # Other - act = category + '_other' - - if group: - rbtns[act] = Gtk.RadioButton() - rbtns[act].join_group(group) - else: - rbtns[act] = group = Gtk.RadioButton() - - icon = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.MENU) - hbox = Gtk.HBox(homogeneous=False, spacing=5) - hbox.pack_start(icon, False, False, 0) - lbl = Gtk.Label( - label='<b>%s</b>' % ACTIVITIES[category]['category']) - lbl.set_use_markup(True) - hbox.pack_start(lbl, False, False, 0) - rbtns[act].add(hbox) - rbtns[act].connect( - 'toggled', self.on_rbtn_toggled, [category, 'other']) - vbox.pack_start(rbtns[act], False, False, 0) - - activities = list(ACTIVITIES[category].keys()) - activities.sort() - for activity in activities: - if activity == 'category': - continue - - act = category + '_' + activity - - if group: - rbtns[act] = Gtk.RadioButton() - rbtns[act].join_group(group) - else: - rbtns[act] = group = Gtk.RadioButton() - - icon_name = get_activity_icon_name(category, activity) - icon = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.MENU) - label = Gtk.Label(label=ACTIVITIES[category][activity]) - hbox = Gtk.HBox(homogeneous=False, spacing=5) - hbox.pack_start(icon, False, False, 0) - hbox.pack_start(label, False, False, 0) - rbtns[act].connect( - 'toggled', self.on_rbtn_toggled, [category, activity]) - rbtns[act].add(hbox) - vbox.pack_start(rbtns[act], False, False, 0) - - - self.default_radio = rbtns['doing_chores_other'] - - if self.activity in ACTIVITIES: - if not self.subactivity in ACTIVITIES[self.activity]: - self.subactivity = 'other' - - rbtns[self.activity + '_' + self.subactivity].set_active(True) - - self.checkbutton.set_active(True) - self.notebook.set_sensitive(True) - self.entry.set_sensitive(True) - - self.notebook.set_current_page( - self.PAGELIST.index(self.activity)) - self.entry.set_text(text) - - else: - self.checkbutton.set_active(False) - - self.xml.connect_signals(self) - self.window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) - self.window.show_all() - - def on_enable_checkbutton_toggled(self, widget): - self.notebook.set_sensitive(widget.get_active()) - self.entry.set_sensitive(widget.get_active()) - if not self.activity: - self.default_radio.set_active(True) - - def on_rbtn_toggled(self, widget, data): - if widget.get_active(): - self.activity = data[0] - self.subactivity = data[1] - - def on_ok_button_clicked(self, widget): - """ - Return activity and message (None if no activity selected) - """ - if self.checkbutton.get_active(): - self.on_response( - self.activity, self.subactivity, self.entry.get_text()) - else: - self.on_response(None, None, '') - self.window.destroy() - - def on_cancel_button_clicked(self, widget): - self.window.destroy() - -class ChangeMoodDialog: - COLS = 11 - - def __init__(self, on_response, mood_=None, text=''): - self.on_response = on_response - self.mood = mood_ - self.text = text - self.xml = get_builder('change_mood_dialog.ui') - - self.window = self.xml.get_object('change_mood_dialog') - self.window.set_transient_for(app.interface.roster.window) - self.window.set_title(_('Set Mood')) - - table = self.xml.get_object('mood_icons_table') - self.label = self.xml.get_object('mood_label') - self.entry = self.xml.get_object('description_entry') - - no_mood_button = self.xml.get_object('no_mood_button') - no_mood_button.set_mode(False) - no_mood_button.connect('clicked', - self.on_mood_button_clicked, None) - - x = 1 - y = 0 - self.mood_buttons = {} - - # Order them first - self.MOODS = [] - for mood in MOODS: - self.MOODS.append(mood) - self.MOODS.sort() - - for mood in self.MOODS: - image = Gtk.Image.new_from_icon_name( - 'mood-%s' % mood, Gtk.IconSize.MENU) - self.mood_buttons[mood] = Gtk.RadioButton() - self.mood_buttons[mood].join_group(no_mood_button) - self.mood_buttons[mood].set_mode(False) - self.mood_buttons[mood].add(image) - self.mood_buttons[mood].set_relief(Gtk.ReliefStyle.NONE) - self.mood_buttons[mood].set_tooltip_text(MOODS[mood]) - self.mood_buttons[mood].connect('clicked', - self.on_mood_button_clicked, mood) - table.attach(self.mood_buttons[mood], x, y, 1, 1) - - # Calculate the next position - x += 1 - if x >= self.COLS: - x = 0 - y += 1 - - if self.mood in MOODS: - self.mood_buttons[self.mood].set_active(True) - self.label.set_text(MOODS[self.mood]) - self.entry.set_sensitive(True) - if self.text: - self.entry.set_text(self.text) - else: - self.label.set_text(_('None')) - self.entry.set_text('') - self.entry.set_sensitive(False) - - self.xml.connect_signals(self) - self.window.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) - self.window.show_all() - - def on_mood_button_clicked(self, widget, data): - if data: - self.label.set_text(MOODS[data]) - self.entry.set_sensitive(True) - else: - self.label.set_text(_('None')) - self.entry.set_text('') - self.entry.set_sensitive(False) - self.mood = data - - def on_ok_button_clicked(self, widget): - '''Return mood and message (None if no mood selected)''' - message = self.entry.get_text() - self.on_response(self.mood, message) - self.window.destroy() - - def on_cancel_button_clicked(self, widget): - self.window.destroy() - -class TimeoutDialog: - """ - Class designed to be derivated to create timeout'd dialogs (dialogs that - closes automatically after a timeout) - """ - def __init__(self, timeout): - self.countdown_left = timeout - self.countdown_enabled = True - self.title_text = '' - - def run_timeout(self): - if self.countdown_left > 0: - self.countdown() - GLib.timeout_add_seconds(1, self.countdown) - - def on_timeout(self): - """ - To be implemented in derivated classes - """ - - def countdown(self): - if self.countdown_enabled: - if self.countdown_left <= 0: - self.on_timeout() - return False - self.dialog.set_title('%s [%s]' % ( - self.title_text, str(self.countdown_left))) - self.countdown_left -= 1 - return True - - self.dialog.set_title(self.title_text) - return False - -class ChangeStatusMessageDialog(TimeoutDialog): - def __init__(self, on_response, show=None, show_pep=True): - countdown_time = app.config.get('change_status_window_timeout') - TimeoutDialog.__init__(self, countdown_time) - self.show = show - self.pep_dict = {} - self.show_pep = show_pep - self.on_response = on_response - self.xml = get_builder('change_status_message_dialog.ui') - self.dialog = self.xml.get_object('change_status_message_dialog') - self.dialog.set_transient_for(app.interface.roster.window) - msg = None - if show: - uf_show = helpers.get_uf_show(show) - self.title_text = _('%s Status Message') % uf_show - msg = app.config.get_per('statusmsg', '_last_' + self.show, - 'message') - self.pep_dict['activity'] = app.config.get_per('statusmsg', - '_last_' + self.show, 'activity') - self.pep_dict['subactivity'] = app.config.get_per('statusmsg', - '_last_' + self.show, 'subactivity') - self.pep_dict['activity_text'] = app.config.get_per('statusmsg', - '_last_' + self.show, 'activity_text') - self.pep_dict['mood'] = app.config.get_per('statusmsg', - '_last_' + self.show, 'mood') - self.pep_dict['mood_text'] = app.config.get_per('statusmsg', - '_last_' + self.show, 'mood_text') - else: - self.title_text = _('Status Message') - self.dialog.set_title(self.title_text) - - message_textview = self.xml.get_object('message_textview') - self.message_buffer = message_textview.get_buffer() - - if app.config.get('use_speller') and app.is_installed('GSPELL'): - lang = app.config.get('speller_language') - gspell_lang = Gspell.language_lookup(lang) - if gspell_lang is None: - gspell_lang = Gspell.language_get_default() - spell_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer( - self.message_buffer) - spell_buffer.set_spell_checker(Gspell.Checker.new(gspell_lang)) - spell_view = Gspell.TextView.get_from_gtk_text_view( - message_textview) - spell_view.set_inline_spell_checking(True) - spell_view.set_enable_language_menu(True) - - self.message_buffer.connect('changed', self.on_message_buffer_changed) - if not msg: - msg = '' - msg = helpers.from_one_line(msg) - self.message_buffer.set_text(msg) - - # have an empty string selectable, so user can clear msg - self.preset_messages_dict = {'': ['', '', '', '', '', '']} - for msg_name in app.config.get_per('statusmsg'): - if msg_name.startswith('_last_'): - continue - opts = [] - for opt in ['message', 'activity', 'subactivity', 'activity_text', - 'mood', 'mood_text']: - opts.append(app.config.get_per('statusmsg', msg_name, opt)) - opts[0] = helpers.from_one_line(opts[0]) - self.preset_messages_dict[msg_name] = opts - sorted_keys_list = helpers.get_sorted_keys(self.preset_messages_dict) - - self.message_liststore = Gtk.ListStore(str) # msg_name - self.message_combobox = self.xml.get_object('message_combobox') - self.message_combobox.set_model(self.message_liststore) - cellrenderertext = Gtk.CellRendererText() - self.message_combobox.pack_start(cellrenderertext, True) - self.message_combobox.add_attribute(cellrenderertext, 'text', 0) - for msg_name in sorted_keys_list: - self.message_liststore.append((msg_name,)) - - if show_pep: - self.draw_activity() - self.draw_mood() - else: - # remove acvtivity / mood lines - self.xml.get_object('activity_label').set_no_show_all(True) - self.xml.get_object('activity_button').set_no_show_all(True) - self.xml.get_object('mood_label').set_no_show_all(True) - self.xml.get_object('mood_button').set_no_show_all(True) - self.xml.get_object('activity_label').hide() - self.xml.get_object('activity_button').hide() - self.xml.get_object('mood_label').hide() - self.xml.get_object('mood_button').hide() - - self.xml.connect_signals(self) - self.run_timeout() - self.dialog.connect('response', self.on_dialog_response) - self.dialog.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) - self.dialog.show_all() - - def draw_activity(self): - """ - Set activity button - """ - img = self.xml.get_object('activity_image') - label = self.xml.get_object('activity_button_label') - if 'activity' in self.pep_dict and self.pep_dict['activity'] in \ - ACTIVITIES: - if 'subactivity' in self.pep_dict and self.pep_dict['subactivity'] \ - in ACTIVITIES[self.pep_dict['activity']]: - icon_name = get_activity_icon_name(self.pep_dict['activity'], - self.pep_dict['subactivity']) - img.set_from_icon_name(icon_name, Gtk.IconSize.MENU) - else: - icon_name = get_activity_icon_name(self.pep_dict['activity']) - img.set_from_icon_name(icon_name, Gtk.IconSize.MENU) - if self.pep_dict['activity_text']: - label.set_text(self.pep_dict['activity_text']) - else: - label.set_text('') - else: - img.set_from_pixbuf(None) - label.set_text('') - - def draw_mood(self): - """ - Set mood button - """ - img = self.xml.get_object('mood_image') - label = self.xml.get_object('mood_button_label') - if 'mood' in self.pep_dict and self.pep_dict['mood'] in MOODS: - img.set_from_icon_name('mood-%s' % self.pep_dict['mood'], - Gtk.IconSize.MENU) - if self.pep_dict['mood_text']: - label.set_text(self.pep_dict['mood_text']) - else: - label.set_text('') - else: - img.set_from_pixbuf(None) - label.set_text('') - - def on_timeout(self): - # Prevent GUI freeze when the combobox menu is opened on close - self.message_combobox.popdown() - self.dialog.response(Gtk.ResponseType.OK) - - def on_dialog_response(self, dialog, response): - if response == Gtk.ResponseType.OK: - beg, end = self.message_buffer.get_bounds() - message = self.message_buffer.get_text(beg, end, True).strip() - message = helpers.remove_invalid_xml_chars(message) - msg = helpers.to_one_line(message) - if self.show: - app.config.set_per('statusmsg', '_last_' + self.show, - 'message', msg) - if self.show_pep: - app.config.set_per('statusmsg', '_last_' + self.show, - 'activity', self.pep_dict['activity']) - app.config.set_per('statusmsg', '_last_' + self.show, - 'subactivity', self.pep_dict['subactivity']) - app.config.set_per('statusmsg', '_last_' + self.show, - 'activity_text', self.pep_dict['activity_text']) - app.config.set_per('statusmsg', '_last_' + self.show, - 'mood', self.pep_dict['mood']) - app.config.set_per('statusmsg', '_last_' + self.show, - 'mood_text', self.pep_dict['mood_text']) - else: - message = None # user pressed Cancel button or X wm button - self.dialog.destroy() - self.on_response(message, self.pep_dict) - - def on_message_combobox_changed(self, widget): - self.countdown_enabled = False - model = widget.get_model() - active = widget.get_active() - if active < 0: - return None - name = model[active][0] - self.message_buffer.set_text(self.preset_messages_dict[name][0]) - self.pep_dict['activity'] = self.preset_messages_dict[name][1] - self.pep_dict['subactivity'] = self.preset_messages_dict[name][2] - self.pep_dict['activity_text'] = self.preset_messages_dict[name][3] - self.pep_dict['mood'] = self.preset_messages_dict[name][4] - self.pep_dict['mood_text'] = self.preset_messages_dict[name][5] - self.draw_activity() - self.draw_mood() - - def on_change_status_message_dialog_key_press_event(self, widget, event): - self.countdown_enabled = False - if event.keyval == Gdk.KEY_Return or \ - event.keyval == Gdk.KEY_KP_Enter: # catch CTRL+ENTER - if event.get_state() & Gdk.ModifierType.CONTROL_MASK: - self.dialog.response(Gtk.ResponseType.OK) - # Stop the event - return True - - def on_message_buffer_changed(self, widget): - self.countdown_enabled = False - self.toggle_sensitiviy_of_save_as_preset() - - def toggle_sensitiviy_of_save_as_preset(self): - btn = self.xml.get_object('save_as_preset_button') - if self.message_buffer.get_char_count() == 0: - btn.set_sensitive(False) - else: - btn.set_sensitive(True) - - def on_save_as_preset_button_clicked(self, widget): - self.countdown_enabled = False - start_iter, finish_iter = self.message_buffer.get_bounds() - status_message_to_save_as_preset = self.message_buffer.get_text( - start_iter, finish_iter, True) - - 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_overwrite_preset(): - self.preset_messages_dict[msg_name] = [ - msg_text, self.pep_dict.get('activity'), - self.pep_dict.get('subactivity'), - self.pep_dict.get('activity_text'), - self.pep_dict.get('mood'), self.pep_dict.get('mood_text')] - app.config.set_per('statusmsg', msg_name, 'message', - msg_text_1l) - app.config.set_per('statusmsg', msg_name, 'activity', - self.pep_dict.get('activity')) - app.config.set_per('statusmsg', msg_name, 'subactivity', - self.pep_dict.get('subactivity')) - app.config.set_per('statusmsg', msg_name, 'activity_text', - self.pep_dict.get('activity_text')) - app.config.set_per('statusmsg', msg_name, 'mood', - 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'), - _('Overwrite Status Message?'), - _('This name is already in use. Do you want to ' - 'overwrite this preset?'), - [DialogButton.make('Cancel'), - DialogButton.make('Remove', - text=_('_Overwrite'), - callback=_on_overwrite_preset)], - transient_for=self.dialog).show() - return - - app.config.add_per('statusmsg', msg_name) - _on_overwrite_preset() - iter_ = self.message_liststore.append((msg_name,)) - # Select the one we just saved in combobox - self.message_combobox.set_active_iter(iter_) - - 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 - def on_response(activity, subactivity, text): - self.pep_dict['activity'] = activity or '' - self.pep_dict['subactivity'] = subactivity or '' - self.pep_dict['activity_text'] = text - self.draw_activity() - ChangeActivityDialog(on_response, self.pep_dict['activity'], - self.pep_dict['subactivity'], self.pep_dict['activity_text']) - - def on_mood_button_clicked(self, widget): - self.countdown_enabled = False - def on_response(mood, text): - self.pep_dict['mood'] = mood or '' - self.pep_dict['mood_text'] = text - self.draw_mood() - ChangeMoodDialog(on_response, self.pep_dict['mood'], - self.pep_dict['mood_text']) - - class SynchroniseSelectAccountDialog: def __init__(self, account): # 'account' can be None if we are about to create our first one
===================================== gajim/gtk/const.py ===================================== @@ -121,4 +121,5 @@ WINDOW_MODULES = { 'ChangePassword': 'gajim.gtk.change_password', 'PluginsWindow': 'gajim.plugins.gui', 'Features': 'gajim.gtk.features', + 'StatusChange': 'gajim.gtk.status_change', }
===================================== gajim/gtk/dialogs.py ===================================== @@ -518,6 +518,40 @@ class InputDialog(NewConfirmationDialog): super()._on_response(_dialog, response)
+class TimeoutWindow: + """ + Class designed to be derivated by other windows + Derived windows close automatically after reaching the timeout + """ + def __init__(self, timeout): + self.countdown_left = timeout + self.countdown_enabled = True + self.title_text = '' + + def run_timeout(self): + if self.countdown_left > 0: + self.countdown() + GLib.timeout_add_seconds(1, self.countdown) + + def on_timeout(self): + """ + To be implemented by derivated classes + """ + + def countdown(self): + if self.countdown_enabled: + if self.countdown_left <= 0: + self.on_timeout() + return False + self.set_title('%s [%s]' % ( + self.title_text, str(self.countdown_left))) + self.countdown_left -= 1 + return True + + self.set_title(self.title_text) + return False + + class ShortcutsWindow: def __init__(self): transient = app.app.get_active_window()
===================================== gajim/gtk/status_change.py ===================================== @@ -0,0 +1,515 @@ +# This file is part of Gajim. +# +# Gajim is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# Gajim is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Gajim. If not, see http://www.gnu.org/licenses/. + +from gi.repository import Gdk +from gi.repository import Gtk + +from gajim.common import app +from gajim.common.const import ACTIVITIES +from gajim.common.const import MOODS +from gajim.common.const import PEPEventType +from gajim.common.helpers import from_one_line +from gajim.common.helpers import to_one_line +from gajim.common.helpers import remove_invalid_xml_chars +from gajim.common.i18n import _ + +from gajim.gtk.dialogs import TimeoutWindow +from gajim.gtk.dialogs import DialogButton +from gajim.gtk.dialogs import NewConfirmationDialog +from gajim.gtk.dialogs import InputDialog +from gajim.gtk.util import get_builder +from gajim.gtk.util import get_activity_icon_name + +if app.is_installed('GSPELL'): + from gi.repository import Gspell # pylint: disable=ungrouped-imports + +ACTIVITY_PAGELIST = [ + 'doing_chores', + 'drinking', + 'eating', + 'exercising', + 'grooming', + 'having_appointment', + 'inactive', + 'relaxing', + 'talking', + 'traveling', + 'working', +] + + +class StatusChange(Gtk.ApplicationWindow, TimeoutWindow): + def __init__(self, callback, account=None, show=None, show_pep=True): + Gtk.ApplicationWindow.__init__(self) + countdown_time = app.config.get('change_status_window_timeout') + TimeoutWindow.__init__(self, countdown_time) + self.set_name('StatusChange') + self.set_application(app.app) + self.set_position(Gtk.WindowPosition.CENTER) + self.set_show_menubar(False) + self.set_transient_for(app.interface.roster.window) + self.title_text = _('Status Message') # TimeoutWindow + + self.account = account + self._callback = callback + self._show = show + self._show_pep = show_pep + + self._ui = get_builder('status_change_window.ui') + self.add(self._ui.status_stack) + + self._status_message = '' + self._pep_dict = { + 'activity': '', + 'subactivity': '', + 'mood': '', + } + self._get_current_status_data() + self._preset_messages_dict = {} + self._get_presets() + + if self._show: + self._ui.activity_switch.set_active(self._pep_dict['activity']) + self._ui.activity_page_button.set_sensitive( + self._pep_dict['activity']) + self._ui.mood_switch.set_active(self._pep_dict['mood']) + self._ui.mood_page_button.set_sensitive(self._pep_dict['mood']) + + self._message_buffer = self._ui.message_textview.get_buffer() + self._apply_speller() + self._message_buffer.set_text(from_one_line(self._status_message)) + + if show_pep: + self._draw_activity() + self._init_activities() + self._draw_mood() + self._init_moods() + else: + self._ui.activity_label.set_no_show_all(True) + self._ui.activity_button.set_no_show_all(True) + self._ui.mood_label.set_no_show_all(True) + self._ui.mood_button.set_no_show_all(True) + self._ui.activity_label.hide() + self._ui.activity_button.hide() + self._ui.mood_label.hide() + self._ui.mood_button.hide() + + self._message_buffer.connect('changed', self._stop_timeout) + self.connect('key-press-event', self._on_key_press) + self._ui.connect_signals(self) + + self.show_all() + self.run_timeout() + + def on_timeout(self): + self._change_status() + + def _stop_timeout(self, *args): + self.countdown_enabled = False + + def _on_key_press(self, _widget, event): + self.countdown_enabled = False + if event.keyval in (Gdk.KEY_Return, Gdk.KEY_KP_Enter): + if event.get_state() & Gdk.ModifierType.CONTROL_MASK: + self._change_status() + if event.keyval == Gdk.KEY_Escape: + self.destroy() + + def _apply_speller(self): + if app.config.get('use_speller') and app.is_installed('GSPELL'): + lang = app.config.get('speller_language') + gspell_lang = Gspell.language_lookup(lang) + if gspell_lang is None: + gspell_lang = Gspell.language_get_default() + spell_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer( + self._message_buffer) + spell_buffer.set_spell_checker(Gspell.Checker.new(gspell_lang)) + spell_view = Gspell.TextView.get_from_gtk_text_view( + self._ui.message_textview) + spell_view.set_inline_spell_checking(True) + spell_view.set_enable_language_menu(True) + + def _get_current_status_data(self): + ''' + Gathers status/pep data for a given account or checks if all accounts + are synchronized. If not, no status message/pep data will be displayed. + ''' + if self.account: + self._status_message = app.connections[self.account].status_message + activity_data = app.connections[self.account].pep.get( + PEPEventType.ACTIVITY) + mood_data = app.connections[self.account].pep.get( + PEPEventType.MOOD) + if activity_data: + self._pep_dict['activity'] = activity_data.activity + self._pep_dict['subactivity'] = activity_data.subactivity + if mood_data: + self._pep_dict['mood'] = mood_data.mood + else: + status_messages = [] + activities = [] + subactivities = [] + moods = [] + for account in app.get_connected_accounts(): + status_messages.append(app.connections[account].status_message) + activity_data = app.connections[account].pep.get( + PEPEventType.ACTIVITY) + mood_data = app.connections[account].pep.get(PEPEventType.MOOD) + if activity_data: + activities.append(activity_data.activity) + subactivities.append(activity_data.subactivity) + if mood_data: + moods.append(mood_data.mood) + equal_messages = all(x == status_messages[0] for x in + status_messages) + equal_activities = all(x == activities[0] for x in activities) + equal_subactivities = all(x == subactivities[0] for x in + subactivities) + equal_moods = all(x == moods[0] for x in moods) + if equal_messages: + self._status_message = status_messages[0] + if activities and equal_activities: + self._pep_dict['activity'] = activities[0] + if subactivities and equal_subactivities: + self._pep_dict['subactivity'] = subactivities[0] + if moods and equal_moods: + self._pep_dict['mood'] = moods[0] + + def _get_presets(self): + self._preset_messages_dict = {} + for msg_name in app.config.get_per('statusmsg'): + if msg_name.startswith('_last_'): + continue + opts = [] + for opt in ['message', 'activity', 'subactivity', 'mood']: + opts.append(app.config.get_per('statusmsg', msg_name, opt)) + opts[0] = from_one_line(opts[0]) + self._preset_messages_dict[msg_name] = opts + self._build_preset_popover() + + def _build_preset_popover(self): + child = self._ui.preset_popover.get_children() + if child: + self._ui.preset_popover.remove(child[0]) + + preset_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + preset_box.get_style_context().add_class('margin-3') + self._ui.preset_popover.add(preset_box) + + for preset in self._preset_messages_dict: + button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + + preset_button = Gtk.Button() + preset_button.set_name(preset) + preset_button.set_relief(Gtk.ReliefStyle.NONE) + preset_button.set_hexpand(True) + preset_button.add(Gtk.Label(label=preset, halign=Gtk.Align.START)) + preset_button.connect('clicked', self._on_preset_select) + button_box.add(preset_button) + + remove_button = Gtk.Button() + remove_button.set_name(preset) + remove_button.set_relief(Gtk.ReliefStyle.NONE) + remove_button.set_halign(Gtk.Align.END) + remove_button.add(Gtk.Image.new_from_icon_name( + 'edit-delete-symbolic', Gtk.IconSize.MENU)) + remove_button.connect('clicked', self._on_preset_remove) + button_box.add(remove_button) + preset_box.add(button_box) + preset_box.show_all() + + def _init_activities(self): + radio_btns = {} + group = None + + for category in ACTIVITIES: + icon_name = get_activity_icon_name(category) + item = self._ui.get_object(category + '_image') + item.set_from_icon_name(icon_name, Gtk.IconSize.MENU) + item.set_tooltip_text(ACTIVITIES[category]['category']) + + category_box = self._ui.get_object(category + '_box') + + # Other + act = category + '_other' + if group: + radio_btns[act] = Gtk.RadioButton() + radio_btns[act].join_group(group) + else: + radio_btns[act] = group = Gtk.RadioButton() + + icon = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.MENU) + icon_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, + spacing=6) + icon_box.pack_start(icon, False, False, 0) + label = Gtk.Label( + label='<b>%s</b>' % ACTIVITIES[category]['category']) + label.set_use_markup(True) + icon_box.pack_start(label, False, False, 0) + radio_btns[act].add(icon_box) + radio_btns[act].join_group(self._ui.no_activity_button) + radio_btns[act].connect( + 'toggled', self._on_activity_toggled, [category, 'other']) + category_box.pack_start(radio_btns[act], False, False, 0) + + activities = list(ACTIVITIES[category].keys()) + activities.sort() + for activity in activities: + if activity == 'category': + continue + + act = category + '_' + activity + + if group: + radio_btns[act] = Gtk.RadioButton() + radio_btns[act].join_group(group) + else: + radio_btns[act] = group = Gtk.RadioButton() + + icon_name = get_activity_icon_name(category, activity) + icon = Gtk.Image.new_from_icon_name( + icon_name, Gtk.IconSize.MENU) + label = Gtk.Label(label=ACTIVITIES[category][activity]) + icon_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, + spacing=6) + icon_box.pack_start(icon, False, False, 0) + icon_box.pack_start(label, False, False, 0) + radio_btns[act].join_group(self._ui.no_activity_button) + radio_btns[act].connect('toggled', self._on_activity_toggled, + [category, activity]) + radio_btns[act].add(icon_box) + category_box.pack_start(radio_btns[act], False, False, 0) + + if not self._pep_dict['activity']: + self._ui.no_activity_button.set_active(True) + + if self._pep_dict['activity'] in ACTIVITIES: + if self._pep_dict['subactivity'] not in ACTIVITIES[ + self._pep_dict['activity']]: + self._pep_dict['subactivity'] = 'other' + + radio_btns[self._pep_dict['activity'] + '_' + self._pep_dict[ + 'subactivity']].set_active(True) + + self._ui.activity_notebook.set_current_page( + ACTIVITY_PAGELIST.index(self._pep_dict['activity'])) + + def _draw_activity(self): + if self._pep_dict['activity'] in ACTIVITIES: + if (self._pep_dict['subactivity'] in + ACTIVITIES[self._pep_dict['activity']]): + icon_name = get_activity_icon_name( + self._pep_dict['activity'], + self._pep_dict['subactivity']) + self._ui.activity_image.set_from_icon_name( + icon_name, Gtk.IconSize.MENU) + self._ui.activity_button_label.set_text( + ACTIVITIES[self._pep_dict['activity']][ + self._pep_dict['subactivity']]) + else: + icon_name = get_activity_icon_name(self._pep_dict['activity']) + self._ui.activity_image.set_from_icon_name( + icon_name, Gtk.IconSize.MENU) + self._ui.activity_button_label.set_text( + ACTIVITIES[self._pep_dict['activity']]['category']) + else: + self._ui.activity_image.set_from_pixbuf(None) + self._ui.activity_button_label.set_text(_('No activity')) + + def _init_moods(self): + self._ui.no_mood_button.set_mode(False) + self._ui.no_mood_button.connect( + 'clicked', self._on_mood_button_clicked, None) + + x_position = 1 + y_position = 0 + mood_buttons = {} + + # Order them first + moods = [] + for mood in MOODS: + moods.append(mood) + moods.sort() + + for mood in moods: + image = Gtk.Image.new_from_icon_name( + 'mood-%s' % mood, Gtk.IconSize.MENU) + mood_buttons[mood] = Gtk.RadioButton() + mood_buttons[mood].join_group(self._ui.no_mood_button) + mood_buttons[mood].set_mode(False) + mood_buttons[mood].add(image) + mood_buttons[mood].set_relief(Gtk.ReliefStyle.NONE) + mood_buttons[mood].set_tooltip_text(MOODS[mood]) + mood_buttons[mood].connect( + 'clicked', self._on_mood_button_clicked, mood) + self._ui.moods_grid.attach( + mood_buttons[mood], x_position, y_position, 1, 1) + + # Calculate the next position + x_position += 1 + if x_position >= 11: + x_position = 0 + y_position += 1 + + if self._pep_dict['mood'] in MOODS: + mood_buttons[self._pep_dict['mood']].set_active(True) + self._ui.mood_label.set_text(MOODS[self._pep_dict['mood']]) + else: + self._ui.mood_label.set_text(_('No mood selected')) + + def _draw_mood(self): + if self._pep_dict['mood'] in MOODS: + self._ui.mood_image.set_from_icon_name( + 'mood-%s' % self._pep_dict['mood'], Gtk.IconSize.MENU) + self._ui.mood_button_label.set_text( + MOODS[self._pep_dict['mood']]) + else: + self._ui.mood_image.set_from_pixbuf(None) + self._ui.mood_button_label.set_text(_('No mood')) + + def _on_preset_select(self, widget): + self.countdown_enabled = False + self._ui.preset_popover.popdown() + name = widget.get_name() + self._message_buffer.set_text(self._preset_messages_dict[name][0]) + self._pep_dict['activity'] = self._preset_messages_dict[name][1] + self._pep_dict['subactivity'] = self._preset_messages_dict[name][2] + self._pep_dict['mood'] = self._preset_messages_dict[name][3] + self._draw_activity() + self._draw_mood() + + self._ui.activity_switch.set_active(self._pep_dict['activity']) + self._ui.activity_page_button.set_sensitive(self._pep_dict['activity']) + self._ui.mood_switch.set_active(self._pep_dict['mood']) + self._ui.mood_page_button.set_sensitive(self._pep_dict['mood']) + + def _on_preset_remove(self, widget): + self.countdown_enabled = False + name = widget.get_name() + app.config.del_per('statusmsg', name) + self._get_presets() + + def _on_save_as_preset_clicked(self, _widget): + self.countdown_enabled = False + start_iter, finish_iter = self._message_buffer.get_bounds() + message_text = self._message_buffer.get_text( + start_iter, finish_iter, True) + + def _on_save_preset(preset_name): + msg_text_one_line = to_one_line(message_text) + if not preset_name: + preset_name = msg_text_one_line + + def _on_set_config(): + activity = '' + subactivity = '' + mood = '' + if self._ui.activity_switch.get_active(): + activity = self._pep_dict['activity'] + subactivity = self._pep_dict['subactivity'] + if self._ui.mood_switch.get_active(): + mood = self._pep_dict['mood'] + app.config.set_per('statusmsg', preset_name, 'message', + msg_text_one_line) + app.config.set_per('statusmsg', preset_name, 'activity', + activity) + app.config.set_per('statusmsg', preset_name, 'subactivity', + subactivity) + app.config.set_per('statusmsg', preset_name, 'mood', mood) + self._get_presets() + + if preset_name in self._preset_messages_dict: + NewConfirmationDialog( + _('Overwrite'), + _('Overwrite Status Message?'), + _('This name is already in use. Do you want to ' + 'overwrite this preset?'), + [DialogButton.make('Cancel'), + DialogButton.make('Remove', + text=_('_Overwrite'), + callback=_on_set_config)], + transient_for=self).show() + return + + app.config.add_per('statusmsg', preset_name) + _on_set_config() + + 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).show() + + def _on_activity_page_clicked(self, _widget): + self.countdown_enabled = False + self._ui.status_stack.set_visible_child_full( + 'activity-page', + Gtk.StackTransitionType.SLIDE_LEFT) + + def _on_activity_toggled(self, widget, data): + if widget.get_active(): + self._pep_dict['activity'] = data[0] + self._pep_dict['subactivity'] = data[1] + + def _on_no_activity_toggled(self, _widget): + self._pep_dict['activity'] = '' + self._pep_dict['subactivity'] = '' + + def _on_mood_page_clicked(self, _widget): + self.countdown_enabled = False + self._ui.status_stack.set_visible_child_full( + 'mood-page', + Gtk.StackTransitionType.SLIDE_LEFT) + + def _on_mood_button_clicked(self, _widget, data): + if data: + self._ui.mood_label.set_text(MOODS[data]) + else: + self._ui.mood_label.set_text(_('No mood selected')) + self._pep_dict['mood'] = data + + def _on_back_clicked(self, _widget): + self._ui.status_stack.set_visible_child_full( + 'status-page', + Gtk.StackTransitionType.SLIDE_RIGHT) + self._draw_activity() + self._draw_mood() + + def _on_activity_switch(self, switch, *args): + self.countdown_enabled = False + self._ui.activity_page_button.set_sensitive(switch.get_active()) + + def _on_mood_switch(self, switch, *args): + self.countdown_enabled = False + self._ui.mood_page_button.set_sensitive(switch.get_active()) + + def _change_status(self, *args): + beg, end = self._message_buffer.get_bounds() + message = self._message_buffer.get_text(beg, end, True).strip() + message = remove_invalid_xml_chars(message) + + if not self._ui.activity_switch.get_active(): + self._pep_dict['activity'] = '' + self._pep_dict['subactivity'] = '' + + if not self._ui.mood_switch.get_active(): + self._pep_dict['mood'] = '' + + self._callback(message, self._pep_dict) + self.destroy()
===================================== gajim/gtk/status_selector.py ===================================== @@ -20,9 +20,9 @@ from gajim.common.helpers import get_uf_show from gajim.common.helpers import get_global_show from gajim.common.helpers import statuses_unified from gajim.common.i18n import _ -from gajim.dialogs import ChangeStatusMessageDialog
from gajim.gtk.util import get_icon_name +from gajim.gtk.util import open_window
class StatusSelector(Gtk.MenuButton): @@ -101,7 +101,7 @@ class StatusSelector(Gtk.MenuButton):
def _on_change_status(self, button): def _on_response(message, pep_dict): - if message is None: # None if user pressed Cancel + if message is None: # None if user canceled return for account in app.contacts.get_accounts(): sync_account = app.config.get_per( @@ -115,7 +115,7 @@ class StatusSelector(Gtk.MenuButton): new_show = button.get_name() if new_show == 'change_status_message': new_show = get_global_show() - ChangeStatusMessageDialog(_on_response, new_show) + open_window('StatusChange', callback=_on_response, show=new_show) return
app.interface.roster.get_status_message(new_show, _on_response)
===================================== gajim/roster_window.py ===================================== @@ -2159,7 +2159,7 @@ class RosterWindow: app.interface.systray.change_status(show) self._status_selector.update()
- def get_status_message(self, show, on_response, show_pep=True, + def get_status_message(self, show, callback, show_pep=True, always_ask=False): """ Get the status message by: @@ -2174,22 +2174,21 @@ class RosterWindow: 'mood': '', 'mood_text': ''} if not always_ask and ((show == 'online' and not app.config.get( - 'ask_online_status')) or (show == 'offline' and not \ - app.config.get('ask_offline_status'))): - on_response('', empty_pep) + 'ask_online_status')) or (show == 'offline' and not + app.config.get('ask_offline_status'))): + callback('', empty_pep) return
- dlg = dialogs.ChangeStatusMessageDialog(on_response, show, show_pep) - dlg.dialog.present() # show it on current workspace + open_window('StatusChange', callback=callback, show=show, + show_pep=show_pep)
def change_status(self, widget, account, status): - def on_response(message, pep_dict): - if message is None: - # user pressed Cancel to change status message dialog + def _on_response(message, pep_dict): + if message is None: # None if user canceled return self.send_status(account, status, message) self.send_pep(account, pep_dict) - self.get_status_message(status, on_response) + self.get_status_message(status, _on_response)
def get_show(self, lcontact): prio = lcontact[0].priority @@ -2928,12 +2927,13 @@ class RosterWindow:
def on_change_status_message_activate(self, widget, account): show = app.connections[account].status - def on_response(message, pep_dict): - if message is None: # None is if user pressed Cancel + def _on_response(message, pep_dict): + if message is None: # None if user canceled return self.send_status(account, show, message) self.send_pep(account, pep_dict) - dialogs.ChangeStatusMessageDialog(on_response, show) + open_window('StatusChange', account=account, callback=_on_response, + show=show)
def on_add_to_roster(self, widget, contact, account): AddNewContactWindow(account, contact.jid, contact.name) @@ -3031,7 +3031,7 @@ class RosterWindow: if keyval == Gdk.KEY_s: # CTRL + s show = helpers.get_global_show() def _on_response(message, pep_dict): - if message is not None: # None if user pressed Cancel + if message is not None: # None if user canceled for account in app.contacts.get_accounts(): sync_account = app.config.get_per( 'accounts', account, 'sync_with_global_status') @@ -3039,9 +3039,9 @@ class RosterWindow: continue self.send_status(account, show, message) self.send_pep(account, pep_dict) - dialogs.ChangeStatusMessageDialog(_on_response, show) + open_window('StatusChange', callback=_on_response, show=show) return True - if keyval == Gdk.KEY_k: # CTRL + k + if keyval == Gdk.KEY_k: # CTRL + k self.enable_rfilter('')
def on_roster_treeview_button_press_event(self, widget, event): @@ -3084,17 +3084,17 @@ class RosterWindow: show = helpers.get_global_show() if show == 'offline': return True - def on_response(message, pep_dict): - if message is None: + def _on_response(message, pep_dict): + if message is None: # None if user canceled return True for acct in app.connections: if not app.config.get_per('accounts', acct, - 'sync_with_global_status'): + 'sync_with_global_status'): continue current_show = app.connections[acct].status self.send_status(acct, current_show, message) self.send_pep(acct, pep_dict) - dialogs.ChangeStatusMessageDialog(on_response, show) + open_window('StatusChange', callback=_on_response, show=show) return True
if event.button == 1: # Left click
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/commit/3069253637125bcafa4fefc58390ec046...