Rework SingleMessageWindow
This commit is contained in:
parent
87bbf4738a
commit
f6c3d03261
|
@ -1,98 +1,101 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Generated with glade 3.18.3 -->
|
<!-- Generated with glade 3.22.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.12"/>
|
<requires lib="gtk+" version="3.20"/>
|
||||||
<object class="GtkImage" id="image1">
|
<object class="GtkImage" id="image1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-ok</property>
|
<property name="icon_name">mail-reply-sender-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkImage" id="image2">
|
<object class="GtkImage" id="image2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-ok</property>
|
<property name="icon_name">mail-send-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkImage" id="image3">
|
<object class="GtkImage" id="image3">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-jump-to</property>
|
<property name="icon_name">mail-send-symbolic</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">user-info-symbolic</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkWindow" id="single_message_window">
|
<object class="GtkWindow" id="single_message_window">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="border_width">6</property>
|
|
||||||
<property name="default_width">550</property>
|
|
||||||
<property name="default_height">280</property>
|
|
||||||
<signal name="delete-event" handler="on_single_message_window_delete_event" swapped="no"/>
|
<signal name="delete-event" handler="on_single_message_window_delete_event" swapped="no"/>
|
||||||
<signal name="destroy" handler="on_single_message_window_destroy" swapped="no"/>
|
<signal name="destroy" handler="on_single_message_window_destroy" swapped="no"/>
|
||||||
<signal name="key-press-event" handler="on_single_message_window_key_press_event" swapped="no"/>
|
<signal name="key-press-event" handler="on_single_message_window_key_press_event" swapped="no"/>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="vbox97">
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="border_width">18</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="spacing">6</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkGrid" id="grid1">
|
<object class="GtkGrid" id="send_grid">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="row_spacing">3</property>
|
<property name="no_show_all">True</property>
|
||||||
<property name="column_spacing">3</property>
|
<property name="row_spacing">6</property>
|
||||||
<child>
|
<property name="column_spacing">12</property>
|
||||||
<object class="GtkLabel" id="from_label">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="no_show_all">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">From:</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="to_label">
|
<object class="GtkLabel" id="to_label">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="no_show_all">True</property>
|
<property name="halign">end</property>
|
||||||
<property name="xalign">0</property>
|
<property name="label" translatable="yes">_To</property>
|
||||||
<property name="label" translatable="yes">To:</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="mnemonic_widget">to_entry</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label"/>
|
||||||
|
</style>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
<property name="top_attach">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="label335">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="label" translatable="yes">Subject:</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">0</property>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkEntry" id="from_entry">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="no_show_all">True</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="top_attach">0</property>
|
<property name="top_attach">0</property>
|
||||||
<property name="width">2</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkEntry" id="to_entry">
|
<object class="GtkEntry" id="to_entry">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="no_show_all">True</property>
|
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">True</property>
|
||||||
|
<property name="placeholder_text" translatable="yes">user@example.org</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="subject_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="label" translatable="yes">Su_bject</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="mnemonic_widget">subject_entry</property>
|
||||||
|
<property name="single_line_mode">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="GtkEntry" id="subject_entry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="placeholder_text" translatable="yes">Type the subject here...</property>
|
||||||
|
<property name="show_emoji_icon">True</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
|
@ -101,10 +104,163 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkEntry" id="subject_entry">
|
<object class="GtkLabel" id="message_label_send">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="label" translatable="yes">_Message</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="mnemonic_widget">message_textview</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="GtkScrolledWindow" id="message_scrolledwindow">
|
||||||
|
<property name="height_request">100</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="vexpand">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-char</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="left_attach">1</property>
|
||||||
|
<property name="top_attach">2</property>
|
||||||
|
<property name="width">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="count_chars_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="label" translatable="yes">Characters typed: 0</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">3</property>
|
||||||
|
<property name="width">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="show_contact_info_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Query Contact Info</property>
|
||||||
|
<property name="image">image4</property>
|
||||||
|
<signal name="clicked" handler="on_show_contact_info_button_clicked" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">2</property>
|
||||||
|
<property name="top_attach">0</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="received_grid">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="no_show_all">True</property>
|
||||||
|
<property name="row_spacing">6</property>
|
||||||
|
<property name="column_spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="from_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="label" translatable="yes">_From</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" id="subject_from_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="label" translatable="yes">Subject</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="from_entry_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes"><user@example.org></property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<style>
|
||||||
|
<class name="bold"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="subject_from_entry_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes"><from Subject></property>
|
||||||
|
<property name="wrap">True</property>
|
||||||
|
<property name="max_width_chars">50</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow" id="conversation_scrolledwindow">
|
||||||
|
<property name="height_request">100</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="hexpand">True</property>
|
<property name="hexpand">True</property>
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
|
@ -112,33 +268,21 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="count_chars_label">
|
<object class="GtkLabel" id="message_label_received">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="label" translatable="yes">0</property>
|
<property name="halign">end</property>
|
||||||
|
<property name="label" translatable="yes">Message</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label"/>
|
||||||
|
</style>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">2</property>
|
<property name="left_attach">0</property>
|
||||||
<property name="top_attach">2</property>
|
<property name="top_attach">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkScrolledWindow" id="conversation_scrolledwindow">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="no_show_all">True</property>
|
|
||||||
<property name="shadow_type">in</property>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">True</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
|
@ -146,29 +290,10 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="message_scrolledwindow">
|
<object class="GtkButtonBox">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="no_show_all">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>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButtonBox" id="hbuttonbox26">
|
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_top">12</property>
|
||||||
<property name="spacing">12</property>
|
<property name="spacing">12</property>
|
||||||
<property name="layout_style">end</property>
|
<property name="layout_style">end</property>
|
||||||
<child>
|
<child>
|
||||||
|
@ -188,23 +313,6 @@
|
||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<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="no_show_all">True</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">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="send_button">
|
<object class="GtkButton" id="send_button">
|
||||||
<property name="label" translatable="yes">Sen_d</property>
|
<property name="label" translatable="yes">Sen_d</property>
|
||||||
|
@ -214,7 +322,7 @@
|
||||||
<property name="receives_default">False</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="no_show_all">True</property>
|
<property name="no_show_all">True</property>
|
||||||
<property name="tooltip_text" translatable="yes">Send message</property>
|
<property name="tooltip_text" translatable="yes">Send message</property>
|
||||||
<property name="image">image3</property>
|
<property name="image">image2</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<signal name="clicked" handler="on_send_button_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_send_button_clicked" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
|
@ -236,6 +344,9 @@
|
||||||
<property name="image">image1</property>
|
<property name="image">image1</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<signal name="clicked" handler="on_reply_button_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_reply_button_clicked" swapped="no"/>
|
||||||
|
<style>
|
||||||
|
<class name="suggested-action"/>
|
||||||
|
</style>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
@ -252,9 +363,12 @@
|
||||||
<property name="receives_default">False</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="no_show_all">True</property>
|
<property name="no_show_all">True</property>
|
||||||
<property name="tooltip_text" translatable="yes">Send message and close window</property>
|
<property name="tooltip_text" translatable="yes">Send message and close window</property>
|
||||||
<property name="image">image2</property>
|
<property name="image">image3</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<signal name="clicked" handler="on_send_and_close_button_clicked" swapped="no"/>
|
<signal name="clicked" handler="on_send_and_close_button_clicked" swapped="no"/>
|
||||||
|
<style>
|
||||||
|
<class name="suggested-action"/>
|
||||||
|
</style>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
@ -267,7 +381,7 @@
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="padding">6</property>
|
<property name="padding">6</property>
|
||||||
<property name="position">3</property>
|
<property name="position">4</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|
|
@ -16,7 +16,9 @@ from typing import List # pylint: disable=unused-import
|
||||||
|
|
||||||
from gi.repository import Gdk
|
from gi.repository import Gdk
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
from gajim import vcard
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
from gajim.common.i18n import _
|
from gajim.common.i18n import _
|
||||||
|
@ -37,16 +39,17 @@ if app.is_installed('GSPELL'):
|
||||||
from gi.repository import Gspell # pylint: disable=ungrouped-imports
|
from gi.repository import Gspell # pylint: disable=ungrouped-imports
|
||||||
|
|
||||||
|
|
||||||
class SingleMessageWindow:
|
class SingleMessageWindow(Gtk.ApplicationWindow):
|
||||||
"""
|
"""
|
||||||
SingleMessageWindow can send or show a received singled message depending on
|
SingleMessageWindow can send or show a received singled message depending on
|
||||||
action argument which can be 'send' or 'receive'
|
action argument which can be 'send' or 'receive'
|
||||||
"""
|
"""
|
||||||
# Keep a reference on windows so garbage collector don't restroy them
|
|
||||||
instances = [] # type: List[SingleMessageWindow]
|
|
||||||
def __init__(self, account, to='', action='', from_whom='', subject='',
|
def __init__(self, account, to='', action='', from_whom='', subject='',
|
||||||
message='', resource='', session=None, form_node=None):
|
message='', resource='', session=None, form_node=None):
|
||||||
self.instances.append(self)
|
Gtk.ApplicationWindow.__init__(self)
|
||||||
|
self.set_application(app.app)
|
||||||
|
self.set_title(_('Send Single Message'))
|
||||||
|
self.set_name('SendSingleMessageWindow')
|
||||||
self.account = account
|
self.account = account
|
||||||
self.action = action
|
self.action = action
|
||||||
|
|
||||||
|
@ -57,51 +60,38 @@ class SingleMessageWindow:
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
self.session = session
|
self.session = session
|
||||||
|
|
||||||
self.xml = get_builder('single_message_window.ui')
|
self._ui = get_builder('single_message_window.ui')
|
||||||
self.window = self.xml.get_object('single_message_window')
|
self.message_tv_buffer = self._ui.message_textview.get_buffer()
|
||||||
self.count_chars_label = self.xml.get_object('count_chars_label')
|
|
||||||
self.from_label = self.xml.get_object('from_label')
|
|
||||||
self.from_entry = self.xml.get_object('from_entry')
|
|
||||||
self.to_label = self.xml.get_object('to_label')
|
|
||||||
self.to_entry = self.xml.get_object('to_entry')
|
|
||||||
self.subject_entry = self.xml.get_object('subject_entry')
|
|
||||||
self.message_scrolledwindow = self.xml.get_object(
|
|
||||||
'message_scrolledwindow')
|
|
||||||
self.message_textview = self.xml.get_object('message_textview')
|
|
||||||
self.message_tv_buffer = self.message_textview.get_buffer()
|
|
||||||
self.conversation_scrolledwindow = self.xml.get_object(
|
|
||||||
'conversation_scrolledwindow')
|
|
||||||
self.conversation_textview = ConversationTextview(
|
self.conversation_textview = ConversationTextview(
|
||||||
account, used_in_history_window=True)
|
account, used_in_history_window=True)
|
||||||
self.conversation_textview.tv.show()
|
self.conversation_textview.tv.show()
|
||||||
|
self.conversation_textview.tv.set_left_margin(6)
|
||||||
|
self.conversation_textview.tv.set_right_margin(6)
|
||||||
|
self.conversation_textview.tv.set_top_margin(6)
|
||||||
|
self.conversation_textview.tv.set_bottom_margin(6)
|
||||||
self.conversation_tv_buffer = self.conversation_textview.tv.get_buffer()
|
self.conversation_tv_buffer = self.conversation_textview.tv.get_buffer()
|
||||||
self.xml.get_object('conversation_scrolledwindow').add(
|
self._ui.conversation_scrolledwindow.add(
|
||||||
self.conversation_textview.tv)
|
self.conversation_textview.tv)
|
||||||
|
|
||||||
self.form_widget = None
|
self.form_widget = None
|
||||||
parent_box = self.xml.get_object('conversation_scrolledwindow').\
|
parent_box = self._ui.conversation_scrolledwindow.get_parent()
|
||||||
get_parent()
|
|
||||||
if form_node:
|
if form_node:
|
||||||
self.form_widget = DataFormWidget(form_node)
|
self.form_widget = DataFormWidget(form_node)
|
||||||
self.form_widget.show_all()
|
self.form_widget.show_all()
|
||||||
|
self._ui.conversation_scrolledwindow.hide()
|
||||||
|
self._ui.message_label_received.hide()
|
||||||
parent_box.add(self.form_widget)
|
parent_box.add(self.form_widget)
|
||||||
parent_box.child_set_property(self.form_widget, 'position',
|
parent_box.child_set_property(self.form_widget, 'top-attach', 2)
|
||||||
parent_box.child_get_property(self.xml.get_object(
|
parent_box.child_set_property(self.form_widget, 'left-attach', 0)
|
||||||
'conversation_scrolledwindow'), 'position'))
|
parent_box.child_set_property(self.form_widget, 'width', 2)
|
||||||
self.action = 'form'
|
self.action = 'form'
|
||||||
|
|
||||||
self.send_button = self.xml.get_object('send_button')
|
|
||||||
self.reply_button = self.xml.get_object('reply_button')
|
|
||||||
self.send_and_close_button = self.xml.get_object('send_and_close_button')
|
|
||||||
self.cancel_button = self.xml.get_object('cancel_button')
|
|
||||||
self.close_button = self.xml.get_object('close_button')
|
|
||||||
self.message_tv_buffer.connect('changed', self.update_char_counter)
|
self.message_tv_buffer.connect('changed', self.update_char_counter)
|
||||||
if isinstance(to, list):
|
if isinstance(to, list):
|
||||||
jid = ', '.join([i[0].get_full_jid() for i in to])
|
jid = ', '.join([i[0].get_full_jid() for i in to])
|
||||||
self.to_entry.set_text(jid)
|
self._ui.to_entry.set_text(jid)
|
||||||
self.to_entry.set_sensitive(False)
|
|
||||||
else:
|
else:
|
||||||
self.to_entry.set_text(to)
|
self._ui.to_entry.set_text(to)
|
||||||
|
|
||||||
if app.config.get('use_speller') and app.is_installed('GSPELL') and action == 'send':
|
if app.config.get('use_speller') and app.is_installed('GSPELL') and action == 'send':
|
||||||
lang = app.config.get('speller_language')
|
lang = app.config.get('speller_language')
|
||||||
|
@ -110,10 +100,10 @@ class SingleMessageWindow:
|
||||||
AspellDictError(lang)
|
AspellDictError(lang)
|
||||||
else:
|
else:
|
||||||
spell_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer(
|
spell_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer(
|
||||||
self.message_textview.get_buffer())
|
self._ui.message_textview.get_buffer())
|
||||||
spell_buffer.set_spell_checker(Gspell.Checker.new(gspell_lang))
|
spell_buffer.set_spell_checker(Gspell.Checker.new(gspell_lang))
|
||||||
spell_view = Gspell.TextView.get_from_gtk_text_view(
|
spell_view = Gspell.TextView.get_from_gtk_text_view(
|
||||||
self.message_textview)
|
self._ui.message_textview)
|
||||||
spell_view.set_inline_spell_checking(True)
|
spell_view.set_inline_spell_checking(True)
|
||||||
spell_view.set_enable_language_menu(True)
|
spell_view.set_enable_language_menu(True)
|
||||||
|
|
||||||
|
@ -121,12 +111,12 @@ class SingleMessageWindow:
|
||||||
|
|
||||||
# set_text(None) raises TypeError exception
|
# set_text(None) raises TypeError exception
|
||||||
if self.subject is None:
|
if self.subject is None:
|
||||||
self.subject = ''
|
self.subject = _('(No subject)')
|
||||||
self.subject_entry.set_text(self.subject)
|
self._ui.subject_entry.set_text(self.subject)
|
||||||
|
self._ui.subject_from_entry_label.set_text(self.subject)
|
||||||
|
|
||||||
if to == '':
|
if to == '':
|
||||||
liststore = get_completion_liststore(self.to_entry)
|
liststore = get_completion_liststore(self._ui.to_entry)
|
||||||
self.completion_dict = helpers.get_contact_dict_for_account(account)
|
self.completion_dict = helpers.get_contact_dict_for_account(account)
|
||||||
keys = sorted(self.completion_dict.keys())
|
keys = sorted(self.completion_dict.keys())
|
||||||
for jid in keys:
|
for jid in keys:
|
||||||
|
@ -135,20 +125,21 @@ class SingleMessageWindow:
|
||||||
liststore.append((status_icon, jid))
|
liststore.append((status_icon, jid))
|
||||||
else:
|
else:
|
||||||
self.completion_dict = {}
|
self.completion_dict = {}
|
||||||
self.xml.connect_signals(self)
|
|
||||||
|
self._ui.to_entry.connect('changed', self.on_to_entry_changed)
|
||||||
|
self._ui.connect_signals(self)
|
||||||
|
|
||||||
# get window position and size from config
|
# get window position and size from config
|
||||||
resize_window(self.window,
|
resize_window(self._ui.single_message_window,
|
||||||
app.config.get('single-msg-width'),
|
app.config.get('single-msg-width'),
|
||||||
app.config.get('single-msg-height'))
|
app.config.get('single-msg-height'))
|
||||||
move_window(self.window,
|
move_window(self._ui.single_message_window,
|
||||||
app.config.get('single-msg-x-position'),
|
app.config.get('single-msg-x-position'),
|
||||||
app.config.get('single-msg-y-position'))
|
app.config.get('single-msg-y-position'))
|
||||||
|
|
||||||
self.window.show_all()
|
self._ui.single_message_window.show_all()
|
||||||
|
|
||||||
def on_single_message_window_destroy(self, widget):
|
def on_single_message_window_destroy(self, widget):
|
||||||
self.instances.remove(self)
|
|
||||||
c = app.contacts.get_contact_with_highest_priority(self.account,
|
c = app.contacts.get_contact_with_highest_priority(self.account,
|
||||||
self.from_whom)
|
self.from_whom)
|
||||||
if not c:
|
if not c:
|
||||||
|
@ -166,16 +157,44 @@ class SingleMessageWindow:
|
||||||
|
|
||||||
def save_pos(self):
|
def save_pos(self):
|
||||||
# save the window size and position
|
# save the window size and position
|
||||||
x, y = self.window.get_position()
|
x, y = self._ui.single_message_window.get_position()
|
||||||
app.config.set('single-msg-x-position', x)
|
app.config.set('single-msg-x-position', x)
|
||||||
app.config.set('single-msg-y-position', y)
|
app.config.set('single-msg-y-position', y)
|
||||||
width, height = self.window.get_size()
|
width, height = self._ui.single_message_window.get_size()
|
||||||
app.config.set('single-msg-width', width)
|
app.config.set('single-msg-width', width)
|
||||||
app.config.set('single-msg-height', height)
|
app.config.set('single-msg-height', height)
|
||||||
|
|
||||||
def on_single_message_window_delete_event(self, window, ev):
|
def on_single_message_window_delete_event(self, window, ev):
|
||||||
self.save_pos()
|
self.save_pos()
|
||||||
|
|
||||||
|
def on_show_contact_info_button_clicked(self, widget):
|
||||||
|
"""
|
||||||
|
Ask for vCard
|
||||||
|
"""
|
||||||
|
entry = self._ui.to_entry.get_text().strip()
|
||||||
|
|
||||||
|
keys = sorted(self.completion_dict.keys())
|
||||||
|
for key in keys:
|
||||||
|
contact = self.completion_dict[key]
|
||||||
|
if entry in key:
|
||||||
|
entry = contact.jid
|
||||||
|
break
|
||||||
|
|
||||||
|
if entry in app.interface.instances[self.account]['infos']:
|
||||||
|
app.interface.instances[self.account]['infos'][entry].window.present()
|
||||||
|
else:
|
||||||
|
contact = app.contacts.create_contact(jid=entry, account=self.account)
|
||||||
|
app.interface.instances[self.account]['infos'][entry] = \
|
||||||
|
vcard.VcardWindow(contact, self.account)
|
||||||
|
# Remove xmpp page
|
||||||
|
app.interface.instances[self.account]['infos'][entry].xml.\
|
||||||
|
get_object('information_notebook').remove_page(0)
|
||||||
|
|
||||||
|
def on_to_entry_changed(self, widget):
|
||||||
|
entry = self._ui.to_entry.get_text()
|
||||||
|
is_empty = bool(not entry == '' and not ',' in entry)
|
||||||
|
self._ui.show_contact_info_button.set_sensitive(is_empty)
|
||||||
|
|
||||||
def prepare_widgets_for(self, action):
|
def prepare_widgets_for(self, action):
|
||||||
if len(app.connections) > 1:
|
if len(app.connections) > 1:
|
||||||
if action == 'send':
|
if action == 'send':
|
||||||
|
@ -187,75 +206,67 @@ class SingleMessageWindow:
|
||||||
|
|
||||||
if action == 'send': # prepare UI for Sending
|
if action == 'send': # prepare UI for Sending
|
||||||
title = _('Send %s') % title
|
title = _('Send %s') % title
|
||||||
self.send_button.show()
|
self._ui.send_button.show()
|
||||||
self.send_and_close_button.show()
|
self._ui.send_and_close_button.show()
|
||||||
self.to_label.show()
|
self._ui.reply_button.hide()
|
||||||
self.to_entry.show()
|
self._ui.close_button.hide()
|
||||||
self.reply_button.hide()
|
|
||||||
self.from_label.hide()
|
self._ui.send_grid.show()
|
||||||
self.from_entry.hide()
|
self._ui.received_grid.hide()
|
||||||
self.conversation_scrolledwindow.hide()
|
|
||||||
self.message_scrolledwindow.show()
|
|
||||||
|
|
||||||
if self.message: # we come from a reply?
|
if self.message: # we come from a reply?
|
||||||
self.message_textview.grab_focus()
|
self._ui.show_contact_info_button.set_sensitive(True)
|
||||||
self.cancel_button.hide()
|
self._ui.message_textview.grab_focus()
|
||||||
self.close_button.show()
|
|
||||||
self.message_tv_buffer.set_text(self.message)
|
self.message_tv_buffer.set_text(self.message)
|
||||||
GLib.idle_add(self.set_cursor_to_end)
|
GLib.idle_add(self.set_cursor_to_end)
|
||||||
else: # we write a new message (not from reply)
|
else: # we write a new message (not from reply)
|
||||||
self.close_button.hide()
|
|
||||||
if self.to: # do we already have jid?
|
if self.to: # do we already have jid?
|
||||||
self.subject_entry.grab_focus()
|
self._ui.subject_entry.grab_focus()
|
||||||
|
|
||||||
elif action == 'receive': # prepare UI for Receiving
|
elif action == 'receive': # prepare UI for Receiving
|
||||||
title = _('Received %s') % title
|
title = _('Received %s') % title
|
||||||
self.reply_button.show()
|
self._ui.reply_button.show()
|
||||||
self.from_label.show()
|
self._ui.close_button.show()
|
||||||
self.from_entry.show()
|
self._ui.send_button.hide()
|
||||||
self.send_button.hide()
|
self._ui.send_and_close_button.hide()
|
||||||
self.send_and_close_button.hide()
|
self._ui.reply_button.grab_focus()
|
||||||
self.to_label.hide()
|
|
||||||
self.to_entry.hide()
|
self._ui.received_grid.show()
|
||||||
self.conversation_scrolledwindow.show()
|
self._ui.send_grid.hide()
|
||||||
self.message_scrolledwindow.hide()
|
|
||||||
|
|
||||||
if self.message:
|
if self.message:
|
||||||
self.conversation_textview.print_real_text(self.message)
|
self.conversation_textview.print_real_text(self.message)
|
||||||
fjid = self.from_whom
|
fjid = self.from_whom
|
||||||
if self.resource:
|
if self.resource:
|
||||||
fjid += '/' + self.resource # Full jid of sender (with resource)
|
fjid += '/' + self.resource # Full jid of sender (with resource)
|
||||||
self.from_entry.set_text(fjid)
|
self._ui.from_entry_label.set_text(fjid)
|
||||||
self.from_entry.set_property('editable', False)
|
|
||||||
self.subject_entry.set_property('editable', False)
|
|
||||||
self.reply_button.grab_focus()
|
|
||||||
self.cancel_button.hide()
|
|
||||||
self.close_button.show()
|
|
||||||
elif action == 'form': # prepare UI for Receiving
|
elif action == 'form': # prepare UI for Receiving
|
||||||
title = _('Form %s') % title
|
title = self.form_widget.title
|
||||||
self.send_button.show()
|
title = _('Form: %s') % title
|
||||||
self.send_and_close_button.show()
|
self._ui.send_button.hide()
|
||||||
self.to_label.show()
|
self._ui.send_and_close_button.hide()
|
||||||
self.to_entry.show()
|
self._ui.reply_button.show()
|
||||||
self.reply_button.hide()
|
self._ui.close_button.show()
|
||||||
self.from_label.hide()
|
|
||||||
self.from_entry.hide()
|
|
||||||
self.conversation_scrolledwindow.hide()
|
|
||||||
self.message_scrolledwindow.hide()
|
|
||||||
|
|
||||||
self.window.set_title(title)
|
self._ui.send_grid.hide()
|
||||||
|
self._ui.received_grid.show()
|
||||||
|
|
||||||
def on_cancel_button_clicked(self, widget):
|
fjid = self.from_whom
|
||||||
self.save_pos()
|
if self.resource:
|
||||||
self.window.destroy()
|
fjid += '/' + self.resource # Full jid of sender (with resource)
|
||||||
|
self._ui.from_entry_label.set_text(fjid)
|
||||||
|
|
||||||
|
self._ui.single_message_window.set_title(title)
|
||||||
|
|
||||||
def on_close_button_clicked(self, widget):
|
def on_close_button_clicked(self, widget):
|
||||||
self.save_pos()
|
self.save_pos()
|
||||||
self.window.destroy()
|
self._ui.single_message_window.destroy()
|
||||||
|
|
||||||
def update_char_counter(self, widget):
|
def update_char_counter(self, widget):
|
||||||
characters_no = self.message_tv_buffer.get_char_count()
|
characters_no = self.message_tv_buffer.get_char_count()
|
||||||
self.count_chars_label.set_text(str(characters_no))
|
self._ui.count_chars_label.set_text(
|
||||||
|
_('Characters typed: %s') % str(characters_no))
|
||||||
|
|
||||||
def send_single_message(self):
|
def send_single_message(self):
|
||||||
if app.connections[self.account].connected <= 1:
|
if app.connections[self.account].connected <= 1:
|
||||||
|
@ -271,10 +282,10 @@ class SingleMessageWindow:
|
||||||
else:
|
else:
|
||||||
sender_list.append(i[0].jid)
|
sender_list.append(i[0].jid)
|
||||||
else:
|
else:
|
||||||
sender_list = [j.strip() for j in self.to_entry.get_text().split(
|
sender_list = [j.strip() for j in self._ui.to_entry.get_text().split(
|
||||||
',')]
|
',')]
|
||||||
|
|
||||||
subject = self.subject_entry.get_text()
|
subject = self._ui.subject_entry.get_text()
|
||||||
begin, end = self.message_tv_buffer.get_bounds()
|
begin, end = self.message_tv_buffer.get_bounds()
|
||||||
message = self.message_tv_buffer.get_text(begin, end, True)
|
message = self.message_tv_buffer.get_text(begin, end, True)
|
||||||
|
|
||||||
|
@ -292,8 +303,8 @@ class SingleMessageWindow:
|
||||||
to_whom_jid = helpers.parse_jid(to_whom_jid)
|
to_whom_jid = helpers.parse_jid(to_whom_jid)
|
||||||
except helpers.InvalidFormat:
|
except helpers.InvalidFormat:
|
||||||
ErrorDialog(_('Invalid JID'),
|
ErrorDialog(_('Invalid JID'),
|
||||||
_('It is not possible to send a message to %s, this JID is not '
|
_('It is not possible to send a message to %s, this JID '
|
||||||
'valid.') % to_whom_jid)
|
'is not valid.') % to_whom_jid)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if '/announce/' in to_whom_jid:
|
if '/announce/' in to_whom_jid:
|
||||||
|
@ -307,7 +318,7 @@ class SingleMessageWindow:
|
||||||
account=self.account, jid=recipient_list, message=message,
|
account=self.account, jid=recipient_list, message=message,
|
||||||
type_='normal', subject=subject, form_node=form_node))
|
type_='normal', subject=subject, form_node=form_node))
|
||||||
|
|
||||||
self.subject_entry.set_text('') # we sent ok, clear the subject
|
self._ui.subject_entry.set_text('') # we sent ok, clear the subject
|
||||||
self.message_tv_buffer.set_text('') # we sent ok, clear the textview
|
self.message_tv_buffer.set_text('') # we sent ok, clear the textview
|
||||||
|
|
||||||
def on_send_button_clicked(self, widget):
|
def on_send_button_clicked(self, widget):
|
||||||
|
@ -319,7 +330,7 @@ class SingleMessageWindow:
|
||||||
self.message = _('%s wrote:\n') % self.from_whom + self.message
|
self.message = _('%s wrote:\n') % self.from_whom + self.message
|
||||||
# add > at the begining of each line
|
# add > at the begining of each line
|
||||||
self.message = self.message.replace('\n', '\n> ') + '\n\n'
|
self.message = self.message.replace('\n', '\n> ') + '\n\n'
|
||||||
self.window.destroy()
|
self._ui.single_message_window.destroy()
|
||||||
SingleMessageWindow(self.account, to=self.from_whom, action='send',
|
SingleMessageWindow(self.account, to=self.from_whom, action='send',
|
||||||
from_whom=self.from_whom, subject=self.subject, message=self.message,
|
from_whom=self.from_whom, subject=self.subject, message=self.message,
|
||||||
session=self.session)
|
session=self.session)
|
||||||
|
@ -328,9 +339,9 @@ class SingleMessageWindow:
|
||||||
if self.send_single_message():
|
if self.send_single_message():
|
||||||
return
|
return
|
||||||
self.save_pos()
|
self.save_pos()
|
||||||
self.window.destroy()
|
self._ui.single_message_window.destroy()
|
||||||
|
|
||||||
def on_single_message_window_key_press_event(self, widget, event):
|
def on_single_message_window_key_press_event(self, widget, event):
|
||||||
if event.keyval == Gdk.KEY_Escape: # ESCAPE
|
if event.keyval == Gdk.KEY_Escape: # ESCAPE
|
||||||
self.save_pos()
|
self.save_pos()
|
||||||
self.window.destroy()
|
self._ui.single_message_window.destroy()
|
||||||
|
|
Loading…
Reference in New Issue