merge from trunk

This commit is contained in:
Dimitur Kirov 2006-09-26 15:57:47 +00:00
parent d4663922c7
commit 5fc8cf20f3
37 changed files with 2791 additions and 1129 deletions

View File

@ -1,14 +1,38 @@
Gajim 0.11 (XX October 2006)
* Put your stuff here [each dev put their own please; next time we do this everytime we commit sth major and not in the end]
* We can now operate on more than one contact in one in time in roster (#1514)
* Connection lost is now a non-intrusive popup
* Try to get contact desired nick when we add him to roster aka User Nickname (JEP-0172)
* Better design of User Profile window, with a progress bar
* New Add User dialog, with possibility to register to transport directly from it
* Completion for "Start Chat" input dialog
* We can now have a different spellchecking language in each chat window. (#2383 and #746)
* Support for Privacy Lists
* Forbid to run multiple instances (but you can use differents profiles)
* We can save avatar with right click on avatar in chat banner
* Use differents colors for nickname colors of occupants in groupchats.
* Ability to show only Join/Leave in groupchats instead of all status changes
* New possibilities to insert nickname of an occupant in groupchats conversations : Tab in an empty line now cycle through nicks, maj+right click->insert nickname, maj+click on name in gc-roster, /names command to show all users presents
* Fixed bugs when removing or renaming an account with tabs open (#2369 and #2370)
* FIXME : Ad-Hoc for 0.11 ?
* FIXME : does that work ? not tested : Metacontacts across accounts (#1596)
* Gajim now requires Python 2.4 to run
Gajim 0.10.1 (06 June 2006)
* freeze and lost contacts in roster (#1953)
* popup menus are correctly placed
* high CPU usage on FreeBSD (#1963)
* nickname can contain '|' (#1913)
* update pl, cs, fr translations
* don't play sound, when no event is shown (#1970)
* set gajim icon for history manager
* Freeze and lost contacts in roster (#1953)
* Popup menus are correctly placed
* High CPU usage on FreeBSD (#1963)
* Nickname can contain '|' (#1913)
* Update pl, cs, fr translations
* Don't play sound, when no event is shown (#1970)
* Set gajim icon for history manager
* gajim.desktop is generated with translation (#834)
* preventing several TBs and annoyances (r6273, r6275, r6279, r6301,
* Preventing several TBs and annoyances (r6273, r6275, r6279, r6301,
r6308, r6311, r6323, r6326, r6327, r6335, r6342, r6346, r6348)
Gajim 0.10 (01 May 2006)

16
README
View File

@ -1,10 +1,10 @@
Welcome and thanks for trying out Gajim.
=RUNTIME REQUIREMENTS=
python2.4 (python2.3 should work too)
python2.4 or higher
pygtk2.6 or higher
python-libglade
pysqlite2 (aka. python-pysqlite2)
pysqlite2 (if you have python 2.5, you already have this)
some distros also split too much python standard library.
I know SUSE does. In such distros you also need python-xml
@ -29,7 +29,8 @@ notification-daemon (and D-Bus) to get cooler popups
D-Bus to have gajim-remote working
NOTE TO PACKAGERS:
Gajim is a GTK+ app and not a gnome one. Just do 'make' so you don't require gnomepythonextras
Gajim is a GTK+ app and not a gnome one.
Just do 'make' so you don't require gnomepythonextras
which is gnome dep
=INSTALLATION PROCEDURE=
@ -65,9 +66,6 @@ you're advised to enable verbose via advanced configuration window.
If you don't want to make this permanent, execute gajim with --verbose
everytime you want to have verbose output.
Cannot join room with password:
please read the FAQ for the reply on this issue
=FAQ/Wiki=
FAQ can be found at http://trac.gajim.org/wiki/GajimFaq
Wiki can be found at http://trac.gajim.org/wiki
@ -75,13 +73,13 @@ Wiki can be found at http://trac.gajim.org/wiki
That is all, enjoy!
(C) 2003-2005
(C) 2003-2006
The Gajim Team
http://gajim.org
PS.
we use original art and parts of sounds and other art from Psi, Gossip,
We use original art and parts of sounds and other art from Psi, Gossip,
Gnomebaker, Gaim and some icons from various gnome-icons
(mostly Dropline Etiquette) we found at art.gnome.org
If you think we're violating a license please inform us
If you think we're violating a license please inform us. Thank you

View File

@ -554,52 +554,6 @@ Banner</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label388">
<property name="visible">True</property>
<property name="label" translatable="yes">Active</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkColorButton" id="active_colorbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="use_alpha">False</property>
<property name="focus_on_click">True</property>
<signal name="color_set" handler="on_active_colorbutton_color_set" last_modification_time="Sat, 18 Mar 2006 22:34:13 GMT"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label393">
<property name="visible">True</property>

View File

@ -374,7 +374,7 @@ Status message</property>
<child>
<widget class="GtkImage" id="image1338">
<property name="visible">True</property>
<property name="stock">gtk-preferences</property>
<property name="stock">gtk-execute</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
@ -916,7 +916,7 @@ topic</property>
<child>
<widget class="GtkImage" id="image1344">
<property name="visible">True</property>
<property name="stock">gtk-preferences</property>
<property name="stock">gtk-execute</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>

View File

@ -819,7 +819,7 @@ Per type</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">before_time_entry</property>
<property name="mnemonic_widget">scrolledwindow25</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
@ -848,7 +848,7 @@ Per type</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">after_nickname_entry</property>
<property name="mnemonic_widget">scrolledwindow28</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
@ -998,7 +998,7 @@ Per type</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">after_time_entry</property>
<property name="mnemonic_widget">scrolledwindow26</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
@ -1027,7 +1027,7 @@ Per type</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">before_nickname_entry</property>
<property name="mnemonic_widget">scrolledwindow27</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
@ -1043,54 +1043,6 @@ Per type</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="after_time_entry">
<property name="width_request">39</property>
<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>
<signal name="focus_out_event" handler="on_after_time_entry_focus_out_event" last_modification_time="Fri, 01 Apr 2005 15:57:17 GMT"/>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="after_nickname_entry">
<property name="width_request">40</property>
<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>
<signal name="focus_out_event" handler="on_after_nickname_entry_focus_out_event" last_modification_time="Fri, 01 Apr 2005 15:58:07 GMT"/>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkColorButton" id="incoming_msg_colorbutton">
<property name="visible">True</property>
@ -1132,54 +1084,6 @@ Per type</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="before_nickname_entry">
<property name="width_request">40</property>
<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>
<signal name="focus_out_event" handler="on_before_nickname_entry_focus_out_event" last_modification_time="Fri, 01 Apr 2005 15:57:44 GMT"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="before_time_entry">
<property name="width_request">40</property>
<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>
<signal name="focus_out_event" handler="on_before_time_entry_focus_out_event" last_modification_time="Fri, 01 Apr 2005 15:54:51 GMT"/>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox3022">
<property name="visible">True</property>
@ -1298,6 +1202,170 @@ Per type</property>
<property name="x_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow26">
<property name="height_request">30</property>
<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_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="after_time_textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_CHAR</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
<signal name="focus_out_event" handler="on_after_time_textview_focus_out_event" last_modification_time="Wed, 20 Sep 2006 19:52:22 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow28">
<property name="height_request">30</property>
<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_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="after_nickname_textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_CHAR</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
<signal name="focus_out_event" handler="on_after_nickname_textview_focus_out_event" last_modification_time="Wed, 20 Sep 2006 19:52:51 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow27">
<property name="height_request">30</property>
<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_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="before_nickname_textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_CHAR</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
<signal name="focus_out_event" handler="on_before_nickname_textview_focus_out_event" last_modification_time="Wed, 20 Sep 2006 19:52:05 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow25">
<property name="height_request">30</property>
<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_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="before_time_textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_CHAR</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
<signal name="focus_out_event" handler="on_before_time_textview_focus_out_event" last_modification_time="Wed, 20 Sep 2006 18:21:39 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
@ -2543,6 +2611,26 @@ Disabled</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="set_status_msg_from_current_music_track_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Set status message to reflect currently playing _music track</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="set_status_msg_from_current_music_track_checkbutton_toggled" last_modification_time="Fri, 22 Sep 2006 18:13:39 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="eventbox6">
<property name="visible">True</property>

View File

@ -0,0 +1,779 @@
<?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="privacy_list_edit_window">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="title" translatable="yes">Privacy List</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">False</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_privacy_list_edit_window_destroy" last_modification_time="Sun, 02 Jul 2006 22:34:41 GMT"/>
<child>
<widget class="GtkVBox" id="main_vbox">
<property name="width_request">600</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHBox" id="title_hbox">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="privacy_lists_title_label">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;i&gt;Privacy List&lt;/i&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="privacy_list_active_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Active for this session</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_privacy_list_active_checkbutton_toggled" last_modification_time="Sat, 01 Jul 2006 13:09:51 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="privacy_list_default_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Active on each startup</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_privacy_list_default_checkbutton_toggled" last_modification_time="Sat, 01 Jul 2006 13:10:00 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="title_hseparator">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="list_of_rules_label">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;List of rules&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="list_of_rules_combobox">
<property name="visible">True</property>
<property name="items" translatable="yes"></property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
<signal name="changed" handler="on_list_of_rules_combobox_changed" last_modification_time="Mon, 03 Jul 2006 20:44:19 GMT"/>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="delete_open_buttons_hbox">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="new_rule_button">
<property name="border_width">5</property>
<property name="visible">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>
<signal name="clicked" handler="on_new_rule_button_clicked" last_modification_time="Sat, 01 Jul 2006 13:09:03 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="delete_rule_button">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-remove</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_delete_rule_button_clicked" last_modification_time="Sat, 01 Jul 2006 13:08:57 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="open_rule_button">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-edit</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_open_rule_button_clicked" last_modification_time="Sat, 01 Jul 2006 13:08:50 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="add_edit_vbox">
<property name="border_width">5</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHSeparator" id="edit_between_list_edit_hseparator">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="add_edit_rule_label">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Add / Edit a rule&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="edit_fields_hbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkVBox" id="edit_allow_deny_vbox">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkRadioButton" id="edit_allow_radiobutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Allow</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="edit_deny_radiobutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Deny</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<property name="group">edit_allow_radiobutton</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="edit_type_vbox">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHBox" id="edit_type_jabberid_hbox">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkRadioButton" id="edit_type_jabberid_radiobutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">JabberID</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="edit_type_jabberid_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">5</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="edit_type_group_hbox">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkRadioButton" id="edit_type_group_radiobutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">all in the group</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<property name="group">edit_type_jabberid_radiobutton</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="edit_type_group_combobox">
<property name="visible">True</property>
<property name="items" translatable="yes"></property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="edit_type_subscription_hbox">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkRadioButton" id="edit_type_subscription_radiobutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">all by subscription</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<property name="group">edit_type_jabberid_radiobutton</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="edit_type_subscription_combobox">
<property name="visible">True</property>
<property name="items" translatable="yes">none
both
from
to</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="edit_type_select_all_hbox">
<property name="border_width">10</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkRadioButton" id="edit_type_select_all_radiobutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">All</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<property name="group">edit_type_jabberid_radiobutton</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="edit_items_vbox">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkCheckButton" id="edit_send_messages_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">to send me messages</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="edit_queries_send_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">to send me queries</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="edit_send_status_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">to view my status</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="edit_view_status_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">to send me status</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="edit_order_new_save_buttons_hbox">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHBox" id="edit_order_hbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="edit_order_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Order:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkSpinButton" id="edit_order_spinbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="climb_rate">1</property>
<property name="digits">0</property>
<property name="numeric">False</property>
<property name="update_policy">GTK_UPDATE_ALWAYS</property>
<property name="snap_to_ticks">False</property>
<property name="wrap">False</property>
<property name="adjustment">1 0 100 1 10 10</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="save_rule_button">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-save</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_save_rule_button_clicked" last_modification_time="Sat, 01 Jul 2006 13:08:40 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="edit_last_buttons_separator">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="last_buttons_hbox">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="privacy_list_refresh_button">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-refresh</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_privacy_list_refresh_button_clicked" last_modification_time="Sat, 01 Jul 2006 13:09:35 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="privacy_list_close_button">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_privacy_list_close_button_clicked" last_modification_time="Sat, 01 Jul 2006 13:09:28 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -0,0 +1,255 @@
<?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="privacy_lists_first_window">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="title" translatable="yes">window1</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</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_privacy_lists_first_window_destroy" last_modification_time="Sun, 02 Jul 2006 20:56:21 GMT"/>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="Server-based_privacy_lists_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Server-based Privacy Lists</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">5</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</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="list_of_privacy_lists_combobox">
<property name="border_width">4</property>
<property name="visible">True</property>
<property name="items" translatable="yes"></property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="buttons_hbox">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="delete_privacy_list_button">
<property name="border_width">5</property>
<property name="visible">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>
<signal name="clicked" handler="on_delete_privacy_list_button_clicked" last_modification_time="Sun, 02 Jul 2006 16:47:54 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="open_privacy_list_button">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-open</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_open_privacy_list_button_clicked" last_modification_time="Sun, 02 Jul 2006 16:47:34 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator1">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="create_privacy_list_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Create your own Privacy Lists</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">5</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</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="new_privacy_list_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">4</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="new_privacy_list_button">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-new</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_new_privacy_list_button_clicked" last_modification_time="Sun, 02 Jul 2006 16:47:16 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator2">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">5</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="homogeneous">True</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="privacy_lists_refresh_button">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-refresh</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_privacy_lists_refresh_button_clicked" last_modification_time="Sun, 02 Jul 2006 16:46:48 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="close_privacy_lists_window_button">
<property name="border_width">5</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_close_button_clicked" last_modification_time="Sun, 02 Jul 2006 20:53:03 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</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

@ -4,7 +4,6 @@
<glade-interface>
<widget class="GtkWindow" id="profile_window">
<property name="border_width">12</property>
<property name="title">Personal Information</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
@ -29,6 +28,7 @@
<child>
<widget class="GtkNotebook" id="information_notebook">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="show_tabs">True</property>
<property name="show_border">True</property>
@ -1016,7 +1016,7 @@
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="left_attach">1</property>
<property name="right_attach">4</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
@ -1024,6 +1024,34 @@
<property name="y_options">expand</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label58">
<property name="visible">True</property>
<property name="label" translatable="yes">Avatar:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
@ -1800,159 +1828,201 @@
</child>
<child>
<widget class="GtkHButtonBox" id="information_hbuttonbox">
<widget class="GtkHBox" id="hbox2">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="spacing">12</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="publish_button">
<widget class="GtkProgressBar" id="progressbar">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_publish_button_clicked"/>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-go-up</property>
<property name="icon_size">4</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">_Publish</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
<property name="fraction">0</property>
<property name="pulse_step">0.10000000149</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="retrieve_button">
<widget class="GtkHButtonBox" id="information_hbuttonbox">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_retrieve_button_clicked"/>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="spacing">12</property>
<child>
<widget class="GtkAlignment" id="alignment2">
<widget class="GtkButton" id="publish_button">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_publish_button_clicked"/>
<child>
<widget class="GtkHBox" id="hbox2">
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkImage" id="image2">
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="stock">gtk-go-down</property>
<property name="icon_size">4</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">_Retrieve</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-go-up</property>
<property name="icon_size">4</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">_Publish</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkButton" id="retrieve_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_retrieve_button_clicked"/>
<child>
<widget class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="stock">gtk-go-down</property>
<property name="icon_size">4</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">_Retrieve</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</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>
</child>
<child>
<widget class="GtkButton" id="close_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_close_button_clicked" last_modification_time="Mon, 25 Sep 2006 04:58:43 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
@ -1961,6 +2031,18 @@
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkStatusbar" id="statusbar">
<property name="visible">True</property>
<property name="has_resize_grip">False</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>

View File

@ -1,328 +1,413 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!-- Generated with glade3
Version: 3.0.0
Date: Fri Aug 18 19:07:58 2006
User: kirov
Host: kirov
-->
<?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="roster_window">
<property name="width_request">85</property>
<property name="height_request">200</property>
<property name="title">Gajim</property>
<property name="role">roster</property>
<property name="default_width">150</property>
<property name="default_height">400</property>
<signal name="focus_out_event" handler="on_roster_window_focus_out_event"/>
<signal name="focus_in_event" handler="on_roster_window_focus_in_event"/>
<signal name="key_press_event" handler="on_roster_window_key_press_event"/>
<signal name="delete_event" handler="on_roster_window_delete_event"/>
<child>
<widget class="GtkVBox" id="roster_vbox">
<property name="visible">True</property>
<child>
<widget class="GtkMenuBar" id="menubar">
<property name="visible">True</property>
<child>
<widget class="GtkMenuItem" id="actions_menu">
<property name="visible">True</property>
<property name="label">_Actions</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_actions_menuitem_activate"/>
<child>
<widget class="GtkMenu" id="actions_menu_menu">
<child>
<widget class="GtkImageMenuItem" id="new_chat_menuitem">
<property name="visible">True</property>
<property name="label">_Start Chat</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1444">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-jump-to</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="join_gc_menuitem">
<property name="visible">True</property>
<property name="label">_Group Chat</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1445">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-connect</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="add_new_contact_menuitem">
<property name="visible">True</property>
<property name="label">Add _Contact</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1446">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-add</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="service_disco_menuitem">
<property name="visible">True</property>
<property name="label">_Discover Services</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1447">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-find</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="advanced_menuitem">
<property name="visible">True</property>
<property name="label">_Advanced</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="show_offline_contacts_menuitem">
<property name="visible">True</property>
<property name="label">Show _Offline Contacts</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_show_offline_contacts_menuitem_activate"/>
<accelerator key="O" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator1">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="quit_menuitem">
<property name="visible">True</property>
<property name="label">_Quit</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_quit_menuitem_activate"/>
<accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1448">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-quit</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="edit_menu">
<property name="visible">True</property>
<property name="label">_Edit</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_edit_menuitem_activate"/>
<child>
<widget class="GtkMenu" id="edit_menu_menu">
<child>
<widget class="GtkImageMenuItem" id="accounts_menuitem">
<property name="visible">True</property>
<property name="label">A_ccounts</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_accounts_menuitem_activate"/>
<accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1449">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-network</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="file_transfers_menuitem">
<property name="visible">True</property>
<property name="label">File _Transfers</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_file_transfers_menuitem_activate"/>
<accelerator key="T" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1450">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="profile_avatar_menuitem">
<property name="visible">True</property>
<property name="label">Profile, Avatar</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1305">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-properties</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator2">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="preferences_menuitem">
<property name="visible">True</property>
<property name="label">_Preferences</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_preferences_menuitem_activate"/>
<accelerator key="P" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1451">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-preferences</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="help_menu">
<property name="visible">True</property>
<property name="label">_Help</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="help_menu_menu">
<child>
<widget class="GtkImageMenuItem" id="contents_menuitem">
<property name="visible">True</property>
<property name="tooltip">Help online</property>
<property name="label">_Contents</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_contents_menuitem_activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1452">
<property name="visible">True</property>
<property name="xalign">0,000000</property>
<property name="yalign">0,000000</property>
<property name="stock">gtk-help</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="faq_menuitem">
<property name="visible">True</property>
<property name="tooltip">Frequently Asked Questions (online)</property>
<property name="label">_FAQ</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_faq_menuitem_activate"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="about_menuitem">
<property name="visible">True</property>
<property name="label">gtk-about</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_about_menuitem_activate"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">2</property>
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<child>
<widget class="GtkTreeView" id="roster_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="reorderable">True</property>
<signal name="leave_notify_event" handler="on_roster_treeview_leave_notify_event"/>
<signal name="button_press_event" handler="on_roster_treeview_button_press_event"/>
<signal name="motion_notify_event" handler="on_roster_treeview_motion_notify_event"/>
<signal name="row_collapsed" handler="on_roster_treeview_row_collapsed"/>
<signal name="row_expanded" handler="on_roster_treeview_row_expanded"/>
<signal name="key_press_event" handler="on_roster_treeview_key_press_event"/>
<signal name="row_activated" handler="on_roster_treeview_row_activated"/>
<signal name="scroll_event" handler="on_roster_treeview_scroll_event"/>
<signal name="style_set" handler="on_roster_treeview_style_set"/>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="status_combobox">
<property name="visible">True</property>
<signal name="changed" handler="on_status_combobox_changed"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkWindow" id="roster_window">
<property name="width_request">85</property>
<property name="height_request">200</property>
<property name="title" translatable="yes">Gajim</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">150</property>
<property name="default_height">400</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="role">roster</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="delete_event" handler="on_roster_window_delete_event" last_modification_time="Mon, 21 Mar 2005 12:34:59 GMT"/>
<signal name="focus_in_event" handler="on_roster_window_focus_in_event" last_modification_time="Sun, 04 Sep 2005 16:33:35 GMT"/>
<signal name="key_press_event" handler="on_roster_window_key_press_event" last_modification_time="Tue, 20 Sep 2005 19:26:27 GMT"/>
<signal name="focus_out_event" handler="on_roster_window_focus_out_event" last_modification_time="Tue, 08 Nov 2005 14:01:01 GMT"/>
<child>
<widget class="GtkVBox" id="roster_vbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkMenuBar" id="menubar">
<property name="visible">True</property>
<property name="pack_direction">GTK_PACK_DIRECTION_LTR</property>
<property name="child_pack_direction">GTK_PACK_DIRECTION_LTR</property>
<child>
<widget class="GtkMenuItem" id="actions_menu">
<property name="visible">True</property>
<property name="label" translatable="yes">_Actions</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_actions_menuitem_activate" last_modification_time="Sun, 19 Feb 2006 17:10:56 GMT"/>
<child>
<widget class="GtkMenu" id="actions_menu_menu">
<child>
<widget class="GtkImageMenuItem" id="new_chat_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">_Start Chat</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1444">
<property name="visible">True</property>
<property name="stock">gtk-jump-to</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="join_gc_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">_Group Chat</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1445">
<property name="visible">True</property>
<property name="stock">gtk-connect</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="add_new_contact_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">Add _Contact</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1446">
<property name="visible">True</property>
<property name="stock">gtk-add</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="service_disco_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">_Discover Services</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1447">
<property name="visible">True</property>
<property name="stock">gtk-find</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="advanced_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">_Advanced</property>
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="show_offline_contacts_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">Show _Offline Contacts</property>
<property name="use_underline">True</property>
<property name="active">False</property>
<signal name="activate" handler="on_show_offline_contacts_menuitem_activate" last_modification_time="Tue, 01 Mar 2005 23:29:52 GMT"/>
<accelerator key="O" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator1">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="quit_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">_Quit</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_quit_menuitem_activate" last_modification_time="Tue, 01 Mar 2005 23:37:49 GMT"/>
<accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1448">
<property name="visible">True</property>
<property name="stock">gtk-quit</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="edit_menu">
<property name="visible">True</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_edit_menuitem_activate" last_modification_time="Fri, 07 Apr 2006 22:46:56 GMT"/>
<child>
<widget class="GtkMenu" id="edit_menu_menu">
<child>
<widget class="GtkImageMenuItem" id="accounts_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">A_ccounts</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_accounts_menuitem_activate" last_modification_time="Tue, 01 Mar 2005 23:23:19 GMT"/>
<accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1449">
<property name="visible">True</property>
<property name="stock">gtk-network</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="file_transfers_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">File _Transfers</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_file_transfers_menuitem_activate" last_modification_time="Wed, 03 Aug 2005 15:44:28 GMT"/>
<accelerator key="T" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1450">
<property name="visible">True</property>
<property name="stock">gtk-file</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="profile_avatar_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">Profile, Avatar</property>
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1305">
<property name="visible">True</property>
<property name="stock">gtk-properties</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separator2">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="preferences_menuitem">
<property name="visible">True</property>
<property name="label" translatable="yes">_Preferences</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_preferences_menuitem_activate" last_modification_time="Tue, 01 Mar 2005 22:58:18 GMT"/>
<accelerator key="P" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1451">
<property name="visible">True</property>
<property name="stock">gtk-preferences</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="help_menu">
<property name="visible">True</property>
<property name="label" translatable="yes">_Help</property>
<property name="use_underline">True</property>
<child>
<widget class="GtkMenu" id="help_menu_menu">
<child>
<widget class="GtkImageMenuItem" id="contents_menuitem">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Help online</property>
<property name="label" translatable="yes">_Contents</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_contents_menuitem_activate" last_modification_time="Thu, 06 Oct 2005 23:29:10 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image1452">
<property name="visible">True</property>
<property name="stock">gtk-help</property>
<property name="icon_size">1</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="faq_menuitem">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Frequently Asked Questions (online)</property>
<property name="label" translatable="yes">_FAQ</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_faq_menuitem_activate" last_modification_time="Thu, 06 Oct 2005 23:29:10 GMT"/>
</widget>
</child>
<child>
<widget class="GtkImageMenuItem" id="about_menuitem">
<property name="visible">True</property>
<property name="label">gtk-about</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_about_menuitem_activate" last_modification_time="Tue, 01 Mar 2005 22:56:45 GMT"/>
</widget>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow">
<property name="border_width">2</property>
<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_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="roster_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="reorderable">True</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>
<signal name="button_press_event" handler="on_roster_treeview_button_press_event" last_modification_time="Mon, 28 Feb 2005 14:16:44 GMT"/>
<signal name="row_activated" handler="on_roster_treeview_row_activated" last_modification_time="Mon, 28 Feb 2005 14:18:06 GMT"/>
<signal name="row_expanded" handler="on_roster_treeview_row_expanded" last_modification_time="Mon, 28 Feb 2005 14:18:14 GMT"/>
<signal name="row_collapsed" handler="on_roster_treeview_row_collapsed" last_modification_time="Mon, 28 Feb 2005 14:18:33 GMT"/>
<signal name="key_press_event" handler="on_roster_treeview_key_press_event" last_modification_time="Sat, 26 Mar 2005 20:39:36 GMT"/>
<signal name="motion_notify_event" handler="on_roster_treeview_motion_notify_event" last_modification_time="Wed, 06 Jul 2005 14:38:58 GMT"/>
<signal name="leave_notify_event" handler="on_roster_treeview_leave_notify_event" last_modification_time="Wed, 06 Jul 2005 14:39:06 GMT"/>
<signal name="scroll_event" handler="on_roster_treeview_scroll_event" last_modification_time="Fri, 08 Jul 2005 22:09:03 GMT"/>
<signal name="style_set" handler="on_roster_treeview_style_set" last_modification_time="Tue, 08 Nov 2005 14:03:30 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="status_combobox">
<property name="visible">True</property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
<signal name="changed" handler="on_status_combobox_changed" last_modification_time="Sat, 05 Nov 2005 18:07:49 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -2,6 +2,7 @@
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkMenu" id="systray_context_menu">
<child>
@ -11,7 +12,7 @@
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1371">
<widget class="GtkImage" id="image1455">
<property name="visible">True</property>
<property name="stock">gtk-network</property>
<property name="icon_size">1</property>
@ -31,7 +32,7 @@
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1372">
<widget class="GtkImage" id="image1456">
<property name="visible">True</property>
<property name="stock">gtk-jump-to</property>
<property name="icon_size">1</property>
@ -51,7 +52,7 @@
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1445">
<widget class="GtkImage" id="image1457">
<property name="visible">True</property>
<property name="stock">gtk-connect</property>
<property name="icon_size">1</property>
@ -71,7 +72,7 @@
<property name="use_underline">True</property>
<child internal-child="image">
<widget class="GtkImage" id="image1373">
<widget class="GtkImage" id="image1458">
<property name="visible">True</property>
<property name="stock">gtk-new</property>
<property name="icon_size">1</property>
@ -107,7 +108,7 @@
<signal name="activate" handler="on_show_roster_menuitem_activate" last_modification_time="Sat, 29 Oct 2005 23:55:24 GMT"/>
<child internal-child="image">
<widget class="GtkImage" id="image1374">
<widget class="GtkImage" id="image1459">
<property name="visible">True</property>
<property name="stock">gtk-home</property>
<property name="icon_size">1</property>
@ -144,4 +145,5 @@
</widget>
</child>
</widget>
</glade-interface>

View File

@ -652,7 +652,7 @@
</child>
<child>
<widget class="GtkTable" id="table2">
<widget class="GtkTable" id="personal_info_table">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="n_rows">6</property>
@ -1640,34 +1640,6 @@
</packing>
</child>
<child>
<widget class="GtkLabel" id="URL_label">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">5</property>
<property name="ypad">5</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="TEL_HOME_NUMBER_label">
<property name="visible">True</property>
@ -2581,6 +2553,60 @@
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkProgressBar" id="progressbar">
<property name="visible">True</property>
<property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
<property name="fraction">0</property>
<property name="pulse_step">0.10000000149</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="close_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_close_button_clicked" last_modification_time="Mon, 25 Sep 2006 05:08:55 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>

View File

@ -1334,7 +1334,7 @@ msgstr "W każdej _wiadomości"
#: ../data/glade/preferences_window.glade.h:58
msgid "One message _window:"
msgstr "Wyślij wiadomość i _zamknij okno"
msgstr "Grupuj okna:"
#: ../data/glade/preferences_window.glade.h:59
msgid "Play _sounds"

View File

@ -196,7 +196,6 @@ class ChatControlBase(MessageControl):
self.msg_textview.lang = lang
spell.set_language(lang)
except (gobject.GError, RuntimeError), msg:
#FIXME: add a ui for this use spell.set_language()
dialogs.ErrorDialog(unicode(msg), _('If that is not your language '
'for which you want to highlight misspelled words, then please '
'set your $LANG as appropriate. Eg. for French do export '
@ -1018,7 +1017,7 @@ class ChatControl(ChatControlBase):
acct_info = ''
self.account_displayed = False
for ctrl in self.parent_win.controls():
if ctrl == self:
if ctrl == self or ctrl.type_id == 'gc':
continue
if self.contact.get_shown_name() == ctrl.contact.get_shown_name()\
and not avoid_showing_account_too:
@ -1276,9 +1275,6 @@ class ChatControl(ChatControlBase):
elif chatstate == 'paused':
color = gajim.config.get_per('themes', theme,
'state_paused_color')
else:
color = gajim.config.get_per('themes', theme,
'state_active_color')
if color:
# We set the color for when it's the current tab or not
color = gtk.gdk.colormap_get_system().alloc_color(color)
@ -1287,6 +1283,9 @@ class ChatControl(ChatControlBase):
if chatstate in ('inactive', 'gone') and\
self.parent_win.get_active_control() != self:
color = self.lighten_color(color)
elif chatstate == 'active' : # active, get color from gtk
color = self.parent_win.notebook.style.fg[gtk.STATE_ACTIVE]
name = self.contact.get_shown_name()
if self.resource:

View File

@ -37,6 +37,8 @@ opt_bool = [ 'boolean', 0 ]
opt_color = [ 'color', '^(#[0-9a-fA-F]{6})|()$' ]
opt_one_window_types = ['never', 'always', 'peracct', 'pertype']
DEFAULT_ICONSET = 'dcraven'
class Config:
__options = {
@ -67,7 +69,7 @@ class Config:
'last_status_msg_invisible': [ opt_str, '' ],
'last_status_msg_offline': [ opt_str, '' ],
'trayicon': [ opt_bool, True, '', True ],
'iconset': [ opt_str, 'dcraven', '', True ],
'iconset': [ opt_str, DEFAULT_ICONSET, '', True ],
'use_transports_iconsets': [ opt_bool, True, '', True ],
'inmsgcolor': [ opt_color, '#a34526', '', True ],
'outmsgcolor': [ opt_color, '#164e6f', '', True ],
@ -126,6 +128,7 @@ class Config:
'before_nickname': [ opt_str, '' ],
'after_nickname': [ opt_str, ':' ],
'send_os_info': [ opt_bool, True ],
'set_status_msg_from_current_music_track': [ opt_bool, False ],
'notify_on_new_gmail_email': [ opt_bool, True ],
'notify_on_new_gmail_email_extra': [ opt_bool, False ],
'usegpg': [ opt_bool, False, '', True ],
@ -188,7 +191,7 @@ class Config:
'restored_messages_color': [opt_str, 'grey'],
'restored_messages_small': [opt_bool, True, _('If True, restored messages will use a smaller font than the default one.')],
'hide_avatar_of_transport': [opt_bool, False, _('Don\'t show avatar for the transport itself.')],
'roster_window_skip_taskbar': [opt_bool, False],
'roster_window_skip_taskbar': [opt_bool, False, _('Don\'t show roster in the system taskbar.')],
'use_urgency_hint': [opt_bool, True, _('If True and installed GTK+ and PyGTK versions are at least 2.8, make the window flash (the default behaviour in most Window Managers) when holding pending events.')],
'notification_timeout': [opt_int, 5],
'send_sha_in_gc_presence': [opt_bool, True, _('Jabberd1.4 does not like sha info when one join a password protected room. Turn this option to False to stop sending sha info in group chat presences.')],
@ -290,8 +293,6 @@ class Config:
'bannerfontattrs': [ opt_str, 'B', '', True ],
# http://www.pitt.edu/~nisg/cis/web/cgi/rgb.html
# FIXME: not black but the default color from gtk+ theme
'state_active_color': [ opt_color, 'black' ],
'state_inactive_color': [ opt_color, 'grey62' ],
'state_composing_color': [ opt_color, 'green4' ],
'state_paused_color': [ opt_color, 'mediumblue' ],

View File

@ -175,7 +175,7 @@ class ConnectionBytestream:
except socket.gaierror:
self.dispatch('ERROR', (_('Wrong host'), _('The host you configured as the ft_override_host_to_send advanced option is not valid, so ignored.')))
ft_override_host_to_send = self.peerhost[0]
listener = gajim.socks5queue.start_listener(self.peerhost[0], port,
listener = gajim.socks5queue.start_listener(port,
sha_str, self._result_socks5_sid, file_props['sid'])
if listener == None:
file_props['error'] = -5
@ -1134,6 +1134,12 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco)
raise common.xmpp.NodeProcessed
def _ErrorCB(self, con, iq_obj):
gajim.log.debug('ErrorCB')
if iq_obj.getQueryNS() == common.xmpp.NS_VERSION:
who = helpers.get_full_jid_from_iq(iq_obj)
jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who)
self.dispatch('OS_INFO', (jid_stripped, resource, '', ''))
return
errmsg = iq_obj.getErrorMsg()
errcode = iq_obj.getErrorCode()
jid_from = helpers.get_full_jid_from_iq(iq_obj)

View File

@ -290,6 +290,21 @@ def get_uf_role(role, plural = False):
else:
role_name = _('Visitor')
return role_name
def get_uf_affiliation(affiliation):
'''Get a nice and translated affilition for muc'''
if affiliation == 'none':
affiliation_name = Q_('?Group Chat Contact Affiliation:None')
elif affiliation == 'owner':
affiliation_name = _('Owner')
elif affiliation == 'admin':
affiliation_name = _('Administrator')
elif affiliation == 'member':
affiliation_name = _('Member')
else: # Argl ! An unknown affiliation !
affiliation_name = affiliation.capitalize()
return affiliation_name
def get_sorted_keys(adict):
keys = adict.keys()

View File

@ -74,13 +74,13 @@ class SocksQueue:
self.on_success = None
self.on_failure = None
def start_listener(self, host, port, sha_str, sha_handler, sid):
def start_listener(self, port, sha_str, sha_handler, sid):
''' start waiting for incomming connections on (host, port)
and do a socks5 authentication using sid for generated sha
'''
self.sha_handlers[sha_str] = (sha_handler, sid)
if self.listener == None:
self.listener = Socks5Listener(self.idlequeue, host, port)
self.listener = Socks5Listener(self.idlequeue, port)
self.listener.queue = self
self.listener.bind()
if self.listener.started is False:
@ -790,12 +790,12 @@ class Socks5Sender(Socks5, IdleObject):
self.queue.remove_sender(self.queue_idx, False)
class Socks5Listener(IdleObject):
def __init__(self, idlequeue, host, port):
''' handle all incomming connections on (host, port)
def __init__(self, idlequeue, port):
''' handle all incomming connections on (0.0.0.0, port)
This class implements IdleObject, but we will expect
only pollin events though
'''
self.host, self.port = host, port
self.port = port
self.queue_idx = -1
self.idlequeue = idlequeue
self.queue = None

View File

@ -19,7 +19,7 @@ Protocol module contains tools that is needed for processing of
xmpp-related data structures.
"""
from simplexml import Node,ustr
from simplexml import Node,NodeBuilder,ustr
import time
NS_ACTIVITY ='http://jabber.org/protocol/activity' # JEP-0108
NS_ADDRESS ='http://jabber.org/protocol/address' # JEP-0033
@ -94,6 +94,7 @@ NS_VCARD_UPDATE =NS_VCARD+':x:update'
NS_VERSION ='jabber:iq:version'
NS_WAITINGLIST ='http://jabber.org/protocol/waitinglist' # JEP-0130
NS_XHTML_IM ='http://jabber.org/protocol/xhtml-im' # JEP-0071
NS_XHTML = 'http://www.w3.org/1999/xhtml' # "
NS_DATA_LAYOUT ='http://jabber.org/protocol/xdata-layout' # JEP-0141
NS_DATA_VALIDATE='http://jabber.org/protocol/xdata-validate' # JEP-0122
NS_XMPP_STREAMS ='urn:ietf:params:xml:ns:xmpp-streams'
@ -385,16 +386,21 @@ class Protocol(Node):
class Message(Protocol):
""" XMPP Message stanza - "push" mechanism."""
def __init__(self, to=None, body=None, typ=None, subject=None, attrs={}, frm=None, payload=[], timestamp=None, xmlns=NS_CLIENT, node=None):
def __init__(self, to=None, body=None, xhtml=None, typ=None, subject=None, attrs={}, frm=None, payload=[], timestamp=None, xmlns=NS_CLIENT, node=None):
""" Create message object. You can specify recipient, text of message, type of message
any additional attributes, sender of the message, any additional payload (f.e. jabber:x:delay element) and namespace in one go.
Alternatively you can pass in the other XML object as the 'node' parameted to replicate it as message. """
Protocol.__init__(self, 'message', to=to, typ=typ, attrs=attrs, frm=frm, payload=payload, timestamp=timestamp, xmlns=xmlns, node=node)
if body: self.setBody(body)
if xhtml: self.setXHTML(xhtml)
if subject: self.setSubject(subject)
def getBody(self):
""" Returns text of the message. """
return self.getTagData('body')
def getXHTML(self):
""" Returns serialized xhtml-im body text of the message. """
xhtml = self.getTag('html')
return str(xhtml.getTag('body'))
def getSubject(self):
""" Returns subject of the message. """
return self.getTagData('subject')
@ -404,6 +410,11 @@ class Message(Protocol):
def setBody(self,val):
""" Sets the text of the message. """
self.setTagData('body',val)
def setXHTML(self,val):
""" Sets the xhtml text of the message (JEP-0071).
The parameter is the "inner html" to the body."""
dom = NodeBuilder(val)
self.setTag('html',namespace=NS_XHTML_IM).setTag('body',namespace=NS_XHTML).addChild(node=dom.getDom())
def setSubject(self,val):
""" Sets the subject of the message. """
self.setTagData('subject',val)

View File

@ -1,7 +1,7 @@
## config.py
##
## Copyright (C) 2003-2006 Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <nkour@jabber.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem@gmail.com>
## Copyright (C) 2005 Dimitur Kirov <dkirov@gmail.com>
## Copyright (C) 2003-2005 Vincent Hanquez <tab@snarc.org>
##
@ -182,7 +182,7 @@ class PreferencesWindow:
theme = config_theme.replace('_', ' ')
model.append([theme])
if gajim.config.get('roster_theme') == config_theme:
theme_combobox.set_active(i)
theme_combobox.set_active(i)
i += 1
self.on_theme_combobox_changed(theme_combobox)
@ -212,19 +212,23 @@ class PreferencesWindow:
#before time
st = gajim.config.get('before_time')
self.xml.get_widget('before_time_entry').set_text(st)
st = helpers.from_one_line(st)
self.xml.get_widget('before_time_textview').get_buffer().set_text(st)
#after time
st = gajim.config.get('after_time')
self.xml.get_widget('after_time_entry').set_text(st)
st = helpers.from_one_line(st)
self.xml.get_widget('after_time_textview').get_buffer().set_text(st)
#before nickname
st = gajim.config.get('before_nickname')
self.xml.get_widget('before_nickname_entry').set_text(st)
st = helpers.from_one_line(st)
self.xml.get_widget('before_nickname_textview').get_buffer().set_text(st)
#after nickanme
st = gajim.config.get('after_nickname')
self.xml.get_widget('after_nickname_entry').set_text(st)
st = helpers.from_one_line(st)
self.xml.get_widget('after_nickname_textview').get_buffer().set_text(st)
#Color for incomming messages
colSt = gajim.config.get('inmsgcolor')
@ -455,12 +459,18 @@ class PreferencesWindow:
# send os info
st = gajim.config.get('send_os_info')
self.xml.get_widget('send_os_info_checkbutton').set_active(st)
# set status msg from currently playing music track
st = gajim.config.get('set_status_msg_from_current_music_track')
self.xml.get_widget(
'set_status_msg_from_current_music_track_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')
notify_gmail_checkbutton = self.xml.get_widget('notify_gmail_checkbutton')
notify_gmail_extra_checkbutton = self.xml.get_widget('notify_gmail_extra_checkbutton')
notify_gmail_extra_checkbutton = self.xml.get_widget(
'notify_gmail_extra_checkbutton')
frame_gmail.set_no_show_all(True)
for account in gajim.config.get_per('accounts'):
@ -512,6 +522,8 @@ class PreferencesWindow:
gajim.interface.systray.change_status(show)
else:
gajim.config.set('trayicon', False)
if not gajim.interface.roster.window.get_property('visible'):
gajim.interface.roster.window.present()
gajim.interface.hide_systray()
gajim.config.set('show_roster_on_startup', True) # no tray, show roster!
gajim.interface.roster.draw_roster()
@ -523,7 +535,7 @@ class PreferencesWindow:
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_status_msgs_in_roster_checkbutton_toggled(self, widget):
self.on_checkbutton_toggled(widget, 'show_status_msgs_in_roster')
gajim.interface.roster.draw_roster()
@ -643,9 +655,9 @@ class PreferencesWindow:
def _set_sensitivity_for_before_after_time_widgets(self, sensitive):
self.xml.get_widget('before_time_label').set_sensitive(sensitive)
self.xml.get_widget('before_time_entry').set_sensitive(sensitive)
self.xml.get_widget('before_time_textview').set_sensitive(sensitive)
self.xml.get_widget('after_time_label').set_sensitive(sensitive)
self.xml.get_widget('after_time_entry').set_sensitive(sensitive)
self.xml.get_widget('after_time_textview').set_sensitive(sensitive)
def on_time_never_radiobutton_toggled(self, widget):
if widget.get_active():
@ -665,20 +677,33 @@ class PreferencesWindow:
self._set_sensitivity_for_before_after_time_widgets(True)
gajim.interface.save_config()
def on_before_time_entry_focus_out_event(self, widget, event):
gajim.config.set('before_time', widget.get_text().decode('utf-8'))
def _get_textview_text(self, tv):
buffer = tv.get_buffer()
begin, end = buffer.get_bounds()
return buffer.get_text(begin, end).decode('utf-8')
def on_before_time_textview_focus_out_event(self, widget, event):
text = self._get_textview_text(widget)
text = helpers.to_one_line(text)
gajim.config.set('before_time', text)
gajim.interface.save_config()
def on_after_time_entry_focus_out_event(self, widget, event):
gajim.config.set('after_time', widget.get_text().decode('utf-8'))
def on_after_time_textview_focus_out_event(self, widget, event):
text = self._get_textview_text(widget)
text = helpers.to_one_line(text)
gajim.config.set('after_time', text)
gajim.interface.save_config()
def on_before_nickname_entry_focus_out_event(self, widget, event):
gajim.config.set('before_nickname', widget.get_text().decode('utf-8'))
def on_before_nickname_textview_focus_out_event(self, widget, event):
text = self._get_textview_text(widget)
text = helpers.to_one_line(text)
gajim.config.set('before_nickname', text)
gajim.interface.save_config()
def on_after_nickname_entry_focus_out_event(self, widget, event):
gajim.config.set('after_nickname', widget.get_text().decode('utf-8'))
def on_after_nickname_textview_focus_out_event(self, widget, event):
text = self._get_textview_text(widget)
text = helpers.to_one_line(text)
gajim.config.set('after_nickname', text)
gajim.interface.save_config()
def update_text_tags(self):
@ -1064,6 +1089,13 @@ class PreferencesWindow:
gajim.interface.instances['advanced_config'] = \
dialogs.AdvancedConfigurationWindow()
def set_status_msg_from_current_music_track_checkbutton_toggled(self,
widget):
self.on_checkbutton_toggled(widget,
'set_status_msg_from_current_music_track')
gajim.interface.roster.enable_syncing_status_msg_from_current_music_track(
widget.get_active())
#---------- AccountModificationWindow class -------------#
class AccountModificationWindow:
'''Class for account informations'''
@ -1097,11 +1129,12 @@ class AccountModificationWindow:
'''set or unset sensitivity of widgets when widget is toggled'''
for w in widgets:
w.set_sensitive(widget.get_active())
def init_account_gpg(self):
keyid = gajim.config.get_per('accounts', self.account, 'keyid')
keyname = gajim.config.get_per('accounts', self.account, 'keyname')
savegpgpass = gajim.config.get_per('accounts', self.account,'savegpgpass')
savegpgpass = gajim.config.get_per('accounts', self.account,
'savegpgpass')
if not keyid or not gajim.config.get('usegpg'):
return
@ -1358,8 +1391,7 @@ class AccountModificationWindow:
gajim.events.change_account_name(self.account, name)
# change account variable for chat / gc controls
for ctrl in gajim.interface.msg_win_mgr.get_controls():
ctrl.account = name
gajim.interface.msg_win_mgr.change_account_name(self.account, name)
# upgrade account variable in opened windows
for kind in ('infos', 'disco', 'gc_config'):
for j in gajim.interface.instances[name][kind]:
@ -1857,6 +1889,7 @@ class AccountsWindow:
else:
gajim.interface.roster.regroup = False
gajim.interface.roster.draw_roster()
def on_enable_zeroconf_checkbutton_toggled(self, widget):
if gajim.config.get('enable_zeroconf'):
@ -2987,9 +3020,6 @@ _('You can set advanced account options by pressing Advanced button, or later by
con = connection.Connection(self.account)
con.password = password
if not savepass:
password = ""
config = {}
config['name'] = login
config['hostname'] = server
@ -3018,6 +3048,10 @@ _('You can set advanced account options by pressing Advanced button, or later by
def create_vars(self, config):
gajim.config.add_per('accounts', self.account)
if not config['savepass']:
config['password'] = ''
for opt in config:
gajim.config.set_per('accounts', self.account, opt, config[opt])

View File

@ -138,6 +138,9 @@ class ConversationTextview:
self.focus_out_end_iter_offset = None
self.line_tooltip = tooltips.BaseTooltip()
path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'muc_separator.png')
self.focus_out_line_pixbuf = gtk.gdk.pixbuf_new_from_file(path_to_file)
def del_handlers(self):
for i in self.handlers.keys():
@ -230,19 +233,14 @@ class ConversationTextview:
end_iter_for_previous_line)
# add the new focus out line
# FIXME: Why is this loaded from disk everytime
path_to_file = os.path.join(gajim.DATA_DIR, 'pixmaps', 'muc_separator.png')
focus_out_line_pixbuf = gtk.gdk.pixbuf_new_from_file(path_to_file)
end_iter = buffer.get_end_iter()
buffer.insert(end_iter, '\n')
buffer.insert_pixbuf(end_iter, focus_out_line_pixbuf)
buffer.insert_pixbuf(end_iter, self.focus_out_line_pixbuf)
end_iter = buffer.get_end_iter()
before_img_iter = end_iter.copy()
before_img_iter.backward_char() # one char back (an image also takes one char)
buffer.apply_tag_by_name('focus-out-line', before_img_iter, end_iter)
#FIXME: remove this workaround when bug is fixed
# c http://bugzilla.gnome.org/show_bug.cgi?id=318569
self.allow_focus_out_line = False
@ -562,6 +560,7 @@ class ConversationTextview:
img.show()
#add with possible animation
self.tv.add_child_at_anchor(img, anchor)
#FIXME: one day, somehow sync with regexp in gajim.py
elif special_text.startswith('http://') or \
special_text.startswith('www.') or \
special_text.startswith('ftp://') or \
@ -664,7 +663,9 @@ class ConversationTextview:
current_print_time = gajim.config.get('print_time')
if current_print_time == 'always' and kind != 'info':
before_str = gajim.config.get('before_time')
before_str = helpers.from_one_line(before_str)
after_str = gajim.config.get('after_time')
after_str = helpers.from_one_line(after_str)
# get difference in days since epoch (86400 = 24*3600)
# number of days since epoch for current time (in GMT) -
# number of days since epoch for message (in GMT)
@ -748,7 +749,9 @@ class ConversationTextview:
name_tags = other_tags_for_name[:] # create a new list
name_tags.append(kind)
before_str = gajim.config.get('before_nickname')
before_str = helpers.from_one_line(before_str)
after_str = gajim.config.get('after_nickname')
after_str = helpers.from_one_line(after_str)
format = before_str + name + after_str + ' '
buffer.insert_with_tags_by_name(end_iter, format, *name_tags)

View File

@ -23,25 +23,17 @@ from common import exceptions
try:
import dbus
version = getattr(dbus, 'version', (0, 20, 0))
supported = True
import dbus.service
import dbus.glib
supported = True # does use have D-Bus bindings?
except ImportError:
version = (0, 0, 0)
supported = False
if not os.name == 'nt': # only say that to non Windows users
print _('D-Bus python bindings are missing in this computer')
print _('D-Bus capabilities of Gajim cannot be used')
# dbus 0.23 leads to segfault with threads_init()
if sys.version[:4] >= '2.4' and version[1] < 30:
supported = False
if version >= (0, 41, 0):
import dbus.service
import dbus.glib # cause dbus 0.35+ doesn't return signal replies without it
class SessionBus:
'''A Singleton for the DBus SessionBus'''
'''A Singleton for the D-Bus SessionBus'''
def __init__(self):
self.session_bus = None

View File

@ -837,27 +837,31 @@ class FileChooserDialog(gtk.FileChooserDialog):
self.set_current_folder(current_folder)
else:
self.set_current_folder(helpers.get_documents_path())
buttons = self.action_area.get_children()
possible_responses = {gtk.STOCK_OPEN: on_response_ok,
gtk.STOCK_SAVE: on_response_ok,
gtk.STOCK_CANCEL: on_response_cancel}
for b in buttons:
for response in possible_responses:
if b.get_label() == response:
if not possible_responses[response]:
b.connect('clicked', self.just_destroy)
elif isinstance(possible_responses[response], tuple):
if len(possible_responses[response]) == 1:
b.connect('clicked', possible_responses[response][0])
else:
b.connect('clicked', *possible_responses[response])
else:
b.connect('clicked', possible_responses[response])
break
self.response_ok, self.response_cancel = \
on_response_ok, on_response_cancel
# in gtk+-2.10 clicked signal on some of the buttons in a dialog
# is emitted twice, so we cannot rely on 'clicked' signal
self.connect('response', self.on_dialog_response)
self.show_all()
def on_dialog_response(self, dialog, response):
if response in (gtk.RESPONSE_CANCEL, gtk.RESPONSE_CLOSE):
if self.response_cancel:
if isinstance(self.response_cancel, tuple):
self.response_cancel[0](dialog, *self.response_cancel[1:])
else:
self.response_cancel(dialog)
else:
self.just_destroy(dialog)
elif response == gtk.RESPONSE_OK:
if self.response_ok:
if isinstance(self.response_ok, tuple):
self.response_ok[0](dialog, *self.response_ok[1:])
else:
self.response_ok(dialog)
else:
self.just_destroy(dialog)
def just_destroy(self, widget):
self.destroy()
@ -1192,7 +1196,7 @@ class NewChatDialog(InputDialog):
title = _('Start Chat with account %s') % account
else:
title = _('Start Chat')
prompt_text = _('Fill in the jid, or nick of the contact you would like\nto send a chat message to:')
prompt_text = _('Fill in the nickname or the Jabber ID of the contact you would like\nto send a chat message to:')
InputDialog.__init__(self, title, prompt_text, is_modal = False)
self.completion_dict = {}
@ -1725,10 +1729,13 @@ class XMLConsoleWindow:
self.input_textview.grab_focus()
class PrivacyListWindow:
def __init__(self, account, privacy_list, list_type):
'''list_type can be 0 if list is created or 1 if it id edited'''
'''Window that is used for creating NEW or EDITING already there privacy
lists'''
def __init__(self, account, privacy_list_name, action):
'''action is 'edit' or 'new' depending on if we create a new priv list
or edit an already existing one'''
self.account = account
self.privacy_list = privacy_list
self.privacy_list_name = privacy_list_name
# Dicts and Default Values
self.active_rule = ''
@ -1740,7 +1747,7 @@ class PrivacyListWindow:
self.allow_deny = 'allow'
# Connect to glade
self.xml = gtkgui_helpers.get_glade('privacy_list_edit_window.glade')
self.xml = gtkgui_helpers.get_glade('privacy_list_window.glade')
self.window = self.xml.get_widget('privacy_list_edit_window')
# Add Widgets
@ -1762,10 +1769,10 @@ class PrivacyListWindow:
'privacy_list_default_checkbutton']:
self.__dict__[widget_to_add] = self.xml.get_widget(widget_to_add)
# Send translations
self.privacy_lists_title_label.set_label(
_('Privacy List <b><i>%s</i></b>') % \
gtkgui_helpers.escape_for_pango_markup(self.privacy_list))
gtkgui_helpers.escape_for_pango_markup(self.privacy_list_name))
if len(gajim.connections) > 1:
title = _('Privacy List for %s') % self.account
@ -1777,8 +1784,7 @@ class PrivacyListWindow:
self.privacy_list_active_checkbutton.set_sensitive(False)
self.privacy_list_default_checkbutton.set_sensitive(False)
# Check if list is created (0) or edited (1)
if list_type == 1:
if action == 'edit':
self.refresh_rules()
count = 0
@ -1799,16 +1805,16 @@ class PrivacyListWindow:
def on_privacy_list_edit_window_destroy(self, widget):
'''close window'''
if gajim.interface.instances[self.account].has_key('privacy_list_%s' % \
self.privacy_list):
self.privacy_list_name):
del gajim.interface.instances[self.account]['privacy_list_%s' % \
self.privacy_list]
self.privacy_list_name]
def check_active_default(self, a_d_dict):
if a_d_dict['active'] == self.privacy_list:
if a_d_dict['active'] == self.privacy_list_name:
self.privacy_list_active_checkbutton.set_active(True)
else:
self.privacy_list_active_checkbutton.set_active(False)
if a_d_dict['default'] == self.privacy_list:
if a_d_dict['default'] == self.privacy_list_name:
self.privacy_list_default_checkbutton.set_active(True)
else:
self.privacy_list_default_checkbutton.set_active(False)
@ -1845,7 +1851,7 @@ class PrivacyListWindow:
gajim.connections[self.account].get_active_default_lists()
def refresh_rules(self):
gajim.connections[self.account].get_privacy_list(self.privacy_list)
gajim.connections[self.account].get_privacy_list(self.privacy_list_name)
def on_delete_rule_button_clicked(self, widget):
tags = []
@ -1854,7 +1860,7 @@ class PrivacyListWindow:
self.list_of_rules_combobox.get_active_text().decode('utf-8'):
tags.append(self.global_rules[rule])
gajim.connections[self.account].set_privacy_list(
self.privacy_list, tags)
self.privacy_list_name, tags)
self.privacy_list_received(tags)
self.add_edit_vbox.hide()
@ -1918,13 +1924,13 @@ class PrivacyListWindow:
def on_privacy_list_active_checkbutton_toggled(self, widget):
if widget.get_active():
gajim.connections[self.account].set_active_list(self.privacy_list)
gajim.connections[self.account].set_active_list(self.privacy_list_name)
else:
gajim.connections[self.account].set_active_list(None)
def on_privacy_list_default_checkbutton_toggled(self, widget):
if widget.get_active():
gajim.connections[self.account].set_default_list(self.privacy_list)
gajim.connections[self.account].set_default_list(self.privacy_list_name)
else:
gajim.connections[self.account].set_default_list(None)
@ -1994,7 +2000,7 @@ class PrivacyListWindow:
else:
tags.append(current_tags)
gajim.connections[self.account].set_privacy_list(self.privacy_list, tags)
gajim.connections[self.account].set_privacy_list(self.privacy_list_name, tags)
self.privacy_list_received(tags)
self.add_edit_vbox.hide()
@ -2019,7 +2025,9 @@ class PrivacyListWindow:
self.add_edit_vbox.hide()
class PrivacyListsWindow:
# To do: UTF-8 ???????
'''Window that is the main window for Privacy Lists;
we can list there the privacy lists and ask to create a new one
or edit an already there one'''
def __init__(self, account):
self.account = account
@ -2027,7 +2035,7 @@ class PrivacyListsWindow:
self.privacy_lists_save = []
self.xml = gtkgui_helpers.get_glade('privacy_lists_first_window.glade')
self.xml = gtkgui_helpers.get_glade('privacy_lists_window.glade')
self.window = self.xml.get_widget('privacy_lists_first_window')
for widget_to_add in ['list_of_privacy_lists_combobox',
@ -2087,7 +2095,7 @@ class PrivacyListsWindow:
self.list_of_privacy_lists_combobox.get_active()]
gajim.connections[self.account].del_privacy_list(active_list)
self.privacy_lists_save.remove(active_list)
self.privacy_lists_received({'lists':self.privacy_lists_save})
self.privacy_lists_received({'lists': self.privacy_lists_save})
def privacy_lists_received(self, lists):
if not lists:
@ -2107,7 +2115,7 @@ class PrivacyListsWindow:
window.present()
else:
gajim.interface.instances[self.account]['privacy_list_%s' % name] = \
PrivacyListWindow(self.account, name, 0)
PrivacyListWindow(self.account, name, 'new')
self.new_privacy_list_entry.set_text('')
def on_privacy_lists_refresh_button_clicked(self, widget):
@ -2122,7 +2130,7 @@ class PrivacyListsWindow:
window.present()
else:
gajim.interface.instances[self.account]['privacy_list_%s' % name] = \
PrivacyListWindow(self.account, name, 1)
PrivacyListWindow(self.account, name, 'edit')
class InvitationReceivedDialog:
def __init__(self, account, room_jid, contact_jid, password = None, comment = None):
@ -2291,6 +2299,18 @@ class ImageChooserDialog(FileChooserDialog):
return
widget.get_preview_widget().set_from_pixbuf(pixbuf)
class AvatarChooserDialog(ImageChooserDialog):
def __init__(self, path_to_file = '', on_response_ok = None,
on_response_cancel = None, on_response_clear = None):
ImageChooserDialog.__init__(self, path_to_file, on_response_ok,
on_response_cancel)
button = gtk.Button(None, gtk.STOCK_CLEAR)
if on_response_clear:
button.connect('clicked', on_response_clear)
button.show_all()
self.action_area.pack_start(button)
self.action_area.reorder_child(button, 0)
class AddSpecialNotificationDialog:
def __init__(self, jid):
'''jid is the jid for which we want to add special notification

View File

@ -36,10 +36,10 @@
# - def update_actions(self)
# - def default_action(self)
# - def _find_item(self, jid, node)
# - def _add_item(self, model, jid, node, item, force)
# - def _update_item(self, model, iter, jid, node, item)
# - def _update_info(self, model, iter, jid, node, identities, features, data)
# - def _update_error(self, model, iter, jid, node)
# - def _add_item(self, jid, node, item, force)
# - def _update_item(self, iter, jid, node, item)
# - def _update_info(self, iter, jid, node, identities, features, data)
# - def _update_error(self, iter, jid, node)
#
# * Should call the super class for this method.
# All others do not have to call back to the super class. (but can if they want
@ -215,8 +215,8 @@ class ServicesCache:
ServiceCache instance.'''
def __init__(self, account):
self.account = account
self._items = CacheDictionary(15, getrefresh = False)
self._info = CacheDictionary(15, getrefresh = False)
self._items = CacheDictionary(1, getrefresh = True)
self._info = CacheDictionary(1, getrefresh = True)
self._cbs = {}
def _clean_closure(self, cb, type, addr):
@ -422,6 +422,7 @@ _('Without a connection, you can not browse available services'))
self.xml = gtkgui_helpers.get_glade('service_discovery_window.glade')
self.window = self.xml.get_widget('service_discovery_window')
self.services_treeview = self.xml.get_widget('services_treeview')
self.model = None
# This is more reliable than the cursor-changed signal.
selection = self.services_treeview.get_selection()
selection.connect_after('changed',
@ -452,7 +453,6 @@ _('Without a connection, you can not browse available services'))
liststore = gtk.ListStore(str)
self.address_comboboxentry.set_model(liststore)
self.address_comboboxentry.set_text_column(0)
self.latest_addresses = gajim.config.get(
'latest_disco_addresses').split()
if jid in self.latest_addresses:
@ -720,9 +720,9 @@ class AgentBrowser:
note that the first two columns should ALWAYS be of type string and
contain the JID and node of the item respectively.'''
# JID, node, name, address
model = gtk.ListStore(str, str, str, str)
model.set_sort_column_id(3, gtk.SORT_ASCENDING)
self.window.services_treeview.set_model(model)
self.model = gtk.ListStore(str, str, str, str)
self.model.set_sort_column_id(3, gtk.SORT_ASCENDING)
self.window.services_treeview.set_model(self.model)
# Name column
col = gtk.TreeViewColumn(_('Name'))
renderer = gtk.CellRendererText()
@ -740,7 +740,7 @@ class AgentBrowser:
self.window.services_treeview.set_headers_visible(True)
def _clean_treemodel(self):
self.window.services_treeview.get_model().clear()
self.model.clear()
for col in self.window.services_treeview.get_columns():
self.window.services_treeview.remove_column(col)
self.window.services_treeview.set_headers_visible(False)
@ -872,8 +872,7 @@ class AgentBrowser:
def browse(self, force = False):
'''Fill the treeview with agents, fetching the info if necessary.'''
model = self.window.services_treeview.get_model()
model.clear()
self.model.clear()
self._total_items = self._progress = 0
self.window.progressbar.show()
self._pulse_timeout = gobject.timeout_add(250, self._pulse_timeout_cb)
@ -890,21 +889,21 @@ class AgentBrowser:
def _find_item(self, jid, node):
'''Check if an item is already in the treeview. Return an iter to it
if so, None otherwise.'''
model = self.window.services_treeview.get_model()
iter = model.get_iter_root()
iter = self.model.get_iter_root()
while iter:
cjid = model.get_value(iter, 0).decode('utf-8')
cnode = model.get_value(iter, 1).decode('utf-8')
cjid = self.model.get_value(iter, 0).decode('utf-8')
cnode = self.model.get_value(iter, 1).decode('utf-8')
if jid == cjid and node == cnode:
break
iter = model.iter_next(iter)
iter = self.model.iter_next(iter)
if iter:
return iter
return None
def _agent_items(self, jid, node, items, force):
'''Callback for when we receive a list of agent items.'''
model = self.window.services_treeview.get_model()
self.model.clear()
self._total_items = 0
gobject.source_remove(self._pulse_timeout)
self.window.progressbar.hide()
# The server returned an error
@ -916,53 +915,48 @@ class AgentBrowser:
_('This service does not contain any items to browse.'))
return
# We got a list of items
self.window.services_treeview.set_model(None)
for item in items:
jid = item['jid']
node = item.get('node', '')
iter = self._find_item(jid, node)
if iter:
# Already in the treeview
self._update_item(model, iter, jid, node, item)
else:
# Not in the treeview
self._total_items += 1
self._add_item(model, jid, node, item, force)
self._total_items += 1
self._add_item(jid, node, item, force)
self.window.services_treeview.set_model(self.model)
def _agent_info(self, jid, node, identities, features, data):
'''Callback for when we receive info about an agent's item.'''
addr = get_agent_address(jid, node)
model = self.window.services_treeview.get_model()
iter = self._find_item(jid, node)
if not iter:
# Not in the treeview, stop
return
if identities == 0:
# The server returned an error
self._update_error(model, iter, jid, node)
self._update_error(iter, jid, node)
else:
# We got our info
self._update_info(model, iter, jid, node,
self._update_info(iter, jid, node,
identities, features, data)
self.update_actions()
def _add_item(self, model, jid, node, item, force):
def _add_item(self, jid, node, item, force):
'''Called when an item should be added to the model. The result of a
disco#items query.'''
model.append((jid, node, item.get('name', ''),
self.model.append((jid, node, item.get('name', ''),
get_agent_address(jid, node)))
def _update_item(self, model, iter, jid, node, item):
def _update_item(self, iter, jid, node, item):
'''Called when an item should be updated in the model. The result of a
disco#items query. (seldom)'''
if item.has_key('name'):
model[iter][2] = item['name']
self.model[iter][2] = item['name']
def _update_info(self, model, iter, jid, node, identities, features, data):
def _update_info(self, iter, jid, node, identities, features, data):
'''Called when an item should be updated in the model with further info.
The result of a disco#info query.'''
model[iter][2] = identities[0].get('name', '')
self.model[iter][2] = identities[0].get('name', '')
def _update_error(self, model, iter, jid, node):
def _update_error(self, iter, jid, node):
'''Called when a disco#info query failed for an item.'''
pass
@ -1046,14 +1040,12 @@ class ToplevelAgentBrowser(AgentBrowser):
# These are all callbacks to make tooltips work
def on_treeview_leave_notify_event(self, widget, event):
model = widget.get_model()
props = widget.get_path_at_pos(int(event.x), int(event.y))
if self.tooltip.timeout > 0:
if not props or self.tooltip.id == props[0]:
self.tooltip.hide_tooltip()
def on_treeview_motion_notify_event(self, widget, event):
model = widget.get_model()
props = widget.get_path_at_pos(int(event.x), int(event.y))
if self.tooltip.timeout > 0:
if not props or self.tooltip.id != props[0]:
@ -1062,12 +1054,12 @@ class ToplevelAgentBrowser(AgentBrowser):
[row, col, x, y] = props
iter = None
try:
iter = model.get_iter(row)
iter = self.model.get_iter(row)
except:
self.tooltip.hide_tooltip()
return
jid = model[iter][0]
state = model[iter][4]
jid = self.model[iter][0]
state = self.model[iter][4]
# Not a category, and we have something to say about state
if jid and state > 0 and \
(self.tooltip.timeout == 0 or self.tooltip.id != props[0]):
@ -1084,10 +1076,10 @@ class ToplevelAgentBrowser(AgentBrowser):
# JID, node, icon, description, state
# State means 2 when error, 1 when fetching, 0 when succes.
view = self.window.services_treeview
model = gtk.TreeStore(str, str, gtk.gdk.Pixbuf, str, int)
model.set_sort_func(4, self._treemodel_sort_func)
model.set_sort_column_id(4, gtk.SORT_ASCENDING)
view.set_model(model)
self.model = gtk.TreeStore(str, str, gtk.gdk.Pixbuf, str, int)
self.model.set_sort_func(4, self._treemodel_sort_func)
self.model.set_sort_column_id(4, gtk.SORT_ASCENDING)
view.set_model(self.model)
col = gtk.TreeViewColumn()
# Icon Renderer
@ -1329,41 +1321,38 @@ class ToplevelAgentBrowser(AgentBrowser):
def _create_category(self, cat, type=None):
'''Creates a category row.'''
model = self.window.services_treeview.get_model()
cat, prio = self._friendly_category(cat, type)
return model.append(None, ('', '', None, cat, prio))
return self.model.append(None, ('', '', None, cat, prio))
def _find_category(self, cat, type=None):
'''Looks up a category row and returns the iterator to it, or None.'''
model = self.window.services_treeview.get_model()
cat, prio = self._friendly_category(cat, type)
iter = model.get_iter_root()
iter = self.model.get_iter_root()
while iter:
if model.get_value(iter, 3).decode('utf-8') == cat:
if self.model.get_value(iter, 3).decode('utf-8') == cat:
break
iter = model.iter_next(iter)
iter = self.model.iter_next(iter)
if iter:
return iter
return None
def _find_item(self, jid, node):
model = self.window.services_treeview.get_model()
iter = None
cat_iter = model.get_iter_root()
cat_iter = self.model.get_iter_root()
while cat_iter and not iter:
iter = model.iter_children(cat_iter)
iter = self.model.iter_children(cat_iter)
while iter:
cjid = model.get_value(iter, 0).decode('utf-8')
cnode = model.get_value(iter, 1).decode('utf-8')
cjid = self.model.get_value(iter, 0).decode('utf-8')
cnode = self.model.get_value(iter, 1).decode('utf-8')
if jid == cjid and node == cnode:
break
iter = model.iter_next(iter)
cat_iter = model.iter_next(cat_iter)
iter = self.model.iter_next(iter)
cat_iter = self.model.iter_next(cat_iter)
if iter:
return iter
return None
def _add_item(self, model, jid, node, item, force):
def _add_item(self, jid, node, item, force):
# Row text
addr = get_agent_address(jid, node)
if item.has_key('name'):
@ -1387,21 +1376,21 @@ class ToplevelAgentBrowser(AgentBrowser):
cat = self._find_category(*cat_args)
if not cat:
cat = self._create_category(*cat_args)
model.append(cat, (item['jid'], item.get('node', ''), pix, descr, 1))
self.model.append(cat, (item['jid'], item.get('node', ''), pix, descr, 1))
self._expand_all()
# Grab info on the service
self.cache.get_info(jid, node, self._agent_info, force = force)
self._update_progressbar()
def _update_item(self, model, iter, jid, node, item):
def _update_item(self, iter, jid, node, item):
addr = get_agent_address(jid, node)
if item.has_key('name'):
descr = "<b>%s</b>\n%s" % (item['name'], addr)
else:
descr = "<b>%s</b>" % addr
model[iter][3] = descr
self.model[iter][3] = descr
def _update_info(self, model, iter, jid, node, identities, features, data):
def _update_info(self, iter, jid, node, identities, features, data):
addr = get_agent_address(jid, node)
name = identities[0].get('name', '')
if name:
@ -1423,32 +1412,32 @@ class ToplevelAgentBrowser(AgentBrowser):
break
# Check if we have to move categories
old_cat_iter = model.iter_parent(iter)
old_cat = model.get_value(old_cat_iter, 3).decode('utf-8')
if model.get_value(old_cat_iter, 3) == cat:
old_cat_iter = self.model.iter_parent(iter)
old_cat = self.model.get_value(old_cat_iter, 3).decode('utf-8')
if self.model.get_value(old_cat_iter, 3) == cat:
# Already in the right category, just update
model[iter][2] = pix
model[iter][3] = descr
model[iter][4] = 0
self.model[iter][2] = pix
self.model[iter][3] = descr
self.model[iter][4] = 0
return
# Not in the right category, move it.
model.remove(iter)
self.model.remove(iter)
# Check if the old category is empty
if not model.iter_is_valid(old_cat_iter):
if not self.model.iter_is_valid(old_cat_iter):
old_cat_iter = self._find_category(old_cat)
if not model.iter_children(old_cat_iter):
model.remove(old_cat_iter)
if not self.model.iter_children(old_cat_iter):
self.model.remove(old_cat_iter)
cat_iter = self._find_category(cat, type)
if not cat_iter:
cat_iter = self._create_category(cat, type)
model.append(cat_iter, (jid, node, pix, descr, 0))
self.model.append(cat_iter, (jid, node, pix, descr, 0))
self._expand_all()
def _update_error(self, model, iter, jid, node):
def _update_error(self, iter, jid, node):
addr = get_agent_address(jid, node)
model[iter][4] = 2
self.model[iter][4] = 2
self._progress += 1
self._update_progressbar()
@ -1462,11 +1451,13 @@ class MucBrowser(AgentBrowser):
# JID, node, name, users, description, fetched
# This is rather long, I'd rather not use a data_func here though.
# Users is a string, because want to be able to leave it empty.
model = gtk.ListStore(str, str, str, str, str, bool)
model.set_sort_column_id(2, gtk.SORT_ASCENDING)
self.window.services_treeview.set_model(model)
self.model = gtk.ListStore(str, str, str, str, str, bool)
self.model.set_sort_column_id(2, gtk.SORT_ASCENDING)
self.window.services_treeview.set_model(self.model)
# Name column
col = gtk.TreeViewColumn(_('Name'))
col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
col.set_fixed_width(100)
renderer = gtk.CellRendererText()
col.pack_start(renderer)
col.set_attributes(renderer, text = 2)
@ -1486,6 +1477,13 @@ class MucBrowser(AgentBrowser):
col.set_attributes(renderer, text = 4)
self.window.services_treeview.insert_column(col, -1)
col.set_resizable(True)
# Id column
col = gtk.TreeViewColumn(_('Id'))
renderer = gtk.CellRendererText()
col.pack_start(renderer)
col.set_attributes(renderer, text = 0)
self.window.services_treeview.insert_column(col, -1)
col.set_resizable(True)
self.window.services_treeview.set_headers_visible(True)
# Source id for idle callback used to start disco#info queries.
self._fetch_source = None
@ -1568,7 +1566,6 @@ class MucBrowser(AgentBrowser):
# Prevent a silly warning, try again in a bit.
self._fetch_source = gobject.timeout_add(100, self._start_info_query)
return
model = view.get_model()
# We have to do this in a pygtk <2.8 compatible way :/
#start, end = self.window.services_treeview.get_visible_range()
rect = view.get_visible_rect()
@ -1577,7 +1574,7 @@ class MucBrowser(AgentBrowser):
try:
sx, sy = view.tree_to_widget_coords(rect.x, rect.y)
spath = view.get_path_at_pos(sx, sy)[0]
iter = model.get_iter(spath)
iter = self.model.get_iter(spath)
except TypeError:
self._fetch_source = None
return
@ -1591,14 +1588,14 @@ class MucBrowser(AgentBrowser):
except TypeError:
# We're at the end of the model, we can leave end=None though.
pass
while iter and model.get_path(iter) != end:
if not model.get_value(iter, 5):
jid = model.get_value(iter, 0).decode('utf-8')
node = model.get_value(iter, 1).decode('utf-8')
while iter and self.model.get_path(iter) != end:
if not self.model.get_value(iter, 5):
jid = self.model.get_value(iter, 0).decode('utf-8')
node = self.model.get_value(iter, 1).decode('utf-8')
self.cache.get_info(jid, node, self._agent_info)
self._fetch_source = True
return
iter = model.iter_next(iter)
iter = self.model.iter_next(iter)
self._fetch_source = None
def _channel_altinfo(self, jid, node, items, name = None):
@ -1619,22 +1616,21 @@ class MucBrowser(AgentBrowser):
self._fetch_source = None
return
else:
model = self.window.services_treeview.get_model()
iter = self._find_item(jid, node)
if iter:
if name:
model[iter][2] = name
model[iter][3] = len(items) # The number of users
model[iter][5] = True
self.model[iter][2] = name
self.model[iter][3] = len(items) # The number of users
self.model[iter][5] = True
self._fetch_source = None
self._query_visible()
def _add_item(self, model, jid, node, item, force):
model.append((jid, node, item.get('name', ''), '', '', False))
def _add_item(self, jid, node, item, force):
self.model.append((jid, node, item.get('name', ''), '', '', False))
if not self._fetch_source:
self._fetch_source = gobject.idle_add(self._start_info_query)
def _update_info(self, model, iter, jid, node, identities, features, data):
def _update_info(self, iter, jid, node, identities, features, data):
name = identities[0].get('name', '')
for form in data:
typefield = form.getField('FORM_TYPE')
@ -1644,14 +1640,14 @@ class MucBrowser(AgentBrowser):
users = form.getField('muc#roominfo_occupants')
descr = form.getField('muc#roominfo_description')
if users:
model[iter][3] = users.getValue()
self.model[iter][3] = users.getValue()
if descr:
model[iter][4] = descr.getValue()
self.model[iter][4] = descr.getValue()
# Only set these when we find a form with additional info
# Some servers don't support forms and put extra info in
# the name attribute, so we preserve it in that case.
model[iter][2] = name
model[iter][5] = True
self.model[iter][2] = name
self.model[iter][5] = True
break
else:
# We didn't find a form, switch to alternate query mode
@ -1661,7 +1657,7 @@ class MucBrowser(AgentBrowser):
self._fetch_source = None
self._query_visible()
def _update_error(self, model, iter, jid, node):
def _update_error(self, iter, jid, node):
# switch to alternate query mode
self.cache.get_items(jid, node, self._channel_altinfo)

View File

@ -246,11 +246,16 @@ _('Connection with peer cannot be established.'))
gtk.RESPONSE_OK,
True, # select multiple true as we can select many files to send
gajim.config.get('last_send_dir'),
on_response_ok = on_ok,
on_response_cancel = lambda e:dialog.destroy()
)
btn = dialog.add_button(_('_Send'), gtk.RESPONSE_OK)
btn.set_use_stock(True) # FIXME: add send icon to this button (JUMP_TO)
btn.connect('clicked', on_ok)
btn = gtk.Button(_('_Send'))
btn.set_property('can-default', True)
# FIXME: add send icon to this button (JUMP_TO)
dialog.add_action_widget(btn, gtk.RESPONSE_OK)
dialog.set_default_response(gtk.RESPONSE_OK)
btn.show()
def send_file(self, account, contact, file_path):
''' start the real transfer(upload) of the file '''
@ -450,8 +455,10 @@ _('Connection with peer cannot be established.'))
for ev_type in ('file-error', 'file-completed', 'file-request-error',
'file-send-error', 'file-stopped'):
for event in gajim.events.get_events(account, jid, [ev_type]):
if event.parameters[1]['sid'] == file_props['sid']:
if event.parameters['sid'] == file_props['sid']:
gajim.events.remove_events(account, jid, event)
gajim.interface.roster.draw_contact(jid, account)
gajim.interface.roster.show_title()
del(self.files_props[sid[0]][sid[1:]])
del(file_props)

View File

@ -51,13 +51,10 @@ def send_error(error_message):
try:
import dbus
except:
raise exceptions.DbusNotSupported
_version = getattr(dbus, 'version', (0, 20, 0))
if _version[1] >= 41:
import dbus.service
import dbus.glib
except:
raise exceptions.DbusNotSupported
OBJ_PATH = '/org/gajim/dbus/RemoteObject'
INTERFACE = 'org.gajim.dbus.RemoteInterface'
@ -320,14 +317,8 @@ class GajimRemote:
except:
raise exceptions.SessionBusNotPresent
if _version[1] >= 30:
obj = self.sbus.get_object(SERVICE, OBJ_PATH)
interface = dbus.Interface(obj, INTERFACE)
elif _version[1] < 30:
self.service = self.sbus.get_service(SERVICE)
interface = self.service.get_object(OBJ_PATH, INTERFACE)
else:
send_error(_('Unknown D-Bus version: %s') % _version[1])
obj = self.sbus.get_object(SERVICE, OBJ_PATH)
interface = dbus.Interface(obj, INTERFACE)
# get the function asked
self.method = interface.__getattr__(self.command)
@ -447,10 +438,7 @@ class GajimRemote:
''' calls self.method with arguments from sys.argv[2:] '''
args = sys.argv[2:]
args = [i.decode(PREFERRED_ENCODING) for i in sys.argv[2:]]
if _version[1] >= 41:
args = [dbus.String(i) for i in args]
else:
args = [i.encode('UTF-8') for i in sys.argv[2:]]
args = [dbus.String(i) for i in args]
try:
res = self.method(*args)
return res

View File

@ -552,7 +552,7 @@ class Interface:
chat_control = self.msg_win_mgr.get_control(jid, account)
# Handle chat states
contact = gajim.contacts.get_contact(account, jid, resource)
contact = gajim.contacts.get_contact(account, jid)
if contact and isinstance(contact, list):
contact = contact[0]
if contact:
@ -582,7 +582,10 @@ class Interface:
if gajim.config.get('ignore_unknown_contacts') and \
not gajim.contacts.get_contact(account, jid) and not pm:
return
if not contact:
# contact is not in the roster, create a fake one to display
# notification
contact = common.contacts.Contact(jid = jid, resource = resource)
advanced_notif_num = notify.get_advanced_notification('message_received',
account, contact)
@ -606,7 +609,7 @@ class Interface:
msg = message
if subject:
msg = _('Subject: %s') % subject + '\n' + msg
notify.notify('new_message', jid, account, [msg_type, first, nickname,
notify.notify('new_message', full_jid_with_resource, account, [msg_type, first, nickname,
msg], advanced_notif_num)
if self.remote_ctrl:
@ -851,6 +854,7 @@ class Interface:
self.remote_ctrl.raise_signal('LastStatusTime', (account, array))
def handle_event_os_info(self, account, array):
#'OS_INFO' (account, (jid, resource, client_info, os_info))
win = None
if self.instances[account]['infos'].has_key(array[0]):
win = self.instances[account]['infos'][array[0]]
@ -1010,7 +1014,7 @@ class Interface:
return
# Add it to roster
contact = gajim.contacts.create_contact(jid = jid, name = name,
groups = groups, show = 'offline', sub = sub, ask = ask)
groups = groups, show = 'offline', sub = sub, ask = ask)
gajim.contacts.add_contact(account, contact)
self.roster.add_contact_to_roster(jid, account)
else:
@ -1075,7 +1079,7 @@ class Interface:
gmail_messages_list = array[2]
if gajim.config.get('notify_on_new_gmail_email'):
img = os.path.join(gajim.DATA_DIR, 'pixmaps', 'events',
'single_msg_recv.png') #FIXME: find a better image
'new_email_recv.png')
title = _('New E-mail on %(gmail_mail_address)s') % \
{'gmail_mail_address': jid}
text = i18n.ngettext('You have %d new E-mail message', 'You have %d new E-mail messages', gmail_new_messages, gmail_new_messages, gmail_new_messages)
@ -1328,7 +1332,9 @@ class Interface:
self.instances[account]['xml_console'].print_stanza(stanza, 'outgoing')
def handle_event_vcard_published(self, account, array):
dialogs.InformationDialog(_('vCard publication succeeded'), _('Your personal information has been published successfully.'))
if self.instances[account].has_key('profile'):
win = self.instances[account]['profile']
win.vcard_published()
for gc_control in self.msg_win_mgr.get_controls(message_control.TYPE_GC):
if gc_control.account == account:
show = gajim.SHOW_LIST[gajim.connections[account].connected]
@ -1337,7 +1343,9 @@ class Interface:
gc_control.room_jid, show, status)
def handle_event_vcard_not_published(self, account, array):
dialogs.InformationDialog(_('vCard publication failed'), _('There was an error while publishing your personal information, try again later.'))
if self.instances[account].has_key('profile'):
win = self.instances[account]['profile']
win.vcard_not_published()
def handle_event_signed_in(self, account, empty):
'''SIGNED_IN event is emitted when we sign in, so handle it'''
@ -1406,10 +1414,10 @@ class Interface:
if response == gtk.RESPONSE_OK:
new_name = dlg.input_entry.get_text()
print 'account, data', account, data, new_name
gajim.config.set_per('accounts', gajim.LOCAL_ACC, 'name', new_name)
gajim.config.set_per('accounts', account, 'name', new_name)
status = gajim.connections[account].status
print 'status', status
gajim.connections[account].reconnect()
gajim.connections[account].username = new_name
gajim.connections[account].change_status(status, '')
def read_sleepy(self):
@ -1744,14 +1752,17 @@ class Interface:
jid = gajim.get_jid_without_resource(jid)
if type_ in ('printed_gc_msg', 'gc_msg'):
w = self.msg_win_mgr.get_window(jid, account)
elif type_ in ('printed_chat', 'chat'):
elif type_ in ('printed_chat', 'chat', ''):
# '' is for log in/out notifications
if self.msg_win_mgr.has_window(fjid, account):
w = self.msg_win_mgr.get_window(fjid, account)
elif self.msg_win_mgr.has_window(jid, account):
w = self.msg_win_mgr.get_window(jid, account)
else:
contact = gajim.contacts.get_contact(account, jid, resource)
if isinstance(contact, list):
if not contact or isinstance(contact, list):
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
self.roster.new_chat(contact, account, resource = resource)
self.roster.new_chat(contact, account)
w = self.msg_win_mgr.get_window(fjid, account)
gajim.last_message_time[account][jid] = 0 # long time ago
elif type_ in ('printed_pm', 'pm'):
@ -1774,9 +1785,15 @@ class Interface:
elif type_ in ('normal', 'file-request', 'file-request-error',
'file-send-error', 'file-error', 'file-stopped', 'file-completed'):
# Get the first single message event
event = gajim.events.get_first_event(account, jid, type_)
# Open the window
self.roster.open_event(account, jid, event)
event = gajim.events.get_first_event(account, fjid, type_)
if not event:
# default to jid without resource
event = gajim.events.get_first_event(account, jid, type_)
# Open the window
self.roster.open_event(account, jid, event)
else:
# Open the window
self.roster.open_event(account, fjid, event)
elif type_ == 'gmail':
if gajim.config.get_per('accounts', account, 'savepass'):
url = ('http://www.google.com/accounts/ServiceLoginAuth?service=mail&Email=%s&Passwd=%s&continue=https://mail.google.com/mail') %\
@ -1873,9 +1890,12 @@ class Interface:
for account in gajim.config.get_per('accounts'):
if account != gajim.ZEROCONF_ACC_NAME:
gajim.connections[account] = common.connection.Connection(account)
# gtk hooks
gtk.about_dialog_set_email_hook(self.on_launch_browser_mailer, 'mail')
gtk.about_dialog_set_url_hook(self.on_launch_browser_mailer, 'url')
if gtk.pygtk_version >= (2, 10, 0) and gtk.gtk_version >= (2, 10, 0):
gtk.link_button_set_uri_hook(self.on_launch_browser_mailer, 'url')
self.instances = {'logs': {}}
@ -1919,6 +1939,8 @@ class Interface:
self.systray_capabilities = False
if os.name == 'nt':
pass
'''
try:
import systraywin32
except: # user doesn't have trayicon capabilities
@ -1926,6 +1948,7 @@ class Interface:
else:
self.systray_capabilities = True
self.systray = systraywin32.SystrayWin32()
'''
else:
self.systray_capabilities = systray.HAS_SYSTRAY_CAPABILITIES
if self.systray_capabilities:

View File

@ -51,7 +51,7 @@ class GajimThemesWindow:
self.themes_tree = self.xml.get_widget('themes_treeview')
self.theme_options_vbox = self.xml.get_widget('theme_options_vbox')
self.colorbuttons = {}
for chatstate in ('active', 'inactive', 'composing', 'paused', 'gone',
for chatstate in ('inactive', 'composing', 'paused', 'gone',
'muc_msg', 'muc_directed_msg'):
self.colorbuttons[chatstate] = self.xml.get_widget(chatstate + \
'_colorbutton')
@ -198,7 +198,7 @@ class GajimThemesWindow:
self.no_update = False
gajim.interface.roster.change_roster_style(None)
for chatstate in ('active', 'inactive', 'composing', 'paused', 'gone',
for chatstate in ('inactive', 'composing', 'paused', 'gone',
'muc_msg', 'muc_directed_msg'):
color = gajim.config.get_per('themes', theme, 'state_' + chatstate + \
'_color')
@ -333,11 +333,6 @@ class GajimThemesWindow:
font_props[1] = True
return font_props
def on_active_colorbutton_color_set(self, widget):
self.no_update = True
self._set_color(True, widget, 'state_active_color')
self.no_update = False
def on_inactive_colorbutton_color_set(self, widget):
self.no_update = True
self._set_color(True, widget, 'state_inactive_color')

View File

@ -226,9 +226,6 @@ class GroupchatControl(ChatControlBase):
self.gc_popup_menu = xm.get_widget('gc_control_popup_menu')
self.name_label = self.xml.get_widget('banner_name_label')
id = self.parent_win.window.connect('focus-in-event',
self._on_window_focus_in_event)
self.handlers[id] = self.parent_win.window
# set the position of the current hpaned
self.hpaned_position = gajim.config.get('gc-hpaned-position')
@ -320,11 +317,6 @@ class GroupchatControl(ChatControlBase):
return gajim.config.get('notify_on_all_muc_messages') or \
self.attention_flag
def _on_window_focus_in_event(self, widget, event):
'''When window gets focus'''
if self.parent_win.get_active_jid() == self.room_jid:
self.conv_textview.allow_focus_out_line = True
def on_treeview_size_allocate(self, widget, allocation):
'''The MUC treeview has resized. Move the hpaned in all tabs to match'''
self.hpaned_position = self.hpaned.get_position()
@ -371,23 +363,24 @@ class GroupchatControl(ChatControlBase):
has_focus = self.parent_win.window.get_property('has-toplevel-focus')
current_tab = self.parent_win.get_active_control() == self
color_name = None
color = None
theme = gajim.config.get('roster_theme')
if chatstate == 'attention' and (not has_focus or not current_tab):
self.attention_flag = True
color = gajim.config.get_per('themes', theme,
color_name = gajim.config.get_per('themes', theme,
'state_muc_directed_msg_color')
elif chatstate:
if chatstate == 'active' or (current_tab and has_focus):
self.attention_flag = False
color = gajim.config.get_per('themes', theme,
'state_active_color')
# get active color from gtk
color = self.parent_win.notebook.style.fg[gtk.STATE_ACTIVE]
elif chatstate == 'newmsg' and (not has_focus or not current_tab) and\
not self.attention_flag:
color = gajim.config.get_per('themes', theme, 'state_muc_msg_color')
if color:
color = gtk.gdk.colormap_get_system().alloc_color(color)
color_name = gajim.config.get_per('themes', theme, 'state_muc_msg_color')
if color_name:
color = gtk.gdk.colormap_get_system().alloc_color(color_name)
label_str = self.name
return (label_str, color)
@ -865,7 +858,9 @@ class GroupchatControl(ChatControlBase):
print_status = gajim.config.get('print_status_in_muc')
nick_jid = nick
if jid:
nick_jid += ' (%s)' % jid
# delete ressource
simple_jid = gajim.get_jid_without_resource(jid)
nick_jid += ' (%s)' % simple_jid
if show == 'offline' and print_status in ('all', 'in_and_out'):
st = _('%s has left') % nick_jid
if reason:
@ -1268,6 +1263,10 @@ class GroupchatControl(ChatControlBase):
del self.handlers[i]
def allow_shutdown(self):
model, iter = self.list_treeview.get_selection().get_selected()
if iter:
self.list_treeview.get_selection().unselect_all()
return False
retval = True
includes = gajim.config.get('confirm_close_muc_rooms').split(' ')
excludes = gajim.config.get('noconfirm_close_muc_rooms').split(' ')
@ -1293,6 +1292,7 @@ class GroupchatControl(ChatControlBase):
return retval
def set_control_active(self, state):
self.conv_textview.allow_focus_out_line = True
self.attention_flag = False
ChatControlBase.set_control_active(self, state)
if not state:
@ -1453,7 +1453,11 @@ class GroupchatControl(ChatControlBase):
def on_list_treeview_key_press_event(self, widget, event):
if event.keyval == gtk.keysyms.Escape:
widget.get_selection().unselect_all()
selection = widget.get_selection()
model, iter = selection.get_selected()
if iter:
widget.get_selection().unselect_all()
return True
def on_list_treeview_row_expanded(self, widget, iter, path):
'''When a row is expanded: change the icon of the arrow'''

View File

@ -390,7 +390,7 @@ def possibly_move_window_in_current_desktop(window):
current virtual desktop
window is GTK window'''
if os.name == 'nt':
return
return False
root_window = gtk.gdk.screen_get_default().get_root_window()
# current user's vd
@ -406,6 +406,8 @@ def possibly_move_window_in_current_desktop(window):
# we are in another VD that the window was
# so show it in current VD
window.present()
return True
return False
def file_is_locked(path_to_file):
'''returns True if file is locked (WINDOWS ONLY)'''
@ -680,6 +682,14 @@ default_name = ''):
file_path = dialog.get_filename()
file_path = decode_filechooser_file_paths((file_path,))[0]
if os.path.exists(file_path):
# check if we have write permissions
if not os.access(file_path, os.W_OK):
file_name = os.path.basename(file_path)
dialogs.ErrorDialog(_('Cannot overwrite existing file "%s"' %
file_name),
_('A file with this name already exists and you do not have '
'permission to overwrite it.'))
return
dialog2 = dialogs.FTOverwriteConfirmationDialog(
_('This file already exists'), _('What do you want to do?'),
False)
@ -688,6 +698,13 @@ default_name = ''):
response = dialog2.get_response()
if response < 0:
return
else:
dirname = os.path.dirname(file_path)
if not os.access(dirname, os.W_OK):
dialogs.ErrorDialog(_('Directory "%s" is not writable') % \
dirname, _('You do not have permission to create files in this'
' directory.'))
return
# Get pixbuf
pixbuf = None
@ -710,8 +727,8 @@ default_name = ''):
try:
pixbuf.save(file_path, type_)
except:
#XXX Check for permissions
os.remove(file_path)
if os.path.exists(file_path):
os.remove(file_path)
new_file_path = '.'.join(file_path.split('.')[:-1]) + '.jpeg'
dialog2 = dialogs.ConfirmationDialog(_('Extension not supported'),
_('Image cannot be saved in %(type)s format. Save as %(new_filename)s?') % {'type': type_, 'new_filename': new_file_path},
@ -735,3 +752,6 @@ default_name = ''):
dialog.set_current_name(default_name)
dialog.connect('delete-event', lambda widget, event:
on_cancel(widget))
def on_bm_header_changed_state(widget, event):
widget.set_state(gtk.STATE_NORMAL) #do not allow selected_state

View File

@ -104,6 +104,16 @@ class MessageWindow:
self.notebook.drag_dest_set(gtk.DEST_DEFAULT_ALL, self.DND_TARGETS,
gtk.gdk.ACTION_MOVE)
def change_account_name(self, old_name, new_name):
if self._controls.has_key(old_name):
self._controls[new_name] = self._controls[old_name]
del self._controls[old_name]
for ctrl in self.controls():
if ctrl.account == old_name:
ctrl.account = new_name
if self.account == old_name:
self.account = new_name
def get_num_controls(self):
n = 0
for dict in self._controls.values():
@ -618,7 +628,11 @@ class MessageWindowMgr:
# Map the mode to a int constant for frequent compares
mode = gajim.config.get('one_message_window')
self.mode = common.config.opt_one_window_types.index(mode)
def change_account_name(self, old_name, new_name):
for win in self.windows():
win.change_account_name(old_name, new_name)
def _new_window(self, acct, type):
win = MessageWindow(acct, type)
# we track the lifetime of this window

118
src/music_track_listener.py Normal file
View File

@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
## musictracklistener.py
##
## Copyright (C) 2006 Gustavo Carneiro <gjcarneiro@gmail.com>
## Copyright (C) 2006 Nikos Kouremenos <kourem@gmail.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 2 only.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
import gobject
import dbus_support
if dbus_support.supported:
import dbus
import dbus.glib
class MusicTrackInfo(object):
__slots__ = ['title', 'album', 'artist', 'duration', 'track_number']
class MusicTrackListener(gobject.GObject):
__gsignals__ = { 'music-track-changed': (gobject.SIGNAL_RUN_LAST, None,
(object,)) }
_instance = None
@classmethod
def get(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
def __init__(self):
super(MusicTrackListener, self).__init__()
bus = dbus.SessionBus()
bus.add_signal_receiver(self._muine_music_track_change_cb, 'SongChanged',
'org.gnome.Muine.Player')
bus.add_signal_receiver(self._rhythmbox_music_track_change_cb,
'playingUriChanged', 'org.gnome.Rhythmbox.Player')
def _muine_properties_extract(self, song_string):
d = dict((x.strip() for x in s1.split(':', 1)) for s1 in song_string.split('\n'))
info = MusicTrackInfo()
info.title = d['title']
info.album = d['album']
info.artist = d['artist']
info.duration = int(d['duration'])
info.track_number = int(d['track_number'])
return info
def _muine_music_track_change_cb(self, arg):
info = self._muine_properties_extract(arg)
self.emit('music-track-changed', info)
def _rhythmbox_properties_extract(self, props):
info = MusicTrackInfo()
info.title = props['title']
info.album = props['album']
info.artist = props['artist']
info.duration = int(props['duration'])
info.track_number = int(props['track-number'])
return info
def _rhythmbox_music_track_change_cb(self, uri):
bus = dbus.SessionBus()
rbshellobj = bus.get_object('org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Shell')
rbshell = dbus.Interface(rbshellobj, 'org.gnome.Rhythmbox.Shell')
props = rbshell.getSongProperties(uri)
info = self._rhythmbox_properties_extract(props)
self.emit('music-track-changed', info)
def get_playing_track(self):
'''Return a MusicTrackInfo for the currently playing
song, or None if no song is playing'''
bus = dbus.SessionBus()
## Check Muine playing track
if dbus.dbus_bindings.bus_name_has_owner(bus.get_connection(),
'org.gnome.Muine'):
obj = bus.get_object('org.gnome.Muine', '/org/gnome/Muine/Player')
player = dbus.Interface(obj, 'org.gnome.Muine.Player')
if player.GetPlaying():
song_string = player.GetCurrentSong()
song = self._muine_properties_extract(song_string)
return song
## Check Rhythmbox playing song
if dbus.dbus_bindings.bus_name_has_owner(bus.get_connection(),
'org.gnome.Rhythmbox'):
rbshellobj = bus.get_object('org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Shell')
player = dbus.Interface(
bus.get_object('org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Player'),
'org.gnome.Rhythmbox.Player')
rbshell = dbus.Interface(rbshellobj, 'org.gnome.Rhythmbox.Shell')
uri = player.getPlayingUri()
props = rbshell.getSongProperties(uri)
info = self._rhythmbox_properties_extract(props)
return info
return None
# here we test :)
if __name__ == '__main__':
def music_track_change_cb(listener, music_track_info):
print music_track_info.title
listener = MusicTrackListener.get()
listener.connect('music-track-changed', music_track_change_cb)
track = listener.get_playing_track()
if track is None:
print 'Now not playing anything'
else:
print 'Now playing: "%s" by %s' % (track.title, track.artist)
gobject.MainLoop().run()

View File

@ -28,9 +28,8 @@ from common import helpers
import dbus_support
if dbus_support.supported:
import dbus
if dbus_support.version >= (0, 41, 0):
import dbus.glib
import dbus.service
import dbus.glib
import dbus.service
def get_show_in_roster(event, account, contact):
'''Return True if this event must be shown in roster, else False'''
@ -42,11 +41,9 @@ def get_show_in_roster(event, account, contact):
return False
if event == 'message_received':
chat_control = helpers.get_chat_control(account, contact)
if not chat_control:
return True
elif event == 'ft_request':
return True
return False
if chat_control:
return False
return True
def get_show_in_systray(event, account, contact):
'''Return True if this event must be shown in roster, else False'''
@ -56,10 +53,7 @@ def get_show_in_systray(event, account, contact):
return True
if gajim.config.get_per('notifications', str(num), 'systray') == 'no':
return False
if event in ('message_received', 'ft_request', 'gc_msg_highlight',
'ft_request'):
return True
return False
return True
def get_advanced_notification(event, account, contact):
'''Returns the number of the first advanced notification or None'''

View File

@ -60,17 +60,40 @@ class ProfileWindow:
def __init__(self, account):
self.xml = gtkgui_helpers.get_glade('profile_window.glade')
self.window = self.xml.get_widget('profile_window')
self.progressbar = self.xml.get_widget('progressbar')
self.statusbar = self.xml.get_widget('statusbar')
self.context_id = self.statusbar.get_context_id('profile')
self.account = account
self.jid = gajim.get_jid_from_account(account)
self.avatar_mime_type = None
self.avatar_encoded = None
self.message_id = self.statusbar.push(self.context_id,
_('Retrieving profile...'))
self.update_progressbar_timeout_id = gobject.timeout_add(100,
self.update_progressbar)
self.remove_statusbar_timeout_id = None
# Create Image for avatar button
image = gtk.Image()
self.xml.get_widget('PHOTO_button').set_image(image)
self.xml.signal_autoconnect(self)
self.window.show_all()
def update_progressbar(self):
self.progressbar.pulse()
return True # loop forever
def remove_statusbar(self, message_id):
self.statusbar.remove(self.context_id, message_id)
self.remove_statusbar_timeout_id = None
def on_profile_window_destroy(self, widget):
if self.update_progressbar_timeout_id is not None:
gobject.source_remove(self.update_progressbar_timeout_id)
if self.remove_statusbar_timeout_id is not None:
gobject.source_remove(self.remove_statusbar_timeout_id)
del gajim.interface.instances[self.account]['profile']
def on_profile_window_key_press_event(self, widget, event):
@ -79,8 +102,10 @@ class ProfileWindow:
def on_clear_button_clicked(self, widget):
# empty the image
self.xml.get_widget('PHOTO_image').set_from_icon_name('stock_person',
gtk.ICON_SIZE_DIALOG)
button = self.xml.get_widget('PHOTO_button')
image = button.get_image()
image.set_from_pixbuf(None)
button.set_label(_('Click to set your avatar'))
self.avatar_encoded = None
self.avatar_mime_type = None
@ -124,24 +149,39 @@ class ProfileWindow:
pixbuf = gtkgui_helpers.get_pixbuf_from_data(data)
# rescale it
pixbuf = gtkgui_helpers.get_scaled_pixbuf(pixbuf, 'vcard')
image = self.xml.get_widget('PHOTO_image')
button = self.xml.get_widget('PHOTO_button')
image = button.get_image()
image.set_from_pixbuf(pixbuf)
button.set_label('')
self.avatar_encoded = base64.encodestring(data)
# returns None if unknown type
self.avatar_mime_type = mimetypes.guess_type(path_to_file)[0]
self.dialog = dialogs.ImageChooserDialog(on_response_ok = on_ok)
def on_clear(widget):
self.dialog.destroy()
self.on_clear_button_clicked(widget)
self.dialog = dialogs.AvatarChooserDialog(on_response_ok = on_ok,
on_response_clear = on_clear)
def on_PHOTO_button_press_event(self, widget, event):
'''If right-clicked, show popup'''
if event.button == 3 and self.avatar_encoded: # right click
menu = gtk.Menu()
nick = gajim.config.get_per('accounts', self.account, 'name')
menuitem = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS)
menuitem.connect('activate',
gtkgui_helpers.on_avatar_save_as_menuitem_activate,
self.jid, None, nick + '.jpeg')
menu.append(menuitem)
# Try to get pixbuf
is_fake = False
if account and gajim.contacts.is_pm_from_jid(account, jid):
is_fake = True
pixbuf = get_avatar_pixbuf_from_cache(jid, is_fake)
if pixbuf:
nick = gajim.config.get_per('accounts', self.account, 'name')
menuitem = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS)
menuitem.connect('activate',
gtkgui_helpers.on_avatar_save_as_menuitem_activate,
self.jid, None, nick + '.jpeg')
menu.append(menuitem)
# show clear
menuitem = gtk.ImageMenuItem(gtk.STOCK_CLEAR)
menuitem.connect('activate', self.on_clear_button_clicked)
@ -162,18 +202,23 @@ class ProfileWindow:
def set_values(self, vcard):
if not 'PHOTO' in vcard:
# set default image
image = self.xml.get_widget('PHOTO_image')
image.set_from_icon_name('stock_person', gtk.ICON_SIZE_DIALOG)
button = self.xml.get_widget('PHOTO_button')
image = button.get_image()
image.set_from_pixbuf(None)
button.set_label(_('Click to set your avatar'))
for i in vcard.keys():
if i == 'PHOTO':
pixbuf, self.avatar_encoded, self.avatar_mime_type = \
get_avatar_pixbuf_encoded_mime(vcard[i])
image = self.xml.get_widget('PHOTO_image')
button = self.xml.get_widget('PHOTO_button')
image = button.get_image()
if not pixbuf:
image.set_from_icon_name('stock_person', gtk.ICON_SIZE_DIALOG)
image.set_from_pixbuf(None)
button.set_label(_('Click to set your avatar'))
continue
pixbuf = gtkgui_helpers.get_scaled_pixbuf(pixbuf, 'vcard')
image.set_from_pixbuf(pixbuf)
button.set_label('')
continue
if i == 'ADR' or i == 'TEL' or i == 'EMAIL':
for entry in vcard[i]:
@ -191,6 +236,18 @@ class ProfileWindow:
vcard[i], 0)
else:
self.set_value(i + '_entry', vcard[i])
if self.update_progressbar_timeout_id is not None:
if self.message_id:
self.statusbar.remove(self.context_id, self.message_id)
self.message_id = self.statusbar.push(self.context_id,
_('Information received'))
self.remove_statusbar_timeout_id = gobject.timeout_add(3000,
self.remove_statusbar, self.message_id)
gobject.source_remove(self.update_progressbar_timeout_id)
# redraw progressbar after avatar is set so that windows is already
# resized. Else progressbar is not correctly redrawn
gobject.idle_add(self.progressbar.set_fraction, 0)
self.update_progressbar_timeout_id = None
def add_to_vcard(self, vcard, entry, txt):
'''Add an information to the vCard dictionary'''
@ -248,6 +305,9 @@ class ProfileWindow:
return vcard
def on_publish_button_clicked(self, widget):
if self.update_progressbar_timeout_id:
# Operation in progress
return
if gajim.connections[self.account].connected < 2:
dialogs.ErrorDialog(_('You are not connected to the server'),
_('Without a connection you can not publish your contact '
@ -261,8 +321,42 @@ class ProfileWindow:
nick = gajim.config.get_per('accounts', self.account, 'name')
gajim.nicks[self.account] = nick
gajim.connections[self.account].send_vcard(vcard)
self.message_id = self.statusbar.push(self.context_id,
_('Sending profile...'))
self.update_progressbar_timeout_id = gobject.timeout_add(100,
self.update_progressbar)
def vcard_published(self):
if self.message_id:
self.statusbar.remove(self.context_id, self.message_id)
self.message_id = self.statusbar.push(self.context_id,
_('Information published'))
self.remove_statusbar_timeout_id = gobject.timeout_add(3000,
self.remove_statusbar, self.message_id)
if self.update_progressbar_timeout_id is not None:
gobject.source_remove(self.update_progressbar_timeout_id)
self.progressbar.set_fraction(0)
self.update_progressbar_timeout_id = None
def vcard_not_published(self):
if self.message_id:
self.statusbar.remove(self.context_id, self.message_id)
self.message_id = self.statusbar.push(self.context_id,
_('Information NOT published'))
self.remove_statusbar_timeout_id = gobject.timeout_add(3000,
self.remove_statusbar, self.message_id)
if self.update_progressbar_timeout_id is not None:
gobject.source_remove(self.update_progressbar_timeout_id)
self.progressbar.set_fraction(0)
self.update_progressbar_timeout_id = None
dialogs.InformationDialog(_('vCard publication failed'),
_('There was an error while publishing your personal information, '
'try again later.'))
def on_retrieve_button_clicked(self, widget):
if self.update_progressbar_timeout_id:
# Operation in progress
return
entries = ['FN', 'NICKNAME', 'BDAY', 'EMAIL_HOME_USERID', 'URL',
'TEL_HOME_NUMBER', 'N_FAMILY', 'N_GIVEN', 'N_MIDDLE', 'N_PREFIX',
'N_SUFFIX', 'ADR_HOME_STREET', 'ADR_HOME_EXTADR', 'ADR_HOME_LOCALITY',
@ -275,9 +369,18 @@ class ProfileWindow:
for e in entries:
self.xml.get_widget(e + '_entry').set_text('')
self.xml.get_widget('DESC_textview').get_buffer().set_text('')
self.xml.get_widget('PHOTO_image').set_from_icon_name('stock_person',
gtk.ICON_SIZE_DIALOG)
button = self.xml.get_widget('PHOTO_button')
image = button.get_image()
image.set_from_pixbuf(None)
button.set_label(_('Click to set your avatar'))
gajim.connections[self.account].request_vcard(self.jid)
else:
dialogs.ErrorDialog(_('You are not connected to the server'),
_('Without a connection, you can not get your contact information.'))
_('Without a connection, you can not get your contact information.'))
self.message_id = self.statusbar.push(self.context_id,
_('Retrieving profile...'))
self.update_progressbar_timeout_id = gobject.timeout_add(100,
self.update_progressbar)
def on_close_button_clicked(self, widget):
self.window.destroy()

View File

@ -1,19 +1,9 @@
## remote_control.py
##
## Contributors for this file:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Nikos Kouremenos <kourem@gmail.com>
## - Dimitur Kirov <dkirov@gmail.com>
## - Andrew Sayman <lorien420@myrealbox.com>
##
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
## Copyright (C) 2005-2006 Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem@gmail.com>
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov@gmail.com>
## Copyright (C) 2005-2006 Andrew Sayman <lorien420@myrealbox.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
@ -36,57 +26,30 @@ from dialogs import AddNewContactWindow, NewChatDialog
import dbus_support
if dbus_support.supported:
import dbus
if dbus_support.version >= (0, 41, 0):
if dbus_support:
import dbus.service
import dbus.glib # cause dbus 0.35+ doesn't return signal replies without it
DbusPrototype = dbus.service.Object
elif dbus_support.version >= (0, 20, 0):
DbusPrototype = dbus.Object
else: #dbus is not defined
DbusPrototype = str
import dbus.glib
INTERFACE = 'org.gajim.dbus.RemoteInterface'
OBJ_PATH = '/org/gajim/dbus/RemoteObject'
SERVICE = 'org.gajim.dbus'
# type mapping, it is different in each version
ident = lambda e: e
if dbus_support.version[1] >= 43:
# in most cases it is a utf-8 string
DBUS_STRING = dbus.String
# type mapping
# general type (for use in dicts,
# where all values should have the same type)
DBUS_VARIANT = dbus.Variant
DBUS_BOOLEAN = dbus.Boolean
DBUS_DOUBLE = dbus.Double
DBUS_INT32 = dbus.Int32
# dictionary with string key and binary value
DBUS_DICT_SV = lambda : dbus.Dictionary({}, signature="sv")
# dictionary with string key and value
DBUS_DICT_SS = lambda : dbus.Dictionary({}, signature="ss")
# empty type
DBUS_NONE = lambda : dbus.Variant(0)
# in most cases it is a utf-8 string
DBUS_STRING = dbus.String
else: # 33, 35, 36
DBUS_DICT_SV = lambda : {}
DBUS_DICT_SS = lambda : {}
DBUS_STRING = lambda e: unicode(e).encode('utf-8')
# this is the only way to return lists and dicts of mixed types
DBUS_VARIANT = lambda e: (isinstance(e, (str, unicode)) and \
DBUS_STRING(e)) or repr(e)
DBUS_NONE = lambda : ''
if dbus_support.version[1] >= 41: # 35, 36
DBUS_BOOLEAN = dbus.Boolean
DBUS_DOUBLE = dbus.Double
DBUS_INT32 = dbus.Int32
else: # 33
DBUS_BOOLEAN = ident
DBUS_INT32 = ident
DBUS_DOUBLE = ident
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
'invisible']
# general type (for use in dicts, where all values should have the same type)
DBUS_VARIANT = dbus.Variant
DBUS_BOOLEAN = dbus.Boolean
DBUS_DOUBLE = dbus.Double
DBUS_INT32 = dbus.Int32
# dictionary with string key and binary value
DBUS_DICT_SV = lambda : dbus.Dictionary({}, signature="sv")
# dictionary with string key and value
DBUS_DICT_SS = lambda : dbus.Dictionary({}, signature="ss")
# empty type
DBUS_NONE = lambda : dbus.Variant(0)
def get_dbus_struct(obj):
''' recursively go through all the items and replace
@ -123,65 +86,35 @@ class Remote:
self.signal_object = None
session_bus = dbus_support.session_bus.SessionBus()
if dbus_support.version[1] >= 41:
service = dbus.service.BusName(SERVICE, bus=session_bus)
self.signal_object = SignalObject(service)
elif dbus_support.version[1] <= 40 and dbus_support.version[1] >= 20:
service=dbus.Service(SERVICE, session_bus)
self.signal_object = SignalObject(service)
service = dbus.service.BusName(SERVICE, bus=session_bus)
self.signal_object = SignalObject(service)
def raise_signal(self, signal, arg):
if self.signal_object:
self.signal_object.raise_signal(signal,
get_dbus_struct(arg))
get_dbus_struct(arg))
class SignalObject(DbusPrototype):
''' Local object definition for /org/gajim/dbus/RemoteObject. This doc must
not be visible, because the clients can access only the remote object. '''
class SignalObject(dbus.service.Object):
''' Local object definition for /org/gajim/dbus/RemoteObject.
(This docstring is not be visible, because the clients can access only the remote object.)'''
def __init__(self, service):
self.first_show = True
self.vcard_account = None
# register our dbus API
if dbus_support.version[1] >= 41:
DbusPrototype.__init__(self, service, OBJ_PATH)
elif dbus_support.version[1] >= 30:
DbusPrototype.__init__(self, OBJ_PATH, service)
else:
DbusPrototype.__init__(self, OBJ_PATH, service,
[ self.toggle_roster_appearance,
self.show_next_unread,
self.list_contacts,
self.list_accounts,
self.account_info,
self.change_status,
self.open_chat,
self.send_message,
self.send_single_message,
self.contact_info,
self.send_file,
self.prefs_list,
self.prefs_store,
self.prefs_del,
self.prefs_put,
self.add_contact,
self.remove_contact,
self.get_status,
self.get_status_message,
self.start_chat,
self.send_xml,
])
dbus.service.Object.__init__(self, service, OBJ_PATH)
def raise_signal(self, signal, arg):
''' raise a signal, with a single string message '''
'''raise a signal, with a single string message'''
from dbus import dbus_bindings
message = dbus_bindings.Signal(OBJ_PATH, INTERFACE, signal)
i = message.get_iter(True)
i.append(arg)
self._connection.send(message)
@dbus.service.method(INTERFACE)
def get_status(self, *args):
'''get_status(account = None)
returns status (show to be exact) which is the global one
@ -193,8 +126,9 @@ class SignalObject(DbusPrototype):
return helpers.get_global_show()
# return show for the given account
index = gajim.connections[account].connected
return DBUS_STRING(STATUS_LIST[index])
return DBUS_STRING(gajim.SHOW_LIST[index])
@dbus.service.method(INTERFACE)
def get_status_message(self, *args):
'''get_status(account = None)
returns status which is the global one
@ -208,7 +142,7 @@ class SignalObject(DbusPrototype):
status = gajim.connections[account].status
return DBUS_STRING(status)
@dbus.service.method(INTERFACE)
def get_account_and_contact(self, account, jid):
''' get the account (if not given) and contact instance from jid'''
connected_account = None
@ -236,6 +170,7 @@ class SignalObject(DbusPrototype):
return connected_account, contact
@dbus.service.method(INTERFACE)
def send_file(self, *args):
'''send_file(file_path, jid, account=None)
send file, located at 'file_path' to 'jid', using account
@ -254,7 +189,7 @@ class SignalObject(DbusPrototype):
return False
def _send_message(self, jid, message, keyID, account, type = 'chat', subject = None):
''' can be called from send_chat_message (default when send_message)
'''can be called from send_chat_message (default when send_message)
or send_single_message'''
if not jid or not message:
return None # or raise error
@ -269,22 +204,25 @@ class SignalObject(DbusPrototype):
return True
return False
@dbus.service.method(INTERFACE)
def send_chat_message(self, *args):
''' send_message(jid, message, keyID=None, account=None)
'''send_message(jid, message, keyID=None, account=None)
send chat 'message' to 'jid', using account (optional) 'account'.
if keyID is specified, encrypt the message with the pgp key '''
jid, message, keyID, account = self._get_real_arguments(args, 4)
jid = self._get_real_jid(jid, account)
return self._send_message(jid, message, keyID, account)
@dbus.service.method(INTERFACE)
def send_single_message(self, *args):
''' send_single_message(jid, subject, message, keyID=None, account=None)
'''send_single_message(jid, subject, message, keyID=None, account=None)
send single 'message' to 'jid', using account (optional) 'account'.
if keyID is specified, encrypt the message with the pgp key '''
jid, subject, message, keyID, account = self._get_real_arguments(args, 5)
jid = self._get_real_jid(jid, account)
return self._send_message(jid, message, keyID, account, type, subject)
@dbus.service.method(INTERFACE)
def open_chat(self, *args):
''' start_chat(jid, account=None) -> shows the tabbed window for new
message to 'jid', using account(optional) 'account' '''
@ -332,6 +270,7 @@ class SignalObject(DbusPrototype):
return True
return False
@dbus.service.method(INTERFACE)
def change_status(self, *args, **keywords):
''' change_status(status, message, account). account is optional -
if not specified status is changed for all accounts. '''
@ -352,13 +291,15 @@ class SignalObject(DbusPrototype):
status, message)
return None
@dbus.service.method(INTERFACE)
def show_next_unread(self, *args):
''' Show the window(s) with next waiting messages in tabbed/group chats. '''
'''Show the window(s) with next waiting messages in tabbed/group chats. '''
if gajim.events.get_nb_events():
gajim.interface.systray.handle_first_event()
@dbus.service.method(INTERFACE)
def contact_info(self, *args):
''' get vcard info for a contact. Return cached value of the vcard.
'''get vcard info for a contact. Return cached value of the vcard.
'''
[jid] = self._get_real_arguments(args, 1)
if not isinstance(jid, unicode):
@ -375,8 +316,9 @@ class SignalObject(DbusPrototype):
# return empty dict
return DBUS_DICT_SV()
@dbus.service.method(INTERFACE)
def list_accounts(self, *args):
''' list register accounts '''
'''list register accounts'''
result = gajim.contacts.get_accounts()
if result and len(result) > 0:
result_array = []
@ -385,8 +327,9 @@ class SignalObject(DbusPrototype):
return result_array
return None
@dbus.service.method(INTERFACE)
def account_info(self, *args):
''' show info on account: resource, jid, nick, prio, message '''
'''show info on account: resource, jid, nick, prio, message'''
[for_account] = self._get_real_arguments(args, 1)
if not gajim.connections.has_key(for_account):
# account is invalid
@ -394,19 +337,20 @@ class SignalObject(DbusPrototype):
account = gajim.connections[for_account]
result = DBUS_DICT_SS()
index = account.connected
result['status'] = DBUS_STRING(STATUS_LIST[index])
result['status'] = DBUS_STRING(gajim.SHOW_LIST[index])
result['name'] = DBUS_STRING(account.name)
result['jid'] = DBUS_STRING(gajim.get_jid_from_account(account.name))
result['message'] = DBUS_STRING(account.status)
result['priority'] = DBUS_STRING(unicode(gajim.config.get_per('accounts',
account.name, 'priority')))
account.name, 'priority')))
result['resource'] = DBUS_STRING(unicode(gajim.config.get_per('accounts',
account.name, 'resource')))
account.name, 'resource')))
return result
@dbus.service.method(INTERFACE)
def list_contacts(self, *args):
''' list all contacts in the roster. If the first argument is specified,
then return the contacts for the specified account '''
'''list all contacts in the roster. If the first argument is specified,
then return the contacts for the specified account'''
[for_account] = self._get_real_arguments(args, 1)
result = []
accounts = gajim.contacts.get_accounts()
@ -428,6 +372,7 @@ class SignalObject(DbusPrototype):
return None
return result
@dbus.service.method(INTERFACE)
def toggle_roster_appearance(self, *args):
''' shows/hides the roster window '''
win = gajim.interface.roster.window
@ -441,6 +386,7 @@ class SignalObject(DbusPrototype):
else:
win.window.focus(long(time()))
@dbus.service.method(INTERFACE)
def prefs_list(self, *args):
prefs_dict = DBUS_DICT_SS()
def get_prefs(data, name, path, value):
@ -455,6 +401,7 @@ class SignalObject(DbusPrototype):
gajim.config.foreach(get_prefs)
return prefs_dict
@dbus.service.method(INTERFACE)
def prefs_store(self, *args):
try:
gajim.interface.save_config()
@ -462,6 +409,7 @@ class SignalObject(DbusPrototype):
return False
return True
@dbus.service.method(INTERFACE)
def prefs_del(self, *args):
[key] = self._get_real_arguments(args, 1)
if not key:
@ -475,6 +423,7 @@ class SignalObject(DbusPrototype):
gajim.config.del_per(key_path[0], key_path[1], key_path[2])
return True
@dbus.service.method(INTERFACE)
def prefs_put(self, *args):
[key] = self._get_real_arguments(args, 1)
if not key:
@ -488,6 +437,7 @@ class SignalObject(DbusPrototype):
gajim.config.set_per(key_path[0], key_path[1], subname, value)
return True
@dbus.service.method(INTERFACE)
def add_contact(self, *args):
[jid, account] = self._get_real_arguments(args, 2)
if account:
@ -503,6 +453,7 @@ class SignalObject(DbusPrototype):
AddNewContactWindow(account = None, jid = jid)
return True
@dbus.service.method(INTERFACE)
def remove_contact(self, *args):
[jid, account] = self._get_real_arguments(args, 2)
jid = self._get_real_jid(jid, account)
@ -597,9 +548,11 @@ class SignalObject(DbusPrototype):
contact_dict['resources'] = DBUS_VARIANT(contact_dict['resources'])
return contact_dict
@dbus.service.method(INTERFACE)
def get_unread_msgs_number(self, *args):
return str(gajim.events.get_nb_events)
@dbus.service.method(INTERFACE)
def start_chat(self, *args):
[account] = self._get_real_arguments(args, 1)
if not account:
@ -608,6 +561,7 @@ class SignalObject(DbusPrototype):
NewChatDialog(account)
return True
@dbus.service.method(INTERFACE)
def send_xml(self, *args):
xml, account = self._get_real_arguments(args, 2)
if account:
@ -615,36 +569,3 @@ class SignalObject(DbusPrototype):
else:
for acc in gajim.contacts.get_accounts():
gajim.connections[acc].send_stanza(xml)
if dbus_support.version[1] >= 30 and dbus_support.version[1] <= 40:
method = dbus.method
signal = dbus.signal
elif dbus_support.version[1] >= 41:
method = dbus.service.method
signal = dbus.service.signal
# prevent using decorators, because they are not supported
# on python < 2.4
# FIXME: use decorators when python2.3 (and dbus 0.23) is OOOOOOLD
toggle_roster_appearance = method(INTERFACE)(toggle_roster_appearance)
list_contacts = method(INTERFACE)(list_contacts)
list_accounts = method(INTERFACE)(list_accounts)
show_next_unread = method(INTERFACE)(show_next_unread)
change_status = method(INTERFACE)(change_status)
open_chat = method(INTERFACE)(open_chat)
contact_info = method(INTERFACE)(contact_info)
send_message = method(INTERFACE)(send_chat_message)
send_single_message = method(INTERFACE)(send_single_message)
send_file = method(INTERFACE)(send_file)
prefs_list = method(INTERFACE)(prefs_list)
prefs_put = method(INTERFACE)(prefs_put)
prefs_del = method(INTERFACE)(prefs_del)
prefs_store = method(INTERFACE)(prefs_store)
remove_contact = method(INTERFACE)(remove_contact)
add_contact = method(INTERFACE)(add_contact)
get_status = method(INTERFACE)(get_status)
get_status_message = method(INTERFACE)(get_status_message)
account_info = method(INTERFACE)(account_info)
get_unread_msgs_number = method(INTERFACE)(get_unread_msgs_number)
start_chat = method(INTERFACE)(start_chat)
send_xml = method(INTERFACE)(send_xml)

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
## roster_window.py
##
## Copyright (C) 2003-2006 Yann Le Boulanger <asterix@lagaule.org>
@ -39,6 +40,10 @@ from chat_control import ChatControl
from groupchat_control import GroupchatControl
from groupchat_control import PrivateChatControl
import dbus_support
if dbus_support.supported:
from music_track_listener import MusicTrackListener
#(icon, name, type, jid, account, editable, second pixbuf)
(
C_IMG, # image to show state (online, new message etc)
@ -50,9 +55,6 @@ C_EDITABLE, # cellrenderer text that holds name editable or not?
C_SECPIXBUF, # secondary_pixbuf (holds avatar or padlock)
) = range(7)
DEFAULT_ICONSET = 'dcraven'
class RosterWindow:
'''Class for main window of gtkgui interface'''
@ -624,9 +626,6 @@ class RosterWindow:
self.join_gc_room(account, bookmark['jid'], bookmark['nick'],
bookmark['password'])
def on_bm_header_changed_state(self, widget, event):
widget.set_state(gtk.STATE_NORMAL) #do not allow selected_state
def on_send_server_message_menuitem_activate(self, widget, account):
server = gajim.config.get_per('accounts', account, 'hostname')
server += '/announce/online'
@ -717,6 +716,11 @@ class RosterWindow:
return
new_chat_menuitem = self.xml.get_widget('new_chat_menuitem')
join_gc_menuitem = self.xml.get_widget('join_gc_menuitem')
iconset = gajim.config.get('iconset')
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
state_images = self.load_iconset(path)
if state_images.has_key('muc_active'):
join_gc_menuitem.set_image(state_images['muc_active'])
add_new_contact_menuitem = self.xml.get_widget('add_new_contact_menuitem')
service_disco_menuitem = self.xml.get_widget('service_disco_menuitem')
advanced_menuitem = self.xml.get_widget('advanced_menuitem')
@ -787,7 +791,7 @@ class RosterWindow:
label.set_use_underline(False)
gc_item = gtk.MenuItem()
gc_item.add(label)
gc_item.connect('state-changed', self.on_bm_header_changed_state)
gc_item.connect('state-changed', gtkgui_helpers.on_bm_header_changed_state)
gc_sub_menu.append(gc_item)
self.add_bookmarks_list(gc_sub_menu, account)
@ -1084,8 +1088,12 @@ class RosterWindow:
win.redraw_tab(ctrl)
name = contact.get_shown_name()
if contact.resource != '':
# if multiple resources (or second one disconnecting)
if (len(contact_instances) > 1 or (len(contact_instances) == 1 and \
show in ('offline', 'error'))) and contact.resource != '':
name += '/' + contact.resource
uf_show = helpers.get_uf_show(show)
if status:
ctrl.print_conversation(_('%s is now %s (%s)') % (name, uf_show,
@ -1204,7 +1212,7 @@ class RosterWindow:
gajim.connections[account].request_register_agent_info(contact.jid)
def on_remove_agent(self, widget, list_):
'''When an agent is requested to log in or off. list_ is a list of
'''When an agent is requested to be removed. list_ is a list of
(contact, account) tuple'''
for (contact, account) in list_:
if gajim.config.get_per('accounts', account, 'hostname') == \
@ -1226,6 +1234,17 @@ class RosterWindow:
gajim.contacts.remove_jid(account, contact.jid)
gajim.contacts.remove_contact(account, contact)
# Check if there are unread events from some contacts
has_unread_events = False
for (contact, account) in list_:
for jid in gajim.events.get_events(account):
if jid.endswith(contact.jid):
has_unread_events = True
break
if has_unread_events:
dialogs.ErrorDialog(_('You have unread messages'),
_('You must read them before removing this transport.'))
return
if len(list_) == 1:
pritext = _('Transport "%s" will be removed') % contact.jid
sectext = _('You will no longer be able to send and receive messages to contacts from this transport.')
@ -1332,7 +1351,7 @@ class RosterWindow:
'''Make contact's popup menu'''
model = self.tree.get_model()
jid = model[iter][C_JID].decode('utf-8')
path = model.get_path(iter)
tree_path = model.get_path(iter)
account = model[iter][C_ACCOUNT].decode('utf-8')
our_jid = jid == gajim.get_jid_from_account(account)
contact = gajim.contacts.get_contact_with_highest_priority(account, jid)
@ -1368,6 +1387,12 @@ class RosterWindow:
img.set_from_file(path_to_kbd_input_img)
rename_menuitem.set_image(img)
iconset = gajim.config.get('iconset')
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
state_images = self.load_iconset(path)
if state_images.has_key('muc_active'):
invite_menuitem.set_image(state_images['muc_active'])
above_subscription_separator = xml.get_widget(
'above_subscription_separator')
subscription_menuitem = xml.get_widget('subscription_menuitem')
@ -1387,8 +1412,6 @@ class RosterWindow:
start_chat_menuitem.set_submenu(sub_menu)
iconset = gajim.config.get('iconset')
if not iconset:
iconset = DEFAULT_ICONSET
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
for c in contacts:
# icon MUST be different instance for every item
@ -1403,7 +1426,7 @@ class RosterWindow:
else: # one resource
start_chat_menuitem.connect('activate',
self.on_roster_treeview_row_activated, path)
self.on_roster_treeview_row_activated, tree_path)
if contact.resource:
send_file_menuitem.connect('activate',
@ -1444,7 +1467,7 @@ class RosterWindow:
menuitem.connect('activate', self.on_invite_to_room,
[(contact, account)], room_jid, acct)
submenu.append(menuitem)
rename_menuitem.connect('activate', self.on_rename, iter, path)
rename_menuitem.connect('activate', self.on_rename, iter, tree_path)
remove_from_roster_menuitem.connect('activate', self.on_req_usub,
[(contact, account)])
information_menuitem.connect('activate', self.on_info, contact,
@ -1774,8 +1797,6 @@ class RosterWindow:
# we have to create our own set of icons for the menu
# using self.jabber_status_images is poopoo
iconset = gajim.config.get('iconset')
if not iconset:
iconset = DEFAULT_ICONSET
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
state_images = self.load_iconset(path)
@ -1908,8 +1929,6 @@ class RosterWindow:
else:
menu = gtk.Menu()
iconset = gajim.config.get('iconset')
if not iconset:
iconset = DEFAULT_ICONSET
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
accounts = [] # Put accounts in a list to sort them
for account in gajim.connections:
@ -2419,6 +2438,41 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
self.send_status(acct, status, message)
self.update_status_combobox()
## enable setting status msg from currently playing music track
def enable_syncing_status_msg_from_current_music_track(self, enabled):
'''if enabled is True, we listen to events from music players about
currently played music track, and we update our
status message accordinly'''
if not dbus_support.supported:
# do nothing if user doesn't have D-Bus bindings
return
if enabled:
if self._music_track_changed_signal is None:
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)
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)
def _music_track_changed(self, unused_listener, music_track_info):
accounts = gajim.connections.keys()
if music_track_info is None:
status_message = ''
else:
status_message = _('"%(title)s" by %(artist)s') % \
{'title': music_track_info.title,
'artist': music_track_info.artist }
for acct in accounts:
current_show = gajim.SHOW_LIST[gajim.connections[acct].connected]
self.send_status(acct, current_show, status_message)
def update_status_combobox(self):
# table to change index in connection.connected to index in combobox
table = {'offline':9, 'connecting':9, 'online':0, 'chat':1, 'away':2,
@ -2599,12 +2653,12 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
# We save it in a queue
type_ = 'chat'
event_type = 'message_received'
if msg_type == 'normal':
type_ = 'normal'
show_in_roster = notify.get_show_in_roster('message_received', account,
contact)
show_in_systray = notify.get_show_in_systray('message_received', account,
contact)
event_type = 'single_message_received'
show_in_roster = notify.get_show_in_roster(event_type, account, contact)
show_in_systray = notify.get_show_in_systray(event_type, account, contact)
event = gajim.events.create_event(type_, (msg, subject, msg_type, tim,
encrypted, resource, msg_id), show_in_roster = show_in_roster,
show_in_systray = show_in_systray)
@ -3134,8 +3188,13 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
def make_jabber_state_images(self):
'''initialise jabber_state_images dict'''
iconset = gajim.config.get('iconset')
if not iconset:
iconset = 'dcraven'
if iconset:
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
if not os.path.exists(path):
iconset = gajim.config.DEFAULT_ICONSET
else:
iconset = gajim.config.DEFAULT_ICONSET
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '32x32')
self.jabber_state_images['32'] = self.load_iconset(path)
@ -3174,7 +3233,8 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
model[iter][1] = self.jabber_state_images['16'][model[iter][2]]
iter = model.iter_next(iter)
# Update the systray
gajim.interface.systray.set_img()
if gajim.interface.systray_enabled:
gajim.interface.systray.set_img()
for win in gajim.interface.msg_win_mgr.windows():
for ctrl in win.controls():
@ -3722,6 +3782,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
def __init__(self):
self.xml = gtkgui_helpers.get_glade('roster_window.glade')
self.window = self.xml.get_widget('roster_window')
self._music_track_changed_signal = None
gajim.interface.msg_win_mgr = MessageWindowMgr()
self.advanced_menus = [] # We keep them to destroy them
if gajim.config.get('roster_window_skip_taskbar'):
@ -3898,6 +3959,13 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
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.
gobject.timeout_add(1000,
self.enable_syncing_status_msg_from_current_music_track,
gajim.config.get('set_status_msg_from_current_music_track'))
if gajim.config.get('show_roster_on_startup'):
self.window.show_all()
else:

View File

@ -124,11 +124,12 @@ class Systray:
# We need our own set of status icons, let's make 'em!
iconset = gajim.config.get('iconset')
if not iconset:
iconset = 'dcraven'
path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16')
state_images = gajim.interface.roster.load_iconset(path)
if state_images.has_key('muc_active'):
join_gc_menuitem.set_image(state_images['muc_active'])
for show in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
uf_show = helpers.get_uf_show(show, use_mnemonic = True)
item = gtk.ImageMenuItem(uf_show)
@ -194,6 +195,7 @@ class Systray:
label.set_use_underline(False)
gc_item = gtk.MenuItem()
gc_item.add(label)
gc_item.connect('state-changed', gtkgui_helpers.on_bm_header_changed_state)
gc_sub_menu.append(gc_item)
gajim.interface.roster.add_bookmarks_list(gc_sub_menu, account)
@ -250,11 +252,11 @@ class Systray:
if len(gajim.events.get_systray_events()) == 0:
# no pending events, so toggle visible/hidden for roster window
if win.get_property('visible'): # visible in ANY virtual desktop?
win.hide() # we hide it from VD that was visible in
# but we could be in another VD right now. eg vd2
# and we want not only to hide it in vd1 but also show it in vd2
gtkgui_helpers.possibly_move_window_in_current_desktop(win)
# we could be in another VD right now. eg vd2
# and we want to show it in vd2
if not gtkgui_helpers.possibly_move_window_in_current_desktop(win):
win.hide() # else we hide it from VD that was visible in
else:
win.present()
else:

View File

@ -61,6 +61,7 @@ class VcardWindow:
# the contact variable is the jid if vcard is true
self.xml = gtkgui_helpers.get_glade('vcard_information_window.glade')
self.window = self.xml.get_widget('vcard_information_window')
self.progressbar = self.xml.get_widget('progressbar')
self.contact = contact
self.account = account
@ -68,13 +69,23 @@ class VcardWindow:
self.avatar_mime_type = None
self.avatar_encoded = None
self.vcard_arrived = False
self.os_info_arrived = False
self.update_progressbar_timeout_id = gobject.timeout_add(100,
self.update_progressbar)
self.fill_jabber_page()
self.xml.signal_autoconnect(self)
self.window.show_all()
def update_progressbar(self):
self.progressbar.pulse()
return True # loop forever
def on_vcard_information_window_destroy(self, widget):
if self.update_progressbar_timeout_id is not None:
gobject.source_remove(self.update_progressbar_timeout_id)
del gajim.interface.instances[self.account]['infos'][self.contact.jid]
def on_vcard_information_window_key_press_event(self, widget, event):
@ -113,7 +124,15 @@ class VcardWindow:
def set_value(self, entry_name, value):
try:
self.xml.get_widget(entry_name).set_text(value)
if value and entry_name == 'URL_label':
if gtk.pygtk_version >= (2, 10, 0) and gtk.gtk_version >= (2, 10, 0):
widget = gtk.LinkButton(value, value)
else:
widget = gtk.Label(value)
table = self.xml.get_widget('personal_info_table')
table.attach(widget, 1, 4, 3, 4, yoptions = 0)
else:
self.xml.get_widget(entry_name).set_text(value)
except AttributeError:
pass
@ -144,8 +163,17 @@ class VcardWindow:
if i == 'DESC':
self.xml.get_widget('DESC_textview').get_buffer().set_text(
vcard[i], 0)
else:
elif i != 'jid': # Do not override jid_label
self.set_value(i + '_label', vcard[i])
self.vcard_arrived = True
self.test_remove_progressbar()
def test_remove_progressbar(self):
if self.update_progressbar_timeout_id is not None and \
self.vcard_arrived and self.os_info_arrived:
gobject.source_remove(self.update_progressbar_timeout_id)
self.progressbar.hide()
self.update_progressbar_timeout_id = None
def set_last_status_time(self):
self.fill_status_label()
@ -174,6 +202,8 @@ class VcardWindow:
os = Q_('?OS:Unknown')
self.xml.get_widget('client_name_version_label').set_text(client)
self.xml.get_widget('os_label').set_text(os)
self.os_info_arrived = True
self.test_remove_progressbar()
def fill_status_label(self):
if self.xml.get_widget('information_notebook').get_n_pages() < 4:
@ -251,8 +281,10 @@ class VcardWindow:
gajim.connections[self.account].request_last_status_time(self.contact.jid,
self.contact.resource)
# Request os info in contact is connected
if self.contact.show not in ('offline', 'error'):
# do not wait for os_info if contact is not connected
if self.contact.show in ('offline', 'error'):
self.os_info_arrived = True
else: # Request os info if contact is connected
gobject.idle_add(gajim.connections[self.account].request_os_info,
self.contact.jid, self.contact.resource)
self.os_info = {0: {'resource': self.contact.resource, 'client': '',
@ -283,3 +315,6 @@ class VcardWindow:
self.fill_status_label()
gajim.connections[self.account].request_vcard(self.contact.jid, self.is_fake)
def on_close_button_clicked(self, widget):
self.window.destroy()