merge pep branch to trunk. set use_pep to true and restart to use it

This commit is contained in:
Yann Leboulanger 2007-12-12 19:03:25 +00:00
commit 16e9aab801
21 changed files with 1942 additions and 40 deletions

15
TODO.pep Normal file
View File

@ -0,0 +1,15 @@
• configure access model when changing it in the combobox
• PEP in status change
Tune use cases:
• on disconnection of an account set Tune to None
Tooltips use cases:
• Show PEP in contact tooltips
• Show PEP in GC tooltips
• Show PEP in account tooltips
Mood/Activity use cases
• on connection of an account set them to None
• on disconnection of an account set them to None
• on explicit set publish them

View File

@ -17,6 +17,20 @@
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="pep_menuitem">
<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="label" translatable="yes">_Personal Events</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image7">
<property name="stock">gtk-home</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
<property name="visible">True</property>

View File

@ -0,0 +1,158 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkDialog" id="change_activity_dialog">
<property name="border_width">6</property>
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">270</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="has_separator">True</property>
<signal name="key_press_event" handler="on_change_status_message_dialog_key_press_event" last_modification_time="Wed, 16 Mar 2005 00:53:06 GMT"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox5">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-6</property>
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="ok_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
<signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame38">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkAlignment" id="alignment107">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkVBox" id="vbox112">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkComboBox" id="combobox1">
<property name="visible">True</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="combobox2">
<property name="visible">True</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -0,0 +1,145 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkDialog" id="change_mood_dialog">
<property name="border_width">6</property>
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">270</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="has_separator">True</property>
<signal name="key_press_event" handler="on_change_status_message_dialog_key_press_event" last_modification_time="Wed, 16 Mar 2005 00:53:06 GMT"/>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox5">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-6</property>
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="ok_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
<signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame38">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkAlignment" id="alignment107">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkVBox" id="vbox112">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkComboBox" id="combobox">
<property name="visible">True</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">●</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="manage_pep_services_window">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">350</property>
<property name="default_height">150</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<signal name="destroy" handler="on_manage_pep_services_window_destroy"/>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<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_NONE</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="services_treeview">
<property name="visible">True</property>
<property name="can_focus">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="headers_visible">True</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="add_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-add</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
<signal name="clicked" handler="on_add_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="delete_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-delete</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
<signal name="clicked" handler="on_delete_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-6</property>
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
</widget>
</child>
<child>
<widget class="GtkButton" id="ok_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
<signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -438,9 +438,6 @@ Single message</property>
</packing>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label74">
@ -449,7 +446,6 @@ Single message</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -880,7 +876,6 @@ Disabled</property>
</widget>
<packing>
<property name="position">1</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -891,7 +886,6 @@ Disabled</property>
<packing>
<property name="type">tab</property>
<property name="position">1</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -1229,7 +1223,6 @@ Show only in roster</property>
</widget>
<packing>
<property name="position">2</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -1240,7 +1233,6 @@ Show only in roster</property>
<packing>
<property name="type">tab</property>
<property name="position">2</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -1638,7 +1630,6 @@ Show only in roster</property>
</widget>
<packing>
<property name="position">3</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -1649,7 +1640,6 @@ Show only in roster</property>
<packing>
<property name="type">tab</property>
<property name="position">3</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
@ -2048,7 +2038,6 @@ Custom</property>
</widget>
<packing>
<property name="position">4</property>
<property name="tab_expand">False</property>
</packing>
</child>
<child>
@ -2059,7 +2048,193 @@ Custom</property>
<packing>
<property name="type">tab</property>
<property name="position">4</property>
<property name="tab_expand">False</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox2">
<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">6</property>
<child>
<widget class="GtkFrame" id="frame6">
<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="label_xalign">0</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkAlignment" id="alignment6">
<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="left_padding">12</property>
<child>
<widget class="GtkVBox" id="vbox3">
<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="GtkCheckButton" id="publish_mood_checkbutton">
<property name="visible">True</property>
<property name="can_focus">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="label" translatable="yes">Publish _Mood</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_publish_mood_checkbutton_toggled"/>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="publish_activity_checkbutton">
<property name="visible">True</property>
<property name="can_focus">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="label" translatable="yes">Publish _Activity</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_publish_activity_checkbutton_toggled"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="publish_tune_checkbutton">
<property name="visible">True</property>
<property name="can_focus">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="label" translatable="yes">Publish _Tune</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_publish_tune_checkbutton_toggled"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label10">
<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="label" translatable="yes">&lt;b&gt;Publish Personal Events&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame7">
<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="label_xalign">0</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkAlignment" id="alignment7">
<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="left_padding">12</property>
<child>
<widget class="GtkVBox" id="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>
<child>
<widget class="GtkCheckButton" id="subscribe_mood_checkbutton">
<property name="visible">True</property>
<property name="can_focus">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="label" translatable="yes">Subscribe to M_ood</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_subscribe_mood_checkbutton_toggled"/>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="subscribe_activity_checkbutton">
<property name="visible">True</property>
<property name="can_focus">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="label" translatable="yes">Subscribe to A_ctivity</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_subscribe_activity_checkbutton_toggled"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="subscribe_tune_checkbutton">
<property name="visible">True</property>
<property name="can_focus">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="label" translatable="yes">Subscribe to T_une</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_subscribe_tune_checkbutton_toggled"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label11">
<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="label" translatable="yes">&lt;b&gt;Subscribe to Personal Events&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="position">5</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label9">
<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="label" translatable="yes">Personal Events</property>
</widget>
<packing>
<property name="type">tab</property>
<property name="position">5</property>
<property name="tab_fill">False</property>
</packing>
</child>

View File

@ -193,6 +193,14 @@
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="pep_services_menuitem">
<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="label" translatable="yes">_Services</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
</child>
</widget>

400
po/fr.po
View File

@ -6537,6 +6537,406 @@ msgstr "Connecté"
msgid "Disconnected"
msgstr "Déconnecté"
#pep
msgid "afraid"
msgstr "appeuré"
msgid "amazed"
msgstr "surpris, amusé"
msgid "angry"
msgstr "en colère"
msgid "annoyed"
msgstr "dérangé"
msgid "anxious"
msgstr "anxieux"
msgid "aroused"
msgstr "excité"
msgid "ashamed"
msgstr "honteux/éhonté"
msgid "bored"
msgstr "ennuyé"
msgid "brave"
msgstr "courageux"
msgid "calm"
msgstr "calme"
msgid "cold"
msgstr "froid"
msgid "confused"
msgstr "confus"
msgid "contented"
msgstr "contenté"
msgid "cranky"
msgstr "excentrique"
msgid "curious"
msgstr "curieux"
msgid "depressed"
msgstr "déprimé"
msgid "disappointed"
msgstr "décu"
msgid "disgusted"
msgstr "dégouté"
msgid "distracted"
msgstr "distrait"
msgid "embarrassed"
msgstr "embarssé"
msgid "excited"
msgstr "excité"
msgid "flirtatious"
msgstr "coquet"
msgid "frustrated"
msgstr "frustré"
msgid "grumpy"
msgstr "grognon"
msgid "guilty"
msgstr "coupable"
msgid "happy"
msgstr "joyeux"
msgid "hot"
msgstr "chaud"
msgid "humbled"
msgstr "humilié"
msgid "humiliated"
msgstr "humilié"
msgid "hungry"
msgstr "affamé"
msgid "hurt"
msgstr "blessé"
msgid "impressed"
msgstr "impressionné"
msgid "in_awe"
msgstr "dans la crainte"
msgid "in_love"
msgstr "amoureux"
msgid "indignant"
msgstr "indigné"
msgid "interested"
msgstr "interessé"
msgid "intoxicated"
msgstr "intoxiqué"
msgid "invincible"
msgstr "invincible"
msgid "jealous"
msgstr "jaloux"
msgid "lonely"
msgstr "seul/esseulé"
msgid "mean"
msgstr "méchant"
msgid "moody"
msgstr "déprimé"
msgid "nervous"
msgstr "nerveux"
msgid "neutral"
msgstr "neutre"
msgid "offended"
msgstr "offensé"
msgid "playful"
msgstr "joueur"
msgid "proud"
msgstr "fier"
msgid "relieved"
msgstr "soulagé"
msgid "remorseful"
msgstr "plein de remord"
msgid "restless"
msgstr "infatiguable"
msgid "sad"
msgstr "triste"
msgid "sarcastic"
msgstr "sarcastique"
msgid "serious"
msgstr "serieux"
msgid "shocked"
msgstr "choqué"
msgid "shy"
msgstr "timide"
msgid "sick"
msgstr "malade"
msgid "sleepy"
msgstr "endormi"
msgid "stressed"
msgstr "stressé"
msgid "surprised"
msgstr "surpris"
msgid "thirsty"
msgstr "assoiffé"
msgid "worried"
msgstr "inquiet"
msgid "_Personnal Events"
msgstr "Évènements _Personnels"
msgid "Activity"
msgstr "Activité"
msgid "doing_chores"
msgstr "fait des corvées"
msgid "buying_groceries"
msgstr "achète des épiceries"
msgid "cleaning"
msgstr "nettoie"
msgid "cooking"
msgstr "cuisine"
msgid "doing_maintenance"
msgstr "fait de la maintenance"
msgid "doing_the_dishes"
msgstr "fait la vaiselle"
msgid "doing_the_laundry"
msgstr "fait la blanchisserie"
msgid "gardening"
msgstr "jardine"
msgid "running_an_errand"
msgstr "fait une course"
msgid "walking_the_dog"
msgstr "promène le chien"
msgid "drinking"
msgstr "boit"
msgid "having_a_beer"
msgstr "prend une bière"
msgid "having_coffee"
msgstr "prend un café"
msgid "having_tea"
msgstr "prend un thé"
msgid "eating"
msgstr "mange"
msgid "having_a_snack"
msgstr "prend un snack"
msgid "having_breakfast"
msgstr "prend le petit-déjeuner"
msgid "having_dinner"
msgstr "soupe"
msgid "having_lunch"
msgstr "dîne"
msgid "exercising"
msgstr "fait de l'exercice"
msgid "cycling"
msgstr "fait du vélo"
msgid "hiking"
msgstr "fait de la randonnée"
msgid "jogging"
msgstr "fait un jogging"
msgid "playing_sports"
msgstr "fait du sport"
msgid "running"
msgstr "court"
msgid "skiing"
msgstr "skie"
msgid "swimming"
msgstr "nage"
msgid "working_out"
msgstr "élabore"
msgid "grooming"
msgstr "se toilette"
msgid "at_the_spa"
msgstr "à la station thermale"
msgid "brushing_teeth"
msgstr "se brosse les dents"
msgid "getting_a_haircut"
msgstr "se fait couper les cheveux"
msgid "shaving"
msgstr "se rase"
msgid "taking_a_bath"
msgstr "prend un bain"
msgid "taking_a_shower"
msgstr "prend une douche"
msgid "having_appointment"
msgstr "à un rendez-vous"
msgid "inactive"
msgstr "inactif"
msgid "day_off"
msgstr "en congé"
msgid "hanging_out"
msgstr "traîne"
msgid "on_vacation"
msgstr "en vacances"
msgid "scheduled_holiday"
msgstr "en vacances organisées"
msgid "sleeping"
msgstr "dort"
msgid "relaxing"
msgstr "se relaxe"
msgid "gaming"
msgstr "joue"
msgid "going_out"
msgstr "sort"
msgid "partying"
msgstr "fait la fête"
msgid "reading"
msgstr "lit"
msgid "rehearsing"
msgstr "se prépare"
msgid "shopping"
msgstr "fait les magasins"
msgid "socializing"
msgstr "se socialise"
msgid "sunbathing"
msgstr "prend un bain de soleil"
msgid "watching_tv"
msgstr "regarde la TV"
msgid "watching_a_movie"
msgstr "regarde un film"
msgid "talking"
msgstr "discute"
msgid "in_real_life"
msgstr "dans la vraie vie"
msgid "on_the_phone"
msgstr "au téléphone"
msgid "traveling"
msgstr "voyage"
msgid "commuting"
msgstr "permute"
msgid "driving"
msgstr "conduit"
msgid "in_a_car"
msgstr "en voiture"
msgid "on_a_bus"
msgstr "en bus"
msgid "on_a_plane"
msgstr "en avion"
msgid "on_a_train"
msgstr "en train"
msgid "on_a_trip"
msgstr "en séjour"
msgid "walking"
msgstr "marche"
msgid "working"
msgstr "travaille"
msgid "coding"
msgstr "programme"
msgid "in_a_meeting"
msgstr "en réunion"
msgid "studying"
msgstr "étudie"
msgid "writing"
msgstr "écrit"
#~ msgid "2003-12-13T18:30:02Z"
#~ msgstr "2003-12-13T18:30:02Z"
#~ msgid "<small>Romeo and Juliet</small>"

View File

@ -250,7 +250,14 @@ class Config:
'use_latex': [opt_bool, False, _('If True, Gajim will convert string between $$ and $$ to an image using dvips and convert before insterting it in chat window.')],
'change_status_window_timeout': [opt_int, 15, _('Time of inactivity needed before the change status window closes down.')],
'max_conversation_lines': [opt_int, 500, _('Maximum number of lines that are printed in conversations. Oldest lines are cleared.')],
'publish_mood': [opt_bool, False],
'publish_activity': [opt_bool, False],
'publish_tune': [opt_bool, False],
'subscribe_mood': [opt_bool, True],
'subscribe_activity': [opt_bool, True],
'subscribe_tune': [opt_bool, True],
'attach_notifications_to_systray': [opt_bool, False, _('If True, notification windows from notification-daemon will be attached to systray icon.')],
'use_pep': [opt_bool, False, 'temporary variable to enable pep support'],
}
__options_per_key = {

View File

@ -186,6 +186,8 @@ class Connection(ConnectionHandlers):
# We are doing disconnect at so many places, better use one function in all
def disconnect(self, on_purpose=False):
#FIXME: set the Tune to None before disconnection per account
#gajim.interface.roster._music_track_changed(None, None)
self.on_purpose = on_purpose
self.connected = 0
self.time_to_reconnect = None

View File

@ -39,11 +39,17 @@ from common import GnuPG
from common import helpers
from common import gajim
from common import atom
from common import pep
from common import exceptions
from common.commands import ConnectionCommands
from common.pubsub import ConnectionPubSub
from common.caps import ConnectionCaps
from common import dbus_support
if dbus_support.supported:
import dbus
from music_track_listener import MusicTrackListener
from common.stanza_session import EncryptedStanzaSession
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
@ -54,6 +60,7 @@ VCARD_ARRIVED = 'vcard_arrived'
AGENT_REMOVED = 'agent_removed'
METACONTACTS_ARRIVED = 'metacontacts_arrived'
PRIVACY_ARRIVED = 'privacy_arrived'
PEP_ACCESS_MODEL = 'pep_access_model'
HAS_IDLE = True
try:
import idle
@ -750,6 +757,13 @@ class ConnectionDisco:
q.addChild('feature', attrs = {'var': common.xmpp.NS_MUC})
q.addChild('feature', attrs = {'var': common.xmpp.NS_COMMANDS})
q.addChild('feature', attrs = {'var': common.xmpp.NS_DISCO_INFO})
if gajim.config.get('use_pep'):
q.addChild('feature', attrs = {'var': common.xmpp.NS_ACTIVITY})
q.addChild('feature', attrs = {'var': common.xmpp.NS_ACTIVITY + '+notify'})
q.addChild('feature', attrs = {'var': common.xmpp.NS_TUNE})
q.addChild('feature', attrs = {'var': common.xmpp.NS_TUNE + '+notify'})
q.addChild('feature', attrs = {'var': common.xmpp.NS_MOOD})
q.addChild('feature', attrs = {'var': common.xmpp.NS_MOOD + '+notify'})
q.addChild('feature', attrs = {'var': common.xmpp.NS_ESESSION_INIT})
if (node is None or extension == 'cstates') and gajim.config.get('outgoing_chat_state_notifactions') != 'disabled':
@ -821,6 +835,11 @@ class ConnectionDisco:
if identity['category'] == 'pubsub' and identity['type'] == \
'pep':
self.pep_supported = True
listener = MusicTrackListener.get()
track = listener.get_playing_track()
if gajim.config.get('publish_tune'):
gajim.interface.roster._music_track_changed(listener,
track, self.name)
break
if features.__contains__(common.xmpp.NS_BYTESTREAM):
gajim.proxy65_manager.resolve(jid, self.connection, self.name)
@ -1099,6 +1118,15 @@ class ConnectionVcard:
self.get_privacy_list('block')
# Ask metacontacts before roster
self.get_metacontacts()
elif self.awaiting_answers[id][0] == PEP_ACCESS_MODEL:
conf = iq_obj.getTag('pubsub').getTag('configure')
node = conf.getAttr('node')
form_tag = conf.getTag('x', namespace=common.xmpp.NS_DATA)
form = common.dataforms.ExtendForm(node=form_tag)
for field in form.iter_fields():
if field.var == 'pubsub#access_model':
self.dispatch('PEP_ACCESS_MODEL', (node, field.value))
break
del self.awaiting_answers[id]
@ -1770,8 +1798,22 @@ returns the session that we last sent a message to.'''
''' Called when we receive <message/> with pubsub event. '''
# TODO: Logging? (actually services where logging would be useful, should
# TODO: allow to access archives remotely...)
jid = helpers.get_full_jid_from_iq(msg)
event = msg.getTag('event')
# XEP-0107: User Mood
items = event.getTag('items', {'node': common.xmpp.NS_MOOD})
if items: pep.user_mood(items, self.name, jid)
# XEP-0118: User Tune
items = event.getTag('items', {'node': common.xmpp.NS_TUNE})
if items: pep.user_tune(items, self.name, jid)
# XEP-0080: User Geolocation
items = event.getTag('items', {'node': common.xmpp.NS_GEOLOC})
if items: pep.user_geoloc(items, self.name, jid)
# XEP-0108: User Activity
items = event.getTag('items', {'node': common.xmpp.NS_ACTIVITY})
if items: pep.user_activity(items, self.name, jid)
items = event.getTag('items')
if items is None: return

View File

@ -34,6 +34,10 @@ class Contact:
self.groups = groups
self.show = show
self.status = status
# FIXME
self.mood = dict()
self.activity = dict()
self.tune = dict()
self.sub = sub
self.ask = ask
self.resource = resource
@ -169,8 +173,8 @@ class Contacts:
def copy_contact(self, contact):
return self.create_contact(jid = contact.jid, name = contact.name,
groups = contact.groups, show = contact.show, status = contact.status,
sub = contact.sub, ask = contact.ask, resource = contact.resource,
groups = contact.groups, show = contact.show, status =
contact.status, sub = contact.sub, ask = contact.ask, resource = contact.resource,
priority = contact.priority, keyID = contact.keyID,
our_chatstate = contact.our_chatstate, chatstate = contact.chatstate,
last_status_time = contact.last_status_time)

View File

@ -56,7 +56,7 @@ If you start gajim from svn:
interface = None # The actual interface (the gtk one for the moment)
config = config.Config()
version = config.get('version')
version = config.get('version') + 'dh'
connections = {} # 'account name': 'account (connection.Connection) instance'
verbose = False

129
src/common/pep.py Normal file
View File

@ -0,0 +1,129 @@
from common import gajim, xmpp
def user_mood(items, name, jid):
(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
contact = gajim.contacts.get_contact(name, user, resource=resource)
if not contact:
return
for item in items.getTags('item'):
child = item.getTag('mood')
if child is not None:
if contact.mood.has_key('mood'):
del contact.mood['mood']
if contact.mood.has_key('text'):
del contact.mood['text']
for ch in child.getChildren():
if ch.getName() != 'text':
contact.mood['mood'] = ch.getName()
else:
contact.mood['text'] = ch.getData()
def user_tune(items, name, jid):
(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
contact = gajim.contacts.get_contact(name, user, resource=resource)
if not contact:
return
for item in items.getTags('item'):
child = item.getTag('tune')
if child is not None:
if contact.tune.has_key('artist'):
del contact.tune['artist']
if contact.tune.has_key('title'):
del contact.tune['title']
if contact.tune.has_key('source'):
del contact.tune['source']
if contact.tune.has_key('track'):
del contact.tune['track']
if contact.tune.has_key('length'):
del contact.tune['length']
for ch in child.getChildren():
if ch.getName() == 'artist':
contact.tune['artist'] = ch.getData()
elif ch.getName() == 'title':
contact.tune['title'] = ch.getData()
elif ch.getName() == 'source':
contact.tune['source'] = ch.getData()
elif ch.getName() == 'track':
contact.tune['track'] = ch.getData()
elif ch.getName() == 'length':
contact.tune['length'] = ch.getData()
def user_geoloc(items, name, jid):
pass
def user_activity(items, name, jid):
(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
contact = gajim.contacts.get_contact(name, user, resource=resource)
if not contact:
return
for item in items.getTags('item'):
child = item.getTag('activity')
if child is not None:
if contact.activity.has_key('activity'):
del contact.activity['activity']
if contact.activity.has_key('subactivity'):
del contact.activity['subactivity']
if contact.activity.has_key('text'):
del contact.activity['text']
for ch in child.getChildren():
if ch.getName() != 'text':
contact.activity['activity'] = ch.getName()
for chi in ch.getChildren():
contact.activity['subactivity'] = chi.getName()
else:
contact.activity['text'] = ch.getData()
def user_send_mood(account, mood, message = ''):
print "Sending %s: %s" % (mood, message)
if gajim.config.get('publish_mood') == False:
return
item = xmpp.Node('mood', {'xmlns': xmpp.NS_MOOD})
if mood != '':
item.addChild(mood)
if message != '':
i = item.addChild('text')
i.addData(message)
gajim.connections[account].send_pb_publish('', xmpp.NS_MOOD, item, '0')
def user_send_activity(account, activity, subactivity = '', message = ''):
if gajim.config.get('publish_activity') == False:
return
item = xmpp.Node('activity', {'xmlns': xmpp.NS_ACTIVITY})
if activity != '':
i = item.addChild(activity)
if subactivity != '':
i.addChild(subactivity)
if message != '':
i = item.addChild('text')
i.addData(message)
gajim.connections[account].send_pb_publish('', xmpp.NS_ACTIVITY, item, '0')
def user_send_tune(account, artist = '', title = '', source = '', track = 0,length = 0, items = None):
print "Tune to be created"
if (gajim.config.get('publish_tune') == False) or \
(gajim.connections[account].pep_supported == False):
return
print "publish_tune == True and pep_supported"
item = xmpp.Node('tune', {'xmlns': xmpp.NS_TUNE})
if artist != '':
i = item.addChild('artist')
i.addData(artist)
if title != '':
i = item.addChild('title')
i.addData(title)
if source != '':
i = item.addChild('source')
i.addData(source)
if track != 0:
i = item.addChild('track')
i.addData(track)
if length != 0:
i = item.addChild('length')
i.addData(length)
if items is not None:
item.addChild(payload=items)
gajim.connections[account].send_pb_publish('', xmpp.NS_TUNE, item, '0')
print "Tune published"

View File

@ -1,5 +1,7 @@
import xmpp
import gajim
import dataforms
import connection_handlers
class ConnectionPubSub:
def __init__(self):
@ -43,9 +45,61 @@ class ConnectionPubSub:
self.connection.send(query)
def send_pb_delete(self, jid, node):
'''Deletes node.'''
query = xmpp.Iq('set', to=jid)
d = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
d = d.addChild('delete', {'node': node})
self.connection.send(query)
def send_pb_create(self, jid, node, configure = False, configure_form = None):
'''Creates new node.'''
query = xmpp.Iq('set', to=jid)
c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
c = c.addChild('create', {'node': node})
if configure:
conf = c.addChild('configure')
if configure_form is not None:
conf.addChild(node=configuration_form)
self.connection.send(query)
def send_pb_configure(self, jid, node, cb, *cbargs, **cbkwargs):
query = xmpp.Iq('set', to=jid)
c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
c = c.addChild('configure', {'node': node})
id = self.connection.send(query)
def on_configure(self, connection, query):
try:
filledform = cb(stanza['pubsub']['configure']['x'], *cbargs, **cbkwargs)
#TODO: Build a form
#TODO: Send it
except CancelConfigure:
cancel = xmpp.Iq('set', to=jid)
ca = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
ca = ca.addChild('configure', {'node': node})
#ca = ca.addChild('x', namespace=xmpp.NS_DATA, {'type': 'cancel'})
self.connection.send(cancel)
self.__callbacks[id] = (on_configure, (), {})
def _PubSubCB(self, conn, stanza):
try:
cb, args, kwargs = self.__callbacks.pop(stanza.getID())
cb(conn, stanza, *args, **kwargs)
except:
pass
def request_pb_configuration(self, jid, node):
query = xmpp.Iq('get', to=jid)
e = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB_OWNER)
e = e.addChild('configure', {'node': node})
id = self.connection.getAnID()
query.setID(id)
self.awaiting_answers[id] = (connection_handlers.PEP_ACCESS_MODEL,)
self.connection.send(query)

View File

@ -27,11 +27,14 @@ NS_AGENTS ='jabber:iq:agents'
NS_AMP ='http://jabber.org/protocol/amp'
NS_AMP_ERRORS =NS_AMP+'#errors'
NS_AUTH ='jabber:iq:auth'
NS_AVATAR ='http://www.xmpp.org/extensions/xep-0084.html#ns-metadata'
NS_BIND ='urn:ietf:params:xml:ns:xmpp-bind'
NS_BROWSE ='jabber:iq:browse'
NS_BYTESTREAM ='http://jabber.org/protocol/bytestreams' # XEP-0065
NS_CAPS ='http://jabber.org/protocol/caps' # XEP-0115
NS_CHATSTATES ='http://jabber.org/protocol/chatstates' # XEP-0085
NS_BROWSING ='http://jabber.org/protocol/browsing' # XEP-0195
NS_BYTESTREAM ='http://jabber.org/protocol/bytestreams' # JEP-0065
NS_CAPS ='http://jabber.org/protocol/caps' # JEP-0115
NS_CHATSTATES ='http://jabber.org/protocol/chatstates' # JEP-0085
NS_CHATTING ='http://jabber.org/protocol/chatting' # XEP-0194
NS_CLIENT ='jabber:client'
NS_COMMANDS ='http://jabber.org/protocol/commands'
NS_COMPONENT_ACCEPT='jabber:component:accept'
@ -48,8 +51,9 @@ NS_ENCRYPTED ='jabber:x:encrypted' # XEP-00
NS_ESESSION_INIT='http://www.xmpp.org/extensions/xep-0116.html#ns-init' # XEP-0116
NS_EVENT ='jabber:x:event' # XEP-0022
NS_FEATURE ='http://jabber.org/protocol/feature-neg'
NS_FILE ='http://jabber.org/protocol/si/profile/file-transfer' # XEP-0096
NS_GEOLOC ='http://jabber.org/protocol/geoloc' # XEP-0080
NS_FILE ='http://jabber.org/protocol/si/profile/file-transfer' # JEP-0096
NS_GAMING ='http://jabber.org/protocol/gaming' # XEP-0196
NS_GEOLOC ='http://jabber.org/protocol/geoloc' # JEP-0080
NS_GROUPCHAT ='gc-1.0'
NS_HTTP_AUTH ='http://jabber.org/protocol/http-auth' # XEP-0070
NS_HTTP_BIND ='http://jabber.org/protocol/httpbind' # XEP-0124
@ -72,6 +76,7 @@ NS_PRIVACY ='jabber:iq:privacy'
NS_PRIVATE ='jabber:iq:private'
NS_PROFILE ='http://jabber.org/protocol/profile' # XEP-0154
NS_PUBSUB ='http://jabber.org/protocol/pubsub' # XEP-0060
NS_PUBSUB_OWNER ='http://jabber.org/protocol/pubsub#owner' # JEP-0060
NS_REGISTER ='jabber:iq:register'
NS_ROSTER ='jabber:iq:roster'
NS_ROSTERX ='http://jabber.org/protocol/rosterx' # XEP-0144
@ -90,12 +95,14 @@ NS_STREAMS ='http://etherx.jabber.org/streams'
NS_TIME ='jabber:iq:time' # XEP-0900
NS_TIME_REVISED ='urn:xmpp:time' # XEP-0202
NS_TLS ='urn:ietf:params:xml:ns:xmpp-tls'
NS_TUNE ='http://jabber.org/protocol/tune' # XEP-0118
NS_VACATION ='http://jabber.org/protocol/vacation'
NS_VCARD ='vcard-temp'
NS_GMAILNOTIFY ='google:mail:notify'
NS_GTALKSETTING ='google:setting'
NS_VCARD_UPDATE =NS_VCARD+':x:update'
NS_VERSION ='jabber:iq:version'
NS_VIEWING ='http://jabber.org/protocol/viewing' # XEP--197
NS_PING ='urn:xmpp:ping' # XEP-0199
NS_WAITINGLIST ='http://jabber.org/protocol/waitinglist' # XEP-0130
NS_XHTML_IM ='http://jabber.org/protocol/xhtml-im' # XEP-0071

View File

@ -49,6 +49,7 @@ from common import passwords
from common import zeroconf
from common import dbus_support
from common import dataforms
from common import pep
from common.exceptions import GajimGeneralException
@ -458,6 +459,25 @@ class PreferencesWindow:
else:
widget.set_sensitive(False)
# PEP
st = gajim.config.get('publish_mood')
self.xml.get_widget('publish_mood_checkbutton').set_active(st)
st = gajim.config.get('publish_activity')
self.xml.get_widget('publish_activity_checkbutton').set_active(st)
st = gajim.config.get('publish_tune')
self.xml.get_widget('publish_tune_checkbutton').set_active(st)
st = gajim.config.get('subscribe_mood')
self.xml.get_widget('subscribe_mood_checkbutton').set_active(st)
st = gajim.config.get('subscribe_activity')
self.xml.get_widget('subscribe_activity_checkbutton').set_active(st)
st = gajim.config.get('subscribe_tune')
self.xml.get_widget('subscribe_tune_checkbutton').set_active(st)
# Notify user of new gmail e-mail messages,
# only show checkbox if user has a gtalk account
frame_gmail = self.xml.get_widget('frame_gmail')
@ -521,6 +541,8 @@ class PreferencesWindow:
self.theme_preferences = None
self.notebook.set_current_page(0)
if not gajim.config.get('use_pep'):
self.notebook.remove_page(5)
self.window.show_all()
gtkgui_helpers.possibly_move_window_in_current_desktop(self.window)
@ -536,6 +558,45 @@ class PreferencesWindow:
w.set_sensitive(widget.get_active())
gajim.interface.save_config()
def on_publish_mood_checkbutton_toggled(self, widget):
if widget.get_active() == False:
for account in gajim.connections:
if gajim.connections[account].pep_supported:
pep.user_send_mood(account, '')
self.on_checkbutton_toggled(widget, 'publish_mood')
def on_publish_activity_checkbutton_toggled(self, widget):
if widget.get_active() == False:
for account in gajim.connections:
if gajim.connections[account].pep_supported:
pep.user_send_activity(account, '')
self.on_checkbutton_toggled(widget, 'publish_activity')
def on_publish_tune_checkbutton_toggled(self, widget):
if widget.get_active() == False:
for account in gajim.connections:
if gajim.connections[account].pep_supported:
pep.user_send_tune(account, '')
self.on_checkbutton_toggled(widget, 'publish_tune')
gajim.interface.roster.enable_syncing_status_msg_from_current_music_track(
widget.get_active())
def on_subscribe_mood_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'subscribe_mood')
def on_subscribe_activity_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'subscribe_activity')
def on_subscribe_tune_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'subscribe_tune')
def on_save_position_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'saveposition')
def on_sort_by_show_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'sort_by_show')
gajim.interface.roster.draw_roster()
def on_show_avatars_in_roster_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'show_avatars_in_roster')
gajim.interface.roster.draw_roster()
@ -3406,3 +3467,278 @@ class AccountCreationWizardWindow:
gajim.interface.roster.draw_roster()
gajim.interface.roster.set_actions_menu_needs_rebuild()
gajim.interface.save_config()
#---------- ZeroconfPropertiesWindow class -------------#
class ZeroconfPropertiesWindow:
def __init__(self):
self.xml = gtkgui_helpers.get_glade('zeroconf_properties_window.glade')
self.window = self.xml.get_widget('zeroconf_properties_window')
self.window.set_transient_for(gajim.interface.roster.window)
self.xml.signal_autoconnect(self)
self.init_account()
self.init_account_gpg()
self.xml.get_widget('save_button').grab_focus()
self.window.show_all()
def init_account(self):
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
'autoconnect')
if st:
self.xml.get_widget('autoconnect_checkbutton').set_active(st)
list_no_log_for = gajim.config.get_per('accounts',
gajim.ZEROCONF_ACC_NAME,'no_log_for').split()
if gajim.ZEROCONF_ACC_NAME in list_no_log_for:
self.xml.get_widget('log_history_checkbutton').set_active(0)
else:
self.xml.get_widget('log_history_checkbutton').set_active(1)
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
'sync_with_global_status')
if st:
self.xml.get_widget('sync_with_global_status_checkbutton').set_active(
st)
for opt in ('first_name', 'last_name', 'jabber_id', 'email'):
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
'zeroconf_' + opt)
if st:
self.xml.get_widget(opt + '_entry').set_text(st)
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
'custom_port')
if st:
self.xml.get_widget('custom_port_entry').set_text(str(st))
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
'use_custom_host')
if st:
self.xml.get_widget('custom_port_checkbutton').set_active(st)
self.xml.get_widget('custom_port_entry').set_sensitive(bool(st))
if not st:
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
'custom_port', '5298')
def init_account_gpg(self):
keyid = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'keyid')
keyname = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
'keyname')
savegpgpass = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
'savegpgpass')
if not keyid or not gajim.config.get('usegpg'):
return
self.xml.get_widget('gpg_key_label').set_text(keyid)
self.xml.get_widget('gpg_name_label').set_text(keyname)
gpg_save_password_checkbutton = \
self.xml.get_widget('gpg_save_password_checkbutton')
gpg_save_password_checkbutton.set_sensitive(True)
gpg_save_password_checkbutton.set_active(savegpgpass)
if savegpgpass:
entry = self.xml.get_widget('gpg_password_entry')
entry.set_sensitive(True)
gpgpassword = gajim.config.get_per('accounts',
gajim.ZEROCONF_ACC_NAME, 'gpgpassword')
entry.set_text(gpgpassword)
def on_zeroconf_properties_window_destroy(self, widget):
# close window
if gajim.interface.instances.has_key('zeroconf_properties'):
del gajim.interface.instances['zeroconf_properties']
def on_custom_port_checkbutton_toggled(self, widget):
st = self.xml.get_widget('custom_port_checkbutton').get_active()
self.xml.get_widget('custom_port_entry').set_sensitive(bool(st))
def on_cancel_button_clicked(self, widget):
self.window.destroy()
def on_save_button_clicked(self, widget):
config = {}
st = self.xml.get_widget('autoconnect_checkbutton').get_active()
config['autoconnect'] = st
list_no_log_for = gajim.config.get_per('accounts',
gajim.ZEROCONF_ACC_NAME, 'no_log_for').split()
if gajim.ZEROCONF_ACC_NAME in list_no_log_for:
list_no_log_for.remove(gajim.ZEROCONF_ACC_NAME)
if not self.xml.get_widget('log_history_checkbutton').get_active():
list_no_log_for.append(gajim.ZEROCONF_ACC_NAME)
config['no_log_for'] = ' '.join(list_no_log_for)
st = self.xml.get_widget('sync_with_global_status_checkbutton').\
get_active()
config['sync_with_global_status'] = st
st = self.xml.get_widget('first_name_entry').get_text()
config['zeroconf_first_name'] = st.decode('utf-8')
st = self.xml.get_widget('last_name_entry').get_text()
config['zeroconf_last_name'] = st.decode('utf-8')
st = self.xml.get_widget('jabber_id_entry').get_text()
config['zeroconf_jabber_id'] = st.decode('utf-8')
st = self.xml.get_widget('email_entry').get_text()
config['zeroconf_email'] = st.decode('utf-8')
use_custom_port = self.xml.get_widget('custom_port_checkbutton').\
get_active()
config['use_custom_host'] = use_custom_port
old_port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
'custom_port')
if use_custom_port:
port = self.xml.get_widget('custom_port_entry').get_text()
else:
port = 5298
config['custom_port'] = port
config['keyname'] = self.xml.get_widget('gpg_name_label').get_text().\
decode('utf-8')
if config['keyname'] == '': # no key selected
config['keyid'] = ''
config['savegpgpass'] = False
config['gpgpassword'] = ''
else:
config['keyid'] = self.xml.get_widget('gpg_key_label').get_text().\
decode('utf-8')
config['savegpgpass'] = self.xml.get_widget(
'gpg_save_password_checkbutton').get_active()
config['gpgpassword'] = self.xml.get_widget('gpg_password_entry'
).get_text().decode('utf-8')
reconnect = False
for opt in ('zeroconf_first_name','zeroconf_last_name',
'zeroconf_jabber_id', 'zeroconf_email', 'custom_port'):
if gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, opt) != \
config[opt]:
reconnect = True
for opt in config:
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, opt,
config[opt])
if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
if port != old_port or reconnect:
gajim.connections[gajim.ZEROCONF_ACC_NAME].update_details()
self.window.destroy()
def on_gpg_choose_button_clicked(self, widget, data = None):
if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
secret_keys = gajim.connections[gajim.ZEROCONF_ACC_NAME].\
ask_gpg_secrete_keys()
# self.account is None and/or gajim.connections is {}
else:
from common import GnuPG
if GnuPG.USE_GPG:
secret_keys = GnuPG.GnuPG().get_secret_keys()
else:
secret_keys = []
if not secret_keys:
dialogs.ErrorDialog(_('Failed to get secret keys'),
_('There was a problem retrieving your OpenPGP secret keys.'))
return
secret_keys[_('None')] = _('None')
instance = dialogs.ChooseGPGKeyDialog(_('OpenPGP Key Selection'),
_('Choose your OpenPGP key'), secret_keys)
keyID = instance.run()
if keyID is None:
return
checkbutton = self.xml.get_widget('gpg_save_password_checkbutton')
gpg_key_label = self.xml.get_widget('gpg_key_label')
gpg_name_label = self.xml.get_widget('gpg_name_label')
if keyID[0] == _('None'):
gpg_key_label.set_text(_('No key selected'))
gpg_name_label.set_text('')
checkbutton.set_sensitive(False)
self.xml.get_widget('gpg_password_entry').set_sensitive(False)
else:
gpg_key_label.set_text(keyID[0])
gpg_name_label.set_text(keyID[1])
checkbutton.set_sensitive(True)
checkbutton.set_active(False)
self.xml.get_widget('gpg_password_entry').set_text('')
def on_gpg_save_password_checkbutton_toggled(self, widget):
st = widget.get_active()
w = self.xml.get_widget('gpg_password_entry')
w.set_sensitive(bool(st))
class ManagePEPServicesWindow:
def __init__(self, account):
self.xml = gtkgui_helpers.get_glade('manage_pep_services_window.glade')
self.window = self.xml.get_widget('manage_pep_services_window')
self.window.set_transient_for(gajim.interface.roster.window)
self.xml.signal_autoconnect(self)
self.account = account
self.init_services()
self.window.show_all()
def on_manage_pep_services_window_destroy(self, widget):
'''close window'''
del gajim.interface.instances[self.account]['pep_services']
def on_ok_button_clicked(self, widget):
pass
def on_cancel_button_clicked(self, widget):
self.window.destroy()
def cellrenderer_combo_edited(self, cellrenderer, path, new_text):
self.treestore[path][1] = new_text
def init_services(self):
treeview = self.xml.get_widget('services_treeview')
# service, access_model, group
self.treestore = gtk.ListStore(str, str, str)
treeview.set_model(self.treestore)
col = gtk.TreeViewColumn('Service')
treeview.append_column(col)
cellrenderer_text = gtk.CellRendererText()
col.pack_start(cellrenderer_text)
col.add_attribute(cellrenderer_text, 'text', 0)
col = gtk.TreeViewColumn('access model')
treeview.append_column(col)
model = gtk.ListStore(str)
model.append(['open'])
model.append(['presence'])
model.append(['roster'])
model.append(['whitelist'])
cellrenderer_combo = gtk.CellRendererCombo()
cellrenderer_combo.set_property('text-column', 0)
cellrenderer_combo.set_property('model', model)
cellrenderer_combo.set_property('has-entry', False)
cellrenderer_combo.set_property('editable', True)
cellrenderer_combo.connect('edited', self.cellrenderer_combo_edited)
col.pack_start(cellrenderer_combo)
col.add_attribute(cellrenderer_combo, 'text', 1)
our_jid = gajim.get_jid_from_account(self.account)
gajim.connections[self.account].discoverItems(our_jid)
def items_received(self, items):
our_jid = gajim.get_jid_from_account(self.account)
for item in items:
if 'jid' in item and item['jid'] == our_jid and 'node' in item:
# ask <configure> to have access model
gajim.connections[self.account].request_pb_configuration(
item['jid'], item['node'])
def new_service(self, node, model):
self.treestore.append([node, model, ''])

View File

@ -370,6 +370,125 @@ class ChooseGPGKeyDialog:
self.keys_treeview.set_cursor(path)
class ChangeActivityDialog:
activities = [_('doing_chores'), _('drinking'), _('eating'),
_('excercising'), _('grooming'), _('having_appointment'),
_('inactive'), _('relaxing'), _('talking'), _('traveling'),
_('working'), ]
subactivities = [_('at_the_spa'), _('brushing_teeth'),
_('buying_groceries'), _('cleaning'), _('coding'),
_('commuting'), _('cooking'), _('cycling'), _('day_off'),
_('doing_maintenance'), _('doing_the_dishes'),
_('doing_the_laundry'), _('driving'), _('gaming'),
_('gardening'), _('getting_a_haircut'), _('going_out'),
_('hanging_out'), _('having_a_beer'), _('having_a_snack'),
_('having_breakfast'), _('having_coffee'),
_('having_dinner'), _('having_lunch'), _('having_tea'),
_('hiking'), _('in_a_car'), _('in_a_meeting'),
_('in_real_life'), _('jogging'), _('on_a_bus'),
_('on_a_plane'), _('on_a_train'), _('on_a_trip'),
_('on_the_phone'), _('on_vacation'), _('other'),
_('partying'), _('playing_sports'), _('reading'),
_('rehearsing'), _('running'), _('running_an_errand'),
_('scheduled_holiday'), _('shaving'), _('shopping'),
_('skiing'), _('sleeping'), _('socializing'),
_('studying'), _('sunbathing'), _('swimming'),
_('taking_a_bath'), _('taking_a_shower'), _('walking'),
_('walking_the_dog'), _('watching_tv'),
_('watching_a_movie'), _('working_out'), _('writing'), ]
def __init__(self, account):
self.account = account
self.xml = gtkgui_helpers.get_glade('change_activity_dialog.glade')
self.window = self.xml.get_widget('change_activity_dialog')
self.window.set_transient_for(gajim.interface.roster.window)
self.window.set_title(_('Activity'))
self.entry = self.xml.get_widget('entry')
self.combo1 = self.xml.get_widget('combobox1')
self.liststore1 = gtk.ListStore(str)
self.combo1.set_model(self.liststore1)
for activity in self.activities:
self.liststore1.append((activity,))
cellrenderertext = gtk.CellRendererText()
self.combo1.pack_start(cellrenderertext, True)
self.combo1.add_attribute(cellrenderertext, 'text', 0)
self.combo2 = self.xml.get_widget('combobox2')
self.liststore2 = gtk.ListStore(str)
self.combo2.set_model(self.liststore2)
for subactivity in self.subactivities:
self.liststore2.append((subactivity,))
cellrenderertext = gtk.CellRendererText()
self.combo2.pack_start(cellrenderertext, True)
self.combo2.add_attribute(cellrenderertext, 'text', 0)
self.xml.signal_autoconnect(self)
self.window.show_all()
def on_ok_button_clicked(self, widget):
'''Return activity and messsage (None if no activity selected)'''
activity = None
subactivity = None
message = None
active1 = self.combo1.get_active()
active2 = self.combo2.get_active()
if active1 > -1:
activity = self.liststore1[active1][0].decode('utf-8')
if active2 > -1:
subactivity = self.liststore2[active2][0].decode('utf-8')
message = self.entry.get_text().decode('utf-8')
from common import pep
pep.user_send_activity(self.account, activity,
subactivity, message)
self.window.destroy()
def on_cancel_button_clicked(self, widget):
self.window.destroy()
class ChangeMoodDialog:
moods = [_('afraid'), _('amazed'), _('angry'), _('annoyed'), _('anxious'), _('aroused'), _('ashamed'), _('bored'), _('brave'), _('calm'), _('cold'), _('confused'), _('contented'), _('cranky'), _('curious'), _('depressed'), _('disappointed'), _('disgusted'), _('distracted'), _('embarrassed'), _('excited'), _('flirtatious'), _('frustrated'), _('grumpy'), _('guilty'), _('happy'), _('hot'), _('humbled'), _('humiliated'), _('hungry'), _('hurt'), _('impressed'), _('in_awe'), _('in_love'), _('indignant'), _('interested'), _('intoxicated'), _('invincible'), _('jealous'), _('lonely'), _('mean'), _('moody'), _('nervous'), _('neutral'), _('offended'), _('playful'), _('proud'), _('relieved'), _('remorseful'), _('restless'), _('sad'), _('sarcastic'), _('serious'), _('shocked'), _('shy'), _('sick'), _('sleepy'), _('stressed'), _('surprised'), _('thirsty'), _('worried')]
def __init__(self, account):
self.account = account
self.xml = gtkgui_helpers.get_glade('change_mood_dialog.glade')
self.window = self.xml.get_widget('change_mood_dialog')
self.window.set_transient_for(gajim.interface.roster.window)
self.window.set_title(_('Mood'))
self.entry = self.xml.get_widget('entry')
self.combo = self.xml.get_widget('combobox')
self.liststore = gtk.ListStore(str)
self.combo.set_model(self.liststore)
for mood in self.moods:
self.liststore.append((mood,))
cellrenderertext = gtk.CellRendererText()
self.combo.pack_start(cellrenderertext, True)
self.combo.add_attribute(cellrenderertext, 'text', 0)
self.xml.signal_autoconnect(self)
self.window.show_all()
def on_ok_button_clicked(self, widget):
'''Return mood and messsage (None if no mood selected)'''
mood = None
message = None
active = self.combo.get_active()
if active > -1:
mood = self.liststore[active][0].decode('utf-8')
message = self.entry.get_text().decode('utf-8')
from common import pep
pep.user_send_mood(self.account, mood, message)
self.window.destroy()
def on_cancel_button_clicked(self, widget):
self.window.destroy()
class ChangeStatusMessageDialog:
def __init__(self, show = None):
self.show = show

View File

@ -999,6 +999,11 @@ class Interface:
def handle_event_agent_info_items(self, account, array):
#('AGENT_INFO_ITEMS', account, (agent, node, items))
our_jid = gajim.get_jid_from_account(account)
if gajim.interface.instances[account].has_key('pep_services') and \
array[0] == our_jid:
gajim.interface.instances[account]['pep_services'].items_received(
array[2])
try:
gajim.connections[account].services_cache.agent_items(array[0],
array[1], array[2])
@ -2169,6 +2174,11 @@ class Interface:
_('You are already connected to this account with the same resource. Please type a new one'), input_str = gajim.connections[account].server_resource,
is_modal = False, ok_handler = on_ok)
def handle_event_pep_access_model(self, account, data):
# ('PEP_ACCESS_MODEL', account, (node, model))
if self.instances[account].has_key('pep_services'):
self.instances[account]['pep_services'].new_service(data[0], data[1])
def handle_event_unique_room_id_supported(self, account, data):
'''Receive confirmation that unique_room_id are supported'''
# ('UNIQUE_ROOM_ID_SUPPORTED', server, instance, room_id)
@ -2551,6 +2561,7 @@ class Interface:
'SEARCH_FORM': self.handle_event_search_form,
'SEARCH_RESULT': self.handle_event_search_result,
'RESOURCE_CONFLICT': self.handle_event_resource_conflict,
'PEP_ACCESS_MODEL': self.handle_event_pep_access_model,
'UNIQUE_ROOM_ID_UNSUPPORTED': \
self.handle_event_unique_room_id_unsupported,
'UNIQUE_ROOM_ID_SUPPORTED': self.handle_event_unique_room_id_supported,

View File

@ -931,7 +931,11 @@ class RosterWindow:
service_disco_menuitem = self.xml.get_widget('service_disco_menuitem')
advanced_menuitem = self.xml.get_widget('advanced_menuitem')
profile_avatar_menuitem = self.xml.get_widget('profile_avatar_menuitem')
pep_services_menuitem = self.xml.get_widget('pep_services_menuitem')
if not gajim.config.get('use_pep'):
pep_services_menuitem.set_no_show_all(True)
pep_services_menuitem.hide()
# destroy old advanced menus
for m in self.advanced_menus:
m.destroy()
@ -954,6 +958,11 @@ class RosterWindow:
self.new_chat_menuitem_handler_id)
self.new_chat_menuitem_handler_id = None
if self.pep_services_menuitem_handler_id:
pep_services_menuitem.handler_disconnect(
self.pep_services_menuitem_handler_id)
self.pep_services_menuitem_handler_id = None
if self.single_message_menuitem_handler_id:
single_message_menuitem.handler_disconnect(
self.single_message_menuitem_handler_id)
@ -964,7 +973,6 @@ class RosterWindow:
self.profile_avatar_menuitem_handler_id)
self.profile_avatar_menuitem_handler_id = None
# remove the existing submenus
add_new_contact_menuitem.remove_submenu()
service_disco_menuitem.remove_submenu()
@ -973,6 +981,7 @@ class RosterWindow:
new_chat_menuitem.remove_submenu()
advanced_menuitem.remove_submenu()
profile_avatar_menuitem.remove_submenu()
pep_services_menuitem.remove_submenu()
# remove the existing accelerator
if self.have_new_chat_accel:
@ -1131,7 +1140,21 @@ class RosterWindow:
if len(connected_accounts_with_vcard) > 1:
# 2 or more accounts? make submenus
profile_avatar_sub_menu = gtk.Menu()
pep_services_sub_menu = gtk.Menu()
for account in connected_accounts_with_vcard:
if gajim.connections[account].pep_supported:
# profile, avatar
profile_avatar_item = gtk.MenuItem(_('of account %s') % account,
False)
profile_avatar_sub_menu.append(profile_avatar_item)
profile_avatar_item.connect('activate',
self.on_profile_avatar_menuitem_activate, account)
# PEP services
pep_services_item = gtk.MenuItem(_('of account %s') % account,
False)
pep_services_sub_menu.append(pep_services_item)
pep_services_item.connect('activate',
self.on_pep_services_menuitem_activate, account)
# profile, avatar
profile_avatar_item = gtk.MenuItem(_('of account %s') % account,
False)
@ -1140,18 +1163,27 @@ class RosterWindow:
self.on_profile_avatar_menuitem_activate, account)
profile_avatar_menuitem.set_submenu(profile_avatar_sub_menu)
profile_avatar_sub_menu.show_all()
pep_services_menuitem.set_submenu(pep_services_sub_menu)
pep_services_sub_menu.show_all()
elif len(connected_accounts_with_vcard) == 1: # user has only one account
account = connected_accounts_with_vcard[0]
# profile, avatar
if not self.profile_avatar_menuitem_handler_id:
self.profile_avatar_menuitem_handler_id = \
profile_avatar_menuitem.connect('activate', self.\
on_profile_avatar_menuitem_activate, account)
profile_avatar_menuitem.connect('activate',
self.on_profile_avatar_menuitem_activate, account)
# PEP services
if not self.pep_services_menuitem_handler_id:
self.pep_services_menuitem_handler_id = \
pep_services_menuitem.connect('activate',
self.on_pep_services_menuitem_activate, account)
if len(connected_accounts_with_vcard) == 0:
profile_avatar_menuitem.set_sensitive(False)
pep_services_menuitem.set_sensitive(False)
else:
profile_avatar_menuitem.set_sensitive(True)
pep_services_menuitem.set_sensitive(True)
# Advanced Actions
if len(gajim.connections) == 0: # user has no accounts
@ -2945,6 +2977,12 @@ class RosterWindow:
if url:
helpers.launch_browser_mailer('url', url)
def on_change_activity_activate(self, widget, account):
dlg = dialogs.ChangeActivityDialog(account)
def on_change_mood_activate(self, widget, account):
dlg = dialogs.ChangeMoodDialog(account)
def on_change_status_message_activate(self, widget, account):
show = gajim.SHOW_LIST[gajim.connections[account].connected]
dlg = dialogs.ChangeStatusMessageDialog(show)
@ -3010,6 +3048,23 @@ class RosterWindow:
sub_menu.append(item)
item.connect('activate', self.change_status, account, 'offline')
pep_menuitem = xml.get_widget('pep_menuitem')
if gajim.connections[account].pep_supported and gajim.config.get('use_pep'):
pep_submenu = gtk.Menu()
pep_menuitem.set_submenu(pep_submenu)
if gajim.config.get('publish_mood'):
item = gtk.MenuItem('Mood')
pep_submenu.append(item)
item.connect('activate', self.on_change_mood_activate, account)
if gajim.config.get('publish_activity'):
item = gtk.MenuItem('Activity')
pep_submenu.append(item)
item.connect('activate', self.on_change_activity_activate,
account)
else:
pep_menuitem.set_no_show_all(True)
pep_menuitem.hide()
if not gajim.connections[account].gmail_url:
open_gmail_inbox_menuitem.set_no_show_all(True)
open_gmail_inbox_menuitem.hide()
@ -3038,8 +3093,7 @@ class RosterWindow:
# make some items insensitive if account is offline
if gajim.connections[account].connected < 2:
for widget in [add_contact_menuitem, service_discovery_menuitem,
join_group_chat_menuitem,
execute_command_menuitem,
join_group_chat_menuitem, execute_command_menuitem, pep_menuitem,
start_chat_menuitem]:
widget.set_sensitive(False)
else:
@ -3663,14 +3717,14 @@ class RosterWindow:
listener = MusicTrackListener.get()
self._music_track_changed_signal = listener.connect(
'music-track-changed', self._music_track_changed)
track = listener.get_playing_track()
self._music_track_changed(listener, track)
track = listener.get_playing_track()
self._music_track_changed(listener, track)
else:
if self._music_track_changed_signal is not None:
listener = MusicTrackListener.get()
listener.disconnect(self._music_track_changed_signal)
self._music_track_changed_signal = None
self._music_track_changed(None, None)
self._music_track_changed(None, None)
## enable setting status msg from a Last.fm account
def enable_syncing_status_msg_from_lastfm(self, enabled):
@ -3718,7 +3772,43 @@ class RosterWindow:
except Exception, e:
pass
def _music_track_changed(self, unused_listener, music_track_info):
def _music_track_changed(self, unused_listener, music_track_info,
account=''):
if gajim.config.get('use_pep'):
from common import pep
if account == '':
accounts = gajim.connections.keys()
if music_track_info is None:
artist = ''
title = ''
source = ''
track = ''
length = ''
elif hasattr(music_track_info, 'paused') and \
music_track_info.paused == 0:
artist = ''
title = ''
source = ''
track = ''
length = ''
else:
artist = music_track_info.artist
title = music_track_info.title
source = music_track_info.album
if account == '':
print "Multi accounts"
for account in accounts:
if not gajim.config.get_per('accounts', account,
'sync_with_global_status'):
continue
if not gajim.connections[account].pep_supported:
continue
pep.user_send_tune(account, artist, title, source)
else:
print "Single account"
pep.user_send_tune(account, artist, title, source)
return
# No PEP
accounts = gajim.connections.keys()
if music_track_info is None:
status_message = ''
@ -4002,6 +4092,13 @@ class RosterWindow:
else:
gajim.interface.instances['preferences'] = config.PreferencesWindow()
def on_pep_services_menuitem_activate(self, widget, account):
if gajim.interface.instances[account].has_key('pep_services'):
gajim.interface.instances[account]['pep_services'].window.present()
else:
gajim.interface.instances[account]['pep_services'] = \
config.ManagePEPServicesWindow(account)
def on_add_new_contact(self, widget, account):
dialogs.AddNewContactWindow(account)
@ -5249,6 +5346,7 @@ class RosterWindow:
self.new_chat_menuitem_handler_id = False
self.single_message_menuitem_handler_id = False
self.profile_avatar_menuitem_handler_id = False
self.pep_services_menuitem_handler_id = False
self.actions_menu_needs_rebuild = True
self.regroup = gajim.config.get('mergeaccounts')
self.clicked_path = None # Used remember on wich row we clicked
@ -5414,18 +5512,20 @@ class RosterWindow:
self.tooltip = tooltips.RosterTooltip()
self.draw_roster()
## Music Track notifications
## FIXME: we use a timeout because changing status of
## accounts has no effect until they are connected.
st = gajim.config.get('set_status_msg_from_current_music_track')
if st:
gobject.timeout_add(1000,
self.enable_syncing_status_msg_from_current_music_track,
st)
if gajim.config.get('use_pep'):
self.enable_syncing_status_msg_from_current_music_track(gajim.config.get('publish_tune'))
else:
gobject.timeout_add(1000,
self.enable_syncing_status_msg_from_lastfm,
gajim.config.get('set_status_msg_from_lastfm'))
## Music Track notifications
## FIXME: we use a timeout because changing status of
## accounts has no effect until they are connected.
st = gajim.config.get('set_status_msg_from_current_music_track')
if st:
gobject.timeout_add(1000,
self.enable_syncing_status_msg_from_current_music_track, st)
else:
gobject.timeout_add(1000,
self.enable_syncing_status_msg_from_lastfm,
gajim.config.get('set_status_msg_from_lastfm'))
if gajim.config.get('show_roster_on_startup'):
self.window.show_all()

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
## tooltips.py
##
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov@gmail.com>
@ -463,6 +464,10 @@ class RosterTooltip(NotificationAreaTooltip):
contact.last_status_time)
properties.append((self.table, None))
else: # only one resource
#FIXME: User {Mood, Activity, Tune} not shown if there are
#multiple resources
#FIXME: User {Mood, Activity, Tune} not shown for self
if contact.show:
show = helpers.get_uf_show(contact.show)
if contact.last_status_time:
@ -494,6 +499,42 @@ class RosterTooltip(NotificationAreaTooltip):
show = '<i>' + show + '</i>'
# we append show below
if contact.mood.has_key('mood'):
mood_string = 'Mood: <b>%s</b>' % contact.mood['mood'].strip()
if contact.mood.has_key('text') and contact.mood['text'] != '':
mood_string += ' (%s)' % contact.mood['text'].strip()
properties.append((mood_string, None))
if contact.activity.has_key('activity'):
activity = contact.activity['activity'].strip()
activity_string = 'Activity: <b>%s' % activity
if contact.activity.has_key('subactivity'):
activity_sub = contact.activity['subactivity'].strip()
activity_string += ' (%s)</b>' % activity_sub
else:
activity_string += '</b>'
if contact.activity.has_key('text'):
activity_text = contact.activity['text'].strip()
activity_string += ' (%s)' % activity_text
properties.append((activity_string, None))
if contact.tune.has_key('artist') or contact.tune.has_key('title'):
if contact.tune.has_key('artist'):
artist = contact.tune['artist'].strip()
else:
artist = _('Unknown Artist')
if contact.tune.has_key('title'):
title = contact.tune['title'].strip()
else:
title = _('Unknown Title')
if contact.tune.has_key('source'):
source = contact.tune['source'].strip()
else:
source = _('Unknown Source')
tune_string = '' + _('<b>"%(title)s"</b> by <i>%(artist)s</i>\nfrom <i>%(source)s</i>' %\
{'title': title, 'artist': artist, 'source': source}) + ''
properties.append((tune_string, None))
if contact.status:
status = contact.status.strip()
if status: