merge jingle branch to default branche
This commit is contained in:
commit
fcafab60a7
14 changed files with 1866 additions and 113 deletions
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--*- mode: xml -*-->
|
||||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<!-- interface-requires gtk+ 2.14 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkWindow" id="message_window">
|
||||
<property name="default_width">480</property>
|
||||
<property name="default_height">440</property>
|
||||
|
@ -40,6 +40,7 @@
|
|||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -54,6 +55,9 @@
|
|||
<property name="label"><span weight="heavy" size="large">Contact name</span></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
|
@ -71,14 +75,17 @@
|
|||
<widget class="GtkImage" id="mood_image">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="stock">None</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImage" id="activity_image">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="stock">None</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
|
@ -87,13 +94,33 @@
|
|||
<child>
|
||||
<widget class="GtkImage" id="tune_image">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="pixbuf">../emoticons/static/music.png</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="pixbuf">../emoticons/static/music.png</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImage" id="audio_banner_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">None</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImage" id="video_banner_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">None</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment3">
|
||||
<property name="width_request">11</property>
|
||||
|
@ -103,7 +130,7 @@
|
|||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -138,6 +165,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -148,35 +176,40 @@
|
|||
<property name="height_request">60</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<widget class="GtkHBox" id="hbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="authentication_button">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="lock_image">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-dialog-authentication</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -184,9 +217,9 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
@ -212,37 +245,40 @@
|
|||
<child>
|
||||
<widget class="GtkButton" id="emoticons_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a list of emoticons (Alt+M)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="emoticons_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="formattings_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a list of formattings</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image10">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-bold</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -268,14 +304,13 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="tooltip" translatable="yes">Add this contact to roster (Ctrl+D)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image9">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -288,16 +323,17 @@
|
|||
<child>
|
||||
<widget class="GtkButton" id="send_file_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Send a file (Ctrl+F)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -307,19 +343,16 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="convert_to_gc_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Invite contacts to the conversation (Ctrl+G)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<widget class="GtkToggleButton" id="audio_togglebutton">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip" translatable="yes">Toggle audio session</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="convert_to_gc_button_image">
|
||||
<widget class="GtkImage" id="audio_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -329,19 +362,16 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="contact_information_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show the contact's profile (Ctrl+I)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<widget class="GtkToggleButton" id="video_togglebutton">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip" translatable="yes">Toggle video session</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image2">
|
||||
<widget class="GtkImage" id="video_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-info</property>
|
||||
<property name="icon_size">2</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -351,19 +381,20 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="history_button">
|
||||
<widget class="GtkButton" id="convert_to_gc_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Browse the chat history (Ctrl+H)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="tooltip" translatable="yes">Invite contacts to the conversation (Ctrl+G)</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image5">
|
||||
<widget class="GtkImage" id="convert_to_gc_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-justify-fill</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -373,9 +404,22 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVSeparator" id="vseparator3">
|
||||
<widget class="GtkButton" id="contact_information_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show the contact's profile (Ctrl+I)</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-info</property>
|
||||
<property name="icon-size">2</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -383,19 +427,20 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="message_window_actions_button">
|
||||
<widget class="GtkButton" id="history_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a menu of advanced functions (Alt+A)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="tooltip" translatable="yes">Browse the chat history (Ctrl+H)</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<widget class="GtkImage" id="image5">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-execute</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="stock">gtk-justify-fill</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -404,6 +449,39 @@
|
|||
<property name="position">9</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVSeparator" id="vseparator3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="message_window_actions_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a menu of advanced functions (Alt+A)</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-execute</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">11</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
|
@ -413,14 +491,14 @@
|
|||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">10</property>
|
||||
<property name="position">12</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="send_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="receives_default">False</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment102">
|
||||
<property name="visible">True</property>
|
||||
|
@ -438,6 +516,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -459,7 +538,7 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">11</property>
|
||||
<property name="position">13</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -486,6 +565,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -493,7 +573,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_END</property>
|
||||
<property name="ellipsize">end</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
|
@ -505,14 +585,14 @@
|
|||
<property name="height_request">20</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1329">
|
||||
<property name="visible">True</property>
|
||||
<property name="ypad">6</property>
|
||||
<property name="stock">gtk-close</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -526,8 +606,8 @@
|
|||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="tab_fill">False</property>
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -555,6 +635,7 @@
|
|||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -569,6 +650,9 @@
|
|||
<property name="label"><span weight="heavy" size="large">room jid</span></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
|
@ -586,6 +670,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -609,21 +694,24 @@
|
|||
<property name="height_request">60</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="message_scrolledwindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
|
@ -634,6 +722,9 @@
|
|||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -646,9 +737,9 @@
|
|||
<property name="width_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="list_treeview">
|
||||
<property name="visible">True</property>
|
||||
|
@ -677,41 +768,45 @@
|
|||
<child>
|
||||
<widget class="GtkButton" id="emoticons_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a list of emoticons (Alt+M)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="emoticons_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-missing-image</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="formattings_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a list of formattings</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image11">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-bold</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -733,16 +828,17 @@
|
|||
<child>
|
||||
<widget class="GtkButton" id="change_nick_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Change your nickname (Ctrl+N)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-edit</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -755,16 +851,17 @@
|
|||
<child>
|
||||
<widget class="GtkButton" id="change_subject_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Change the room's subject (Alt+T)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image6">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-properties</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -777,17 +874,18 @@
|
|||
<child>
|
||||
<widget class="GtkButton" id="bookmark_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="tooltip" translatable="yes">Bookmark this room (Ctrl+B)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -800,16 +898,17 @@
|
|||
<child>
|
||||
<widget class="GtkButton" id="history_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Browse the chat history (Ctrl+H)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image8">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-justify-fill</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -832,11 +931,12 @@
|
|||
<child>
|
||||
<widget class="GtkButton" id="muc_window_actions_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="tooltip" translatable="yes">Show a menu of advanced functions (Alt+A)</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment104">
|
||||
<property name="visible">True</property>
|
||||
|
@ -846,7 +946,7 @@
|
|||
<widget class="GtkImage" id="image1344">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-execute</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -874,7 +974,7 @@
|
|||
<widget class="GtkButton" id="send_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="receives_default">False</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment105">
|
||||
<property name="visible">True</property>
|
||||
|
@ -892,6 +992,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -944,6 +1045,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -963,14 +1065,14 @@
|
|||
<property name="height_request">20</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="relief">none</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1347">
|
||||
<property name="visible">True</property>
|
||||
<property name="ypad">6</property>
|
||||
<property name="stock">gtk-close</property>
|
||||
<property name="icon_size">1</property>
|
||||
<property name="icon-size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -984,9 +1086,9 @@
|
|||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_fill">False</property>
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
|
39
data/glade/voip_call_received_dialog.glade
Normal file
39
data/glade/voip_call_received_dialog.glade
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0"?>
|
||||
<glade-interface>
|
||||
<!-- interface-requires gtk+ 2.14 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkMessageDialog" id="voip_call_received_messagedialog">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="message_type">question</property>
|
||||
<property name="buttons">yes-no</property>
|
||||
<property name="text"><b><big>Incoming call</big></b></property>
|
||||
<property name="use_markup">True</property>
|
||||
<signal name="destroy" handler="on_voip_call_received_messagedialog_destroy"/>
|
||||
<signal name="close" handler="on_voip_call_received_messagedialog_close"/>
|
||||
<signal name="response" handler="on_voip_call_received_messagedialog_response"/>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">end</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
|
@ -51,6 +51,7 @@ from common.logger import constants
|
|||
from common.pep import MOODS, ACTIVITIES
|
||||
from common.xmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
|
||||
from common.xmpp.protocol import NS_RECEIPTS, NS_ESESSION
|
||||
from common.xmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_JINGLE_ICE_UDP
|
||||
|
||||
from command_system.implementation.middleware import ChatCommandProcessor
|
||||
from command_system.implementation.middleware import CommandTools
|
||||
|
@ -1173,6 +1174,15 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
################################################################################
|
||||
class ChatControl(ChatControlBase):
|
||||
'''A control for standard 1-1 chat'''
|
||||
(
|
||||
JINGLE_STATE_NOT_AVAILABLE,
|
||||
JINGLE_STATE_AVAILABLE,
|
||||
JINGLE_STATE_CONNECTING,
|
||||
JINGLE_STATE_CONNECTION_RECEIVED,
|
||||
JINGLE_STATE_CONNECTED,
|
||||
JINGLE_STATE_ERROR
|
||||
) = range(6)
|
||||
|
||||
TYPE_ID = message_control.TYPE_CHAT
|
||||
old_msg_kind = None # last kind of the printed message
|
||||
|
||||
|
@ -1200,6 +1210,14 @@ class ChatControl(ChatControlBase):
|
|||
self._on_add_to_roster_menuitem_activate)
|
||||
self.handlers[id_] = self._add_to_roster_button
|
||||
|
||||
self._audio_button = self.xml.get_widget('audio_togglebutton')
|
||||
id_ = self._audio_button.connect('toggled', self.on_audio_button_toggled)
|
||||
self.handlers[id_] = self._audio_button
|
||||
|
||||
self._video_button = self.xml.get_widget('video_togglebutton')
|
||||
id_ = self._video_button.connect('toggled', self.on_video_button_toggled)
|
||||
self.handlers[id_] = self._video_button
|
||||
|
||||
self._send_file_button = self.xml.get_widget('send_file_button')
|
||||
# add a special img for send file button
|
||||
path_to_upload_img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'upload.png')
|
||||
|
@ -1241,6 +1259,13 @@ class ChatControl(ChatControlBase):
|
|||
img.set_from_pixbuf(gtkgui_helpers.load_icon(
|
||||
'muc_active').get_pixbuf())
|
||||
|
||||
self._audio_banner_image = self.xml.get_widget('audio_banner_image')
|
||||
self._video_banner_image = self.xml.get_widget('video_banner_image')
|
||||
self.audio_sid = None
|
||||
self.audio_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||
self.video_sid = None
|
||||
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||
|
||||
self.update_toolbar()
|
||||
|
||||
self._mood_image = self.xml.get_widget('mood_image')
|
||||
|
@ -1345,6 +1370,38 @@ class ChatControl(ChatControlBase):
|
|||
else:
|
||||
self._add_to_roster_button.hide()
|
||||
|
||||
# Jingle detection
|
||||
if gajim.capscache.is_supported(self.contact, NS_JINGLE_ICE_UDP) and \
|
||||
gajim.HAVE_FARSIGHT and self.contact.resource:
|
||||
if gajim.capscache.is_supported(self.contact, NS_JINGLE_RTP_AUDIO):
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_audio_state('available')
|
||||
else:
|
||||
self.set_audio_state('not_available')
|
||||
|
||||
if gajim.capscache.is_supported(self.contact, NS_JINGLE_RTP_VIDEO):
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_video_state('available')
|
||||
else:
|
||||
self.set_video_state('not_available')
|
||||
else:
|
||||
if self.audio_state != self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_audio_state('not_available')
|
||||
if self.video_state != self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_video_state('not_available')
|
||||
|
||||
# Audio buttons
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self._audio_button.set_sensitive(False)
|
||||
else:
|
||||
self._audio_button.set_sensitive(True)
|
||||
|
||||
# Video buttons
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self._video_button.set_sensitive(False)
|
||||
else:
|
||||
self._video_button.set_sensitive(True)
|
||||
|
||||
# Send file
|
||||
if gajim.capscache.is_supported(self.contact, NS_FILE) and \
|
||||
self.contact.resource:
|
||||
|
@ -1477,6 +1534,34 @@ class ChatControl(ChatControlBase):
|
|||
else:
|
||||
self._tune_image.hide()
|
||||
|
||||
def _update_jingle(self, jingle_type):
|
||||
if jingle_type not in ('audio', 'video'):
|
||||
return
|
||||
if self.__dict__[jingle_type + '_state'] in (
|
||||
self.JINGLE_STATE_NOT_AVAILABLE, self.JINGLE_STATE_AVAILABLE):
|
||||
self.__dict__['_' + jingle_type + '_banner_image'].hide()
|
||||
else:
|
||||
self.__dict__['_' + jingle_type + '_banner_image'].show()
|
||||
if self.audio_state == self.JINGLE_STATE_CONNECTING:
|
||||
self.__dict__['_' + jingle_type + '_banner_image'].set_from_stock(
|
||||
gtk.STOCK_CONVERT, 1)
|
||||
elif self.audio_state == self.JINGLE_STATE_CONNECTION_RECEIVED:
|
||||
self.__dict__['_' + jingle_type + '_banner_image'].set_from_stock(
|
||||
gtk.STOCK_NETWORK, 1)
|
||||
elif self.audio_state == self.JINGLE_STATE_CONNECTED:
|
||||
self.__dict__['_' + jingle_type + '_banner_image'].set_from_stock(
|
||||
gtk.STOCK_CONNECT, 1)
|
||||
elif self.audio_state == self.JINGLE_STATE_ERROR:
|
||||
self.__dict__['_' + jingle_type + '_banner_image'].set_from_stock(
|
||||
gtk.STOCK_DIALOG_WARNING, 1)
|
||||
self.update_toolbar()
|
||||
|
||||
def update_audio(self):
|
||||
self._update_jingle('audio')
|
||||
|
||||
def update_video(self):
|
||||
self._update_jingle('video')
|
||||
|
||||
def change_resource(self, resource):
|
||||
old_full_jid = self.get_full_jid()
|
||||
self.resource = resource
|
||||
|
@ -1490,6 +1575,52 @@ class ChatControl(ChatControlBase):
|
|||
# update MessageWindow._controls
|
||||
self.parent_win.change_jid(self.account, old_full_jid, new_full_jid)
|
||||
|
||||
def _set_jingle_state(self, jingle_type, state, sid=None, reason=None):
|
||||
if jingle_type not in ('audio', 'video'):
|
||||
return
|
||||
if state in ('connecting', 'connected', 'stop') and reason:
|
||||
str = _('%(type)s state : %(state)s, reason: %(reason)s') % {
|
||||
'type': jingle_type.capitalize(), 'state': state, 'reason': reason}
|
||||
self.print_conversation(str, 'info')
|
||||
|
||||
states = {'not_available': self.JINGLE_STATE_NOT_AVAILABLE,
|
||||
'available': self.JINGLE_STATE_AVAILABLE,
|
||||
'connecting': self.JINGLE_STATE_CONNECTING,
|
||||
'connection_received': self.JINGLE_STATE_CONNECTION_RECEIVED,
|
||||
'connected': self.JINGLE_STATE_CONNECTED,
|
||||
'stop': self.JINGLE_STATE_AVAILABLE,
|
||||
'error': self.JINGLE_STATE_ERROR}
|
||||
|
||||
if state in states:
|
||||
jingle_state = states[state]
|
||||
if self.__dict__[jingle_type + '_state'] == jingle_state:
|
||||
return
|
||||
self.__dict__[jingle_type + '_state'] = jingle_state
|
||||
|
||||
# Destroy existing session with the user when he signs off
|
||||
# We need to do that before modifying the sid
|
||||
if state == 'not_available':
|
||||
gajim.connections[self.account].delete_jingle_session(
|
||||
self.contact.get_full_jid(), self.__dict__[jingle_type + '_sid'])
|
||||
|
||||
if state in ('not_available', 'available', 'stop'):
|
||||
self.__dict__[jingle_type + '_sid'] = None
|
||||
if state in ('connection_received', 'connecting'):
|
||||
self.__dict__[jingle_type + '_sid'] = sid
|
||||
|
||||
if state in ('connecting', 'connected', 'connection_received'):
|
||||
self.__dict__['_' + jingle_type + '_button'].set_active(True)
|
||||
elif state in ('not_available', 'stop'):
|
||||
self.__dict__['_' + jingle_type + '_button'].set_active(False)
|
||||
|
||||
eval('self.update_' + jingle_type)()
|
||||
|
||||
def set_audio_state(self, state, sid=None, reason=None):
|
||||
self._set_jingle_state('audio', state, sid=sid, reason=reason)
|
||||
|
||||
def set_video_state(self, state, sid=None, reason=None):
|
||||
self._set_jingle_state('video', state, sid=sid, reason=reason)
|
||||
|
||||
def on_avatar_eventbox_enter_notify_event(self, widget, event):
|
||||
'''
|
||||
we enter the eventbox area so we under conditions add a timeout
|
||||
|
@ -1688,6 +1819,34 @@ class ChatControl(ChatControlBase):
|
|||
banner_name_label.set_markup(label_text)
|
||||
banner_name_label.set_tooltip_text(label_tooltip)
|
||||
|
||||
def on_audio_button_toggled(self, widget):
|
||||
if widget.get_active():
|
||||
if self.audio_state == self.JINGLE_STATE_AVAILABLE:
|
||||
sid = gajim.connections[self.account].startVoIP(
|
||||
self.contact.get_full_jid())
|
||||
self.set_audio_state('connecting', sid)
|
||||
else:
|
||||
session = gajim.connections[self.account].get_jingle_session(
|
||||
self.contact.get_full_jid(), self.audio_sid)
|
||||
if session:
|
||||
content = session.get_content('audio')
|
||||
if content:
|
||||
session.remove_content(content.creator, content.name)
|
||||
|
||||
def on_video_button_toggled(self, widget):
|
||||
if widget.get_active():
|
||||
if self.video_state == self.JINGLE_STATE_AVAILABLE:
|
||||
sid = gajim.connections[self.account].startVideoIP(
|
||||
self.contact.get_full_jid())
|
||||
self.set_video_state('connecting', sid)
|
||||
else:
|
||||
session = gajim.connections[self.account].get_jingle_session(
|
||||
self.contact.get_full_jid(), self.video_sid)
|
||||
if session:
|
||||
content = session.get_content('video')
|
||||
if content:
|
||||
session.remove_content(content.creator, content.name)
|
||||
|
||||
def _toggle_gpg(self):
|
||||
if not self.gpg_is_active and not self.contact.keyID:
|
||||
dialogs.ErrorDialog(_('No GPG key assigned'),
|
||||
|
|
|
@ -52,6 +52,14 @@ from common import exceptions
|
|||
from common.commands import ConnectionCommands
|
||||
from common.pubsub import ConnectionPubSub
|
||||
from common.caps import ConnectionCaps
|
||||
if gajim.HAVE_FARSIGHT:
|
||||
from common.jingle import ConnectionJingle
|
||||
else:
|
||||
class ConnectionJingle():
|
||||
def __init__(self):
|
||||
pass
|
||||
def _JingleCB(self, con, stanza):
|
||||
pass
|
||||
|
||||
from common import dbus_support
|
||||
if dbus_support.supported:
|
||||
|
@ -1445,12 +1453,13 @@ sent a message to.'''
|
|||
|
||||
return sess
|
||||
|
||||
class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, ConnectionCommands, ConnectionPubSub, ConnectionCaps, ConnectionHandlersBase):
|
||||
class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco, ConnectionCommands, ConnectionPubSub, ConnectionCaps, ConnectionHandlersBase, ConnectionJingle):
|
||||
def __init__(self):
|
||||
ConnectionVcard.__init__(self)
|
||||
ConnectionBytestream.__init__(self)
|
||||
ConnectionCommands.__init__(self)
|
||||
ConnectionPubSub.__init__(self)
|
||||
ConnectionJingle.__init__(self)
|
||||
ConnectionHandlersBase.__init__(self)
|
||||
self.gmail_url = None
|
||||
|
||||
|
@ -2807,6 +2816,10 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
common.xmpp.NS_PRIVACY)
|
||||
con.RegisterHandler('iq', self._PubSubCB, 'result')
|
||||
con.RegisterHandler('iq', self._PubSubErrorCB, 'error')
|
||||
con.RegisterHandler('iq', self._JingleCB, 'result')
|
||||
con.RegisterHandler('iq', self._JingleCB, 'error')
|
||||
con.RegisterHandler('iq', self._JingleCB, 'set',
|
||||
common.xmpp.NS_JINGLE)
|
||||
con.RegisterHandler('iq', self._ErrorCB, 'error')
|
||||
con.RegisterHandler('iq', self._IqCB)
|
||||
con.RegisterHandler('iq', self._StanzaArrivedCB)
|
||||
|
|
|
@ -33,7 +33,7 @@ class Event:
|
|||
''' type_ in chat, normal, file-request, file-error, file-completed,
|
||||
file-request-error, file-send-error, file-stopped, gc_msg, pm,
|
||||
printed_chat, printed_gc_msg, printed_marked_gc_msg, printed_pm,
|
||||
gc-invitation, subscription_request, unsubscribed
|
||||
gc-invitation, subscription_request, unsubscribedm jingle-incoming
|
||||
parameters is (per type_):
|
||||
chat, normal, pm: [message, subject, kind, time, encrypted, resource,
|
||||
msg_id]
|
||||
|
@ -46,6 +46,7 @@ class Event:
|
|||
gc-invitation: [room_jid, reason, password, is_continued]
|
||||
subscription_request: [text, nick]
|
||||
unsubscribed: contact
|
||||
jingle-incoming: (fulljid, sessionid, content_types)
|
||||
'''
|
||||
self.type_ = type_
|
||||
self.time_ = time_
|
||||
|
|
|
@ -189,6 +189,11 @@ try:
|
|||
except ImportError:
|
||||
HAVE_INDICATOR = False
|
||||
|
||||
HAVE_FARSIGHT = True
|
||||
try:
|
||||
import farsight, gst
|
||||
except ImportError:
|
||||
HAVE_FARSIGHT = False
|
||||
gajim_identity = {'type': 'pc', 'category': 'client', 'name': 'Gajim'}
|
||||
gajim_common_features = [xmpp.NS_BYTESTREAM, xmpp.NS_SI, xmpp.NS_FILE,
|
||||
xmpp.NS_MUC, xmpp.NS_MUC_USER, xmpp.NS_MUC_ADMIN, xmpp.NS_MUC_OWNER,
|
||||
|
|
|
@ -1357,6 +1357,12 @@ def update_optional_features(account = None):
|
|||
gajim.gajim_optional_features[a].append(xmpp.NS_ESESSION)
|
||||
if gajim.config.get_per('accounts', a, 'answer_receipts'):
|
||||
gajim.gajim_optional_features[a].append(xmpp.NS_RECEIPTS)
|
||||
if gajim.HAVE_FARSIGHT:
|
||||
gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE)
|
||||
gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP)
|
||||
gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP_AUDIO)
|
||||
gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_RTP_VIDEO)
|
||||
gajim.gajim_optional_features[a].append(xmpp.NS_JINGLE_ICE_UDP)
|
||||
gajim.caps_hash[a] = compute_caps_hash([gajim.gajim_identity],
|
||||
gajim.gajim_common_features + gajim.gajim_optional_features[a])
|
||||
# re-send presence with new hash
|
||||
|
|
1165
src/common/jingle.py
Normal file
1165
src/common/jingle.py
Normal file
File diff suppressed because it is too large
Load diff
36
src/common/meta.py
Normal file
36
src/common/meta.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import types
|
||||
|
||||
class VerboseClassType(type):
|
||||
indent = ''
|
||||
|
||||
def __init__(cls, name, bases, dict):
|
||||
super(VerboseClassType, cls).__init__(cls, name, bases, dict)
|
||||
new = {}
|
||||
print 'Initializing new class %s:' % cls
|
||||
for fname, fun in dict.iteritems():
|
||||
wrap = hasattr(fun, '__call__')
|
||||
print '%s%s is %s, we %s wrap it.' % \
|
||||
(cls.__class__.indent, fname, fun, wrap and 'will' or "won't")
|
||||
if not wrap: continue
|
||||
setattr(cls, fname, cls.wrap(name, fname, fun))
|
||||
|
||||
def wrap(cls, name, fname, fun):
|
||||
def verbose(*a, **b):
|
||||
args = ', '.join(map(repr, a)+map(lambda x:'%s=%r'%x, b.iteritems()))
|
||||
print '%s%s.%s(%s):' % (cls.__class__.indent, name, fname, args)
|
||||
cls.__class__.indent += '| '
|
||||
r = fun(*a, **b)
|
||||
cls.__class__.indent = cls.__class__.indent[:-4]
|
||||
print '%s+=%r' % (cls.__class__.indent, r)
|
||||
return r
|
||||
verbose.__name__ = fname
|
||||
return verbose
|
||||
|
||||
def nested_property(f):
|
||||
ret = f()
|
||||
p = {}
|
||||
for v in ('fget', 'fset', 'fdel', 'doc'):
|
||||
if v in ret: p[v]=ret[v]
|
||||
return property(**p)
|
|
@ -63,6 +63,13 @@ NS_HTTP_BIND ='http://jabber.org/protocol/httpbind' # XEP-0124
|
|||
NS_IBB ='http://jabber.org/protocol/ibb'
|
||||
NS_INVISIBLE ='presence-invisible' # Jabberd2
|
||||
NS_IQ ='iq' # Jabberd2
|
||||
NS_JINGLE ='urn:xmpp:jingle:1' # XEP-0166
|
||||
NS_JINGLE_ERRORS='urn:xmpp:jingle:errors:1' # XEP-0166
|
||||
NS_JINGLE_RTP ='urn:xmpp:jingle:apps:rtp:1' # XEP-0167
|
||||
NS_JINGLE_RTP_AUDIO='urn:xmpp:jingle:apps:rtp:audio' # XEP-0167
|
||||
NS_JINGLE_RTP_VIDEO='urn:xmpp:jingle:apps:rtp:video' # XEP-0167
|
||||
NS_JINGLE_RAW_UDP='urn:xmpp:jingle:transports:raw-udp:1' # XEP-0177
|
||||
NS_JINGLE_ICE_UDP='urn:xmpp:jingle:transports:ice-udp:1' # XEP-0176
|
||||
NS_LAST ='jabber:iq:last'
|
||||
NS_MESSAGE ='message' # Jabberd2
|
||||
NS_MOOD ='http://jabber.org/protocol/mood' # XEP-0107
|
||||
|
|
|
@ -297,6 +297,9 @@ class Node(object):
|
|||
def __delitem__(self,item):
|
||||
''' Deletes node's attribute "item". '''
|
||||
return self.delAttr(item)
|
||||
def __contains__(self,item):
|
||||
""" Checks if node has attribute "item" """
|
||||
return self.has_attr(item)
|
||||
def __getattr__(self,attr):
|
||||
''' Reduce memory usage caused by T/NT classes - use memory only when needed. '''
|
||||
if attr=='T':
|
||||
|
|
105
src/dialogs.py
105
src/dialogs.py
|
@ -32,6 +32,7 @@
|
|||
import gtk
|
||||
import gobject
|
||||
import os
|
||||
from weakref import WeakValueDictionary
|
||||
|
||||
import gtkgui_helpers
|
||||
import vcard
|
||||
|
@ -4514,6 +4515,8 @@ class GPGInfoWindow:
|
|||
def on_close_button_clicked(self, widget):
|
||||
self.window.destroy()
|
||||
|
||||
|
||||
|
||||
class ResourceConflictDialog(TimeoutDialog, InputDialog):
|
||||
def __init__(self, title, text, resource, ok_handler):
|
||||
TimeoutDialog.__init__(self, 15, self.on_timeout)
|
||||
|
@ -4525,4 +4528,106 @@ class ResourceConflictDialog(TimeoutDialog, InputDialog):
|
|||
def on_timeout(self):
|
||||
self.on_okbutton_clicked(None)
|
||||
|
||||
|
||||
|
||||
class VoIPCallReceivedDialog(object):
|
||||
instances = {}
|
||||
def __init__(self, account, contact_jid, sid, content_types):
|
||||
self.instances[(contact_jid, sid)] = self
|
||||
self.account = account
|
||||
self.fjid = contact_jid
|
||||
self.sid = sid
|
||||
self.content_types = content_types
|
||||
|
||||
xml = gtkgui_helpers.get_glade('voip_call_received_dialog.glade')
|
||||
xml.signal_autoconnect(self)
|
||||
|
||||
jid = gajim.get_jid_without_resource(self.fjid)
|
||||
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||
if contact and contact.name:
|
||||
self.contact_text = '%s (%s)' % (contact.name, jid)
|
||||
else:
|
||||
self.contact_text = contact_jid
|
||||
|
||||
self.dialog = xml.get_widget('voip_call_received_messagedialog')
|
||||
self.set_secondary_text()
|
||||
|
||||
self.dialog.show_all()
|
||||
|
||||
@classmethod
|
||||
def get_dialog(cls, jid, sid):
|
||||
if (jid, sid) in cls.instances:
|
||||
return cls.instances[(jid, sid)]
|
||||
else:
|
||||
return None
|
||||
|
||||
def set_secondary_text(self):
|
||||
if 'audio' in self.content_types and 'video' in self.content_types:
|
||||
types_text = _('an audio and video')
|
||||
elif 'audio' in self.content_types:
|
||||
types_text = _('an audio')
|
||||
elif 'video' in self.content_types:
|
||||
types_text = _('a video')
|
||||
|
||||
# do the substitution
|
||||
self.dialog.set_property('secondary-text',
|
||||
_('%(contact)s wants to start %(type)s session with you. Do you want '
|
||||
'to answer the call?') % {'contact': self.contact_text, 'type': types_text})
|
||||
|
||||
def add_contents(self, content_types):
|
||||
for type_ in content_types:
|
||||
if type_ not in self.content_types:
|
||||
self.content_types.add(type_)
|
||||
self.set_secondary_text()
|
||||
|
||||
def on_voip_call_received_messagedialog_destroy(self, dialog):
|
||||
if (self.fjid, self.sid) in self.instances:
|
||||
del self.instances[(self.fjid, self.sid)]
|
||||
|
||||
def on_voip_call_received_messagedialog_close(self, dialog):
|
||||
return self.on_voip_call_received_messagedialog_response(dialog,
|
||||
gtk.RESPONSE_NO)
|
||||
|
||||
def on_voip_call_received_messagedialog_response(self, dialog, response):
|
||||
# we've got response from user, either stop connecting or accept the call
|
||||
session = gajim.connections[self.account].get_jingle_session(self.fjid,
|
||||
self.sid)
|
||||
if not session:
|
||||
return
|
||||
if response == gtk.RESPONSE_YES:
|
||||
#TODO: Ensure that ctrl.contact.resource == resource
|
||||
jid = gajim.get_jid_without_resource(self.fjid)
|
||||
resource = gajim.get_resource_from_jid(self.fjid)
|
||||
ctrl = gajim.interface.msg_win_mgr.get_control(self.fjid, self.account)
|
||||
if not ctrl:
|
||||
ctrl = gajim.interface.msg_win_mgr.get_control(jid, self.account)
|
||||
if not ctrl:
|
||||
# open chat control
|
||||
contact = gajim.contacts.get_contact(self.account, jid, resource)
|
||||
if not contact:
|
||||
contact = gajim.contacts.get_contact(self.account, jid)
|
||||
if not contact:
|
||||
return
|
||||
ctrl = gajim.interface.new_chat(contact, self.account)
|
||||
# Chat control opened, update content's status
|
||||
if session.get_content('audio'):
|
||||
ctrl.set_audio_state('connecting', self.sid)
|
||||
if session.get_content('video'):
|
||||
ctrl.set_video_state('connecting', self.sid)
|
||||
# Now, accept the content/sessions.
|
||||
# This should be done after the chat control is running
|
||||
if not session.accepted:
|
||||
session.approve_session()
|
||||
for content in self.content_types:
|
||||
session.approve_content(content)
|
||||
else: # response==gtk.RESPONSE_NO
|
||||
if not session.accepted:
|
||||
session.decline_session()
|
||||
else:
|
||||
for content in self.content_types:
|
||||
session.reject_content(content)
|
||||
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
# vim: se ts=3:
|
||||
|
|
|
@ -107,6 +107,10 @@ class FeaturesWindow:
|
|||
_('Ability to have clickable URLs in chat and groupchat window banners.'),
|
||||
_('Requires python-sexy.'),
|
||||
_('Requires python-sexy.')),
|
||||
_('Audio / Video'): (self.farsight_available,
|
||||
_('Ability to start audio and video chat.'),
|
||||
_('Requires python-farsight.'),
|
||||
_('Feature not available under Windows.')),
|
||||
}
|
||||
|
||||
# name, supported
|
||||
|
@ -265,4 +269,7 @@ class FeaturesWindow:
|
|||
def pysexy_available(self):
|
||||
return gajim.HAVE_PYSEXY
|
||||
|
||||
def farsight_available(self):
|
||||
return gajim.HAVE_FARSIGHT
|
||||
|
||||
# vim: se ts=3:
|
||||
|
|
107
src/gajim.py
107
src/gajim.py
|
@ -2107,6 +2107,102 @@ class Interface:
|
|||
_('You are already connected to this account with the same resource. '
|
||||
'Please type a new one'), resource=proposed_resource, ok_handler=on_ok)
|
||||
|
||||
def handle_event_jingle_incoming(self, account, data):
|
||||
# ('JINGLE_INCOMING', account, peer jid, sid, tuple-of-contents==(type,
|
||||
# data...))
|
||||
# TODO: conditional blocking if peer is not in roster
|
||||
|
||||
# unpack data
|
||||
peerjid, sid, contents = data
|
||||
content_types = set(c[0] for c in contents)
|
||||
|
||||
# check type of jingle session
|
||||
if 'audio' in content_types or 'video' in content_types:
|
||||
# a voip session...
|
||||
# we now handle only voip, so the only thing we will do here is
|
||||
# not to return from function
|
||||
pass
|
||||
else:
|
||||
# unknown session type... it should be declined in common/jingle.py
|
||||
return
|
||||
|
||||
jid = gajim.get_jid_without_resource(peerjid)
|
||||
resource = gajim.get_resource_from_jid(peerjid)
|
||||
ctrl = self.msg_win_mgr.get_control(peerjid, account)
|
||||
if not ctrl:
|
||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||
if ctrl:
|
||||
if 'audio' in content_types:
|
||||
ctrl.set_audio_state('connection_received', sid)
|
||||
if 'video' in content_types:
|
||||
ctrl.set_video_state('connection_received', sid)
|
||||
|
||||
dlg = dialogs.VoIPCallReceivedDialog.get_dialog(peerjid, sid)
|
||||
if dlg:
|
||||
dlg.add_contents(content_types)
|
||||
return
|
||||
|
||||
if helpers.allow_popup_window(account):
|
||||
dialogs.VoIPCallReceivedDialog(account, peerjid, sid, content_types)
|
||||
return
|
||||
|
||||
self.add_event(account, peerjid, 'jingle-incoming', (peerjid, sid,
|
||||
content_types))
|
||||
|
||||
if helpers.allow_showing_notification(account):
|
||||
# TODO: we should use another pixmap ;-)
|
||||
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
|
||||
'ft_request.png')
|
||||
txt = _('%s wants to start a voice chat.') % gajim.get_name_from_jid(
|
||||
account, peerjid)
|
||||
path = gtkgui_helpers.get_path_to_generic_or_avatar(img)
|
||||
event_type = _('Voice Chat Request')
|
||||
notify.popup(event_type, peerjid, account, 'jingle-incoming',
|
||||
path_to_image = path, title = event_type, text = txt)
|
||||
|
||||
def handle_event_jingle_connected(self, account, data):
|
||||
# ('JINGLE_CONNECTED', account, (peerjid, sid, media))
|
||||
peerjid, sid, media = data
|
||||
if media in ('audio', 'video'):
|
||||
jid = gajim.get_jid_without_resource(peerjid)
|
||||
resource = gajim.get_resource_from_jid(peerjid)
|
||||
ctrl = self.msg_win_mgr.get_control(peerjid, account)
|
||||
if not ctrl:
|
||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||
if ctrl:
|
||||
if media == 'audio':
|
||||
ctrl.set_audio_state('connected', sid)
|
||||
else:
|
||||
ctrl.set_video_state('connected', sid)
|
||||
|
||||
def handle_event_jingle_disconnected(self, account, data):
|
||||
# ('JINGLE_DISCONNECTED', account, (peerjid, sid, reason))
|
||||
peerjid, sid, media, reason = data
|
||||
jid = gajim.get_jid_without_resource(peerjid)
|
||||
resource = gajim.get_resource_from_jid(peerjid)
|
||||
ctrl = self.msg_win_mgr.get_control(peerjid, account)
|
||||
if not ctrl:
|
||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||
if ctrl:
|
||||
if media in ('audio', None):
|
||||
ctrl.set_audio_state('stop', sid=sid, reason=reason)
|
||||
if media in ('video', None):
|
||||
ctrl.set_video_state('stop', sid=sid, reason=reason)
|
||||
dialog = dialogs.VoIPCallReceivedDialog.get_dialog(peerjid, sid)
|
||||
if dialog:
|
||||
dialog.dialog.destroy()
|
||||
|
||||
def handle_event_jingle_error(self, account, data):
|
||||
# ('JINGLE_ERROR', account, (peerjid, sid, reason))
|
||||
peerjid, sid, reason = data
|
||||
jid = gajim.get_jid_without_resource(peerjid)
|
||||
resource = gajim.get_resource_from_jid(peerjid)
|
||||
ctrl = self.msg_win_mgr.get_control(peerjid, account)
|
||||
if not ctrl:
|
||||
ctrl = self.msg_win_mgr.get_control(jid, account)
|
||||
if ctrl:
|
||||
ctrl.set_audio_state('error', reason=reason)
|
||||
|
||||
def handle_event_pep_config(self, account, data):
|
||||
# ('PEP_CONFIG', account, (node, form))
|
||||
if 'pep_services' in self.instances[account]:
|
||||
|
@ -2364,6 +2460,10 @@ class Interface:
|
|||
'INSECURE_SSL_CONNECTION': self.handle_event_insecure_ssl_connection,
|
||||
'PUBSUB_NODE_REMOVED': self.handle_event_pubsub_node_removed,
|
||||
'PUBSUB_NODE_NOT_REMOVED': self.handle_event_pubsub_node_not_removed,
|
||||
'JINGLE_INCOMING': self.handle_event_jingle_incoming,
|
||||
'JINGLE_CONNECTED': self.handle_event_jingle_connected,
|
||||
'JINGLE_DISCONNECTED': self.handle_event_jingle_disconnected,
|
||||
'JINGLE_ERROR': self.handle_event_jingle_error,
|
||||
}
|
||||
|
||||
def dispatch(self, event, account, data):
|
||||
|
@ -2388,7 +2488,7 @@ class Interface:
|
|||
jid = gajim.get_jid_without_resource(jid)
|
||||
no_queue = len(gajim.events.get_events(account, jid)) == 0
|
||||
# type_ can be gc-invitation file-send-error file-error file-request-error
|
||||
# file-request file-completed file-stopped
|
||||
# file-request file-completed file-stopped jingle-incoming
|
||||
# event_type can be in advancedNotificationWindow.events_list
|
||||
event_types = {'file-request': 'ft_request',
|
||||
'file-completed': 'ft_finished'}
|
||||
|
@ -2548,6 +2648,11 @@ class Interface:
|
|||
self.show_unsubscribed_dialog(account, contact)
|
||||
gajim.events.remove_events(account, jid, event)
|
||||
self.roster.draw_contact(jid, account)
|
||||
elif type_ == 'jingle-incoming':
|
||||
event = gajim.events.get_first_event(account, jid, type_)
|
||||
peerjid, sid, content_types = event.parameters
|
||||
dialogs.VoIPCallReceivedDialog(account, peerjid, sid, content_types)
|
||||
gajim.events.remove_events(account, jid, event)
|
||||
if w:
|
||||
w.set_active_tab(ctrl)
|
||||
w.window.window.focus(gtk.get_current_event_time())
|
||||
|
|
Loading…
Add table
Reference in a new issue