merged trunk into session_centric branch
This commit is contained in:
parent
b8882ba48e
commit
0b48b05218
68 changed files with 13704 additions and 7863 deletions
13
TODO.pep
Normal file
13
TODO.pep
Normal file
|
@ -0,0 +1,13 @@
|
|||
• configure access model when changing it in the combobox
|
||||
• PEP in status change
|
||||
|
||||
Tune use cases:
|
||||
• on disconnection of an account set Tune to None
|
||||
|
||||
Tooltips use cases:
|
||||
• Show PEP in GC tooltips
|
||||
|
||||
Mood/Activity use cases
|
||||
• on connection of an account set them to None
|
||||
• on disconnection of an account set them to None
|
||||
• on explicit set publish them
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
echo "[encoding: UTF-8]" > po/POTFILES.in \
|
||||
&& ls -1 -U data/gajim.desktop.in.in data/glade/*.glade \
|
||||
src/*py src/common/*py src/common/zeroconf/*.py >> \
|
||||
src/*py src/common/*py src/common/zeroconf/*.py src/osx/*.py >> \
|
||||
po/POTFILES.in || exit 1
|
||||
if test -z `which pkg-config 2>/dev/null`;then
|
||||
echo "***Error: pkg-config not found***"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
AC_INIT([Gajim - A Jabber Instant Messager],
|
||||
[0.11.4.0-svn],[http://trac.gajim.org/],[gajim])
|
||||
[0.11.4.2-svn],[http://trac.gajim.org/],[gajim])
|
||||
AC_PREREQ([2.59])
|
||||
AM_INIT_AUTOMAKE([1.8])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
|
|
@ -14,7 +14,13 @@ sounds_DATA = $(srcdir)/sounds/*.wav
|
|||
otherdir = $(pkgdatadir)/data/other
|
||||
other_DATA = other/servers.xml other/cacerts.pem
|
||||
|
||||
man_MANS = gajim.1 gajim-remote.1
|
||||
if BUILD_REMOTE_CONTROL
|
||||
OPTIONAL_MAN = gajim-remote.1
|
||||
else
|
||||
OPTIONAL_MAN =
|
||||
endif
|
||||
|
||||
man_MANS = gajim.1 $(OPTIONAL_MAN)
|
||||
|
||||
|
||||
EXTRA_DIST = $(desktop_in_files) \
|
||||
|
|
|
@ -17,6 +17,20 @@
|
|||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkImageMenuItem" id="pep_menuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Personal Events</property>
|
||||
<property name="use_underline">True</property>
|
||||
<child internal-child="image">
|
||||
<widget class="GtkImage" id="menu-item-image7">
|
||||
<property name="stock">gtk-home</property>
|
||||
<property name="icon_size">1</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||
<property name="visible">True</property>
|
||||
|
|
|
@ -117,7 +117,7 @@ to the Jabber network.</property>
|
|||
<widget class="GtkLabel" id="label270">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes"><b>Please fill in the data for your new account</b></property>
|
||||
<property name="label" translatable="yes"><b>Please fill in the data for your existing account</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-add</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_add_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -66,6 +67,7 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-remove</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_remove_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -79,6 +81,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_rename_button_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox8">
|
||||
|
@ -138,6 +141,7 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -152,9 +156,6 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
|
@ -175,34 +176,135 @@
|
|||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="resource_entry1">
|
||||
<widget class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Jabber ID:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Password:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="password_entry1">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">Resource is sent to the Jabber server in order to separate the same JID in two or more parts depending on the number of the clients connected in the same server with the same account. So you might be connected in the same account with resource 'Home' and 'Work' at the same time. The resource which has the highest priority will get the events. (see below)</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="invisible_char">*</property>
|
||||
<property name="text" translatable="yes">Gajim</property>
|
||||
<signal name="focus_out_event" handler="on_resource_entry1_focus_out_event"/>
|
||||
<property name="activates_default">True</property>
|
||||
<signal name="changed" handler="on_password_entry1_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="jid_entry1">
|
||||
<widget class="GtkCheckButton" id="save_password_checkbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="invisible_char">*</property>
|
||||
<property name="activates_default">True</property>
|
||||
<signal name="focus_out_event" handler="on_jid_entry1_focus_out_event"/>
|
||||
<property name="tooltip" translatable="yes">If checked, Gajim will remember the password for this account</property>
|
||||
<property name="label" translatable="yes">Save pass_word</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_save_password_checkbutton1_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Resour_ce:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Priori_ty:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="adjust_priority_with_status_checkbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">Priority will change automatically according to your status.</property>
|
||||
<property name="label" translatable="yes">_Adjust to status</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_adjust_priority_with_status_checkbutton1_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="priority_spinbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">Priority is used in Jabber to determine who gets the events from the jabber server when two or more clients are connected using the same account; The client with the highest priority gets the events</property>
|
||||
<property name="adjustment">5 0 127 1 5 5</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="numeric">True</property>
|
||||
<signal name="value_changed" handler="on_priority_spinbutton1_value_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -222,6 +324,7 @@
|
|||
<property name="tooltip" translatable="yes">Click to request authorization to all contacts of another account</property>
|
||||
<property name="label" translatable="yes">Synchronise contacts</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_synchronise_contacts_button1_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -235,6 +338,7 @@
|
|||
<property name="tooltip" translatable="yes">Click to change account's password</property>
|
||||
<property name="label" translatable="yes">Chan_ge Password</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_change_password_button1_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -263,140 +367,38 @@
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSpinButton" id="priority_spinbutton1">
|
||||
<widget class="GtkEntry" id="jid_entry1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">Priority is used in Jabber to determine who gets the events from the jabber server when two or more clients are connected using the same account; The client with the highest priority gets the events</property>
|
||||
<property name="adjustment">5 0 127 1 5 5</property>
|
||||
<property name="climb_rate">1</property>
|
||||
<property name="numeric">True</property>
|
||||
<signal name="value_changed" handler="on_priority_spinbutton1_value_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="adjust_priority_with_status_checkbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">Priority will change automatically according to your status.</property>
|
||||
<property name="label" translatable="yes">_Adjust to status</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_adjust_priority_with_status_checkbutton1_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Priori_ty:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Resour_ce:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="save_password_checkbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">If checked, Gajim will remember the password for this account</property>
|
||||
<property name="label" translatable="yes">Save pass_word</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_save_password_checkbutton1_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="password_entry1">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="invisible_char">*</property>
|
||||
<property name="activates_default">True</property>
|
||||
<signal name="changed" handler="on_password_entry1_changed"/>
|
||||
<signal name="focus_out_event" handler="on_jid_entry1_focus_out_event"/>
|
||||
</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="right_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="resource_entry1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">Resource is sent to the Jabber server in order to separate the same JID in two or more parts depending on the number of the clients connected in the same server with the same account. So you might be connected in the same account with resource 'Home' and 'Work' at the same time. The resource which has the highest priority will get the events. (see below)</property>
|
||||
<property name="invisible_char">*</property>
|
||||
<property name="text" translatable="yes">Gajim</property>
|
||||
<signal name="focus_out_event" handler="on_resource_entry1_focus_out_event"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label3">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Password:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Jabber ID:</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label7">
|
||||
|
@ -405,7 +407,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -421,6 +422,7 @@
|
|||
<property name="tooltip" translatable="yes">If checked, Gajim, when launched, will automatically connect to jabber using this account</property>
|
||||
<property name="label" translatable="yes">C_onnect on Gajim startup</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_autoconnect_checkbutton_toggled"/>
|
||||
</widget>
|
||||
|
@ -435,6 +437,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Auto-reconnect when connection is lost</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_autoreconnect_checkbutton_toggled"/>
|
||||
</widget>
|
||||
|
@ -450,6 +453,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Save conversation _logs for all contacts</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_log_history_checkbutton_toggled"/>
|
||||
|
@ -467,6 +471,7 @@
|
|||
<property name="tooltip" translatable="yes">If checked, any change to the global status (handled by the combobox at the bottom of the roster window) will change the status of this account accordingly</property>
|
||||
<property name="label" translatable="yes">Synch_ronize account status with global status</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_sync_with_global_status_checkbutton_toggled"/>
|
||||
</widget>
|
||||
|
@ -483,6 +488,7 @@
|
|||
<property name="tooltip" translatable="yes">If checked, Gajim will also broadcast some more IPs except from just your IP, so file transfer has higher chances of working.</property>
|
||||
<property name="label" translatable="yes">Use file transfer proxies</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_use_ft_proxies_checkbutton1_toggled"/>
|
||||
</widget>
|
||||
|
@ -495,7 +501,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -507,7 +512,6 @@
|
|||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -517,29 +521,46 @@
|
|||
<property name="border_width">6</property>
|
||||
<property name="spacing">12</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2">
|
||||
<widget class="GtkFrame" id="frame3">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox11">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label9">
|
||||
<widget class="GtkCheckButton" id="use_env_http_proxy_checkbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Proxy:</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">use HTTP_PROXY environment variable</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_use_env_http_proxy_checkbutton1_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="proxy_hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="proxies_combobox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="items" translatable="yes" comments="None means no proxy profile selected">None</property>
|
||||
<signal name="changed" handler="on_proxies_combobox1_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="manage_proxies_button1">
|
||||
|
@ -547,19 +568,38 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Manage...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_manage_proxies_button1_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label9">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes"><b>Proxy</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="misc_frame1">
|
||||
<property name="visible">True</property>
|
||||
|
@ -575,14 +615,15 @@
|
|||
<property name="border_width">6</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="use_ssl_checkbutton1">
|
||||
<widget class="GtkCheckButton" id="warn_when_insecure_connection_checkbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip" translatable="yes">Check this so Gajim will connect in port 5223 where legacy servers are expected to have SSL capabilities. Note that Gajim uses TLS encryption by default if broadcasted by the server, and with this option enabled TLS will be disabled</property>
|
||||
<property name="label" translatable="yes">Use _SSL (legacy)</property>
|
||||
<property name="tooltip" translatable="yes">Check this so Gajim will ask you before sending your password over an insecure connection.</property>
|
||||
<property name="label" translatable="yes">_Warn before using an insecure connection</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_use_ssl_checkbutton1_toggled"/>
|
||||
<signal name="toggled" handler="on_warn_when_insecure_connection_checkbutton1_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -596,6 +637,7 @@
|
|||
<property name="tooltip" translatable="yes">If checked, Gajim will send keep-alive packets to prevent connection timeout which results in disconnection</property>
|
||||
<property name="label" translatable="yes">Send keep-alive packets</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_send_keepalive_checkbutton1_toggled"/>
|
||||
|
@ -612,6 +654,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Use custom hostname/port</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_custom_host_port_checkbutton1_toggled"/>
|
||||
</widget>
|
||||
|
@ -700,7 +743,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -711,7 +753,6 @@
|
|||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">2</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -766,6 +807,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Choose _Key...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_gpg_choose_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -787,12 +829,14 @@
|
|||
<property name="tooltip" translatable="yes">If checked, Gajim will get the password from a GPG agent like seahorse</property>
|
||||
<property name="label" translatable="yes">Use GPG _Agent</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_use_gpg_agent_checkbutton_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -831,6 +875,7 @@
|
|||
<property name="tooltip" translatable="yes">Information about you, as stored in the server</property>
|
||||
<property name="label" translatable="yes">Edit Personal Information...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_edit_details_button1_clicked"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
@ -855,7 +900,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -866,14 +910,12 @@
|
|||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">3</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -892,6 +934,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Enable</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_enable_zeroconf_checkbutton2_toggled"/>
|
||||
</widget>
|
||||
|
@ -915,6 +958,7 @@
|
|||
<property name="tooltip" translatable="yes">If checked, Gajim, when launched, will automatically connect to jabber using this account</property>
|
||||
<property name="label" translatable="yes">C_onnect on Gajim startup</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_autoconnect_checkbutton_toggled"/>
|
||||
</widget>
|
||||
|
@ -929,6 +973,7 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Save conversation _logs for all contacts</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_log_history_checkbutton_toggled"/>
|
||||
</widget>
|
||||
|
@ -945,6 +990,7 @@
|
|||
<property name="tooltip" translatable="yes">If checked, any change to the global status (handled by the combobox at the bottom of the roster window) will change the status of this account accordingly</property>
|
||||
<property name="label" translatable="yes">Synch_ronize account status with global status</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_sync_with_global_status_checkbutton_toggled"/>
|
||||
</widget>
|
||||
|
@ -965,6 +1011,7 @@
|
|||
You might consider to change possible firewall settings.</property>
|
||||
<property name="label" translatable="yes">Use custom port:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_custom_port_checkbutton2_toggled"/>
|
||||
</widget>
|
||||
|
@ -994,9 +1041,6 @@ You might consider to change possible firewall settings.</property>
|
|||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label11">
|
||||
|
@ -1006,7 +1050,6 @@ You might consider to change possible firewall settings.</property>
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -1018,125 +1061,6 @@ You might consider to change possible firewall settings.</property>
|
|||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<property name="row_spacing">5</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="jabber_id_entry2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_jabber_id_entry2_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label12">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Jabber ID:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label13">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">E-Mail:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="email_entry2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_email_entry2_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label14">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Last Name:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="last_name_entry2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_last_name_entry2_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</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="label15">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">First Name:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="first_name_entry2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_first_name_entry2_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label16">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes"><b>Personal Information</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox10">
|
||||
<property name="visible">True</property>
|
||||
|
@ -1181,6 +1105,7 @@ You might consider to change possible firewall settings.</property>
|
|||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Choose _Key...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_gpg_choose_button_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -1201,12 +1126,14 @@ You might consider to change possible firewall settings.</property>
|
|||
<property name="tooltip" translatable="yes">If checked, Gajim will get the password from a GPG agent like seahorse</property>
|
||||
<property name="label" translatable="yes">Use GPG _Agent</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_use_gpg_agent_checkbutton_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -1215,10 +1142,128 @@ You might consider to change possible firewall settings.</property>
|
|||
<property name="x_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label16">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes"><b>Personal Information</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="first_name_entry2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_first_name_entry2_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label15">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">First Name:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="last_name_entry2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_last_name_entry2_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</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="label14">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Last Name:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="email_entry2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_email_entry2_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label13">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">E-Mail:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label12">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Jabber ID:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="jabber_id_entry2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="changed" handler="on_jabber_id_entry2_changed"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1229,7 +1274,6 @@ You might consider to change possible firewall settings.</property>
|
|||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -1241,7 +1285,6 @@ You might consider to change possible firewall settings.</property>
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1251,6 +1294,10 @@ You might consider to change possible firewall settings.</property>
|
|||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
|
@ -1261,24 +1308,14 @@ You might consider to change possible firewall settings.</property>
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Mer_ge accounts</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_merge_checkbutton_toggled"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHSeparator" id="hseparator2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
|
@ -1293,6 +1330,7 @@ You might consider to change possible firewall settings.</property>
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_close_button_clicked"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
|
158
data/glade/change_activity_dialog.glade
Normal file
158
data/glade/change_activity_dialog.glade
Normal file
|
@ -0,0 +1,158 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
|
||||
<widget class="GtkDialog" id="change_activity_dialog">
|
||||
<property name="border_width">6</property>
|
||||
<property name="title" translatable="yes"></property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">270</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">True</property>
|
||||
<signal name="key_press_event" handler="on_change_status_message_dialog_key_press_event" last_modification_time="Wed, 16 Mar 2005 00:53:06 GMT"/>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancel_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="ok_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame38">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="label_yalign">0.5</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment107">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox112">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="combobox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="add_tearoffs">False</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="combobox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="add_tearoffs">False</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="visibility">True</property>
|
||||
<property name="max_length">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
<property name="has_frame">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="activates_default">False</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
145
data/glade/change_mood_dialog.glade
Normal file
145
data/glade/change_mood_dialog.glade
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
|
||||
<widget class="GtkDialog" id="change_mood_dialog">
|
||||
<property name="border_width">6</property>
|
||||
<property name="title" translatable="yes"></property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">270</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">True</property>
|
||||
<signal name="key_press_event" handler="on_change_status_message_dialog_key_press_event" last_modification_time="Wed, 16 Mar 2005 00:53:06 GMT"/>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancel_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="ok_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame38">
|
||||
<property name="visible">True</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="label_yalign">0.5</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment107">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">0</property>
|
||||
<property name="bottom_padding">0</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox112">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="combobox">
|
||||
<property name="visible">True</property>
|
||||
<property name="add_tearoffs">False</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="visibility">True</property>
|
||||
<property name="max_length">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
<property name="has_frame">True</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="activates_default">False</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
|
@ -43,7 +43,7 @@
|
|||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox2">
|
||||
<widget class="GtkVBox" id="welcome_vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
|
|
135
data/glade/manage_pep_services_window.glade
Normal file
135
data/glade/manage_pep_services_window.glade
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||
|
||||
<glade-interface>
|
||||
|
||||
<widget class="GtkWindow" id="manage_pep_services_window">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="title" translatable="yes"></property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">350</property>
|
||||
<property name="default_height">150</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<signal name="destroy" handler="on_manage_pep_services_window_destroy"/>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTreeView" id="services_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="headers_visible">True</property>
|
||||
<property name="rules_hint">False</property>
|
||||
<property name="reorderable">False</property>
|
||||
<property name="enable_search">True</property>
|
||||
<property name="fixed_height_mode">False</property>
|
||||
<property name="hover_selection">False</property>
|
||||
<property name="hover_expand">False</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="add_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-add</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<signal name="clicked" handler="on_add_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="delete_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-delete</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<signal name="clicked" handler="on_delete_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancel_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
<signal name="clicked" handler="on_cancel_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:58:52 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="ok_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-ok</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<signal name="clicked" handler="on_ok_button_clicked" last_modification_time="Sat, 31 Mar 2007 07:57:55 GMT"/>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
|
@ -107,6 +107,20 @@
|
|||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="lock_image">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="stock">gtk-dialog-authentication</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="message_scrolledwindow">
|
||||
<property name="visible">True</property>
|
||||
|
@ -119,6 +133,11 @@
|
|||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
|
@ -136,38 +155,6 @@
|
|||
<widget class="GtkHBox" id="hbox3006">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">1</property>
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="gpg_eventbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">OpenPGP Encryption</property>
|
||||
<child>
|
||||
<widget class="GtkToggleButton" id="gpg_togglebutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="relief">GTK_RELIEF_NONE</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1333">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-dialog-authentication</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVSeparator" id="vseparator4">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -399,6 +386,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="muc_child_vbox">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">3</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment103">
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -193,6 +193,14 @@
|
|||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkMenuItem" id="pep_services_menuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Services</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -222,6 +230,17 @@
|
|||
<signal name="activate" handler="on_show_transports_menuitem_activate"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkCheckMenuItem" id="show_roster_menuitem">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Show _roster</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="active">True</property>
|
||||
<signal name="toggled" handler="on_show_roster_menuitem_toggled"/>
|
||||
<accelerator key="R" modifiers="GDK_CONTROL_MASK" signal="activate"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkSeparatorMenuItem" id="separator3">
|
||||
<property name="visible">True</property>
|
||||
|
@ -343,6 +362,15 @@
|
|||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHPaned" id="roster_hpaned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="roster_vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow">
|
||||
<property name="visible">True</property>
|
||||
|
@ -369,9 +397,6 @@
|
|||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="status_combobox">
|
||||
|
@ -380,7 +405,21 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
<property name="xpad">5</property>
|
||||
<property name="ypad">5</property>
|
||||
<property name="selectable">True</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_END</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -94,6 +95,7 @@
|
|||
<property name="xpad">5</property>
|
||||
<property name="ypad">5</property>
|
||||
<property name="selectable">True</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_END</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
@ -218,8 +220,8 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label59">
|
||||
<property name="visible">True</property>
|
||||
<widget class="GtkLabel" id="user_avatar_label">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="label" translatable="yes">User avatar:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -227,17 +229,6 @@
|
|||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="no_user_avatar_label">
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="label" translatable="yes">None</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="PHOTO_eventbox">
|
||||
<property name="visible">True</property>
|
||||
|
@ -254,7 +245,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -265,7 +256,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -277,11 +268,12 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">4</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -384,9 +376,6 @@
|
|||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label3">
|
||||
|
@ -397,7 +386,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -1014,7 +1002,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1027,7 +1014,6 @@
|
|||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">1</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -1459,7 +1445,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1472,7 +1457,6 @@
|
|||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">2</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -1497,7 +1481,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1510,7 +1493,6 @@
|
|||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">3</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -1533,7 +1515,6 @@
|
|||
</widget>
|
||||
<packing>
|
||||
<property name="position">4</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -1544,7 +1525,6 @@
|
|||
<packing>
|
||||
<property name="type">tab</property>
|
||||
<property name="position">4</property>
|
||||
<property name="tab_expand">False</property>
|
||||
<property name="tab_fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -1588,6 +1568,7 @@
|
|||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
|
||||
data/gajim.desktop.in
|
||||
src/eggtrayicon.c
|
||||
|
|
402
po/fr.po
402
po/fr.po
|
@ -3570,7 +3570,7 @@ msgstr "Fichier"
|
|||
|
||||
#: ../src/filetransfers_window.py:87
|
||||
msgid "Time"
|
||||
msgstr "Moment"
|
||||
msgstr "Durée"
|
||||
|
||||
#: ../src/filetransfers_window.py:99
|
||||
msgid "Progress"
|
||||
|
@ -6537,6 +6537,406 @@ msgstr "Connecté"
|
|||
msgid "Disconnected"
|
||||
msgstr "Déconnecté"
|
||||
|
||||
#pep
|
||||
msgid "afraid"
|
||||
msgstr "appeuré"
|
||||
|
||||
msgid "amazed"
|
||||
msgstr "surpris, amusé"
|
||||
|
||||
msgid "angry"
|
||||
msgstr "en colère"
|
||||
|
||||
msgid "annoyed"
|
||||
msgstr "dérangé"
|
||||
|
||||
msgid "anxious"
|
||||
msgstr "anxieux"
|
||||
|
||||
msgid "aroused"
|
||||
msgstr "excité"
|
||||
|
||||
msgid "ashamed"
|
||||
msgstr "honteux/éhonté"
|
||||
|
||||
msgid "bored"
|
||||
msgstr "ennuyé"
|
||||
|
||||
msgid "brave"
|
||||
msgstr "courageux"
|
||||
|
||||
msgid "calm"
|
||||
msgstr "calme"
|
||||
|
||||
msgid "cold"
|
||||
msgstr "froid"
|
||||
|
||||
msgid "confused"
|
||||
msgstr "confus"
|
||||
|
||||
msgid "contented"
|
||||
msgstr "contenté"
|
||||
|
||||
msgid "cranky"
|
||||
msgstr "excentrique"
|
||||
|
||||
msgid "curious"
|
||||
msgstr "curieux"
|
||||
|
||||
msgid "depressed"
|
||||
msgstr "déprimé"
|
||||
|
||||
msgid "disappointed"
|
||||
msgstr "décu"
|
||||
|
||||
msgid "disgusted"
|
||||
msgstr "dégouté"
|
||||
|
||||
msgid "distracted"
|
||||
msgstr "distrait"
|
||||
|
||||
msgid "embarrassed"
|
||||
msgstr "embarssé"
|
||||
|
||||
msgid "excited"
|
||||
msgstr "excité"
|
||||
|
||||
msgid "flirtatious"
|
||||
msgstr "coquet"
|
||||
|
||||
msgid "frustrated"
|
||||
msgstr "frustré"
|
||||
|
||||
msgid "grumpy"
|
||||
msgstr "grognon"
|
||||
|
||||
msgid "guilty"
|
||||
msgstr "coupable"
|
||||
|
||||
msgid "happy"
|
||||
msgstr "joyeux"
|
||||
|
||||
msgid "hot"
|
||||
msgstr "chaud"
|
||||
|
||||
msgid "humbled"
|
||||
msgstr "humilié"
|
||||
|
||||
msgid "humiliated"
|
||||
msgstr "humilié"
|
||||
|
||||
msgid "hungry"
|
||||
msgstr "affamé"
|
||||
|
||||
msgid "hurt"
|
||||
msgstr "blessé"
|
||||
|
||||
msgid "impressed"
|
||||
msgstr "impressionné"
|
||||
|
||||
msgid "in_awe"
|
||||
msgstr "dans la crainte"
|
||||
|
||||
msgid "in_love"
|
||||
msgstr "amoureux"
|
||||
|
||||
msgid "indignant"
|
||||
msgstr "indigné"
|
||||
|
||||
msgid "interested"
|
||||
msgstr "interessé"
|
||||
|
||||
msgid "intoxicated"
|
||||
msgstr "intoxiqué"
|
||||
|
||||
msgid "invincible"
|
||||
msgstr "invincible"
|
||||
|
||||
msgid "jealous"
|
||||
msgstr "jaloux"
|
||||
|
||||
msgid "lonely"
|
||||
msgstr "seul/esseulé"
|
||||
|
||||
msgid "mean"
|
||||
msgstr "méchant"
|
||||
|
||||
msgid "moody"
|
||||
msgstr "déprimé"
|
||||
|
||||
msgid "nervous"
|
||||
msgstr "nerveux"
|
||||
|
||||
msgid "neutral"
|
||||
msgstr "neutre"
|
||||
|
||||
msgid "offended"
|
||||
msgstr "offensé"
|
||||
|
||||
msgid "playful"
|
||||
msgstr "joueur"
|
||||
|
||||
msgid "proud"
|
||||
msgstr "fier"
|
||||
|
||||
msgid "relieved"
|
||||
msgstr "soulagé"
|
||||
|
||||
msgid "remorseful"
|
||||
msgstr "plein de remord"
|
||||
|
||||
msgid "restless"
|
||||
msgstr "infatiguable"
|
||||
|
||||
msgid "sad"
|
||||
msgstr "triste"
|
||||
|
||||
msgid "sarcastic"
|
||||
msgstr "sarcastique"
|
||||
|
||||
msgid "serious"
|
||||
msgstr "serieux"
|
||||
|
||||
msgid "shocked"
|
||||
msgstr "choqué"
|
||||
|
||||
msgid "shy"
|
||||
msgstr "timide"
|
||||
|
||||
msgid "sick"
|
||||
msgstr "malade"
|
||||
|
||||
msgid "sleepy"
|
||||
msgstr "endormi"
|
||||
|
||||
msgid "stressed"
|
||||
msgstr "stressé"
|
||||
|
||||
msgid "surprised"
|
||||
msgstr "surpris"
|
||||
|
||||
msgid "thirsty"
|
||||
msgstr "assoiffé"
|
||||
|
||||
msgid "worried"
|
||||
msgstr "inquiet"
|
||||
|
||||
msgid "_Personnal Events"
|
||||
msgstr "Évènements _Personnels"
|
||||
|
||||
msgid "Activity"
|
||||
msgstr "Activité"
|
||||
|
||||
msgid "doing_chores"
|
||||
msgstr "fait des corvées"
|
||||
|
||||
msgid "buying_groceries"
|
||||
msgstr "achète des épiceries"
|
||||
|
||||
msgid "cleaning"
|
||||
msgstr "nettoie"
|
||||
|
||||
msgid "cooking"
|
||||
msgstr "cuisine"
|
||||
|
||||
msgid "doing_maintenance"
|
||||
msgstr "fait de la maintenance"
|
||||
|
||||
msgid "doing_the_dishes"
|
||||
msgstr "fait la vaiselle"
|
||||
|
||||
msgid "doing_the_laundry"
|
||||
msgstr "fait la blanchisserie"
|
||||
|
||||
msgid "gardening"
|
||||
msgstr "jardine"
|
||||
|
||||
msgid "running_an_errand"
|
||||
msgstr "fait une course"
|
||||
|
||||
msgid "walking_the_dog"
|
||||
msgstr "promène le chien"
|
||||
|
||||
msgid "drinking"
|
||||
msgstr "boit"
|
||||
|
||||
msgid "having_a_beer"
|
||||
msgstr "prend une bière"
|
||||
|
||||
msgid "having_coffee"
|
||||
msgstr "prend un café"
|
||||
|
||||
msgid "having_tea"
|
||||
msgstr "prend un thé"
|
||||
|
||||
msgid "eating"
|
||||
msgstr "mange"
|
||||
|
||||
msgid "having_a_snack"
|
||||
msgstr "prend un snack"
|
||||
|
||||
msgid "having_breakfast"
|
||||
msgstr "prend le petit-déjeuner"
|
||||
|
||||
msgid "having_dinner"
|
||||
msgstr "soupe"
|
||||
|
||||
msgid "having_lunch"
|
||||
msgstr "dîne"
|
||||
|
||||
msgid "exercising"
|
||||
msgstr "fait de l'exercice"
|
||||
|
||||
msgid "cycling"
|
||||
msgstr "fait du vélo"
|
||||
|
||||
msgid "hiking"
|
||||
msgstr "fait de la randonnée"
|
||||
|
||||
msgid "jogging"
|
||||
msgstr "fait un jogging"
|
||||
|
||||
msgid "playing_sports"
|
||||
msgstr "fait du sport"
|
||||
|
||||
msgid "running"
|
||||
msgstr "court"
|
||||
|
||||
msgid "skiing"
|
||||
msgstr "skie"
|
||||
|
||||
msgid "swimming"
|
||||
msgstr "nage"
|
||||
|
||||
msgid "working_out"
|
||||
msgstr "élabore"
|
||||
|
||||
msgid "grooming"
|
||||
msgstr "se toilette"
|
||||
|
||||
msgid "at_the_spa"
|
||||
msgstr "à la station thermale"
|
||||
|
||||
msgid "brushing_teeth"
|
||||
msgstr "se brosse les dents"
|
||||
|
||||
msgid "getting_a_haircut"
|
||||
msgstr "se fait couper les cheveux"
|
||||
|
||||
msgid "shaving"
|
||||
msgstr "se rase"
|
||||
|
||||
msgid "taking_a_bath"
|
||||
msgstr "prend un bain"
|
||||
|
||||
msgid "taking_a_shower"
|
||||
msgstr "prend une douche"
|
||||
|
||||
msgid "having_appointment"
|
||||
msgstr "à un rendez-vous"
|
||||
|
||||
msgid "inactive"
|
||||
msgstr "inactif"
|
||||
|
||||
msgid "day_off"
|
||||
msgstr "en congé"
|
||||
|
||||
msgid "hanging_out"
|
||||
msgstr "traîne"
|
||||
|
||||
msgid "on_vacation"
|
||||
msgstr "en vacances"
|
||||
|
||||
msgid "scheduled_holiday"
|
||||
msgstr "en vacances organisées"
|
||||
|
||||
msgid "sleeping"
|
||||
msgstr "dort"
|
||||
|
||||
msgid "relaxing"
|
||||
msgstr "se relaxe"
|
||||
|
||||
msgid "gaming"
|
||||
msgstr "joue"
|
||||
|
||||
msgid "going_out"
|
||||
msgstr "sort"
|
||||
|
||||
msgid "partying"
|
||||
msgstr "fait la fête"
|
||||
|
||||
msgid "reading"
|
||||
msgstr "lit"
|
||||
|
||||
msgid "rehearsing"
|
||||
msgstr "se prépare"
|
||||
|
||||
msgid "shopping"
|
||||
msgstr "fait les magasins"
|
||||
|
||||
msgid "socializing"
|
||||
msgstr "se socialise"
|
||||
|
||||
msgid "sunbathing"
|
||||
msgstr "prend un bain de soleil"
|
||||
|
||||
msgid "watching_tv"
|
||||
msgstr "regarde la TV"
|
||||
|
||||
msgid "watching_a_movie"
|
||||
msgstr "regarde un film"
|
||||
|
||||
msgid "talking"
|
||||
msgstr "discute"
|
||||
|
||||
msgid "in_real_life"
|
||||
msgstr "dans la vraie vie"
|
||||
|
||||
msgid "on_the_phone"
|
||||
msgstr "au téléphone"
|
||||
|
||||
msgid "traveling"
|
||||
msgstr "voyage"
|
||||
|
||||
msgid "commuting"
|
||||
msgstr "permute"
|
||||
|
||||
msgid "driving"
|
||||
msgstr "conduit"
|
||||
|
||||
msgid "in_a_car"
|
||||
msgstr "en voiture"
|
||||
|
||||
msgid "on_a_bus"
|
||||
msgstr "en bus"
|
||||
|
||||
msgid "on_a_plane"
|
||||
msgstr "en avion"
|
||||
|
||||
msgid "on_a_train"
|
||||
msgstr "en train"
|
||||
|
||||
msgid "on_a_trip"
|
||||
msgstr "en séjour"
|
||||
|
||||
msgid "walking"
|
||||
msgstr "marche"
|
||||
|
||||
msgid "working"
|
||||
msgstr "travaille"
|
||||
|
||||
msgid "coding"
|
||||
msgstr "programme"
|
||||
|
||||
msgid "in_a_meeting"
|
||||
msgstr "en réunion"
|
||||
|
||||
msgid "studying"
|
||||
msgstr "étudie"
|
||||
|
||||
msgid "writing"
|
||||
msgstr "écrit"
|
||||
|
||||
#~ msgid "2003-12-13T18:30:02Z"
|
||||
#~ msgstr "2003-12-13T18:30:02Z"
|
||||
#~ msgid "<small>Romeo and Juliet</small>"
|
||||
|
|
|
@ -44,26 +44,26 @@ trayicon.c:
|
|||
$(srcdir)/trayicon.defs > $@
|
||||
endif
|
||||
gajimsrcdir = $(pkgdatadir)/src
|
||||
gajimsrc_DATA = $(srcdir)/*.py
|
||||
gajimsrc_PYTHON = $(srcdir)/*.py
|
||||
|
||||
gajimsrc1dir = $(pkgdatadir)/src/common
|
||||
gajimsrc1_DATA = \
|
||||
gajimsrc1_PYTHON = \
|
||||
$(srcdir)/common/*.py
|
||||
|
||||
gajimsrc2dir = $(pkgdatadir)/src/common/xmpp
|
||||
gajimsrc2_DATA = \
|
||||
gajimsrc2_PYTHON = \
|
||||
$(srcdir)/common/xmpp/*.py
|
||||
|
||||
gajimsrc3dir = $(pkgdatadir)/src/common/zeroconf
|
||||
gajimsrc3_DATA = \
|
||||
gajimsrc3_PYTHON = \
|
||||
$(srcdir)/common/zeroconf/*.py
|
||||
|
||||
DISTCLEANFILES =
|
||||
|
||||
EXTRA_DIST = $(gajimsrc_DATA) \
|
||||
$(gajimsrc1_DATA) \
|
||||
$(gajimsrc2_DATA) \
|
||||
$(gajimsrc3_DATA) \
|
||||
EXTRA_DIST = $(gajimsrc_PYTHON) \
|
||||
$(gajimsrc1_PYTHON) \
|
||||
$(gajimsrc2_PYTHON) \
|
||||
$(gajimsrc3_PYTHON) \
|
||||
gtkspellmodule.c \
|
||||
eggtrayicon.c \
|
||||
trayiconmodule.c \
|
||||
|
|
|
@ -151,7 +151,7 @@ class ChatControlBase(MessageControl):
|
|||
self._on_banner_eventbox_button_press_event)
|
||||
self.handlers[id] = widget
|
||||
|
||||
self.urlfinder = re.compile("(https?://|www|ftp)[^ ]+")
|
||||
self.urlfinder = re.compile(r"(www\.(?!\.)|[a-z][a-z0-9+.-]*://)[^\s<>'\"]+[^!,\.\s<>\)'\"\]]")
|
||||
|
||||
if gajim.HAVE_PYSEXY:
|
||||
import sexy
|
||||
|
@ -1018,6 +1018,10 @@ class ChatControl(ChatControlBase):
|
|||
self.widget_set_visible(self.xml.get_widget('banner_eventbox'),
|
||||
gajim.config.get('hide_chat_banner'))
|
||||
|
||||
# Add lock image to show chat encryption
|
||||
self.lock_image = self.xml.get_widget('lock_image')
|
||||
self.lock_tooltip = gtk.Tooltips()
|
||||
|
||||
# keep timeout id and window obj for possible big avatar
|
||||
# it is on enter-notify and leave-notify so no need to be per jid
|
||||
self.show_bigger_avatar_timeout_id = None
|
||||
|
@ -1050,15 +1054,25 @@ class ChatControl(ChatControlBase):
|
|||
self.on_avatar_eventbox_button_press_event)
|
||||
self.handlers[id] = widget
|
||||
|
||||
widget = self.xml.get_widget('gpg_togglebutton')
|
||||
id = widget.connect('clicked', self.on_toggle_gpg_togglebutton)
|
||||
self.handlers[id] = widget
|
||||
|
||||
if self.contact.jid in gajim.encrypted_chats[self.account]:
|
||||
self.xml.get_widget('gpg_togglebutton').set_active(True)
|
||||
|
||||
self.set_session(session)
|
||||
|
||||
# Enable ecryption if needed
|
||||
e2e_is_active = hasattr(self, 'session') and self.session and self.session.enable_encryption
|
||||
self.gpg_is_active = False
|
||||
gpg_pref = gajim.config.get_per('contacts', contact.jid, 'gpg_enabled')
|
||||
|
||||
if not e2e_is_active and gpg_pref and gajim.config.get_per('accounts', self.account, 'keyid') and\
|
||||
gajim.connections[self.account].USE_GPG:
|
||||
self.gpg_is_active = True
|
||||
gajim.encrypted_chats[self.account].append(contact.jid)
|
||||
msg = _('GPG encryption enabled')
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
|
||||
if self.session:
|
||||
self.session.loggable = gajim.config.get('log_encrypted_sessions')
|
||||
self._show_lock_image(self.gpg_is_active, 'GPG', self.gpg_is_active, self.session and \
|
||||
self.session.is_loggable())
|
||||
|
||||
self.status_tooltip = gtk.Tooltips()
|
||||
self.update_ui()
|
||||
# restore previous conversation
|
||||
|
@ -1164,8 +1178,6 @@ class ChatControl(ChatControlBase):
|
|||
gtk.gdk.INTERP_BILINEAR)
|
||||
banner_status_img.set_from_pixbuf(scaled_pix)
|
||||
|
||||
self._update_gpg()
|
||||
|
||||
def draw_banner_text(self):
|
||||
'''Draw the text in the fat line at the top of the window that
|
||||
houses the name, jid.
|
||||
|
@ -1254,34 +1266,52 @@ class ChatControl(ChatControlBase):
|
|||
# setup the label that holds name and jid
|
||||
banner_name_label.set_markup(label_text)
|
||||
|
||||
def on_toggle_gpg_togglebutton(self, widget):
|
||||
gajim.config.set_per('contacts', self.contact.jid, 'gpg_enabled',
|
||||
widget.get_active())
|
||||
|
||||
def _update_gpg(self):
|
||||
tb = self.xml.get_widget('gpg_togglebutton')
|
||||
# we can do gpg
|
||||
# if self.contact is our own contact info (transports),
|
||||
# don't enable pgp
|
||||
if self.contact.keyID and not gajim.jid_is_transport(self.contact.jid):
|
||||
tb.set_sensitive(True)
|
||||
tt = _('OpenPGP Encryption')
|
||||
|
||||
# restore gpg pref
|
||||
gpg_pref = gajim.config.get_per('contacts', self.contact.jid,
|
||||
'gpg_enabled')
|
||||
if gpg_pref == None:
|
||||
gajim.config.add_per('contacts', self.contact.jid)
|
||||
gpg_pref = gajim.config.get_per('contacts', self.contact.jid,
|
||||
'gpg_enabled')
|
||||
tb.set_active(gpg_pref)
|
||||
def _toggle_gpg(self):
|
||||
ec = gajim.encrypted_chats[self.account]
|
||||
if self.gpg_is_active:
|
||||
# Disable encryption
|
||||
ec.remove(self.contact.jid)
|
||||
self.gpg_is_active = False
|
||||
msg = _('GPG encryption disabled')
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
if self.session:
|
||||
self.session.loggable = True
|
||||
|
||||
else:
|
||||
tb.set_sensitive(False)
|
||||
#we talk about a contact here
|
||||
tt = _('%s has not broadcast an OpenPGP key, nor has one been assigned') %\
|
||||
self.contact.get_shown_name()
|
||||
gtk.Tooltips().set_tip(self.xml.get_widget('gpg_eventbox'), tt)
|
||||
# Enable encryption
|
||||
ec.append(self.contact.jid)
|
||||
self.gpg_is_active = True
|
||||
msg = _('GPG encryption enabled')
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
|
||||
if self.session:
|
||||
self.session.loggable = gajim.config.get('log_encrypted_sessions');
|
||||
if self.session and not self.session.is_loggable():
|
||||
msg = _('Session WILL NOT be logged')
|
||||
else:
|
||||
msg = _('Session WILL be logged')
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
|
||||
gpg_pref = gajim.config.get_per('contacts', self.contact.jid,
|
||||
'gpg_enabled')
|
||||
if gpg_pref is None:
|
||||
gajim.config.add_per('contacts', self.contact.jid)
|
||||
gajim.config.set_per('contacts', self.contact.jid, 'gpg_enabled',
|
||||
self.gpg_is_active)
|
||||
|
||||
self._show_lock_image(self.gpg_is_active, 'GPG', self.gpg_is_active, self.session and \
|
||||
self.session.is_loggable())
|
||||
|
||||
def _show_lock_image(self, visible, enc_type = '', enc_enabled = False, chat_logged = False):
|
||||
'''Set lock icon visibiity and create tooltip'''
|
||||
status_string = enc_enabled and 'is' or 'is NOT'
|
||||
logged_string = chat_logged and 'will' or 'will NOT'
|
||||
tooltip = '%s Encryption %s active. \nYour chat session %s be logged.' %\
|
||||
(enc_type, status_string, logged_string)
|
||||
|
||||
self.lock_tooltip.set_tip(self.lock_image, tooltip)
|
||||
self.widget_set_visible(self.lock_image, not visible)
|
||||
self.lock_image.set_sensitive(enc_enabled)
|
||||
|
||||
def _process_command(self, message):
|
||||
if message[0] != '/':
|
||||
|
@ -1369,9 +1399,11 @@ class ChatControl(ChatControlBase):
|
|||
encrypted = bool(self.session) and self.session.enable_encryption
|
||||
|
||||
keyID = ''
|
||||
if self.xml.get_widget('gpg_togglebutton').get_active():
|
||||
if self.gpg_is_active:
|
||||
keyID = contact.keyID
|
||||
encrypted = True
|
||||
if not keyID:
|
||||
keyID = 'UNKNOWN'
|
||||
|
||||
chatstates_on = gajim.config.get('outgoing_chat_state_notifications') != \
|
||||
'disabled'
|
||||
|
@ -1468,13 +1500,14 @@ class ChatControl(ChatControlBase):
|
|||
msg = _('Session negotiation cancelled')
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
|
||||
# print esession settings to textview
|
||||
def print_esession_details(self):
|
||||
if self.session and self.session.enable_encryption:
|
||||
'''print esession settings to textview'''
|
||||
e2e_is_active = self.session and self.session.enable_encryption
|
||||
if e2e_is_active:
|
||||
msg = _('E2E encryption enabled')
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
|
||||
if self.session.loggable:
|
||||
if self.session.is_loggable():
|
||||
msg = _('Session WILL be logged')
|
||||
else:
|
||||
msg = _('Session WILL NOT be logged')
|
||||
|
@ -1483,6 +1516,8 @@ class ChatControl(ChatControlBase):
|
|||
else:
|
||||
msg = _('E2E encryption disabled')
|
||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||
self._show_lock_image(e2e_is_active, 'E2E', e2e_is_active, self.session and \
|
||||
self.session.is_loggable())
|
||||
|
||||
def print_conversation(self, text, frm = '', tim = None,
|
||||
encrypted = False, subject = None, xhtml = None):
|
||||
|
@ -1510,19 +1545,15 @@ class ChatControl(ChatControlBase):
|
|||
'status', '', tim)
|
||||
else:
|
||||
# GPG encryption
|
||||
ec = gajim.encrypted_chats[self.account]
|
||||
if encrypted and jid not in ec:
|
||||
msg = _('OpenPGP Encryption enabled')
|
||||
if encrypted and not self.gpg_is_active:
|
||||
msg = _('The following message was encrypted')
|
||||
ChatControlBase.print_conversation_line(self, msg,
|
||||
'status', '', tim)
|
||||
ec.append(jid)
|
||||
elif not encrypted and jid in ec:
|
||||
msg = _('OpenPGP Encryption disabled')
|
||||
self._toggle_gpg()
|
||||
elif not encrypted and self.gpg_is_active:
|
||||
msg = _('The following message was NOT encrypted')
|
||||
ChatControlBase.print_conversation_line(self, msg,
|
||||
'status', '', tim)
|
||||
ec.remove(jid)
|
||||
self.xml.get_widget('gpg_togglebutton').set_active(encrypted)
|
||||
|
||||
if not frm:
|
||||
kind = 'incoming'
|
||||
name = contact.get_shown_name()
|
||||
|
@ -1650,12 +1681,15 @@ class ChatControl(ChatControlBase):
|
|||
contact = self.parent_win.get_active_contact()
|
||||
jid = contact.jid
|
||||
|
||||
# check if gpg capabitlies or else make gpg toggle insensitive
|
||||
gpg_btn = self.xml.get_widget('gpg_togglebutton')
|
||||
isactive = gpg_btn.get_active()
|
||||
is_sensitive = gpg_btn.get_property('sensitive')
|
||||
toggle_gpg_menuitem.set_active(isactive)
|
||||
toggle_gpg_menuitem.set_property('sensitive', is_sensitive)
|
||||
# check if we support and use gpg
|
||||
if not gajim.config.get_per('accounts', self.account, 'keyid') or\
|
||||
not gajim.connections[self.account].USE_GPG or\
|
||||
gajim.jid_is_transport(jid):
|
||||
toggle_gpg_menuitem.set_sensitive(False)
|
||||
else:
|
||||
e2e_is_active = int(self.session != None and self.session.enable_encryption)
|
||||
toggle_gpg_menuitem.set_sensitive(not e2e_is_active)
|
||||
toggle_gpg_menuitem.set_active(self.gpg_is_active)
|
||||
|
||||
# TODO: check that the remote client supports e2e
|
||||
if not gajim.HAVE_PYCRYPTO:
|
||||
|
@ -1663,6 +1697,7 @@ class ChatControl(ChatControlBase):
|
|||
else:
|
||||
isactive = int(self.session != None and self.session.enable_encryption)
|
||||
toggle_e2e_menuitem.set_active(isactive)
|
||||
toggle_e2e_menuitem.set_sensitive(not self.gpg_is_active)
|
||||
|
||||
# If we don't have resource, we can't do file transfer
|
||||
# in transports, contact holds our info we need to disable it too
|
||||
|
@ -1699,9 +1734,10 @@ class ChatControl(ChatControlBase):
|
|||
self.handlers[id] = add_to_roster_menuitem
|
||||
id = toggle_gpg_menuitem.connect('activate',
|
||||
self._on_toggle_gpg_menuitem_activate)
|
||||
self.handlers[id] = toggle_gpg_menuitem
|
||||
id = toggle_e2e_menuitem.connect('activate',
|
||||
self._on_toggle_e2e_menuitem_activate)
|
||||
self.handlers[id] = toggle_gpg_menuitem
|
||||
self.handlers[id] = toggle_e2e_menuitem
|
||||
id = information_menuitem.connect('activate',
|
||||
self._on_contact_information_menuitem_activate)
|
||||
self.handlers[id] = information_menuitem
|
||||
|
@ -2154,10 +2190,7 @@ class ChatControl(ChatControlBase):
|
|||
gajim.interface.roster.on_info(widget, self.contact, self.account)
|
||||
|
||||
def _on_toggle_gpg_menuitem_activate(self, widget):
|
||||
# update the button
|
||||
# this is reverse logic, as we are on 'activate' (before change happens)
|
||||
tb = self.xml.get_widget('gpg_togglebutton')
|
||||
tb.set_active(not tb.get_active())
|
||||
self._toggle_gpg()
|
||||
|
||||
def _on_convert_to_gc_menuitem_activate(self, widget):
|
||||
'''user want to invite some friends to chat'''
|
||||
|
|
|
@ -28,24 +28,12 @@
|
|||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
import os
|
||||
import gajim
|
||||
from os import tmpfile
|
||||
from common import helpers
|
||||
|
||||
USE_GPG = True
|
||||
|
||||
try:
|
||||
import GnuPGInterface # Debian package doesn't distribute 'our' file
|
||||
except ImportError:
|
||||
try:
|
||||
from common import GnuPGInterface # use 'our' file
|
||||
except ImportError:
|
||||
USE_GPG = False # user can't do OpenGPG only if he or she removed the file!
|
||||
|
||||
else:
|
||||
status = os.system('gpg -h >/dev/null 2>&1')
|
||||
if status != 0:
|
||||
USE_GPG = False
|
||||
if gajim.HAVE_GPG:
|
||||
import GnuPGInterface
|
||||
|
||||
class GnuPG(GnuPGInterface.GnuPG):
|
||||
def __init__(self, use_agent = False):
|
||||
|
@ -57,8 +45,6 @@ else:
|
|||
self.options.armor = 1
|
||||
self.options.meta_interactive = 0
|
||||
self.options.extra_args.append('--no-secmem-warning')
|
||||
# Nolith's patch - prevent crashs on non fully-trusted keys
|
||||
self.options.extra_args.append('--always-trust')
|
||||
if self.use_agent:
|
||||
self.options.extra_args.append('--use-agent')
|
||||
|
||||
|
@ -88,8 +74,6 @@ else:
|
|||
return resp
|
||||
|
||||
def encrypt(self, str, recipients):
|
||||
if not USE_GPG:
|
||||
return str, 'GnuPG not usable'
|
||||
self.options.recipients = recipients # a list!
|
||||
|
||||
proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout', 'status',
|
||||
|
@ -125,8 +109,6 @@ else:
|
|||
return self._stripHeaderFooter(output), error
|
||||
|
||||
def decrypt(self, str, keyID):
|
||||
if not USE_GPG:
|
||||
return str
|
||||
proc = self.run(['--decrypt', '-q', '-u %s'%keyID], create_fhs=['stdin', 'stdout'])
|
||||
enc = self._addHeaderFooter(str, 'MESSAGE')
|
||||
proc.handles['stdin'].write(enc)
|
||||
|
@ -140,8 +122,6 @@ else:
|
|||
return output
|
||||
|
||||
def sign(self, str, keyID):
|
||||
if not USE_GPG:
|
||||
return str
|
||||
proc = self.run(['-b', '-u %s'%keyID], create_fhs=['stdin', 'stdout', 'status', 'stderr'])
|
||||
proc.handles['stdin'].write(str)
|
||||
try:
|
||||
|
@ -170,8 +150,6 @@ else:
|
|||
return 'BAD_PASSPHRASE'
|
||||
|
||||
def verify(self, str, sign):
|
||||
if not USE_GPG:
|
||||
return str
|
||||
if str == None:
|
||||
return ''
|
||||
f = tmpfile()
|
||||
|
@ -200,8 +178,6 @@ else:
|
|||
return keyid
|
||||
|
||||
def get_keys(self, secret = False):
|
||||
if not USE_GPG:
|
||||
return {}
|
||||
if secret:
|
||||
opt = '--list-secret-keys'
|
||||
else:
|
||||
|
@ -217,8 +193,10 @@ else:
|
|||
sline = line.split(':')
|
||||
if (sline[0] == 'sec' and secret) or \
|
||||
(sline[0] == 'pub' and not secret):
|
||||
# decode escaped chars
|
||||
name = eval('"' + sline[9].replace('"', '\\"') + '"')
|
||||
# make it unicode instance
|
||||
keys[sline[4][8:]] = helpers.decode_string(sline[9])
|
||||
keys[sline[4][8:]] = helpers.decode_string(name)
|
||||
return keys
|
||||
try: proc.wait()
|
||||
except IOError: pass
|
||||
|
|
|
@ -45,7 +45,7 @@ opt_int = [ 'integer', 0 ]
|
|||
opt_str = [ 'string', 0 ]
|
||||
opt_bool = [ 'boolean', 0 ]
|
||||
opt_color = [ 'color', '^(#[0-9a-fA-F]{6})|()$' ]
|
||||
opt_one_window_types = ['never', 'always', 'peracct', 'pertype']
|
||||
opt_one_window_types = ['never', 'always', 'always_with_roster', 'peracct', 'pertype']
|
||||
opt_treat_incoming_messages = ['', 'chat', 'normal']
|
||||
|
||||
class Config:
|
||||
|
@ -100,7 +100,6 @@ class Config:
|
|||
'urlmsgcolor': [ opt_color, '#0000ff', '', True ],
|
||||
'collapsed_rows': [ opt_str, '', _('List (space separated) of rows (accounts and groups) that are collapsed.'), True ],
|
||||
'roster_theme': [ opt_str, _('default'), '', True ],
|
||||
'saveposition': [ opt_bool, True ],
|
||||
'mergeaccounts': [ opt_bool, False, '', True ],
|
||||
'sort_by_show': [ opt_bool, True, '', True ],
|
||||
'enable_zeroconf': [opt_bool, False, _('Enable link-local/zeroconf messaging')],
|
||||
|
@ -214,6 +213,7 @@ class Config:
|
|||
'show_unread_tab_icon': [opt_bool, False, _('If True, Gajim will display an icon on each tab containing unread messages. Depending on the theme, this icon may be animated.')],
|
||||
'show_status_msgs_in_roster': [opt_bool, True, _('If True, Gajim will display the status message, if not empty, for every contact under the contact name in roster window.'), True],
|
||||
'show_avatars_in_roster': [opt_bool, True, '', True],
|
||||
'avatar_position_in_roster': [opt_str, 'right', _('Define the position of the avatar in roster. Can be left or right'), True],
|
||||
'ask_avatars_on_startup': [opt_bool, True, _('If True, Gajim will ask for avatar each contact that did not have an avatar last time or has one cached that is too old.')],
|
||||
'print_status_in_chats': [opt_bool, True, _('If False, Gajim will no longer print status line in chats when a contact changes his or her status and/or his or her status message.')],
|
||||
'print_status_in_muc': [opt_str, 'in_and_out', _('can be "none", "all" or "in_and_out". If "none", Gajim will no longer print status line in groupchats when a member changes his or her status and/or his or her status message. If "all" Gajim will print all status messages. If "in_and_out", Gajim will only print FOO enters/leaves group chat.')],
|
||||
|
@ -229,7 +229,7 @@ class Config:
|
|||
'send_sha_in_gc_presence': [opt_bool, True, _('Jabberd1.4 does not like sha info when one join a password protected group chat. Turn this option to False to stop sending sha info in group chat presences.')],
|
||||
'one_message_window': [opt_str, 'always',
|
||||
#always, never, peracct, pertype should not be translated
|
||||
_('Controls the window where new messages are placed.\n\'always\' - All messages are sent to a single window.\n\'never\' - All messages get their own window.\n\'peracct\' - Messages for each account are sent to a specific window.\n\'pertype\' - Each message type (e.g., chats vs. groupchats) are sent to a specific window. Note, changing this option requires restarting Gajim before the changes will take effect.')],
|
||||
_('Controls the window where new messages are placed.\n\'always\' - All messages are sent to a single window.\n\'always_with_roster\' - Like \'always\' but the messages are in a single window along with the roster.\n\'never\' - All messages get their own window.\n\'peracct\' - Messages for each account are sent to a specific window.\n\'pertype\' - Each message type (e.g., chats vs. groupchats) are sent to a specific window.')],
|
||||
'show_avatar_in_chat': [opt_bool, True, _('If False, you will no longer see the avatar in the chat window.')],
|
||||
'escape_key_closes': [opt_bool, True, _('If True, pressing the escape key closes a tab/window.')],
|
||||
'compact_view': [opt_bool, False, _('Hides the buttons in chat windows.')],
|
||||
|
@ -250,7 +250,14 @@ class Config:
|
|||
'use_latex': [opt_bool, False, _('If True, Gajim will convert string between $$ and $$ to an image using dvips and convert before insterting it in chat window.')],
|
||||
'change_status_window_timeout': [opt_int, 15, _('Time of inactivity needed before the change status window closes down.')],
|
||||
'max_conversation_lines': [opt_int, 500, _('Maximum number of lines that are printed in conversations. Oldest lines are cleared.')],
|
||||
'publish_mood': [opt_bool, False],
|
||||
'publish_activity': [opt_bool, False],
|
||||
'publish_tune': [opt_bool, False],
|
||||
'subscribe_mood': [opt_bool, True],
|
||||
'subscribe_activity': [opt_bool, True],
|
||||
'subscribe_tune': [opt_bool, True],
|
||||
'attach_notifications_to_systray': [opt_bool, False, _('If True, notification windows from notification-daemon will be attached to systray icon.')],
|
||||
'use_pep': [opt_bool, False, 'temporary variable to enable pep support'],
|
||||
}
|
||||
|
||||
__options_per_key = {
|
||||
|
@ -275,7 +282,8 @@ class Config:
|
|||
'keyid': [ opt_str, '', '', True ],
|
||||
'gpg_sign_presence': [ opt_bool, True, _('If disabled, don\'t sign presences with GPG key, even if GPG is configured.') ],
|
||||
'keyname': [ opt_str, '', '', True ],
|
||||
'usessl': [ opt_bool, False, '', True ],
|
||||
'connection_types': [ opt_str, 'tls ssl plain', _('Ordered list (space separated) of connection type to try. Can contain tls, ssl or plain')],
|
||||
'warn_when_insecure_connection': [ opt_bool, True, _('Show a warning dialog before sending password on an insecure connection.') ],
|
||||
'ssl_fingerprint_sha1': [ opt_str, '', '', True ],
|
||||
'use_srv': [ opt_bool, True, '', True ],
|
||||
'use_custom_host': [ opt_bool, False, '', True ],
|
||||
|
@ -306,6 +314,7 @@ class Config:
|
|||
'zeroconf_last_name': [ opt_str, '', '', True ],
|
||||
'zeroconf_jabber_id': [ opt_str, '', '', True ],
|
||||
'zeroconf_email': [ opt_str, '', '', True ],
|
||||
'use_env_http_proxy' : [opt_bool, False],
|
||||
}, {}),
|
||||
'statusmsg': ({
|
||||
'message': [ opt_str, '' ],
|
||||
|
@ -354,7 +363,7 @@ class Config:
|
|||
'state_muc_directed_msg_color': [ opt_color, 'red2' ],
|
||||
}, {}),
|
||||
'contacts': ({
|
||||
'gpg_enabled': [ opt_bool, True, _('Is OpenPGP enabled for this contact?')],
|
||||
'gpg_enabled': [ opt_bool, False, _('Is OpenPGP enabled for this contact?')],
|
||||
'speller_language': [ opt_str, '', _('Language for which we want to check misspelled words')],
|
||||
}, {}),
|
||||
'rooms': ({
|
||||
|
@ -400,7 +409,8 @@ class Config:
|
|||
|
||||
soundevents_default = {
|
||||
'first_message_received': [ True, '../data/sounds/message1.wav' ],
|
||||
'next_message_received': [ True, '../data/sounds/message2.wav' ],
|
||||
'next_message_received_focused': [ True, '../data/sounds/message2.wav' ],
|
||||
'next_message_received_unfocused': [ True, '../data/sounds/message2.wav' ],
|
||||
'contact_connected': [ True, '../data/sounds/connected.wav' ],
|
||||
'contact_disconnected': [ True, '../data/sounds/disconnected.wav' ],
|
||||
'message_sent': [ True, '../data/sounds/sent.wav' ],
|
||||
|
|
|
@ -48,7 +48,6 @@ from common import passwords
|
|||
from common import exceptions
|
||||
|
||||
from connection_handlers import *
|
||||
USE_GPG = GnuPG.USE_GPG
|
||||
|
||||
from common.rst_xhtml_generator import create_xhtml
|
||||
|
||||
|
@ -56,8 +55,6 @@ from string import Template
|
|||
import logging
|
||||
log = logging.getLogger('gajim.c.connection')
|
||||
|
||||
import gtkgui_helpers
|
||||
|
||||
ssl_error = {
|
||||
2: _("Unable to get issuer certificate"),
|
||||
3: _("Unable to get certificate CRL"),
|
||||
|
@ -75,9 +72,9 @@ ssl_error = {
|
|||
15: _("Format error in CRL's lastUpdate field"),
|
||||
16: _("Format error in CRL's nextUpdate field"),
|
||||
17: _("Out of memory"),
|
||||
18: _("Self signed certificate in certificate chain"),
|
||||
19: _("Unable to get local issuer certificate"),
|
||||
20: _("Unable to verify the first certificate"),
|
||||
18: _("Self signed certificate"),
|
||||
19: _("Self signed certificate in certificate chain"),
|
||||
20: _("Unable to get local issuer certificate"),
|
||||
21: _("Unable to verify the first certificate"),
|
||||
22: _("Certificate chain too long"),
|
||||
23: _("Certificate revoked"),
|
||||
|
@ -107,7 +104,9 @@ class Connection(ConnectionHandlers):
|
|||
self.last_connection = None # last ClientCommon instance
|
||||
self.is_zeroconf = False
|
||||
self.gpg = None
|
||||
if USE_GPG:
|
||||
self.USE_GPG = False
|
||||
if gajim.HAVE_GPG:
|
||||
self.USE_GPG = True
|
||||
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||
self.status = ''
|
||||
self.priority = gajim.get_priority(name, 'offline')
|
||||
|
@ -142,6 +141,9 @@ class Connection(ConnectionHandlers):
|
|||
self.blocked_contacts = []
|
||||
self.blocked_groups = []
|
||||
self.pep_supported = False
|
||||
self.mood = {}
|
||||
self.tune = {}
|
||||
self.activity = {}
|
||||
# Do we continue connection when we get roster (send presence,get vcard..)
|
||||
self.continue_connect_info = None
|
||||
# To know the groupchat jid associated with a sranza ID. Useful to
|
||||
|
@ -178,7 +180,7 @@ class Connection(ConnectionHandlers):
|
|||
self.dispatch('STATUS', 'connecting')
|
||||
self.retrycount += 1
|
||||
self.on_connect_auth = self._init_roster
|
||||
self.connect_and_init(self.old_show, self.status, self.gpg != None)
|
||||
self.connect_and_init(self.old_show, self.status, self.USE_GPG)
|
||||
else:
|
||||
# reconnect succeeded
|
||||
self.time_to_reconnect = None
|
||||
|
@ -186,6 +188,8 @@ class Connection(ConnectionHandlers):
|
|||
|
||||
# We are doing disconnect at so many places, better use one function in all
|
||||
def disconnect(self, on_purpose=False):
|
||||
#FIXME: set the Tune to None before disconnection per account
|
||||
#gajim.interface.roster._music_track_changed(None, None)
|
||||
self.on_purpose = on_purpose
|
||||
self.connected = 0
|
||||
self.time_to_reconnect = None
|
||||
|
@ -265,7 +269,8 @@ class Connection(ConnectionHandlers):
|
|||
if not common.xmpp.isResultNode(result):
|
||||
self.dispatch('ACC_NOT_OK', (result.getError()))
|
||||
return
|
||||
if USE_GPG:
|
||||
if gajim.HAVE_GPG:
|
||||
self.USE_GPG = True
|
||||
self.gpg = GnuPG.GnuPG(gajim.config.get(
|
||||
'use_gpg_agent'))
|
||||
self.dispatch('ACC_OK', (self.new_account_info))
|
||||
|
@ -279,7 +284,7 @@ class Connection(ConnectionHandlers):
|
|||
# typed, so send them
|
||||
if is_form:
|
||||
#TODO: Check if form has changed
|
||||
iq = Iq('set', NS_REGISTER, to=self._hostname)
|
||||
iq = common.xmpp.Iq('set', common.xmpp.NS_REGISTER, to=self._hostname)
|
||||
iq.setTag('query').addChild(node=self.new_account_form)
|
||||
self.connection.SendAndCallForResponse(iq,
|
||||
_on_register_result)
|
||||
|
@ -313,7 +318,7 @@ class Connection(ConnectionHandlers):
|
|||
ssl_fingerprint = \
|
||||
self.connection.Connection.ssl_fingerprint_sha1
|
||||
self.dispatch('NEW_ACC_CONNECTED', (conf, is_form, ssl_msg,
|
||||
ssl_cert, ssl_fingerprint))
|
||||
errnum, ssl_cert, ssl_fingerprint))
|
||||
self.connection.UnregisterDisconnectHandler(
|
||||
self._on_new_account)
|
||||
self.disconnect(on_purpose=True)
|
||||
|
@ -423,27 +428,56 @@ class Connection(ConnectionHandlers):
|
|||
proxy['user'] = gajim.config.get_per('proxies', p, 'user')
|
||||
proxy['password'] = gajim.config.get_per('proxies', p, 'pass')
|
||||
proxy['type'] = gajim.config.get_per('proxies', p, 'type')
|
||||
elif gajim.config.get_per('accounts', self.name, 'use_env_http_proxy'):
|
||||
try:
|
||||
try:
|
||||
env_http_proxy = os.environ['HTTP_PROXY']
|
||||
except:
|
||||
env_http_proxy = os.environ['http_proxy']
|
||||
env_http_proxy = env_http_proxy.strip('"')
|
||||
# Dispose of the http:// prefix
|
||||
env_http_proxy = env_http_proxy.split('://')
|
||||
env_http_proxy = env_http_proxy[len(env_http_proxy)-1]
|
||||
env_http_proxy = env_http_proxy.split('@')
|
||||
|
||||
if len(env_http_proxy) == 2:
|
||||
login = env_http_proxy[0].split(':')
|
||||
addr = env_http_proxy[1].split(':')
|
||||
else:
|
||||
login = ['', '']
|
||||
addr = env_http_proxy[0].split(':')
|
||||
|
||||
proxy = {'host': addr[0], 'type' : u'http', 'user':login[0]}
|
||||
|
||||
if len(addr) == 2:
|
||||
proxy['port'] = addr[1]
|
||||
else:
|
||||
proxy['port'] = 3128
|
||||
|
||||
if len(login) == 2:
|
||||
proxy['password'] = login[1]
|
||||
else:
|
||||
proxy['password'] = u''
|
||||
|
||||
except:
|
||||
proxy = None
|
||||
else:
|
||||
proxy = None
|
||||
|
||||
h = hostname
|
||||
p = 5222
|
||||
# autodetect [for SSL in 5223/443 and for TLS if broadcasted]
|
||||
secur = None
|
||||
if usessl:
|
||||
p = 5223
|
||||
secur = 1 # 1 means force SSL no matter what the port will be
|
||||
use_srv = False # wants ssl? disable srv lookup
|
||||
ssl_p = 5223
|
||||
# use_srv = False # wants ssl? disable srv lookup
|
||||
if use_custom:
|
||||
h = custom_h
|
||||
p = custom_p
|
||||
ssl_p = custom_p
|
||||
use_srv = False
|
||||
|
||||
hosts = []
|
||||
# SRV resolver
|
||||
self._proxy = proxy
|
||||
self._secure = secur
|
||||
self._hosts = [ {'host': h, 'port': p, 'prio': 10, 'weight': 10} ]
|
||||
self._hosts = [ {'host': h, 'port': p, 'ssl_port': ssl_p, 'prio': 10,
|
||||
'weight': 10} ]
|
||||
self._hostname = hostname
|
||||
if use_srv:
|
||||
# add request for srv query to the resolve, on result '_on_resolve'
|
||||
|
@ -457,6 +491,12 @@ class Connection(ConnectionHandlers):
|
|||
# SRV query returned at least one valid result, we put it in hosts dict
|
||||
if len(result_array) != 0:
|
||||
self._hosts = [i for i in result_array]
|
||||
# Add ssl port
|
||||
ssl_p = 5223
|
||||
if gajim.config.get_per('accounts', self.name, 'use_custom_host'):
|
||||
ssl_p = gajim.config.get_per('accounts', self.name, 'custom_port')
|
||||
for i in self._hosts:
|
||||
i['ssl_port'] = ssl_p
|
||||
self.connect_to_next_host()
|
||||
|
||||
def on_proxy_failure(self, reason):
|
||||
|
@ -468,8 +508,9 @@ class Connection(ConnectionHandlers):
|
|||
self.dispatch('CONNECTION_LOST',
|
||||
(_('Connection to proxy failed'), reason))
|
||||
|
||||
def connect_to_next_host(self, retry = False):
|
||||
if len(self._hosts):
|
||||
def connect_to_next_type(self, retry=False):
|
||||
if len(self._connection_types):
|
||||
self._current_type = self._connection_types.pop(0)
|
||||
if self.last_connection:
|
||||
self.last_connection.socket.disconnect()
|
||||
self.last_connection = None
|
||||
|
@ -478,27 +519,49 @@ class Connection(ConnectionHandlers):
|
|||
con = common.xmpp.NonBlockingClient(self._hostname, caller = self,
|
||||
on_connect = self.on_connect_success,
|
||||
on_proxy_failure = self.on_proxy_failure,
|
||||
on_connect_failure = self.connect_to_next_host)
|
||||
on_connect_failure = self.connect_to_next_type)
|
||||
else:
|
||||
con = common.xmpp.NonBlockingClient(self._hostname, debug = [], caller = self,
|
||||
on_connect = self.on_connect_success,
|
||||
con = common.xmpp.NonBlockingClient(self._hostname, debug = [],
|
||||
caller = self, on_connect = self.on_connect_success,
|
||||
on_proxy_failure = self.on_proxy_failure,
|
||||
on_connect_failure = self.connect_to_next_host)
|
||||
on_connect_failure = self.connect_to_next_type)
|
||||
self.last_connection = con
|
||||
# increase default timeout for server responses
|
||||
common.xmpp.dispatcher_nb.DEFAULT_TIMEOUT_SECONDS = self.try_connecting_for_foo_secs
|
||||
con.set_idlequeue(gajim.idlequeue)
|
||||
host = self.select_next_host(self._hosts)
|
||||
self._current_host = host
|
||||
self._hosts.remove(host)
|
||||
|
||||
# FIXME: this is a hack; need a better way
|
||||
if self.on_connect_success == self._on_new_account:
|
||||
con.RegisterDisconnectHandler(self._on_new_account)
|
||||
|
||||
log.info("Connecting to %s: [%s:%d]", self.name, host['host'], host['port'])
|
||||
con.connect((host['host'], host['port']), proxy = self._proxy,
|
||||
secure = self._secure)
|
||||
if self._current_type == 'ssl':
|
||||
port = self._current_host['ssl_port']
|
||||
secur = 1
|
||||
else:
|
||||
port = self._current_host['port']
|
||||
if self._current_type == 'plain':
|
||||
secur = 0
|
||||
else:
|
||||
secur = None
|
||||
log.info('Connecting to %s: [%s:%d]', self.name,
|
||||
self._current_host['host'], port)
|
||||
con.connect((self._current_host['host'], port), proxy=self._proxy,
|
||||
secure = secur)
|
||||
else:
|
||||
self.connect_to_next_host(retry)
|
||||
|
||||
def connect_to_next_host(self, retry = False):
|
||||
if len(self._hosts):
|
||||
# No config option exist when creating a new account
|
||||
if self.name in gajim.config.get_per('accounts'):
|
||||
self._connection_types = gajim.config.get_per('accounts', self.name,
|
||||
'connection_types').split()
|
||||
else:
|
||||
self._connection_types = ['tls', 'ssl', 'plain']
|
||||
host = self.select_next_host(self._hosts)
|
||||
self._current_host = host
|
||||
self._hosts.remove(host)
|
||||
self.connect_to_next_type()
|
||||
|
||||
else:
|
||||
if not retry and self.retrycount == 0:
|
||||
log.debug("Out of hosts, giving up connecting to %s", self.name)
|
||||
|
@ -527,15 +590,26 @@ class Connection(ConnectionHandlers):
|
|||
if not self.connected: # We went offline during connecting process
|
||||
# FIXME - not possible, maybe it was when we used threads
|
||||
return
|
||||
_con_type = con_type
|
||||
# xmpp returns 'tcp', but we set 'plain' in connection_types in config
|
||||
if _con_type == 'tcp':
|
||||
_con_type = 'plain'
|
||||
if _con_type != self._current_type:
|
||||
self.connect_to_next_type()
|
||||
return
|
||||
if _con_type == 'plain' and gajim.config.get_per('accounts', self.name,
|
||||
'warn_when_insecure_connection'):
|
||||
self.dispatch('PLAIN_CONNECTION', (con,))
|
||||
return True
|
||||
return self.connection_accepted(con, con_type)
|
||||
|
||||
def connection_accepted(self, con, con_type):
|
||||
self.hosts = []
|
||||
if not con_type:
|
||||
log.debug('Could not connect to %s:%s' % (self._current_host['host'],
|
||||
self._current_host['port']))
|
||||
self.connected_hostname = self._current_host['host']
|
||||
self.on_connect_failure = None
|
||||
con.RegisterDisconnectHandler(self._disconnectedReconnCB)
|
||||
log.debug(_('Connected to server %s:%s with %s') % (self._current_host['host'],
|
||||
self._current_host['port'], con_type))
|
||||
log.debug('Connected to server %s:%s with %s' % (
|
||||
self._current_host['host'], self._current_host['port'], con_type))
|
||||
|
||||
name = gajim.config.get_per('accounts', self.name, 'name')
|
||||
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
||||
|
@ -548,10 +622,10 @@ class Connection(ConnectionHandlers):
|
|||
text = _('The authenticity of the %s certificate could be invalid.') %\
|
||||
hostname
|
||||
if errnum in ssl_error:
|
||||
text += _('\nSSL Error: %s') % ssl_error[errnum]
|
||||
text += _('\nSSL Error: <b>%s</b>') % ssl_error[errnum]
|
||||
else:
|
||||
text += _('\nUnknown SSL error: %d') % errnum
|
||||
self.dispatch('SSL_ERROR', (text, con.Connection.ssl_cert_pem,
|
||||
self.dispatch('SSL_ERROR', (text, errnum, con.Connection.ssl_cert_pem,
|
||||
con.Connection.ssl_fingerprint_sha1))
|
||||
return True
|
||||
if hasattr(con.Connection, 'ssl_fingerprint_sha1'):
|
||||
|
@ -565,11 +639,17 @@ class Connection(ConnectionHandlers):
|
|||
self._register_handlers(con, con_type)
|
||||
con.auth(name, self.password, self.server_resource, 1, self.__on_auth)
|
||||
|
||||
|
||||
def ssl_certificate_accepted(self):
|
||||
name = gajim.config.get_per('accounts', self.name, 'name')
|
||||
self._register_handlers(self.connection, 'ssl')
|
||||
self.connection.auth(name, self.password, self.server_resource, 1, self.__on_auth)
|
||||
self.connection.auth(name, self.password, self.server_resource, 1,
|
||||
self.__on_auth)
|
||||
|
||||
def plain_connection_accepted(self):
|
||||
name = gajim.config.get_per('accounts', self.name, 'name')
|
||||
self._register_handlers(self.connection, 'tcp')
|
||||
self.connection.auth(name, self.password, self.server_resource, 1,
|
||||
self.__on_auth)
|
||||
|
||||
def _register_handlers(self, con, con_type):
|
||||
self.peerhost = con.get_peerhost()
|
||||
|
@ -699,6 +779,17 @@ class Connection(ConnectionHandlers):
|
|||
def send_invisible_presence(self, msg, signed, initial = False):
|
||||
if not self.connection:
|
||||
return
|
||||
# If we are already connected, and privacy rules are supported, send
|
||||
# offline presence first as it's required by XEP-0126
|
||||
if self.connected > 1 and self.privacy_rules_supported:
|
||||
self.on_purpose = True
|
||||
p = common.xmpp.Presence(typ = 'unavailable')
|
||||
p = self.add_sha(p, False)
|
||||
if msg:
|
||||
p.setStatus(msg)
|
||||
self.remove_all_transfers()
|
||||
self.connection.send(p)
|
||||
|
||||
# try to set the privacy rule
|
||||
iq = self.build_privacy_rule('invisible', 'deny')
|
||||
self.connection.SendAndCallForResponse(iq, self._continue_invisible,
|
||||
|
@ -707,8 +798,7 @@ class Connection(ConnectionHandlers):
|
|||
def _continue_invisible(self, con, iq_obj, msg, signed, initial):
|
||||
ptype = ''
|
||||
show = ''
|
||||
# FIXME: JEP 126 need some modifications (see http://lists.jabber.ru/pipermail/ejabberd/2005-July/001252.html). So I disable it for the moment
|
||||
if 1 or iq_obj.getType() == 'error': #server doesn't support privacy lists
|
||||
if iq_obj.getType() == 'error': # server doesn't support privacy lists
|
||||
# We use the old way which is not xmpp complient
|
||||
ptype = 'invisible'
|
||||
show = 'invisible'
|
||||
|
@ -760,7 +850,7 @@ class Connection(ConnectionHandlers):
|
|||
callback is the function to call when user give the passphrase'''
|
||||
signed = ''
|
||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||
if keyID and self.gpg:
|
||||
if keyID and self.USE_GPG:
|
||||
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||
if self.gpg.passphrase is None and not use_gpg_agent:
|
||||
# We didn't set a passphrase
|
||||
|
@ -768,7 +858,7 @@ class Connection(ConnectionHandlers):
|
|||
if self.gpg.passphrase is not None or use_gpg_agent:
|
||||
signed = self.gpg.sign(msg, keyID)
|
||||
if signed == 'BAD_PASSPHRASE':
|
||||
self.gpg = None
|
||||
self.USE_GPG = False
|
||||
signed = ''
|
||||
self.dispatch('BAD_PASSPHRASE', ())
|
||||
return signed
|
||||
|
@ -845,7 +935,8 @@ class Connection(ConnectionHandlers):
|
|||
safe_substitute({
|
||||
'hostname': socket.gethostname()
|
||||
})
|
||||
if USE_GPG:
|
||||
if gajim.HAVE_GPG:
|
||||
self.USE_GPG = True
|
||||
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||
self.connect_and_init(show, msg, sign_msg)
|
||||
|
||||
|
@ -922,7 +1013,13 @@ class Connection(ConnectionHandlers):
|
|||
fjid += '/' + resource
|
||||
msgtxt = msg
|
||||
msgenc = ''
|
||||
if keyID and self.gpg:
|
||||
|
||||
if keyID and self.USE_GPG:
|
||||
if keyID == 'UNKNOWN':
|
||||
error = _('Neither the remote presence is signed, nor a key was assigned.')
|
||||
elif keyID[8:] == 'MISMATCH':
|
||||
error = _('The contact\'s key (%s) does not match the key assigned in Gajim.' % keyID[:8])
|
||||
else:
|
||||
#encrypt
|
||||
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
||||
if msgenc and not error:
|
||||
|
@ -1109,7 +1206,7 @@ class Connection(ConnectionHandlers):
|
|||
def send_new_account_infos(self, form, is_form):
|
||||
if is_form:
|
||||
# Get username and password and put them in new_account_info
|
||||
for field in self._data_form.iter_fields():
|
||||
for field in form.iter_fields():
|
||||
if field.var == 'username':
|
||||
self.new_account_info['name'] = field.value
|
||||
if field.var == 'password':
|
||||
|
|
|
@ -35,15 +35,20 @@ from calendar import timegm
|
|||
import socks5
|
||||
import common.xmpp
|
||||
|
||||
from common import GnuPG
|
||||
from common import helpers
|
||||
from common import gajim
|
||||
from common import atom
|
||||
from common import pep
|
||||
from common import exceptions
|
||||
from common.commands import ConnectionCommands
|
||||
from common.pubsub import ConnectionPubSub
|
||||
from common.caps import ConnectionCaps
|
||||
|
||||
from common import dbus_support
|
||||
if dbus_support.supported:
|
||||
import dbus
|
||||
from music_track_listener import MusicTrackListener
|
||||
|
||||
from common.stanza_session import EncryptedStanzaSession
|
||||
|
||||
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||
|
@ -54,6 +59,7 @@ VCARD_ARRIVED = 'vcard_arrived'
|
|||
AGENT_REMOVED = 'agent_removed'
|
||||
METACONTACTS_ARRIVED = 'metacontacts_arrived'
|
||||
PRIVACY_ARRIVED = 'privacy_arrived'
|
||||
PEP_ACCESS_MODEL = 'pep_access_model'
|
||||
HAS_IDLE = True
|
||||
try:
|
||||
import idle
|
||||
|
@ -750,6 +756,13 @@ class ConnectionDisco:
|
|||
q.addChild('feature', attrs = {'var': common.xmpp.NS_MUC})
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_COMMANDS})
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_DISCO_INFO})
|
||||
if gajim.config.get('use_pep'):
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_ACTIVITY})
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_ACTIVITY + '+notify'})
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_TUNE})
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_TUNE + '+notify'})
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_MOOD})
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_MOOD + '+notify'})
|
||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_ESESSION_INIT})
|
||||
|
||||
if (node is None or extension == 'cstates') and gajim.config.get('outgoing_chat_state_notifactions') != 'disabled':
|
||||
|
@ -821,6 +834,12 @@ class ConnectionDisco:
|
|||
if identity['category'] == 'pubsub' and identity['type'] == \
|
||||
'pep':
|
||||
self.pep_supported = True
|
||||
if dbus_support.supported:
|
||||
listener = MusicTrackListener.get()
|
||||
track = listener.get_playing_track()
|
||||
if gajim.config.get('publish_tune'):
|
||||
gajim.interface.roster._music_track_changed(listener,
|
||||
track, self.name)
|
||||
break
|
||||
if features.__contains__(common.xmpp.NS_BYTESTREAM):
|
||||
gajim.proxy65_manager.resolve(jid, self.connection, self.name)
|
||||
|
@ -1099,6 +1118,16 @@ class ConnectionVcard:
|
|||
self.get_privacy_list('block')
|
||||
# Ask metacontacts before roster
|
||||
self.get_metacontacts()
|
||||
elif self.awaiting_answers[id][0] == PEP_ACCESS_MODEL:
|
||||
conf = iq_obj.getTag('pubsub').getTag('configure')
|
||||
node = conf.getAttr('node')
|
||||
form_tag = conf.getTag('x', namespace=common.xmpp.NS_DATA)
|
||||
if form_tag:
|
||||
form = common.dataforms.ExtendForm(node=form_tag)
|
||||
for field in form.iter_fields():
|
||||
if field.var == 'pubsub#access_model':
|
||||
self.dispatch('PEP_ACCESS_MODEL', (node, field.value))
|
||||
break
|
||||
|
||||
del self.awaiting_answers[id]
|
||||
|
||||
|
@ -1251,7 +1280,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
reply.setType('error')
|
||||
|
||||
reply.addChild(feature)
|
||||
reply.addChild(node=xmpp.ErrorNode('service-unavailable', typ='cancel'))
|
||||
reply.addChild(node=common.xmpp.ErrorNode('service-unavailable', typ='cancel'))
|
||||
|
||||
con.send(reply)
|
||||
|
||||
|
@ -1419,7 +1448,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
iq_obj = iq_obj.buildReply('result')
|
||||
qp = iq_obj.getTag('query')
|
||||
qp.setTagData('utc', strftime('%Y%m%dT%T', gmtime()))
|
||||
qp.setTagData('tz', tzname[daylight])
|
||||
qp.setTagData('tz', helpers.decode_string(tzname[daylight]))
|
||||
qp.setTagData('display', helpers.decode_string(strftime('%c',
|
||||
localtime())))
|
||||
self.connection.send(iq_obj)
|
||||
|
@ -1599,7 +1628,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
if not user_nick:
|
||||
user_nick = ''
|
||||
|
||||
if encTag and GnuPG.USE_GPG:
|
||||
if encTag and self.USE_GPG:
|
||||
#decrypt
|
||||
encmsg = encTag.getData()
|
||||
|
||||
|
@ -1770,8 +1799,22 @@ returns the session that we last sent a message to.'''
|
|||
''' Called when we receive <message/> with pubsub event. '''
|
||||
# TODO: Logging? (actually services where logging would be useful, should
|
||||
# TODO: allow to access archives remotely...)
|
||||
jid = helpers.get_full_jid_from_iq(msg)
|
||||
event = msg.getTag('event')
|
||||
|
||||
# XEP-0107: User Mood
|
||||
items = event.getTag('items', {'node': common.xmpp.NS_MOOD})
|
||||
if items: pep.user_mood(items, self.name, jid)
|
||||
# XEP-0118: User Tune
|
||||
items = event.getTag('items', {'node': common.xmpp.NS_TUNE})
|
||||
if items: pep.user_tune(items, self.name, jid)
|
||||
# XEP-0080: User Geolocation
|
||||
items = event.getTag('items', {'node': common.xmpp.NS_GEOLOC})
|
||||
if items: pep.user_geoloc(items, self.name, jid)
|
||||
# XEP-0108: User Activity
|
||||
items = event.getTag('items', {'node': common.xmpp.NS_ACTIVITY})
|
||||
if items: pep.user_activity(items, self.name, jid)
|
||||
|
||||
items = event.getTag('items')
|
||||
if items is None: return
|
||||
|
||||
|
@ -1857,7 +1900,7 @@ returns the session that we last sent a message to.'''
|
|||
except:
|
||||
prio = 0
|
||||
keyID = ''
|
||||
if sigTag and self.gpg:
|
||||
if sigTag and self.USE_GPG:
|
||||
# verify
|
||||
sigmsg = sigTag.getData()
|
||||
keyID = self.gpg.verify(status, sigmsg)
|
||||
|
@ -2109,6 +2152,21 @@ returns the session that we last sent a message to.'''
|
|||
raw_roster = roster.getRaw()
|
||||
roster = {}
|
||||
our_jid = helpers.parse_jid(gajim.get_jid_from_account(self.name))
|
||||
if self.connected > 1 and self.continue_connect_info:
|
||||
msg = self.continue_connect_info[1]
|
||||
sign_msg = self.continue_connect_info[2]
|
||||
signed = ''
|
||||
send_first_presence = True
|
||||
if sign_msg:
|
||||
signed = self.get_signed_presence(msg, self._send_first_presence)
|
||||
if signed is None:
|
||||
self.dispatch('GPG_PASSWORD_REQUIRED',
|
||||
(self._send_first_presence,))
|
||||
# _send_first_presence will be called when user enter passphrase
|
||||
send_first_presence = False
|
||||
if send_first_presence:
|
||||
self._send_first_presence(signed)
|
||||
|
||||
for jid in raw_roster:
|
||||
try:
|
||||
j = helpers.parse_jid(jid)
|
||||
|
@ -2131,20 +2189,6 @@ returns the session that we last sent a message to.'''
|
|||
|
||||
self.dispatch('ROSTER', roster)
|
||||
|
||||
# continue connection
|
||||
if self.connected > 1 and self.continue_connect_info:
|
||||
msg = self.continue_connect_info[1]
|
||||
sign_msg = self.continue_connect_info[2]
|
||||
signed = ''
|
||||
if sign_msg:
|
||||
signed = self.get_signed_presence(msg, self._send_first_presence)
|
||||
if signed is None:
|
||||
self.dispatch('GPG_PASSWORD_REQUIRED',
|
||||
(self._send_first_presence,))
|
||||
# _send_first_presence will be called when user enter passphrase
|
||||
return
|
||||
self._send_first_presence(signed)
|
||||
|
||||
def _send_first_presence(self, signed = ''):
|
||||
show = self.continue_connect_info[0]
|
||||
msg = self.continue_connect_info[1]
|
||||
|
@ -2155,6 +2199,7 @@ returns the session that we last sent a message to.'''
|
|||
self.dispatch('ERROR', (_('OpenPGP passphrase was not given'),
|
||||
#%s is the account name here
|
||||
_('You will be connected to %s without OpenPGP.') % self.name))
|
||||
self.USE_GPG = False
|
||||
signed = ''
|
||||
self.connected = STATUS_LIST.index(show)
|
||||
sshow = helpers.get_xmpp_show(show)
|
||||
|
|
|
@ -27,7 +27,8 @@ class Contact:
|
|||
'''Information concerning each contact'''
|
||||
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
|
||||
ask='', resource='', priority=0, keyID='', our_chatstate=None,
|
||||
chatstate=None, last_status_time=None, msg_id = None, composing_xep = None):
|
||||
chatstate=None, last_status_time=None, msg_id = None, composing_xep = None,
|
||||
mood={}, tune={}, activity={}):
|
||||
self.jid = jid
|
||||
self.name = name
|
||||
self.contact_name = '' # nick choosen by contact
|
||||
|
@ -63,6 +64,10 @@ class Contact:
|
|||
self.chatstate = chatstate
|
||||
self.last_status_time = last_status_time
|
||||
|
||||
self.mood = mood.copy()
|
||||
self.tune = tune.copy()
|
||||
self.activity = activity.copy()
|
||||
|
||||
def get_full_jid(self):
|
||||
if self.resource:
|
||||
return self.jid + '/' + self.resource
|
||||
|
@ -162,15 +167,16 @@ class Contacts:
|
|||
|
||||
def create_contact(self, jid='', name='', groups=[], show='', status='',
|
||||
sub='', ask='', resource='', priority=0, keyID='', our_chatstate=None,
|
||||
chatstate=None, last_status_time=None, composing_xep=None):
|
||||
chatstate=None, last_status_time=None, composing_xep=None,
|
||||
mood={}, tune={}, activity={}):
|
||||
return Contact(jid, name, groups, show, status, sub, ask, resource,
|
||||
priority, keyID, our_chatstate, chatstate, last_status_time,
|
||||
composing_xep)
|
||||
None, composing_xep, mood, tune, activity)
|
||||
|
||||
def copy_contact(self, contact):
|
||||
return self.create_contact(jid = contact.jid, name = contact.name,
|
||||
groups = contact.groups, show = contact.show, status = contact.status,
|
||||
sub = contact.sub, ask = contact.ask, resource = contact.resource,
|
||||
groups = contact.groups, show = contact.show, status =
|
||||
contact.status, sub = contact.sub, ask = contact.ask, resource = contact.resource,
|
||||
priority = contact.priority, keyID = contact.keyID,
|
||||
our_chatstate = contact.our_chatstate, chatstate = contact.chatstate,
|
||||
last_status_time = contact.last_status_time)
|
||||
|
@ -469,6 +475,15 @@ class Contacts:
|
|||
return 1
|
||||
if show2 > show1:
|
||||
return -1
|
||||
server1 = common.gajim.get_server_from_jid(jid1)
|
||||
server2 = common.gajim.get_server_from_jid(jid2)
|
||||
myserver1 = common.gajim.config.get_per('accounts', account1, 'hostname')
|
||||
myserver2 = common.gajim.config.get_per('accounts', account2, 'hostname')
|
||||
if server1 == myserver1:
|
||||
if server2 != myserver2:
|
||||
return 1
|
||||
elif server2 == myserver2:
|
||||
return -1
|
||||
if jid1 > jid2:
|
||||
return 1
|
||||
if jid2 > jid1:
|
||||
|
|
|
@ -2,7 +2,7 @@ docdir = '../'
|
|||
|
||||
datadir = '../'
|
||||
|
||||
version = '0.11.4.0-svn'
|
||||
version = '0.11.4.2-svn'
|
||||
|
||||
import sys, os.path
|
||||
for base in ('.', 'common'):
|
||||
|
|
|
@ -138,9 +138,6 @@ SHOW_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
|||
|
||||
# zeroconf account name
|
||||
ZEROCONF_ACC_NAME = 'Local'
|
||||
priority_dict = {}
|
||||
for status in ('online', 'chat', 'away', 'xa', 'dnd', 'invisible'):
|
||||
priority_dict[status] = config.get('autopriority' + status)
|
||||
|
||||
HAVE_PYCRYPTO = True
|
||||
try:
|
||||
|
@ -154,6 +151,17 @@ try:
|
|||
except ImportError:
|
||||
HAVE_PYSEXY = False
|
||||
|
||||
HAVE_GPG = True
|
||||
try:
|
||||
import GnuPGInterface
|
||||
except ImportError:
|
||||
HAVE_GPG = False
|
||||
else:
|
||||
import os
|
||||
status = os.system('gpg -h >/dev/null 2>&1')
|
||||
if status != 0:
|
||||
HAVE_GPG = False
|
||||
|
||||
def get_nick_from_jid(jid):
|
||||
pos = jid.find('@')
|
||||
return jid[:pos]
|
||||
|
@ -260,13 +268,14 @@ def account_is_disconnected(account):
|
|||
def get_number_of_securely_connected_accounts():
|
||||
'''returns the number of the accounts that are SSL/TLS connected'''
|
||||
num_of_secured = 0
|
||||
for account in connections:
|
||||
for account in connections.keys():
|
||||
if account_is_securely_connected(account):
|
||||
num_of_secured += 1
|
||||
return num_of_secured
|
||||
|
||||
def account_is_securely_connected(account):
|
||||
if account in con_types and con_types[account] in ('tls', 'ssl'):
|
||||
if account_is_connected(account) and \
|
||||
account in con_types and con_types[account] in ('tls', 'ssl'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -429,7 +429,7 @@ def launch_browser_mailer(kind, uri):
|
|||
command = 'kfmclient exec'
|
||||
elif gajim.config.get('openwith') == 'exo-open':
|
||||
command = 'exo-open'
|
||||
elif ((sys.platform == 'darwin') and
|
||||
elif ((sys.platform == 'darwin') and\
|
||||
(gajim.config.get('openwith') == 'open')):
|
||||
command = 'open'
|
||||
elif gajim.config.get('openwith') == 'custom':
|
||||
|
@ -459,7 +459,7 @@ def launch_file_manager(path_to_open):
|
|||
command = 'kfmclient exec'
|
||||
elif gajim.config.get('openwith') == 'exo-open':
|
||||
command = 'exo-open'
|
||||
elif ((sys.platform == 'darwin') and
|
||||
elif ((sys.platform == 'darwin') and\
|
||||
(gajim.config.get('openwith') == 'open')):
|
||||
command = 'open'
|
||||
elif gajim.config.get('openwith') == 'custom':
|
||||
|
@ -784,7 +784,8 @@ def get_os_info():
|
|||
'sourcemage') or not\
|
||||
os.path.basename(path_to_file).startswith('slackware'):
|
||||
text = distro_name + ' ' + text
|
||||
elif path_to_file.endswith('aurox-release'):
|
||||
elif path_to_file.endswith('aurox-release') or \
|
||||
path_to_file.endswith('arch-release'):
|
||||
# file doesn't have version
|
||||
text = distro_name
|
||||
elif path_to_file.endswith('lfs-release'): # file just has version
|
||||
|
@ -792,7 +793,7 @@ def get_os_info():
|
|||
return text
|
||||
|
||||
# our last chance, ask uname and strip it
|
||||
uname_output = get_output_of_command('uname -a | cut -d" " -f1,3')
|
||||
uname_output = get_output_of_command('uname -sr')
|
||||
if uname_output is not None:
|
||||
return uname_output[0] # only first line
|
||||
return 'N/A'
|
||||
|
@ -1092,3 +1093,38 @@ def get_transport_path(transport):
|
|||
elif os.path.isdir(os.path.join(gajim.MY_ICONSETS_PATH, 'transports',
|
||||
transport)):
|
||||
return os.path.join(gajim.MY_ICONSETS_PATH, 'transports', transport)
|
||||
# No transport folder found, use default jabber one
|
||||
return get_iconset_path(gajim.config.get('iconset'))
|
||||
|
||||
def prepare_and_validate_gpg_keyID(account, jid, keyID):
|
||||
'''Returns an eight char long keyID that can be used with for GPG encryption with this contact.
|
||||
If the given keyID is None, return UNKNOWN; if the key does not match the assigned key
|
||||
XXXXXXXXMISMATCH is returned. If the key is trusted and not yet assigned, assign it'''
|
||||
if gajim.connections[account].USE_GPG:
|
||||
if keyID and len(keyID) == 16:
|
||||
keyID = keyID[8:]
|
||||
|
||||
attached_keys = gajim.config.get_per('accounts', account,
|
||||
'attached_gpg_keys').split()
|
||||
|
||||
if jid in attached_keys and keyID:
|
||||
attachedkeyID = attached_keys[attached_keys.index(jid) + 1]
|
||||
if attachedkeyID != keyID:
|
||||
# Mismatch! Another gpg key was expected
|
||||
keyID += 'MISMATCH'
|
||||
elif jid in attached_keys:
|
||||
# An unsigned presence, just use the assigned key
|
||||
keyID = attached_keys[attached_keys.index(jid) + 1]
|
||||
elif keyID:
|
||||
public_keys = gajim.connections[account].ask_gpg_keys()
|
||||
# Assign the corresponding key, if we have it in our keyring
|
||||
if public_keys.has_key(keyID):
|
||||
for u in gajim.contacts.get_contacts(account, jid):
|
||||
u.keyID = keyID
|
||||
keys_str = gajim.config.get_per('accounts', account, 'attached_gpg_keys')
|
||||
keys_str += jid + ' ' + keyID + ' '
|
||||
gajim.config.set_per('accounts', account, 'attached_gpg_keys', keys_str)
|
||||
elif keyID is None:
|
||||
keyID = 'UNKNOWN'
|
||||
return keyID
|
||||
|
||||
|
|
|
@ -174,8 +174,10 @@ class OptionsParser:
|
|||
self.update_config_to_01115()
|
||||
if old < [0, 11, 2, 1] and new >= [0, 11, 2, 1]:
|
||||
self.update_config_to_01121()
|
||||
if old < [0, 11, 2, 2] and new >= [0, 11, 2, 2]:
|
||||
self.update_config_to_01122()
|
||||
if old < [0, 11, 4, 1] and new >= [0, 11, 4, 1]:
|
||||
self.update_config_to_01141()
|
||||
if old < [0, 11, 4, 2] and new >= [0, 11, 4, 2]:
|
||||
self.update_config_to_01142()
|
||||
|
||||
gajim.logger.init_vars()
|
||||
gajim.config.set('version', new_version)
|
||||
|
@ -503,7 +505,7 @@ class OptionsParser:
|
|||
|
||||
gajim.config.set('version', '0.11.2.1')
|
||||
|
||||
def update_config_to_01122(self):
|
||||
def update_config_to_01141(self):
|
||||
back = os.getcwd()
|
||||
os.chdir(logger.LOG_DB_FOLDER)
|
||||
con = sqlite.connect(logger.LOG_DB_FILE)
|
||||
|
@ -524,5 +526,20 @@ class OptionsParser:
|
|||
except sqlite.OperationalError, e:
|
||||
pass
|
||||
con.close()
|
||||
gajim.config.set('version', '0.11.2.2')
|
||||
gajim.config.set('version', '0.11.4.1')
|
||||
|
||||
def update_config_to_01142(self):
|
||||
'''next_message_received sound event is splittedin 2 events'''
|
||||
gajim.config.add_per('soundevents', 'next_message_received_focused')
|
||||
gajim.config.add_per('soundevents', 'next_message_received_unfocused')
|
||||
if gajim.config.get_per('soundevents', 'next_message_received'):
|
||||
enabled = gajim.config.get_per('soundevents', 'next_message_received',
|
||||
'enabled')
|
||||
path = gajim.config.get_per('soundevents', 'next_message_received',
|
||||
'path')
|
||||
gajim.config.del_per('soundevents', 'next_message_received')
|
||||
gajim.config.set_per('soundevents', 'next_message_received_focused',
|
||||
'enabled', enabled)
|
||||
gajim.config.set_per('soundevents', 'next_message_received_focused',
|
||||
'path', path)
|
||||
gajim.config.set('version', '0.11.1.2')
|
||||
|
|
220
src/common/pep.py
Normal file
220
src/common/pep.py
Normal file
|
@ -0,0 +1,220 @@
|
|||
from common import gajim, xmpp
|
||||
|
||||
def user_mood(items, name, jid):
|
||||
has_child = False
|
||||
mood = None
|
||||
text = None
|
||||
for item in items.getTags('item'):
|
||||
child = item.getTag('mood')
|
||||
if child is not None:
|
||||
has_child = True
|
||||
for ch in child.getChildren():
|
||||
if ch.getName() != 'text':
|
||||
mood = ch.getName()
|
||||
else:
|
||||
text = ch.getData()
|
||||
if jid == gajim.get_jid_from_account(name):
|
||||
acc = gajim.connections[name]
|
||||
if has_child:
|
||||
if acc.mood.has_key('mood'):
|
||||
del acc.mood['mood']
|
||||
if acc.mood.has_key('text'):
|
||||
del acc.mood['text']
|
||||
if mood != None:
|
||||
acc.mood['mood'] = mood
|
||||
if text != None:
|
||||
acc.mood['text'] = text
|
||||
|
||||
(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
|
||||
contact = gajim.contacts.get_contact(name, user, resource=resource)
|
||||
if not contact:
|
||||
return
|
||||
if has_child:
|
||||
if contact.mood.has_key('mood'):
|
||||
del contact.mood['mood']
|
||||
if contact.mood.has_key('text'):
|
||||
del contact.mood['text']
|
||||
if mood != None:
|
||||
contact.mood['mood'] = mood
|
||||
if text != None:
|
||||
contact.mood['text'] = text
|
||||
|
||||
def user_tune(items, name, jid):
|
||||
has_child = False
|
||||
artist = None
|
||||
title = None
|
||||
source = None
|
||||
track = None
|
||||
length = None
|
||||
|
||||
for item in items.getTags('item'):
|
||||
child = item.getTag('tune')
|
||||
if child is not None:
|
||||
has_child = True
|
||||
for ch in child.getChildren():
|
||||
if ch.getName() == 'artist':
|
||||
artist = ch.getData()
|
||||
elif ch.getName() == 'title':
|
||||
title = ch.getData()
|
||||
elif ch.getName() == 'source':
|
||||
source = ch.getData()
|
||||
elif ch.getName() == 'track':
|
||||
track = ch.getData()
|
||||
elif ch.getName() == 'length':
|
||||
length = ch.getData()
|
||||
|
||||
if jid == gajim.get_jid_from_account(name):
|
||||
acc = gajim.connections[name]
|
||||
if has_child:
|
||||
if acc.tune.has_key('artist'):
|
||||
del acc.tune['artist']
|
||||
if acc.tune.has_key('title'):
|
||||
del acc.tune['title']
|
||||
if acc.tune.has_key('source'):
|
||||
del acc.tune['source']
|
||||
if acc.tune.has_key('track'):
|
||||
del acc.tune['track']
|
||||
if acc.tune.has_key('length'):
|
||||
del acc.tune['length']
|
||||
if artist != None:
|
||||
acc.tune['artist'] = artist
|
||||
if title != None:
|
||||
acc.tune['title'] = title
|
||||
if source != None:
|
||||
acc.tune['source'] = source
|
||||
if track != None:
|
||||
acc.tune['track'] = track
|
||||
if length != None:
|
||||
acc.tune['length'] = length
|
||||
|
||||
(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
|
||||
contact = gajim.contacts.get_contact(name, user, resource=resource)
|
||||
if not contact:
|
||||
return
|
||||
if has_child:
|
||||
if contact.tune.has_key('artist'):
|
||||
del contact.tune['artist']
|
||||
if contact.tune.has_key('title'):
|
||||
del contact.tune['title']
|
||||
if contact.tune.has_key('source'):
|
||||
del contact.tune['source']
|
||||
if contact.tune.has_key('track'):
|
||||
del contact.tune['track']
|
||||
if contact.tune.has_key('length'):
|
||||
del contact.tune['length']
|
||||
if artist != None:
|
||||
contact.tune['artist'] = artist
|
||||
if title != None:
|
||||
contact.tune['title'] = title
|
||||
if source != None:
|
||||
contact.tune['source'] = source
|
||||
if track != None:
|
||||
contact.tune['track'] = track
|
||||
if length != None:
|
||||
contact.tune['length'] = length
|
||||
|
||||
def user_geoloc(items, name, jid):
|
||||
pass
|
||||
|
||||
def user_activity(items, name, jid):
|
||||
has_child = False
|
||||
activity = None
|
||||
subactivity = None
|
||||
text = None
|
||||
|
||||
for item in items.getTags('item'):
|
||||
child = item.getTag('activity')
|
||||
if child is not None:
|
||||
has_child = True
|
||||
for ch in child.getChildren():
|
||||
if ch.getName() != 'text':
|
||||
activity = ch.getName()
|
||||
for chi in ch.getChildren():
|
||||
subactivity = chi.getName()
|
||||
else:
|
||||
text = ch.getData()
|
||||
|
||||
if jid == gajim.get_jid_from_account(name):
|
||||
acc = gajim.connections[name]
|
||||
if has_child:
|
||||
if acc.activity.has_key('activity'):
|
||||
del acc.activity['activity']
|
||||
if acc.activity.has_key('subactivity'):
|
||||
del acc.activity['subactivity']
|
||||
if acc.activity.has_key('text'):
|
||||
del acc.activity['text']
|
||||
if activity != None:
|
||||
acc.activity['activity'] = activity
|
||||
if subactivity != None:
|
||||
acc.activity['subactivity'] = subactivity
|
||||
if text != None:
|
||||
acc.activity['text'] = text
|
||||
|
||||
(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
|
||||
contact = gajim.contacts.get_contact(name, user, resource=resource)
|
||||
if not contact:
|
||||
return
|
||||
if has_child:
|
||||
if contact.activity.has_key('activity'):
|
||||
del contact.activity['activity']
|
||||
if contact.activity.has_key('subactivity'):
|
||||
del contact.activity['subactivity']
|
||||
if contact.activity.has_key('text'):
|
||||
del contact.activity['text']
|
||||
if activity != None:
|
||||
contact.activity['activity'] = activity
|
||||
if subactivity != None:
|
||||
contact.activity['subactivity'] = subactivity
|
||||
if text != None:
|
||||
contact.activity['text'] = text
|
||||
|
||||
def user_send_mood(account, mood, message = ''):
|
||||
if gajim.config.get('publish_mood') == False:
|
||||
return
|
||||
item = xmpp.Node('mood', {'xmlns': xmpp.NS_MOOD})
|
||||
if mood != '':
|
||||
item.addChild(mood)
|
||||
if message != '':
|
||||
i = item.addChild('text')
|
||||
i.addData(message)
|
||||
|
||||
gajim.connections[account].send_pb_publish('', xmpp.NS_MOOD, item, '0')
|
||||
|
||||
def user_send_activity(account, activity, subactivity = '', message = ''):
|
||||
if gajim.config.get('publish_activity') == False:
|
||||
return
|
||||
item = xmpp.Node('activity', {'xmlns': xmpp.NS_ACTIVITY})
|
||||
if activity != '':
|
||||
i = item.addChild(activity)
|
||||
if subactivity != '':
|
||||
i.addChild(subactivity)
|
||||
if message != '':
|
||||
i = item.addChild('text')
|
||||
i.addData(message)
|
||||
|
||||
gajim.connections[account].send_pb_publish('', xmpp.NS_ACTIVITY, item, '0')
|
||||
|
||||
def user_send_tune(account, artist = '', title = '', source = '', track = 0,length = 0, items = None):
|
||||
if (gajim.config.get('publish_tune') == False) or \
|
||||
(gajim.connections[account].pep_supported == False):
|
||||
return
|
||||
item = xmpp.Node('tune', {'xmlns': xmpp.NS_TUNE})
|
||||
if artist != '':
|
||||
i = item.addChild('artist')
|
||||
i.addData(artist)
|
||||
if title != '':
|
||||
i = item.addChild('title')
|
||||
i.addData(title)
|
||||
if source != '':
|
||||
i = item.addChild('source')
|
||||
i.addData(source)
|
||||
if track != 0:
|
||||
i = item.addChild('track')
|
||||
i.addData(track)
|
||||
if length != 0:
|
||||
i = item.addChild('length')
|
||||
i.addData(length)
|
||||
if items is not None:
|
||||
item.addChild(payload=items)
|
||||
|
||||
gajim.connections[account].send_pb_publish('', xmpp.NS_TUNE, item, '0')
|
|
@ -1,5 +1,6 @@
|
|||
import xmpp
|
||||
import gajim
|
||||
import connection_handlers
|
||||
|
||||
class ConnectionPubSub:
|
||||
def __init__(self):
|
||||
|
@ -43,9 +44,61 @@ class ConnectionPubSub:
|
|||
|
||||
self.connection.send(query)
|
||||
|
||||
def send_pb_delete(self, jid, node):
|
||||
'''Deletes node.'''
|
||||
query = xmpp.Iq('set', to=jid)
|
||||
d = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
|
||||
d = d.addChild('delete', {'node': node})
|
||||
|
||||
self.connection.send(query)
|
||||
|
||||
def send_pb_create(self, jid, node, configure = False, configure_form = None):
|
||||
'''Creates new node.'''
|
||||
query = xmpp.Iq('set', to=jid)
|
||||
c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
|
||||
c = c.addChild('create', {'node': node})
|
||||
if configure:
|
||||
conf = c.addChild('configure')
|
||||
if configure_form is not None:
|
||||
conf.addChild(node=configure_form)
|
||||
|
||||
self.connection.send(query)
|
||||
|
||||
def send_pb_configure(self, jid, node, cb, *cbargs, **cbkwargs):
|
||||
query = xmpp.Iq('set', to=jid)
|
||||
c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
|
||||
c = c.addChild('configure', {'node': node})
|
||||
|
||||
id = self.connection.send(query)
|
||||
|
||||
def on_configure(self, connection, query):
|
||||
try:
|
||||
filledform = cb(stanza['pubsub']['configure']['x'], *cbargs, **cbkwargs)
|
||||
#TODO: Build a form
|
||||
#TODO: Send it
|
||||
|
||||
except CancelConfigure:
|
||||
cancel = xmpp.Iq('set', to=jid)
|
||||
ca = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB)
|
||||
ca = ca.addChild('configure', {'node': node})
|
||||
#ca = ca.addChild('x', namespace=xmpp.NS_DATA, {'type': 'cancel'})
|
||||
|
||||
self.connection.send(cancel)
|
||||
|
||||
self.__callbacks[id] = (on_configure, (), {})
|
||||
|
||||
def _PubSubCB(self, conn, stanza):
|
||||
try:
|
||||
cb, args, kwargs = self.__callbacks.pop(stanza.getID())
|
||||
cb(conn, stanza, *args, **kwargs)
|
||||
except:
|
||||
pass
|
||||
|
||||
def request_pb_configuration(self, jid, node):
|
||||
query = xmpp.Iq('get', to=jid)
|
||||
e = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB_OWNER)
|
||||
e = e.addChild('configure', {'node': node})
|
||||
id = self.connection.getAnID()
|
||||
query.setID(id)
|
||||
self.awaiting_answers[id] = (connection_handlers.PEP_ACCESS_MODEL,)
|
||||
self.connection.send(query)
|
||||
|
|
|
@ -932,7 +932,7 @@ class Socks5Receiver(Socks5, IdleObject):
|
|||
elif self.state == 3: # send 'connect' request
|
||||
self.send_raw(self._get_request_buff(self._get_sha1_auth()))
|
||||
elif self.file_props['type'] != 'r':
|
||||
if self.file_props['paused'] == True:
|
||||
if self.file_props['paused']:
|
||||
self.idlequeue.plug_idle(self, False, False)
|
||||
return
|
||||
result = self.write_next()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from common import gajim
|
||||
|
||||
from common import xmpp
|
||||
from common import helpers
|
||||
from common import exceptions
|
||||
|
||||
import random
|
||||
|
|
|
@ -27,11 +27,14 @@ NS_AGENTS ='jabber:iq:agents'
|
|||
NS_AMP ='http://jabber.org/protocol/amp'
|
||||
NS_AMP_ERRORS =NS_AMP+'#errors'
|
||||
NS_AUTH ='jabber:iq:auth'
|
||||
NS_AVATAR ='http://www.xmpp.org/extensions/xep-0084.html#ns-metadata'
|
||||
NS_BIND ='urn:ietf:params:xml:ns:xmpp-bind'
|
||||
NS_BROWSE ='jabber:iq:browse'
|
||||
NS_BYTESTREAM ='http://jabber.org/protocol/bytestreams' # XEP-0065
|
||||
NS_CAPS ='http://jabber.org/protocol/caps' # XEP-0115
|
||||
NS_CHATSTATES ='http://jabber.org/protocol/chatstates' # XEP-0085
|
||||
NS_BROWSING ='http://jabber.org/protocol/browsing' # XEP-0195
|
||||
NS_BYTESTREAM ='http://jabber.org/protocol/bytestreams' # JEP-0065
|
||||
NS_CAPS ='http://jabber.org/protocol/caps' # JEP-0115
|
||||
NS_CHATSTATES ='http://jabber.org/protocol/chatstates' # JEP-0085
|
||||
NS_CHATTING ='http://jabber.org/protocol/chatting' # XEP-0194
|
||||
NS_CLIENT ='jabber:client'
|
||||
NS_COMMANDS ='http://jabber.org/protocol/commands'
|
||||
NS_COMPONENT_ACCEPT='jabber:component:accept'
|
||||
|
@ -48,8 +51,9 @@ NS_ENCRYPTED ='jabber:x:encrypted' # XEP-00
|
|||
NS_ESESSION_INIT='http://www.xmpp.org/extensions/xep-0116.html#ns-init' # XEP-0116
|
||||
NS_EVENT ='jabber:x:event' # XEP-0022
|
||||
NS_FEATURE ='http://jabber.org/protocol/feature-neg'
|
||||
NS_FILE ='http://jabber.org/protocol/si/profile/file-transfer' # XEP-0096
|
||||
NS_GEOLOC ='http://jabber.org/protocol/geoloc' # XEP-0080
|
||||
NS_FILE ='http://jabber.org/protocol/si/profile/file-transfer' # JEP-0096
|
||||
NS_GAMING ='http://jabber.org/protocol/gaming' # XEP-0196
|
||||
NS_GEOLOC ='http://jabber.org/protocol/geoloc' # JEP-0080
|
||||
NS_GROUPCHAT ='gc-1.0'
|
||||
NS_HTTP_AUTH ='http://jabber.org/protocol/http-auth' # XEP-0070
|
||||
NS_HTTP_BIND ='http://jabber.org/protocol/httpbind' # XEP-0124
|
||||
|
@ -72,6 +76,7 @@ NS_PRIVACY ='jabber:iq:privacy'
|
|||
NS_PRIVATE ='jabber:iq:private'
|
||||
NS_PROFILE ='http://jabber.org/protocol/profile' # XEP-0154
|
||||
NS_PUBSUB ='http://jabber.org/protocol/pubsub' # XEP-0060
|
||||
NS_PUBSUB_OWNER ='http://jabber.org/protocol/pubsub#owner' # JEP-0060
|
||||
NS_REGISTER ='jabber:iq:register'
|
||||
NS_ROSTER ='jabber:iq:roster'
|
||||
NS_ROSTERX ='http://jabber.org/protocol/rosterx' # XEP-0144
|
||||
|
@ -90,12 +95,14 @@ NS_STREAMS ='http://etherx.jabber.org/streams'
|
|||
NS_TIME ='jabber:iq:time' # XEP-0900
|
||||
NS_TIME_REVISED ='urn:xmpp:time' # XEP-0202
|
||||
NS_TLS ='urn:ietf:params:xml:ns:xmpp-tls'
|
||||
NS_TUNE ='http://jabber.org/protocol/tune' # XEP-0118
|
||||
NS_VACATION ='http://jabber.org/protocol/vacation'
|
||||
NS_VCARD ='vcard-temp'
|
||||
NS_GMAILNOTIFY ='google:mail:notify'
|
||||
NS_GTALKSETTING ='google:setting'
|
||||
NS_VCARD_UPDATE =NS_VCARD+':x:update'
|
||||
NS_VERSION ='jabber:iq:version'
|
||||
NS_VIEWING ='http://jabber.org/protocol/viewing' # XEP--197
|
||||
NS_PING ='urn:xmpp:ping' # XEP-0199
|
||||
NS_WAITINGLIST ='http://jabber.org/protocol/waitinglist' # XEP-0130
|
||||
NS_XHTML_IM ='http://jabber.org/protocol/xhtml-im' # XEP-0071
|
||||
|
|
|
@ -87,7 +87,11 @@ class Roster(PlugIn):
|
|||
def PresenceHandler(self,dis,pres):
|
||||
""" Presence tracker. Used internally for setting items' resources state in
|
||||
internal roster representation. """
|
||||
jid=JID(pres.getFrom())
|
||||
jid=pres.getFrom()
|
||||
if not jid:
|
||||
# If no from attribue, it's from server
|
||||
jid=self._owner.Server
|
||||
jid=JID(jid)
|
||||
if not self._data.has_key(jid.getStripped()): self._data[jid.getStripped()]={'name':None,'ask':None,'subscription':'none','groups':['Not in roster'],'resources':{}}
|
||||
if type(self._data[jid.getStripped()]['resources'])!=type(dict()):
|
||||
self._data[jid.getStripped()]['resources']={}
|
||||
|
|
|
@ -761,15 +761,18 @@ class NonBlockingTLS(PlugIn):
|
|||
for line in lines:
|
||||
if 'BEGIN CERTIFICATE' in line:
|
||||
begin = i
|
||||
continue
|
||||
elif 'END CERTIFICATE' in line and begin > -1:
|
||||
cert = ''.join(lines[begin:i+2])
|
||||
try:
|
||||
X509cert = OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, cert)
|
||||
store.add_cert(X509cert)
|
||||
except OpenSSL.crypto.Error, exception_obj:
|
||||
log.warning('Unable to load a certificate from file %s: %s' %\
|
||||
(gajim.MY_CACERTS, exception_obj.args[0][0][2]))
|
||||
except:
|
||||
log.warning('Unable to load a certificate from file %s' % \
|
||||
log.warning(
|
||||
'Unknown error while loading certificate from file %s' % \
|
||||
gajim.MY_CACERTS)
|
||||
begin = -1
|
||||
i += 1
|
||||
|
@ -787,7 +790,8 @@ class NonBlockingTLS(PlugIn):
|
|||
try:
|
||||
self.starttls='in progress'
|
||||
tcpsock._sslObj.do_handshake()
|
||||
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError), e:
|
||||
# Errors are handeled in _do_receive function
|
||||
except:
|
||||
pass
|
||||
tcpsock._sslObj.setblocking(False)
|
||||
log.debug("Synchronous handshake completed")
|
||||
|
@ -1027,7 +1031,7 @@ class NBSOCKS5PROXYsocket(NonBlockingTcp):
|
|||
# use the IPv4 address request even if remote resolving was specified.
|
||||
try:
|
||||
self.ipaddr = socket.inet_aton(self.server[0])
|
||||
req = req + "\x01" + ipaddr
|
||||
req = req + "\x01" + self.ipaddr
|
||||
except socket.error:
|
||||
# Well it's not an IP number, so it's probably a DNS name.
|
||||
# if self.__proxy[3]==True:
|
||||
|
|
|
@ -32,7 +32,6 @@ from calendar import timegm
|
|||
from common import socks5
|
||||
import common.xmpp
|
||||
|
||||
from common import GnuPG
|
||||
from common import helpers
|
||||
from common import gajim
|
||||
from common.zeroconf import zeroconf
|
||||
|
@ -726,13 +725,15 @@ class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream):
|
|||
if not user_nick:
|
||||
user_nick = ''
|
||||
|
||||
if encTag and GnuPG.USE_GPG:
|
||||
if encTag and self.USE_GPG:
|
||||
#decrypt
|
||||
encmsg = encTag.getData()
|
||||
|
||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||
if keyID:
|
||||
decmsg = self.gpg.decrypt(encmsg, keyID)
|
||||
# \x00 chars are not allowed in C (so in GTK)
|
||||
decmsg = decmsg.replace('\x00', '')
|
||||
if decmsg:
|
||||
msgtxt = decmsg
|
||||
encrypted = True
|
||||
|
|
|
@ -49,8 +49,6 @@ from common.zeroconf import client_zeroconf
|
|||
from common.zeroconf import zeroconf
|
||||
from connection_handlers_zeroconf import *
|
||||
|
||||
USE_GPG = GnuPG.USE_GPG
|
||||
|
||||
class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||
'''Connection class'''
|
||||
def __init__(self, name):
|
||||
|
@ -62,7 +60,9 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
|||
self.connected = 0 # offline
|
||||
self.connection = None
|
||||
self.gpg = None
|
||||
if USE_GPG:
|
||||
self.USE_GPG = False
|
||||
if gajim.HAVE_GPG:
|
||||
self.USE_GPG = True
|
||||
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||
self.is_zeroconf = True
|
||||
self.privacy_rules_supported = False
|
||||
|
@ -86,9 +86,13 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
|||
self.no_log_for = False
|
||||
|
||||
self.pep_supported = False
|
||||
self.mood = {}
|
||||
self.tune = {}
|
||||
self.activity = {}
|
||||
# Do we continue connection when we get roster (send presence,get vcard...)
|
||||
self.continue_connect_info = None
|
||||
if USE_GPG:
|
||||
if gajim.HAVE_GPG:
|
||||
self.USE_GPG = True
|
||||
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||
|
||||
self.get_config_values_or_default()
|
||||
|
@ -160,7 +164,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
|||
def get_signed_msg(self, msg):
|
||||
signed = ''
|
||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||
if keyID and USE_GPG:
|
||||
if keyID and self.USE_GPG:
|
||||
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||
if self.connected < 2 and self.gpg.passphrase is None and \
|
||||
not use_gpg_agent:
|
||||
|
@ -168,9 +172,11 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
|||
self.dispatch('ERROR', (_('OpenPGP passphrase was not given'),
|
||||
#%s is the account name here
|
||||
_('You will be connected to %s without OpenPGP.') % self.name))
|
||||
self.USE_GPG = False
|
||||
elif self.gpg.passphrase is not None or use_gpg_agent:
|
||||
signed = self.gpg.sign(msg, keyID)
|
||||
if signed == 'BAD_PASSPHRASE':
|
||||
self.USE_GPG = False
|
||||
signed = ''
|
||||
if self.connected < 2:
|
||||
self.dispatch('BAD_PASSPHRASE', ())
|
||||
|
@ -370,7 +376,12 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
|||
|
||||
msgtxt = msg
|
||||
msgenc = ''
|
||||
if keyID and USE_GPG:
|
||||
if keyID and self.USE_GPG:
|
||||
if keyID == 'UNKNOWN':
|
||||
error = _('Neither the remote presence is signed, nor a key was assigned.')
|
||||
elif keyID[8:] == 'MISMATCH':
|
||||
error = _('The contact\'s key (%s) does not match the key assigned in Gajim.' % keyID[:8])
|
||||
else:
|
||||
# encrypt
|
||||
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
||||
if msgenc and not error:
|
||||
|
@ -507,7 +518,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
|||
gajim.log.debug('This should not happen (send_agent_status)')
|
||||
|
||||
def gpg_passphrase(self, passphrase):
|
||||
if USE_GPG:
|
||||
if self.gpg:
|
||||
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||
if use_gpg_agent:
|
||||
self.gpg.passphrase = None
|
||||
|
@ -515,13 +526,13 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
|||
self.gpg.passphrase = passphrase
|
||||
|
||||
def ask_gpg_keys(self):
|
||||
if USE_GPG:
|
||||
if self.gpg:
|
||||
keys = self.gpg.get_keys()
|
||||
return keys
|
||||
return None
|
||||
|
||||
def ask_gpg_secrete_keys(self):
|
||||
if USE_GPG:
|
||||
if self.gpg:
|
||||
keys = self.gpg.get_secret_keys()
|
||||
return keys
|
||||
return None
|
||||
|
|
637
src/config.py
637
src/config.py
|
@ -6,6 +6,7 @@
|
|||
## Copyright (C) 2003-2005 Vincent Hanquez <tab@snarc.org>
|
||||
## Copyright (C) 2006 Stefan Bethge <stefan@lanpartei.de>
|
||||
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
|
||||
## Copyright (C) 2007 Travis Shirk <travis@pobox.com>
|
||||
##
|
||||
## This file is part of Gajim.
|
||||
##
|
||||
|
@ -49,6 +50,7 @@ from common import passwords
|
|||
from common import zeroconf
|
||||
from common import dbus_support
|
||||
from common import dataforms
|
||||
from common import pep
|
||||
|
||||
from common.exceptions import GajimGeneralException
|
||||
|
||||
|
@ -69,8 +71,6 @@ class PreferencesWindow:
|
|||
self.window = self.xml.get_widget('preferences_window')
|
||||
self.window.set_transient_for(gajim.interface.roster.window)
|
||||
self.notebook = self.xml.get_widget('preferences_notebook')
|
||||
self.treat_incoming_messages_combobox =\
|
||||
self.xml.get_widget('treat_incoming_messages_combobox')
|
||||
self.one_window_type_combobox =\
|
||||
self.xml.get_widget('one_window_type_combobox')
|
||||
self.iconset_combobox = self.xml.get_widget('iconset_combobox')
|
||||
|
@ -90,8 +90,6 @@ class PreferencesWindow:
|
|||
'auto_xa_time_spinbutton')
|
||||
self.auto_xa_message_entry = self.xml.get_widget('auto_xa_message_entry')
|
||||
|
||||
w = self.xml.get_widget('anc_hbox')
|
||||
|
||||
### General tab ###
|
||||
# Display avatars in roster
|
||||
st = gajim.config.get('show_avatars_in_roster')
|
||||
|
@ -132,14 +130,6 @@ class PreferencesWindow:
|
|||
if not gajim.config.get('emoticons_theme'):
|
||||
emoticons_combobox.set_active(len(l)-1)
|
||||
|
||||
# Set default for treat incoming messages
|
||||
choices = common.config.opt_treat_incoming_messages
|
||||
type = gajim.config.get('treat_incoming_messages')
|
||||
if type in choices:
|
||||
self.treat_incoming_messages_combobox.set_active(choices.index(type))
|
||||
else:
|
||||
self.treat_incoming_messages_combobox.set_active(0)
|
||||
|
||||
# Set default for single window type
|
||||
choices = common.config.opt_one_window_types
|
||||
type = gajim.config.get('one_message_window')
|
||||
|
@ -163,6 +153,7 @@ class PreferencesWindow:
|
|||
else:
|
||||
self.xml.get_widget('speller_checkbutton').set_sensitive(False)
|
||||
|
||||
### Style tab ###
|
||||
# Themes
|
||||
theme_combobox = self.xml.get_widget('theme_combobox')
|
||||
cell = gtk.CellRendererText()
|
||||
|
@ -211,7 +202,37 @@ class PreferencesWindow:
|
|||
st = gajim.config.get('use_transports_iconsets')
|
||||
self.xml.get_widget('transports_iconsets_checkbutton').set_active(st)
|
||||
|
||||
### Privacy tab ###
|
||||
# Color for incoming messages
|
||||
colSt = gajim.config.get('inmsgcolor')
|
||||
self.xml.get_widget('incoming_msg_colorbutton').set_color(
|
||||
gtk.gdk.color_parse(colSt))
|
||||
|
||||
# Color for outgoing messages
|
||||
colSt = gajim.config.get('outmsgcolor')
|
||||
self.xml.get_widget('outgoing_msg_colorbutton').set_color(
|
||||
gtk.gdk.color_parse(colSt))
|
||||
|
||||
# Color for status messages
|
||||
colSt = gajim.config.get('statusmsgcolor')
|
||||
self.xml.get_widget('status_msg_colorbutton').set_color(
|
||||
gtk.gdk.color_parse(colSt))
|
||||
|
||||
# Color for hyperlinks
|
||||
colSt = gajim.config.get('urlmsgcolor')
|
||||
self.xml.get_widget('url_msg_colorbutton').set_color(
|
||||
gtk.gdk.color_parse(colSt))
|
||||
|
||||
# Font for messages
|
||||
font = gajim.config.get('conversation_font')
|
||||
# try to set default font for the current desktop env
|
||||
fontbutton = self.xml.get_widget('conversation_fontbutton')
|
||||
if font == '':
|
||||
fontbutton.set_sensitive(False)
|
||||
self.xml.get_widget('default_chat_font').set_active(True)
|
||||
else:
|
||||
fontbutton.set_font_name(font)
|
||||
|
||||
### Personal Events tab ###
|
||||
# outgoing send chat state notifications
|
||||
st = gajim.config.get('outgoing_chat_state_notifications')
|
||||
combo = self.xml.get_widget('outgoing_chat_states_combobox')
|
||||
|
@ -232,11 +253,29 @@ class PreferencesWindow:
|
|||
else: # disabled
|
||||
combo.set_active(2)
|
||||
|
||||
# Ignore messages from unknown contacts
|
||||
self.xml.get_widget('ignore_events_from_unknown_contacts_checkbutton').\
|
||||
set_active(gajim.config.get('ignore_unknown_contacts'))
|
||||
# PEP
|
||||
st = gajim.config.get('publish_mood')
|
||||
self.xml.get_widget('publish_mood_checkbutton').set_active(st)
|
||||
|
||||
### Events tab ###
|
||||
st = gajim.config.get('publish_activity')
|
||||
self.xml.get_widget('publish_activity_checkbutton').set_active(st)
|
||||
|
||||
st = gajim.config.get('publish_tune')
|
||||
self.xml.get_widget('publish_tune_checkbutton').set_active(st)
|
||||
|
||||
st = gajim.config.get('subscribe_mood')
|
||||
self.xml.get_widget('subscribe_mood_checkbutton').set_active(st)
|
||||
|
||||
st = gajim.config.get('subscribe_activity')
|
||||
self.xml.get_widget('subscribe_activity_checkbutton').set_active(st)
|
||||
|
||||
st = gajim.config.get('subscribe_tune')
|
||||
self.xml.get_widget('subscribe_tune_checkbutton').set_active(st)
|
||||
|
||||
if not gajim.config.get('use_pep'):
|
||||
self.xml.get_widget('frame_pep').set_sensitive(False)
|
||||
|
||||
### Notifications tab ###
|
||||
# On new event
|
||||
on_event_combobox = self.xml.get_widget('on_event_combobox')
|
||||
if gajim.config.get('autopopup'):
|
||||
|
@ -306,6 +345,24 @@ class PreferencesWindow:
|
|||
|
||||
self.fill_sound_treeview()
|
||||
|
||||
# Notify user of new gmail e-mail messages,
|
||||
# make checkbox sensitive 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')
|
||||
|
||||
for account in gajim.config.get_per('accounts'):
|
||||
jid = gajim.get_jid_from_account(account)
|
||||
if gajim.get_server_from_jid(jid) in gajim.gmail_domains:
|
||||
frame_gmail.set_sensitive(True)
|
||||
st = gajim.config.get('notify_on_new_gmail_email')
|
||||
notify_gmail_checkbutton.set_active(st)
|
||||
st = gajim.config.get('notify_on_new_gmail_email_extra')
|
||||
notify_gmail_extra_checkbutton.set_active(st)
|
||||
break
|
||||
|
||||
#### Status tab ###
|
||||
# Autoaway
|
||||
st = gajim.config.get('autoaway')
|
||||
self.auto_away_checkbutton.set_active(st)
|
||||
|
@ -356,7 +413,7 @@ class PreferencesWindow:
|
|||
renderer = gtk.CellRendererText()
|
||||
col.pack_start(renderer, False)
|
||||
col.set_attributes(renderer, text = 1)
|
||||
col = gtk.TreeViewColumn('Message')
|
||||
col = gtk.TreeViewColumn('Default Message')
|
||||
self.default_msg_tree.append_column(col)
|
||||
renderer = gtk.CellRendererText()
|
||||
col.pack_start(renderer, True)
|
||||
|
@ -387,6 +444,7 @@ class PreferencesWindow:
|
|||
buf = self.xml.get_widget('msg_textview').get_buffer()
|
||||
buf.connect('changed', self.on_msg_textview_changed)
|
||||
|
||||
### Advanced tab ###
|
||||
# open links with
|
||||
if os.name == 'nt':
|
||||
applications_frame = self.xml.get_widget('applications_frame')
|
||||
|
@ -417,7 +475,7 @@ class PreferencesWindow:
|
|||
self.applications_combobox.set_active(2)
|
||||
elif gajim.config.get('openwith') == 'exo-open':
|
||||
self.applications_combobox.set_active(3)
|
||||
elif ((sys.platform == 'darwin') and
|
||||
elif ((sys.platform == 'darwin') and\
|
||||
(gajim.config.get('openwith') == 'open')):
|
||||
self.applications_combobox.set_active(1)
|
||||
elif gajim.config.get('openwith') == 'custom':
|
||||
|
@ -438,74 +496,21 @@ class PreferencesWindow:
|
|||
st = gajim.config.get('log_contact_status_changes')
|
||||
self.xml.get_widget('log_show_changes_checkbutton').set_active(st)
|
||||
|
||||
# log encrypted chat sessions
|
||||
st = gajim.config.get('log_encrypted_sessions')
|
||||
self.xml.get_widget('log_encrypted_chats_checkbutton').set_active(st)
|
||||
|
||||
# send os info
|
||||
st = gajim.config.get('send_os_info')
|
||||
self.xml.get_widget('send_os_info_checkbutton').set_active(st)
|
||||
|
||||
# send os info
|
||||
# check if gajm is default
|
||||
st = gajim.config.get('check_if_gajim_is_default')
|
||||
self.xml.get_widget('check_default_client_checkbutton').set_active(st)
|
||||
|
||||
# set status msg from currently playing music track
|
||||
widget = self.xml.get_widget(
|
||||
'set_status_msg_from_current_music_track_checkbutton')
|
||||
if os.name == 'nt':
|
||||
widget.set_no_show_all(True)
|
||||
widget.hide()
|
||||
elif dbus_support.supported:
|
||||
st = gajim.config.get('set_status_msg_from_current_music_track')
|
||||
widget.set_active(st)
|
||||
else:
|
||||
widget.set_sensitive(False)
|
||||
|
||||
# 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')
|
||||
|
||||
for account in gajim.config.get_per('accounts'):
|
||||
jid = gajim.get_jid_from_account(account)
|
||||
if gajim.get_server_from_jid(jid) in gajim.gmail_domains:
|
||||
frame_gmail.show_all()
|
||||
st = gajim.config.get('notify_on_new_gmail_email')
|
||||
notify_gmail_checkbutton.set_active(st)
|
||||
st = gajim.config.get('notify_on_new_gmail_email_extra')
|
||||
notify_gmail_extra_checkbutton.set_active(st)
|
||||
break
|
||||
else:
|
||||
frame_gmail.hide()
|
||||
|
||||
# Color for incoming messages
|
||||
colSt = gajim.config.get('inmsgcolor')
|
||||
self.xml.get_widget('incoming_msg_colorbutton').set_color(
|
||||
gtk.gdk.color_parse(colSt))
|
||||
|
||||
# Color for outgoing messages
|
||||
colSt = gajim.config.get('outmsgcolor')
|
||||
self.xml.get_widget('outgoing_msg_colorbutton').set_color(
|
||||
gtk.gdk.color_parse(colSt))
|
||||
|
||||
# Color for status messages
|
||||
colSt = gajim.config.get('statusmsgcolor')
|
||||
self.xml.get_widget('status_msg_colorbutton').set_color(
|
||||
gtk.gdk.color_parse(colSt))
|
||||
|
||||
# Color for hyperlinks
|
||||
colSt = gajim.config.get('urlmsgcolor')
|
||||
self.xml.get_widget('url_msg_colorbutton').set_color(
|
||||
gtk.gdk.color_parse(colSt))
|
||||
|
||||
# Font for messages
|
||||
font = gajim.config.get('conversation_font')
|
||||
# try to set default font for the current desktop env
|
||||
fontbutton = self.xml.get_widget('conversation_fontbutton')
|
||||
if font == '':
|
||||
fontbutton.set_sensitive(False)
|
||||
self.xml.get_widget('default_chat_font').set_active(True)
|
||||
else:
|
||||
fontbutton.set_font_name(font)
|
||||
# Ignore messages from unknown contacts
|
||||
self.xml.get_widget('ignore_events_from_unknown_contacts_checkbutton').\
|
||||
set_active(gajim.config.get('ignore_unknown_contacts'))
|
||||
|
||||
self.xml.signal_autoconnect(self)
|
||||
|
||||
|
@ -521,6 +526,7 @@ class PreferencesWindow:
|
|||
self.theme_preferences = None
|
||||
|
||||
self.notebook.set_current_page(0)
|
||||
|
||||
self.window.show_all()
|
||||
gtkgui_helpers.possibly_move_window_in_current_desktop(self.window)
|
||||
|
||||
|
@ -536,6 +542,42 @@ class PreferencesWindow:
|
|||
w.set_sensitive(widget.get_active())
|
||||
gajim.interface.save_config()
|
||||
|
||||
def on_publish_mood_checkbutton_toggled(self, widget):
|
||||
if widget.get_active() == False:
|
||||
for account in gajim.connections:
|
||||
if gajim.connections[account].pep_supported:
|
||||
pep.user_send_mood(account, '')
|
||||
self.on_checkbutton_toggled(widget, 'publish_mood')
|
||||
|
||||
def on_publish_activity_checkbutton_toggled(self, widget):
|
||||
if widget.get_active() == False:
|
||||
for account in gajim.connections:
|
||||
if gajim.connections[account].pep_supported:
|
||||
pep.user_send_activity(account, '')
|
||||
self.on_checkbutton_toggled(widget, 'publish_activity')
|
||||
|
||||
def on_publish_tune_checkbutton_toggled(self, widget):
|
||||
if widget.get_active() == False:
|
||||
for account in gajim.connections:
|
||||
if gajim.connections[account].pep_supported:
|
||||
pep.user_send_tune(account, '')
|
||||
self.on_checkbutton_toggled(widget, 'publish_tune')
|
||||
gajim.interface.roster.enable_syncing_status_msg_from_current_music_track(
|
||||
widget.get_active())
|
||||
|
||||
def on_subscribe_mood_checkbutton_toggled(self, widget):
|
||||
self.on_checkbutton_toggled(widget, 'subscribe_mood')
|
||||
|
||||
def on_subscribe_activity_checkbutton_toggled(self, widget):
|
||||
self.on_checkbutton_toggled(widget, 'subscribe_activity')
|
||||
|
||||
def on_subscribe_tune_checkbutton_toggled(self, widget):
|
||||
self.on_checkbutton_toggled(widget, 'subscribe_tune')
|
||||
|
||||
def on_sort_by_show_checkbutton_toggled(self, widget):
|
||||
self.on_checkbutton_toggled(widget, 'sort_by_show')
|
||||
gajim.interface.roster.draw_roster()
|
||||
|
||||
def on_show_avatars_in_roster_checkbutton_toggled(self, widget):
|
||||
self.on_checkbutton_toggled(widget, 'show_avatars_in_roster')
|
||||
gajim.interface.roster.draw_roster()
|
||||
|
@ -576,11 +618,6 @@ class PreferencesWindow:
|
|||
for win in gajim.interface.msg_win_mgr.windows():
|
||||
win.toggle_emoticons()
|
||||
|
||||
def on_treat_incoming_messages_combobox_changed(self, widget):
|
||||
active = widget.get_active()
|
||||
config_type = common.config.opt_treat_incoming_messages[active]
|
||||
gajim.config.set('treat_incoming_messages', config_type)
|
||||
|
||||
def on_one_window_type_combo_changed(self, widget):
|
||||
active = widget.get_active()
|
||||
config_type = common.config.opt_one_window_types[active]
|
||||
|
@ -955,6 +992,9 @@ class PreferencesWindow:
|
|||
def on_log_show_changes_checkbutton_toggled(self, widget):
|
||||
self.on_checkbutton_toggled(widget, 'log_contact_status_changes')
|
||||
|
||||
def on_log_encrypted_chats_checkbutton_toggled(self, widget):
|
||||
self.on_checkbutton_toggled(widget, 'log_encrypted_sessions')
|
||||
|
||||
def on_send_os_info_checkbutton_toggled(self, widget):
|
||||
self.on_checkbutton_toggled(widget, 'send_os_info')
|
||||
|
||||
|
@ -1030,26 +1070,23 @@ class PreferencesWindow:
|
|||
def fill_sound_treeview(self):
|
||||
model = self.sound_tree.get_model()
|
||||
model.clear()
|
||||
model.set_sort_column_id(1, gtk.SORT_ASCENDING)
|
||||
|
||||
# NOTE: sounds_ui_names MUST have all items of
|
||||
# sounds = gajim.config.get_per('soundevents') as keys
|
||||
sounds_dict = {
|
||||
'first_message_received': _('First Message Received'),
|
||||
'next_message_received': _('Next Message Received'),
|
||||
'next_message_received_focused': _('Next Message Received Focused'),
|
||||
'next_message_received_unfocused':
|
||||
_('Next Message Received Unfocused'),
|
||||
'contact_connected': _('Contact Connected'),
|
||||
'contact_disconnected': _('Contact Disconnected'),
|
||||
'message_sent': _('Message Sent'),
|
||||
'muc_message_highlight': _('Group Chat Message Highlight'),
|
||||
'muc_message_received': _('Group Chat Message Received')
|
||||
'muc_message_received': _('Group Chat Message Received'),
|
||||
'gmail_received': _('GMail Email Received')
|
||||
}
|
||||
|
||||
# In case of a GMail account we provide a sound notification option
|
||||
for account in gajim.config.get_per('accounts'):
|
||||
jid = gajim.get_jid_from_account(account)
|
||||
if gajim.get_server_from_jid(jid) in gajim.gmail_domains:
|
||||
sounds_dict['gmail_received'] = _('GMail Email Received')
|
||||
break
|
||||
|
||||
for sound_event_config_name, sound_ui_name in sounds_dict.items():
|
||||
enabled = gajim.config.get_per('soundevents',
|
||||
sound_event_config_name, 'enabled')
|
||||
|
@ -1290,6 +1327,7 @@ class AccountsWindow:
|
|||
del gajim.interface.instances['accounts']
|
||||
|
||||
def on_close_button_clicked(self, widget):
|
||||
self.check_resend_relog()
|
||||
self.window.destroy()
|
||||
|
||||
def __init__(self):
|
||||
|
@ -1299,8 +1337,6 @@ class AccountsWindow:
|
|||
self.accounts_treeview = self.xml.get_widget('accounts_treeview')
|
||||
self.remove_button = self.xml.get_widget('remove_button')
|
||||
self.rename_button = self.xml.get_widget('rename_button')
|
||||
#FIXME: I don't understand why this import is necessary
|
||||
import os
|
||||
path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
|
||||
'kbd_input.png')
|
||||
img = self.xml.get_widget('rename_image')
|
||||
|
@ -1327,7 +1363,10 @@ class AccountsWindow:
|
|||
|
||||
# Merge accounts
|
||||
st = gajim.config.get('mergeaccounts')
|
||||
self.xml.get_widget('merge_checkbutton').set_active(st)
|
||||
checkbutton = self.xml.get_widget('merge_checkbutton')
|
||||
checkbutton.set_active(st)
|
||||
# prevent roster redraws by connecting the signal after button state is set
|
||||
checkbutton.connect('toggled', self.on_merge_checkbutton_toggled)
|
||||
|
||||
self.avahi_available = True
|
||||
try:
|
||||
|
@ -1337,6 +1376,7 @@ class AccountsWindow:
|
|||
|
||||
def on_accounts_window_key_press_event(self, widget, event):
|
||||
if event.keyval == gtk.keysyms.Escape:
|
||||
self.check_resend_relog()
|
||||
self.window.destroy()
|
||||
|
||||
def select_account(self, account):
|
||||
|
@ -1354,7 +1394,6 @@ class AccountsWindow:
|
|||
self.remove_button.set_sensitive(False)
|
||||
self.rename_button.set_sensitive(False)
|
||||
self.current_account = None
|
||||
self.init_account()
|
||||
model = self.accounts_treeview.get_model()
|
||||
model.clear()
|
||||
for account in gajim.config.get_per('accounts'):
|
||||
|
@ -1366,37 +1405,7 @@ class AccountsWindow:
|
|||
status = gajim.connections[self.current_account].status
|
||||
gajim.connections[self.current_account].change_status(show, status)
|
||||
|
||||
def on_accounts_treeview_cursor_changed(self, widget):
|
||||
'''Activate modify buttons when a row is selected, update accounts info'''
|
||||
sel = self.accounts_treeview.get_selection()
|
||||
(model, iter) = sel.get_selected()
|
||||
if iter:
|
||||
account = model[iter][0].decode('utf-8')
|
||||
else:
|
||||
account = None
|
||||
if self.current_account and self.current_account == account:
|
||||
# We're comming back to our current account, no need to update widgets
|
||||
return
|
||||
# Save config for previous account if needed cause focus_out event is
|
||||
# called after the changed event
|
||||
if self.current_account:
|
||||
focused_widget = self.window.get_focus()
|
||||
focused_widget_name = focused_widget.get_name()
|
||||
if focused_widget_name in ('jid_entry1', 'resource_entry1',
|
||||
'custom_port_entry'):
|
||||
if focused_widget_name == 'jid_entry1':
|
||||
func = self.on_jid_entry1_focus_out_event
|
||||
elif focused_widget_name == 'resource_entry1':
|
||||
func = self.on_resource_entry1_focus_out_event
|
||||
elif focused_widget_name == 'custom_port_entry':
|
||||
func = self.on_custom_port_entry_focus_out_event
|
||||
if func(focused_widget, None):
|
||||
# Error detected in entry, don't change account, re-put cursor on
|
||||
# previous row
|
||||
self.select_account(self.current_account)
|
||||
return True
|
||||
self.window.set_focus(widget)
|
||||
|
||||
def check_resend_relog(self):
|
||||
if self.need_relogin and self.current_account == gajim.ZEROCONF_ACC_NAME:
|
||||
if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
|
||||
gajim.connections[gajim.ZEROCONF_ACC_NAME].update_details()
|
||||
|
@ -1435,6 +1444,40 @@ class AccountsWindow:
|
|||
|
||||
self.need_relogin = False
|
||||
self.resend_presence = False
|
||||
|
||||
def on_accounts_treeview_cursor_changed(self, widget):
|
||||
'''Activate modify buttons when a row is selected, update accounts info'''
|
||||
sel = self.accounts_treeview.get_selection()
|
||||
(model, iter) = sel.get_selected()
|
||||
if iter:
|
||||
account = model[iter][0].decode('utf-8')
|
||||
else:
|
||||
account = None
|
||||
if self.current_account and self.current_account == account:
|
||||
# We're comming back to our current account, no need to update widgets
|
||||
return
|
||||
# Save config for previous account if needed cause focus_out event is
|
||||
# called after the changed event
|
||||
if self.current_account:
|
||||
focused_widget = self.window.get_focus()
|
||||
focused_widget_name = focused_widget.get_name()
|
||||
if focused_widget_name in ('jid_entry1', 'resource_entry1',
|
||||
'custom_port_entry'):
|
||||
if focused_widget_name == 'jid_entry1':
|
||||
func = self.on_jid_entry1_focus_out_event
|
||||
elif focused_widget_name == 'resource_entry1':
|
||||
func = self.on_resource_entry1_focus_out_event
|
||||
elif focused_widget_name == 'custom_port_entry':
|
||||
func = self.on_custom_port_entry_focus_out_event
|
||||
if func(focused_widget, None):
|
||||
# Error detected in entry, don't change account, re-put cursor on
|
||||
# previous row
|
||||
self.select_account(self.current_account)
|
||||
return True
|
||||
self.window.set_focus(widget)
|
||||
|
||||
self.check_resend_relog()
|
||||
|
||||
self.remove_button.set_sensitive(True)
|
||||
self.rename_button.set_sensitive(True)
|
||||
if iter:
|
||||
|
@ -1585,8 +1628,16 @@ class AccountsWindow:
|
|||
'priority'))
|
||||
|
||||
# Connection tab
|
||||
usessl = gajim.config.get_per('accounts', account, 'usessl')
|
||||
self.xml.get_widget('use_ssl_checkbutton1').set_active(usessl)
|
||||
use_env_http_proxy = gajim.config.get_per('accounts', account,
|
||||
'use_env_http_proxy')
|
||||
self.xml.get_widget('use_env_http_proxy_checkbutton1').set_active(
|
||||
use_env_http_proxy)
|
||||
self.xml.get_widget('proxy_hbox1').set_sensitive(not use_env_http_proxy)
|
||||
|
||||
warn_when_insecure = gajim.config.get_per('accounts', account,
|
||||
'warn_when_insecure_connection')
|
||||
self.xml.get_widget('warn_when_insecure_connection_checkbutton1').\
|
||||
set_active(warn_when_insecure)
|
||||
|
||||
self.xml.get_widget('send_keepalive_checkbutton1').set_active(
|
||||
gajim.config.get_per('accounts', account, 'keep_alives_enabled'))
|
||||
|
@ -1899,7 +1950,8 @@ class AccountsWindow:
|
|||
'no_log_for').split()
|
||||
if self.current_account in list_no_log_for:
|
||||
list_no_log_for.remove(self.current_account)
|
||||
if not self.xml.get_widget('log_history_checkbutton').get_active():
|
||||
|
||||
if not widget.get_active():
|
||||
list_no_log_for.append(self.current_account)
|
||||
gajim.config.set_per('accounts', self.current_account, 'no_log_for',
|
||||
' '.join(list_no_log_for))
|
||||
|
@ -1917,6 +1969,14 @@ class AccountsWindow:
|
|||
self.on_checkbutton_toggled(widget, 'use_ft_proxies',
|
||||
account=self.current_account)
|
||||
|
||||
def on_use_env_http_proxy_checkbutton1_toggled(self, widget):
|
||||
if self.ignore_events:
|
||||
return
|
||||
self.on_checkbutton_toggled(widget, 'use_env_http_proxy',
|
||||
account=self.current_account)
|
||||
hbox = self.xml.get_widget('proxy_hbox1')
|
||||
hbox.set_sensitive(not widget.get_active())
|
||||
|
||||
def on_proxies_combobox1_changed(self, widget):
|
||||
active = widget.get_active()
|
||||
proxy = widget.get_model()[active][0].decode('utf-8')
|
||||
|
@ -1934,20 +1994,11 @@ class AccountsWindow:
|
|||
else:
|
||||
gajim.interface.instances['manage_proxies'] = ManageProxiesWindow()
|
||||
|
||||
def on_use_ssl_checkbutton1_toggled(self, widget):
|
||||
def on_warn_when_insecure_connection_checkbutton1_toggled(self, widget):
|
||||
if self.ignore_events:
|
||||
return
|
||||
|
||||
if self.option_changed('usessl', widget.get_active()):
|
||||
self.need_relogin = True
|
||||
|
||||
isactive = widget.get_active()
|
||||
if isactive:
|
||||
self.xml.get_widget('custom_port_entry1').set_text('5223')
|
||||
else:
|
||||
self.xml.get_widget('custom_port_entry1').set_text('5222')
|
||||
|
||||
self.on_checkbutton_toggled(widget, 'usessl',
|
||||
self.on_checkbutton_toggled(widget, 'warn_when_insecure_connection',
|
||||
account=self.current_account)
|
||||
|
||||
def on_send_keepalive_checkbutton1_toggled(self, widget):
|
||||
|
@ -1992,14 +2043,14 @@ class AccountsWindow:
|
|||
custom_port)
|
||||
|
||||
def on_gpg_choose_button_clicked(self, widget, data = None):
|
||||
if gajim.connections.has_key(self.current_account):
|
||||
if gajim.connections.has_key(self.current_account) and \
|
||||
gajim.connections[self.current_account].gpg:
|
||||
secret_keys = gajim.connections[self.current_account].\
|
||||
ask_gpg_secrete_keys()
|
||||
|
||||
# self.current_account is None and/or gajim.connections is {}
|
||||
else:
|
||||
from common import GnuPG
|
||||
if GnuPG.USE_GPG:
|
||||
if gajim.HAVE_GPG:
|
||||
secret_keys = GnuPG.GnuPG().get_secret_keys()
|
||||
else:
|
||||
secret_keys = []
|
||||
|
@ -3030,7 +3081,7 @@ class AccountCreationWizardWindow:
|
|||
elif cur_page == 1:
|
||||
# We are adding an existing account
|
||||
username = self.xml.get_widget('username_entry').get_text().decode(
|
||||
'utf-8')
|
||||
'utf-8').strip()
|
||||
if not username:
|
||||
pritext = _('Invalid username')
|
||||
sectext = _(
|
||||
|
@ -3038,7 +3089,7 @@ class AccountCreationWizardWindow:
|
|||
dialogs.ErrorDialog(pritext, sectext)
|
||||
return
|
||||
server = self.xml.get_widget('server_comboboxentry').child.get_text().\
|
||||
decode('utf-8')
|
||||
decode('utf-8').strip()
|
||||
savepass = self.xml.get_widget('save_password_checkbutton').\
|
||||
get_active()
|
||||
password = self.xml.get_widget('password_entry').get_text().decode(
|
||||
|
@ -3142,6 +3193,16 @@ class AccountCreationWizardWindow:
|
|||
if checked:
|
||||
hostname = gajim.connections[self.account].new_account_info[
|
||||
'hostname']
|
||||
# Check if cert is already in file
|
||||
certs = ''
|
||||
if os.path.isfile(gajim.MY_CACERTS):
|
||||
f = open(gajim.MY_CACERTS)
|
||||
certs = f.read()
|
||||
f.close()
|
||||
if self.ssl_cert in certs:
|
||||
dialogs.ErrorDialog(_('Certificate Already in File'),
|
||||
_('This certificate is already in file %s, so it\'s not added again.') % gajim.MY_CACERTS)
|
||||
else:
|
||||
f = open(gajim.MY_CACERTS, 'a')
|
||||
f.write(hostname + '\n')
|
||||
f.write(self.ssl_cert + '\n\n')
|
||||
|
@ -3188,7 +3249,7 @@ class AccountCreationWizardWindow:
|
|||
self.progressbar.pulse()
|
||||
return True # loop forever
|
||||
|
||||
def new_acc_connected(self, form, is_form, ssl_msg, ssl_cert,
|
||||
def new_acc_connected(self, form, is_form, ssl_msg, ssl_err, ssl_cert,
|
||||
ssl_fingerprint):
|
||||
'''connection to server succeded, present the form to the user.'''
|
||||
if self.update_progressbar_timeout_id is not None:
|
||||
|
@ -3213,8 +3274,12 @@ class AccountCreationWizardWindow:
|
|||
'SSL Error: %s\n'
|
||||
'Do you still want to connect to this server?') % (hostname,
|
||||
ssl_msg))
|
||||
if ssl_err in (18, 27):
|
||||
text = _('Add this certificate to the list of trusted certificates.\nSHA1 fingerprint of the certificate:\n%s') % ssl_fingerprint
|
||||
self.xml.get_widget('ssl_checkbutton').set_label(text)
|
||||
else:
|
||||
self.xml.get_widget('ssl_checkbutton').set_no_show_all(True)
|
||||
self.xml.get_widget('ssl_checkbutton').hide()
|
||||
self.notebook.set_current_page(3) # show SSL page
|
||||
else:
|
||||
self.notebook.set_current_page(4) # show form page
|
||||
|
@ -3406,3 +3471,277 @@ class AccountCreationWizardWindow:
|
|||
gajim.interface.roster.draw_roster()
|
||||
gajim.interface.roster.set_actions_menu_needs_rebuild()
|
||||
gajim.interface.save_config()
|
||||
|
||||
#---------- ZeroconfPropertiesWindow class -------------#
|
||||
class ZeroconfPropertiesWindow:
|
||||
def __init__(self):
|
||||
self.xml = gtkgui_helpers.get_glade('zeroconf_properties_window.glade')
|
||||
self.window = self.xml.get_widget('zeroconf_properties_window')
|
||||
self.window.set_transient_for(gajim.interface.roster.window)
|
||||
self.xml.signal_autoconnect(self)
|
||||
|
||||
self.init_account()
|
||||
self.init_account_gpg()
|
||||
|
||||
self.xml.get_widget('save_button').grab_focus()
|
||||
self.window.show_all()
|
||||
|
||||
def init_account(self):
|
||||
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'autoconnect')
|
||||
if st:
|
||||
self.xml.get_widget('autoconnect_checkbutton').set_active(st)
|
||||
|
||||
list_no_log_for = gajim.config.get_per('accounts',
|
||||
gajim.ZEROCONF_ACC_NAME,'no_log_for').split()
|
||||
if gajim.ZEROCONF_ACC_NAME in list_no_log_for:
|
||||
self.xml.get_widget('log_history_checkbutton').set_active(0)
|
||||
else:
|
||||
self.xml.get_widget('log_history_checkbutton').set_active(1)
|
||||
|
||||
|
||||
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'sync_with_global_status')
|
||||
if st:
|
||||
self.xml.get_widget('sync_with_global_status_checkbutton').set_active(
|
||||
st)
|
||||
|
||||
for opt in ('first_name', 'last_name', 'jabber_id', 'email'):
|
||||
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'zeroconf_' + opt)
|
||||
if st:
|
||||
self.xml.get_widget(opt + '_entry').set_text(st)
|
||||
|
||||
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'custom_port')
|
||||
if st:
|
||||
self.xml.get_widget('custom_port_entry').set_text(str(st))
|
||||
|
||||
st = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'use_custom_host')
|
||||
if st:
|
||||
self.xml.get_widget('custom_port_checkbutton').set_active(st)
|
||||
|
||||
self.xml.get_widget('custom_port_entry').set_sensitive(bool(st))
|
||||
|
||||
if not st:
|
||||
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'custom_port', '5298')
|
||||
|
||||
def init_account_gpg(self):
|
||||
keyid = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, 'keyid')
|
||||
keyname = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'keyname')
|
||||
savegpgpass = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'savegpgpass')
|
||||
|
||||
if not keyid or not gajim.config.get('usegpg'):
|
||||
return
|
||||
|
||||
self.xml.get_widget('gpg_key_label').set_text(keyid)
|
||||
self.xml.get_widget('gpg_name_label').set_text(keyname)
|
||||
gpg_save_password_checkbutton = \
|
||||
self.xml.get_widget('gpg_save_password_checkbutton')
|
||||
gpg_save_password_checkbutton.set_sensitive(True)
|
||||
gpg_save_password_checkbutton.set_active(savegpgpass)
|
||||
|
||||
if savegpgpass:
|
||||
entry = self.xml.get_widget('gpg_password_entry')
|
||||
entry.set_sensitive(True)
|
||||
gpgpassword = gajim.config.get_per('accounts',
|
||||
gajim.ZEROCONF_ACC_NAME, 'gpgpassword')
|
||||
entry.set_text(gpgpassword)
|
||||
|
||||
def on_zeroconf_properties_window_destroy(self, widget):
|
||||
# close window
|
||||
if gajim.interface.instances.has_key('zeroconf_properties'):
|
||||
del gajim.interface.instances['zeroconf_properties']
|
||||
|
||||
def on_custom_port_checkbutton_toggled(self, widget):
|
||||
st = self.xml.get_widget('custom_port_checkbutton').get_active()
|
||||
self.xml.get_widget('custom_port_entry').set_sensitive(bool(st))
|
||||
|
||||
def on_cancel_button_clicked(self, widget):
|
||||
self.window.destroy()
|
||||
|
||||
def on_save_button_clicked(self, widget):
|
||||
config = {}
|
||||
|
||||
st = self.xml.get_widget('autoconnect_checkbutton').get_active()
|
||||
config['autoconnect'] = st
|
||||
list_no_log_for = gajim.config.get_per('accounts',
|
||||
gajim.ZEROCONF_ACC_NAME, 'no_log_for').split()
|
||||
if gajim.ZEROCONF_ACC_NAME in list_no_log_for:
|
||||
list_no_log_for.remove(gajim.ZEROCONF_ACC_NAME)
|
||||
if not self.xml.get_widget('log_history_checkbutton').get_active():
|
||||
list_no_log_for.append(gajim.ZEROCONF_ACC_NAME)
|
||||
config['no_log_for'] = ' '.join(list_no_log_for)
|
||||
|
||||
st = self.xml.get_widget('sync_with_global_status_checkbutton').\
|
||||
get_active()
|
||||
config['sync_with_global_status'] = st
|
||||
|
||||
st = self.xml.get_widget('first_name_entry').get_text()
|
||||
config['zeroconf_first_name'] = st.decode('utf-8')
|
||||
|
||||
st = self.xml.get_widget('last_name_entry').get_text()
|
||||
config['zeroconf_last_name'] = st.decode('utf-8')
|
||||
|
||||
st = self.xml.get_widget('jabber_id_entry').get_text()
|
||||
config['zeroconf_jabber_id'] = st.decode('utf-8')
|
||||
|
||||
st = self.xml.get_widget('email_entry').get_text()
|
||||
config['zeroconf_email'] = st.decode('utf-8')
|
||||
|
||||
use_custom_port = self.xml.get_widget('custom_port_checkbutton').\
|
||||
get_active()
|
||||
config['use_custom_host'] = use_custom_port
|
||||
|
||||
old_port = gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME,
|
||||
'custom_port')
|
||||
if use_custom_port:
|
||||
port = self.xml.get_widget('custom_port_entry').get_text()
|
||||
else:
|
||||
port = 5298
|
||||
|
||||
config['custom_port'] = port
|
||||
|
||||
config['keyname'] = self.xml.get_widget('gpg_name_label').get_text().\
|
||||
decode('utf-8')
|
||||
if config['keyname'] == '': # no key selected
|
||||
config['keyid'] = ''
|
||||
config['savegpgpass'] = False
|
||||
config['gpgpassword'] = ''
|
||||
else:
|
||||
config['keyid'] = self.xml.get_widget('gpg_key_label').get_text().\
|
||||
decode('utf-8')
|
||||
config['savegpgpass'] = self.xml.get_widget(
|
||||
'gpg_save_password_checkbutton').get_active()
|
||||
config['gpgpassword'] = self.xml.get_widget('gpg_password_entry'
|
||||
).get_text().decode('utf-8')
|
||||
|
||||
reconnect = False
|
||||
for opt in ('zeroconf_first_name','zeroconf_last_name',
|
||||
'zeroconf_jabber_id', 'zeroconf_email', 'custom_port'):
|
||||
if gajim.config.get_per('accounts', gajim.ZEROCONF_ACC_NAME, opt) != \
|
||||
config[opt]:
|
||||
reconnect = True
|
||||
|
||||
for opt in config:
|
||||
gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, opt,
|
||||
config[opt])
|
||||
|
||||
if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
|
||||
if port != old_port or reconnect:
|
||||
gajim.connections[gajim.ZEROCONF_ACC_NAME].update_details()
|
||||
|
||||
self.window.destroy()
|
||||
|
||||
def on_gpg_choose_button_clicked(self, widget, data = None):
|
||||
if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
|
||||
secret_keys = gajim.connections[gajim.ZEROCONF_ACC_NAME].\
|
||||
ask_gpg_secrete_keys()
|
||||
|
||||
# self.account is None and/or gajim.connections is {}
|
||||
else:
|
||||
if gajim.HAVE_GPG:
|
||||
secret_keys = GnuPG.GnuPG().get_secret_keys()
|
||||
else:
|
||||
secret_keys = []
|
||||
if not secret_keys:
|
||||
dialogs.ErrorDialog(_('Failed to get secret keys'),
|
||||
_('There was a problem retrieving your OpenPGP secret keys.'))
|
||||
return
|
||||
secret_keys[_('None')] = _('None')
|
||||
instance = dialogs.ChooseGPGKeyDialog(_('OpenPGP Key Selection'),
|
||||
_('Choose your OpenPGP key'), secret_keys)
|
||||
keyID = instance.run()
|
||||
if keyID is None:
|
||||
return
|
||||
checkbutton = self.xml.get_widget('gpg_save_password_checkbutton')
|
||||
gpg_key_label = self.xml.get_widget('gpg_key_label')
|
||||
gpg_name_label = self.xml.get_widget('gpg_name_label')
|
||||
if keyID[0] == _('None'):
|
||||
gpg_key_label.set_text(_('No key selected'))
|
||||
gpg_name_label.set_text('')
|
||||
checkbutton.set_sensitive(False)
|
||||
self.xml.get_widget('gpg_password_entry').set_sensitive(False)
|
||||
else:
|
||||
gpg_key_label.set_text(keyID[0])
|
||||
gpg_name_label.set_text(keyID[1])
|
||||
checkbutton.set_sensitive(True)
|
||||
checkbutton.set_active(False)
|
||||
self.xml.get_widget('gpg_password_entry').set_text('')
|
||||
|
||||
def on_gpg_save_password_checkbutton_toggled(self, widget):
|
||||
st = widget.get_active()
|
||||
w = self.xml.get_widget('gpg_password_entry')
|
||||
w.set_sensitive(bool(st))
|
||||
|
||||
class ManagePEPServicesWindow:
|
||||
def __init__(self, account):
|
||||
self.xml = gtkgui_helpers.get_glade('manage_pep_services_window.glade')
|
||||
self.window = self.xml.get_widget('manage_pep_services_window')
|
||||
self.window.set_transient_for(gajim.interface.roster.window)
|
||||
self.xml.signal_autoconnect(self)
|
||||
self.account = account
|
||||
|
||||
self.init_services()
|
||||
self.window.show_all()
|
||||
|
||||
def on_manage_pep_services_window_destroy(self, widget):
|
||||
'''close window'''
|
||||
del gajim.interface.instances[self.account]['pep_services']
|
||||
|
||||
def on_ok_button_clicked(self, widget):
|
||||
pass
|
||||
|
||||
def on_cancel_button_clicked(self, widget):
|
||||
self.window.destroy()
|
||||
|
||||
def cellrenderer_combo_edited(self, cellrenderer, path, new_text):
|
||||
self.treestore[path][1] = new_text
|
||||
|
||||
def init_services(self):
|
||||
treeview = self.xml.get_widget('services_treeview')
|
||||
# service, access_model, group
|
||||
self.treestore = gtk.ListStore(str, str, str)
|
||||
treeview.set_model(self.treestore)
|
||||
|
||||
col = gtk.TreeViewColumn('Service')
|
||||
treeview.append_column(col)
|
||||
|
||||
cellrenderer_text = gtk.CellRendererText()
|
||||
col.pack_start(cellrenderer_text)
|
||||
col.add_attribute(cellrenderer_text, 'text', 0)
|
||||
|
||||
col = gtk.TreeViewColumn('access model')
|
||||
treeview.append_column(col)
|
||||
|
||||
model = gtk.ListStore(str)
|
||||
model.append(['open'])
|
||||
model.append(['presence'])
|
||||
model.append(['roster'])
|
||||
model.append(['whitelist'])
|
||||
cellrenderer_combo = gtk.CellRendererCombo()
|
||||
cellrenderer_combo.set_property('text-column', 0)
|
||||
cellrenderer_combo.set_property('model', model)
|
||||
cellrenderer_combo.set_property('has-entry', False)
|
||||
cellrenderer_combo.set_property('editable', True)
|
||||
cellrenderer_combo.connect('edited', self.cellrenderer_combo_edited)
|
||||
col.pack_start(cellrenderer_combo)
|
||||
col.add_attribute(cellrenderer_combo, 'text', 1)
|
||||
|
||||
our_jid = gajim.get_jid_from_account(self.account)
|
||||
gajim.connections[self.account].discoverItems(our_jid)
|
||||
|
||||
def items_received(self, items):
|
||||
our_jid = gajim.get_jid_from_account(self.account)
|
||||
for item in items:
|
||||
if 'jid' in item and item['jid'] == our_jid and 'node' in item:
|
||||
# ask <configure> to have access model
|
||||
gajim.connections[self.account].request_pb_configuration(
|
||||
item['jid'], item['node'])
|
||||
|
||||
def new_service(self, node, model):
|
||||
self.treestore.append([node, model, ''])
|
||||
|
|
|
@ -61,8 +61,8 @@ class TextViewImage(gtk.Image):
|
|||
self.anchor = anchor
|
||||
self._selected = False
|
||||
self._disconnect_funcs = []
|
||||
self.connect("parent-set", self.on_parent_set)
|
||||
self.connect("expose-event", self.on_expose)
|
||||
self.connect('parent-set', self.on_parent_set)
|
||||
self.connect('expose-event', self.on_expose)
|
||||
|
||||
def _get_selected(self):
|
||||
parent = self.get_parent()
|
||||
|
@ -110,13 +110,13 @@ class TextViewImage(gtk.Image):
|
|||
self._disconnect_signals()
|
||||
return
|
||||
|
||||
self._do_connect(parent, "style-set", self.do_queue_draw)
|
||||
self._do_connect(parent, "focus-in-event", self.do_queue_draw)
|
||||
self._do_connect(parent, "focus-out-event", self.do_queue_draw)
|
||||
self._do_connect(parent, 'style-set', self.do_queue_draw)
|
||||
self._do_connect(parent, 'focus-in-event', self.do_queue_draw)
|
||||
self._do_connect(parent, 'focus-out-event', self.do_queue_draw)
|
||||
|
||||
textbuf = parent.get_buffer()
|
||||
self._do_connect(textbuf, "mark-set", self.on_mark_set)
|
||||
self._do_connect(textbuf, "mark-deleted", self.on_mark_deleted)
|
||||
self._do_connect(textbuf, 'mark-set', self.on_mark_set)
|
||||
self._do_connect(textbuf, 'mark-deleted', self.on_mark_deleted)
|
||||
|
||||
def do_queue_draw(self, *args):
|
||||
self.queue_draw()
|
||||
|
@ -186,7 +186,7 @@ class ConversationTextview:
|
|||
self.on_textview_button_press_event)
|
||||
self.handlers[id] = self.tv
|
||||
|
||||
id = self.tv.connect("expose-event",
|
||||
id = self.tv.connect('expose-event',
|
||||
self.on_textview_expose_event)
|
||||
self.handlers[id] = self.tv
|
||||
|
||||
|
@ -213,10 +213,9 @@ class ConversationTextview:
|
|||
|
||||
colors = gajim.config.get('gc_nicknames_colors')
|
||||
colors = colors.split(':')
|
||||
for color in xrange(len(colors)):
|
||||
tagname = 'gc_nickname_color_' + str(color)
|
||||
for i,color in enumerate(colors):
|
||||
tagname = 'gc_nickname_color_' + str(i)
|
||||
tag = buffer.create_tag(tagname)
|
||||
color = colors[color]
|
||||
tag.set_property('foreground', color)
|
||||
|
||||
tag = buffer.create_tag('marked')
|
||||
|
@ -353,9 +352,8 @@ class ConversationTextview:
|
|||
adjustment.set_value(0)
|
||||
return False # when called in an idle_add, just do it once
|
||||
|
||||
def bring_scroll_to_end(self, diff_y = 0,\
|
||||
use_smooth =\
|
||||
gajim.config.get('use_smooth_scrolling')):
|
||||
def bring_scroll_to_end(self, diff_y = 0,
|
||||
use_smooth=gajim.config.get('use_smooth_scrolling')):
|
||||
''' scrolls to the end of textview if end is not visible '''
|
||||
buffer = self.tv.get_buffer()
|
||||
end_iter = buffer.get_end_iter()
|
||||
|
@ -423,7 +421,8 @@ class ConversationTextview:
|
|||
|
||||
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)
|
||||
# one char back (an image also takes one char)
|
||||
before_img_iter.backward_char()
|
||||
buffer.apply_tag_by_name('focus-out-line', before_img_iter, end_iter)
|
||||
|
||||
self.allow_focus_out_line = False
|
||||
|
@ -452,7 +451,8 @@ class ConversationTextview:
|
|||
# check if the current pointer is still over the line
|
||||
position = self.tv.window.get_origin()
|
||||
self.line_tooltip.show_tooltip(_('Text below this line is what has '
|
||||
'been said since the last time you paid attention to this group chat'), 8, position[1] + pointer[1])
|
||||
'been said since the last time you paid attention to this group chat'),
|
||||
8, position[1] + pointer[1])
|
||||
|
||||
def on_textview_expose_event(self, widget, event):
|
||||
expalloc = event.area
|
||||
|
@ -582,7 +582,8 @@ class ConversationTextview:
|
|||
else:
|
||||
if dict_link.find('%s') == -1:
|
||||
# we must have %s in the url if not WIKTIONARY
|
||||
item = gtk.MenuItem(_('Dictionary URL is missing an "%s" and it is not WIKTIONARY'))
|
||||
item = gtk.MenuItem(_(
|
||||
'Dictionary URL is missing an "%s" and it is not WIKTIONARY'))
|
||||
item.set_property('sensitive', False)
|
||||
else:
|
||||
link = dict_link % self.selected_phrase
|
||||
|
@ -639,7 +640,8 @@ class ConversationTextview:
|
|||
if return_val: # if sth was selected when we right-clicked
|
||||
# get the selected text
|
||||
start_sel, finish_sel = return_val[0], return_val[1]
|
||||
self.selected_phrase = buffer.get_text(start_sel, finish_sel).decode('utf-8')
|
||||
self.selected_phrase = buffer.get_text(start_sel, finish_sel).decode(
|
||||
'utf-8')
|
||||
|
||||
def on_open_link_activate(self, widget, kind, text):
|
||||
helpers.launch_browser_mailer(kind, text)
|
||||
|
@ -673,7 +675,8 @@ class ConversationTextview:
|
|||
if kind == 'url':
|
||||
id = childs[0].connect('activate', self.on_copy_link_activate, text)
|
||||
self.handlers[id] = childs[0]
|
||||
id = childs[1].connect('activate', self.on_open_link_activate, kind, text)
|
||||
id = childs[1].connect('activate', self.on_open_link_activate, kind,
|
||||
text)
|
||||
self.handlers[id] = childs[1]
|
||||
childs[2].hide() # copy mail address
|
||||
childs[3].hide() # open mail composer
|
||||
|
@ -691,7 +694,8 @@ class ConversationTextview:
|
|||
text = text.lower()
|
||||
id = childs[2].connect('activate', self.on_copy_link_activate, text)
|
||||
self.handlers[id] = childs[2]
|
||||
id = childs[3].connect('activate', self.on_open_link_activate, kind, text)
|
||||
id = childs[3].connect('activate', self.on_open_link_activate, kind,
|
||||
text)
|
||||
self.handlers[id] = childs[3]
|
||||
id = childs[5].connect('activate', self.on_start_chat_activate, text)
|
||||
self.handlers[id] = childs[5]
|
||||
|
@ -708,7 +712,8 @@ class ConversationTextview:
|
|||
allow_add = True
|
||||
|
||||
if allow_add:
|
||||
id = childs[7].connect('activate', self.on_add_to_roster_activate, text)
|
||||
id = childs[7].connect('activate', self.on_add_to_roster_activate,
|
||||
text)
|
||||
self.handlers[id] = childs[7]
|
||||
childs[7].show() # show add to roster menuitem
|
||||
else:
|
||||
|
@ -729,7 +734,8 @@ class ConversationTextview:
|
|||
# we get the end of the tag
|
||||
while not end_iter.ends_tag(texttag):
|
||||
end_iter.forward_char()
|
||||
word = self.tv.get_buffer().get_text(begin_iter, end_iter).decode('utf-8')
|
||||
word = self.tv.get_buffer().get_text(begin_iter, end_iter).decode(
|
||||
'utf-8')
|
||||
if event.button == 3: # right click
|
||||
self.make_link_menu(event, kind, word)
|
||||
else:
|
||||
|
@ -786,16 +792,16 @@ class ConversationTextview:
|
|||
exitcode = 0
|
||||
|
||||
# some latex commands are really bad
|
||||
blacklist = ["\\def", "\\let", "\\futurelet",
|
||||
"\\newcommand", "\\renewcomment", "\\else", "\\fi", "\\write",
|
||||
"\\input", "\\include", "\\chardef", "\\catcode", "\\makeatletter",
|
||||
"\\noexpand", "\\toksdef", "\\every", "\\errhelp", "\\errorstopmode",
|
||||
"\\scrollmode", "\\nonstopmode", "\\batchmode", "\\read", "\\csname",
|
||||
"\\newhelp", "\\relax", "\\afterground", "\\afterassignment",
|
||||
"\\expandafter", "\\noexpand", "\\special", "\\command", "\\loop",
|
||||
"\\repeat", "\\toks", "\\output", "\\line", "\\mathcode", "\\name",
|
||||
"\\item", "\\section", "\\mbox", "\\DeclareRobustCommand", "\\[",
|
||||
"\\]"]
|
||||
blacklist = ['\\def', '\\let', '\\futurelet',
|
||||
'\\newcommand', '\\renewcomment', '\\else', '\\fi', '\\write',
|
||||
'\\input', '\\include', '\\chardef', '\\catcode', '\\makeatletter',
|
||||
'\\noexpand', '\\toksdef', '\\every', '\\errhelp', '\\errorstopmode',
|
||||
'\\scrollmode', '\\nonstopmode', '\\batchmode', '\\read', '\\csname',
|
||||
'\\newhelp', '\\relax', '\\afterground', '\\afterassignment',
|
||||
'\\expandafter', '\\noexpand', '\\special', '\\command', '\\loop',
|
||||
'\\repeat', '\\toks', '\\output', '\\line', '\\mathcode', '\\name',
|
||||
'\\item', '\\section', '\\mbox', '\\DeclareRobustCommand', '\\[',
|
||||
'\\]']
|
||||
|
||||
str = str[2:len(str)-2]
|
||||
|
||||
|
@ -807,16 +813,18 @@ class ConversationTextview:
|
|||
|
||||
if exitcode == 0:
|
||||
random.seed()
|
||||
tmpfile = os.path.join(gettempdir(), "gajimtex_" + random.randint(0,
|
||||
tmpfile = os.path.join(gettempdir(), 'gajimtex_' + random.randint(0,
|
||||
100).__str__())
|
||||
|
||||
# build latex string
|
||||
texstr = "\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}\\usepackage{amsmath}\\usepackage{amssymb}\\pagestyle{empty}"
|
||||
texstr += "\\begin{document}\\begin{large}\\begin{gather*}"
|
||||
texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
|
||||
texstr += '\\usepackage{amsmath}\\usepackage{amssymb}'
|
||||
texstr += '\\pagestyle{empty}'
|
||||
texstr += '\\begin{document}\\begin{large}\\begin{gather*}'
|
||||
texstr += str
|
||||
texstr += "\\end{gather*}\\end{large}\\end{document}"
|
||||
texstr += '\\end{gather*}\\end{large}\\end{document}'
|
||||
|
||||
file = open(os.path.join(tmpfile + ".tex"), "w+")
|
||||
file = open(os.path.join(tmpfile + '.tex'), 'w+')
|
||||
file.write(texstr)
|
||||
file.flush()
|
||||
file.close()
|
||||
|
@ -831,11 +839,11 @@ class ConversationTextview:
|
|||
exitcode = p.wait()
|
||||
|
||||
if exitcode == 0:
|
||||
p = Popen(['convert', tmpfile + '.ps', tmpfile + '.png'],
|
||||
cwd=gettempdir())
|
||||
p = Popen(['convert', '-alpha', 'off', tmpfile + '.ps',
|
||||
tmpfile + '.png'], cwd=gettempdir())
|
||||
exitcode = p.wait()
|
||||
|
||||
extensions = [".tex", ".log", ".aux", ".dvi", ".ps"]
|
||||
extensions = ['.tex', '.log', '.aux', '.dvi', '.ps']
|
||||
for ext in extensions:
|
||||
try:
|
||||
os.remove(tmpfile + ext)
|
||||
|
@ -895,11 +903,13 @@ class ConversationTextview:
|
|||
use_other_tags = False
|
||||
elif special_text.startswith('*'): # it's a bold text
|
||||
tags.append('bold')
|
||||
if special_text[1] == '/' and special_text[-2] == '/' and len(special_text) > 4: # it's also italic
|
||||
if special_text[1] == '/' and special_text[-2] == '/' and\
|
||||
len(special_text) > 4: # it's also italic
|
||||
tags.append('italic')
|
||||
if not show_ascii_formatting_chars:
|
||||
special_text = special_text[2:-2] # remove */ /*
|
||||
elif special_text[1] == '_' and special_text[-2] == '_' and len(special_text) > 4: # it's also underlined
|
||||
elif special_text[1] == '_' and special_text[-2] == '_' and \
|
||||
len(special_text) > 4: # it's also underlined
|
||||
tags.append('underline')
|
||||
if not show_ascii_formatting_chars:
|
||||
special_text = special_text[2:-2] # remove *_ _*
|
||||
|
@ -908,11 +918,13 @@ class ConversationTextview:
|
|||
special_text = special_text[1:-1] # remove * *
|
||||
elif special_text.startswith('/'): # it's an italic text
|
||||
tags.append('italic')
|
||||
if special_text[1] == '*' and special_text[-2] == '*' and len(special_text) > 4: # it's also bold
|
||||
if special_text[1] == '*' and special_text[-2] == '*' and \
|
||||
len(special_text) > 4: # it's also bold
|
||||
tags.append('bold')
|
||||
if not show_ascii_formatting_chars:
|
||||
special_text = special_text[2:-2] # remove /* */
|
||||
elif special_text[1] == '_' and special_text[-2] == '_' and len(special_text) > 4: # it's also underlined
|
||||
elif special_text[1] == '_' and special_text[-2] == '_' and \
|
||||
len(special_text) > 4: # it's also underlined
|
||||
tags.append('underline')
|
||||
if not show_ascii_formatting_chars:
|
||||
special_text = special_text[2:-2] # remove /_ _/
|
||||
|
@ -921,11 +933,13 @@ class ConversationTextview:
|
|||
special_text = special_text[1:-1] # remove / /
|
||||
elif special_text.startswith('_'): # it's an underlined text
|
||||
tags.append('underline')
|
||||
if special_text[1] == '*' and special_text[-2] == '*' and len(special_text) > 4: # it's also bold
|
||||
if special_text[1] == '*' and special_text[-2] == '*' and \
|
||||
len(special_text) > 4: # it's also bold
|
||||
tags.append('bold')
|
||||
if not show_ascii_formatting_chars:
|
||||
special_text = special_text[2:-2] # remove _* *_
|
||||
elif special_text[1] == '/' and special_text[-2] == '/' and len(special_text) > 4: # it's also italic
|
||||
elif special_text[1] == '/' and special_text[-2] == '/' and \
|
||||
len(special_text) > 4: # it's also italic
|
||||
tags.append('italic')
|
||||
if not show_ascii_formatting_chars:
|
||||
special_text = special_text[2:-2] # remove _/ /_
|
||||
|
@ -1123,8 +1137,8 @@ class ConversationTextview:
|
|||
self.tv.display_html(xhtml.encode('utf-8'))
|
||||
return
|
||||
except Exception, e:
|
||||
gajim.log.debug(str("Error processing xhtml")+str(e))
|
||||
gajim.log.debug(str("with |"+xhtml+"|"))
|
||||
gajim.log.debug(str('Error processing xhtml')+str(e))
|
||||
gajim.log.debug(str('with |'+xhtml+'|'))
|
||||
|
||||
buffer = self.tv.get_buffer()
|
||||
# /me is replaced by name if name is given
|
||||
|
@ -1136,4 +1150,3 @@ class ConversationTextview:
|
|||
# add the rest of text located in the index and after
|
||||
end_iter = buffer.get_end_iter()
|
||||
buffer.insert_with_tags_by_name(end_iter, text[index:], *text_tags)
|
||||
|
||||
|
|
194
src/dialogs.py
194
src/dialogs.py
|
@ -256,7 +256,7 @@ class PassphraseDialog:
|
|||
self.window.destroy()
|
||||
return passphrase, checked
|
||||
|
||||
def __init__(self, titletext, labeltext, checkbuttontext=None, is_modal = True,
|
||||
def __init__(self, titletext, labeltext, checkbuttontext=None, is_modal=True,
|
||||
ok_handler = None, cancel_handler = None):
|
||||
self.xml = gtkgui_helpers.get_glade('passphrase_dialog.glade')
|
||||
self.window = self.xml.get_widget('passphrase_dialog')
|
||||
|
@ -351,9 +351,9 @@ class ChooseGPGKeyDialog:
|
|||
|
||||
def run(self):
|
||||
rep = self.window.run()
|
||||
if rep == gtk.RESPONSE_OK:
|
||||
selection = self.keys_treeview.get_selection()
|
||||
(model, iter) = selection.get_selected()
|
||||
if iter and rep == gtk.RESPONSE_OK:
|
||||
keyID = [ model[iter][0].decode('utf-8'),
|
||||
model[iter][1].decode('utf-8') ]
|
||||
else:
|
||||
|
@ -370,6 +370,125 @@ class ChooseGPGKeyDialog:
|
|||
self.keys_treeview.set_cursor(path)
|
||||
|
||||
|
||||
class ChangeActivityDialog:
|
||||
activities = [_('doing_chores'), _('drinking'), _('eating'),
|
||||
_('excercising'), _('grooming'), _('having_appointment'),
|
||||
_('inactive'), _('relaxing'), _('talking'), _('traveling'),
|
||||
_('working'), ]
|
||||
subactivities = [_('at_the_spa'), _('brushing_teeth'),
|
||||
_('buying_groceries'), _('cleaning'), _('coding'),
|
||||
_('commuting'), _('cooking'), _('cycling'), _('day_off'),
|
||||
_('doing_maintenance'), _('doing_the_dishes'),
|
||||
_('doing_the_laundry'), _('driving'), _('gaming'),
|
||||
_('gardening'), _('getting_a_haircut'), _('going_out'),
|
||||
_('hanging_out'), _('having_a_beer'), _('having_a_snack'),
|
||||
_('having_breakfast'), _('having_coffee'),
|
||||
_('having_dinner'), _('having_lunch'), _('having_tea'),
|
||||
_('hiking'), _('in_a_car'), _('in_a_meeting'),
|
||||
_('in_real_life'), _('jogging'), _('on_a_bus'),
|
||||
_('on_a_plane'), _('on_a_train'), _('on_a_trip'),
|
||||
_('on_the_phone'), _('on_vacation'), _('other'),
|
||||
_('partying'), _('playing_sports'), _('reading'),
|
||||
_('rehearsing'), _('running'), _('running_an_errand'),
|
||||
_('scheduled_holiday'), _('shaving'), _('shopping'),
|
||||
_('skiing'), _('sleeping'), _('socializing'),
|
||||
_('studying'), _('sunbathing'), _('swimming'),
|
||||
_('taking_a_bath'), _('taking_a_shower'), _('walking'),
|
||||
_('walking_the_dog'), _('watching_tv'),
|
||||
_('watching_a_movie'), _('working_out'), _('writing'), ]
|
||||
def __init__(self, account):
|
||||
self.account = account
|
||||
self.xml = gtkgui_helpers.get_glade('change_activity_dialog.glade')
|
||||
self.window = self.xml.get_widget('change_activity_dialog')
|
||||
self.window.set_transient_for(gajim.interface.roster.window)
|
||||
self.window.set_title(_('Activity'))
|
||||
|
||||
self.entry = self.xml.get_widget('entry')
|
||||
|
||||
self.combo1 = self.xml.get_widget('combobox1')
|
||||
self.liststore1 = gtk.ListStore(str)
|
||||
self.combo1.set_model(self.liststore1)
|
||||
|
||||
for activity in self.activities:
|
||||
self.liststore1.append((activity,))
|
||||
|
||||
cellrenderertext = gtk.CellRendererText()
|
||||
self.combo1.pack_start(cellrenderertext, True)
|
||||
self.combo1.add_attribute(cellrenderertext, 'text', 0)
|
||||
|
||||
self.combo2 = self.xml.get_widget('combobox2')
|
||||
self.liststore2 = gtk.ListStore(str)
|
||||
self.combo2.set_model(self.liststore2)
|
||||
|
||||
for subactivity in self.subactivities:
|
||||
self.liststore2.append((subactivity,))
|
||||
|
||||
cellrenderertext = gtk.CellRendererText()
|
||||
self.combo2.pack_start(cellrenderertext, True)
|
||||
self.combo2.add_attribute(cellrenderertext, 'text', 0)
|
||||
|
||||
self.xml.signal_autoconnect(self)
|
||||
self.window.show_all()
|
||||
|
||||
def on_ok_button_clicked(self, widget):
|
||||
'''Return activity and messsage (None if no activity selected)'''
|
||||
activity = None
|
||||
subactivity = None
|
||||
message = None
|
||||
active1 = self.combo1.get_active()
|
||||
active2 = self.combo2.get_active()
|
||||
if active1 > -1:
|
||||
activity = self.liststore1[active1][0].decode('utf-8')
|
||||
if active2 > -1:
|
||||
subactivity = self.liststore2[active2][0].decode('utf-8')
|
||||
message = self.entry.get_text().decode('utf-8')
|
||||
from common import pep
|
||||
pep.user_send_activity(self.account, activity,
|
||||
subactivity, message)
|
||||
self.window.destroy()
|
||||
|
||||
def on_cancel_button_clicked(self, widget):
|
||||
self.window.destroy()
|
||||
|
||||
class ChangeMoodDialog:
|
||||
moods = [_('afraid'), _('amazed'), _('angry'), _('annoyed'), _('anxious'), _('aroused'), _('ashamed'), _('bored'), _('brave'), _('calm'), _('cold'), _('confused'), _('contented'), _('cranky'), _('curious'), _('depressed'), _('disappointed'), _('disgusted'), _('distracted'), _('embarrassed'), _('excited'), _('flirtatious'), _('frustrated'), _('grumpy'), _('guilty'), _('happy'), _('hot'), _('humbled'), _('humiliated'), _('hungry'), _('hurt'), _('impressed'), _('in_awe'), _('in_love'), _('indignant'), _('interested'), _('intoxicated'), _('invincible'), _('jealous'), _('lonely'), _('mean'), _('moody'), _('nervous'), _('neutral'), _('offended'), _('playful'), _('proud'), _('relieved'), _('remorseful'), _('restless'), _('sad'), _('sarcastic'), _('serious'), _('shocked'), _('shy'), _('sick'), _('sleepy'), _('stressed'), _('surprised'), _('thirsty'), _('worried')]
|
||||
def __init__(self, account):
|
||||
self.account = account
|
||||
self.xml = gtkgui_helpers.get_glade('change_mood_dialog.glade')
|
||||
self.window = self.xml.get_widget('change_mood_dialog')
|
||||
self.window.set_transient_for(gajim.interface.roster.window)
|
||||
self.window.set_title(_('Mood'))
|
||||
|
||||
self.entry = self.xml.get_widget('entry')
|
||||
|
||||
self.combo = self.xml.get_widget('combobox')
|
||||
self.liststore = gtk.ListStore(str)
|
||||
self.combo.set_model(self.liststore)
|
||||
|
||||
for mood in self.moods:
|
||||
self.liststore.append((mood,))
|
||||
|
||||
cellrenderertext = gtk.CellRendererText()
|
||||
self.combo.pack_start(cellrenderertext, True)
|
||||
self.combo.add_attribute(cellrenderertext, 'text', 0)
|
||||
self.xml.signal_autoconnect(self)
|
||||
self.window.show_all()
|
||||
|
||||
def on_ok_button_clicked(self, widget):
|
||||
'''Return mood and messsage (None if no mood selected)'''
|
||||
mood = None
|
||||
message = None
|
||||
active = self.combo.get_active()
|
||||
if active > -1:
|
||||
mood = self.liststore[active][0].decode('utf-8')
|
||||
message = self.entry.get_text().decode('utf-8')
|
||||
from common import pep
|
||||
pep.user_send_mood(self.account, mood, message)
|
||||
self.window.destroy()
|
||||
|
||||
def on_cancel_button_clicked(self, widget):
|
||||
self.window.destroy()
|
||||
|
||||
class ChangeStatusMessageDialog:
|
||||
def __init__(self, show = None):
|
||||
self.show = show
|
||||
|
@ -922,7 +1041,7 @@ class HigDialog(gtk.MessageDialog):
|
|||
gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL,
|
||||
type, buttons, message_format = pritext)
|
||||
|
||||
self.format_secondary_text(sectext)
|
||||
self.format_secondary_markup(sectext)
|
||||
|
||||
buttons = self.action_area.get_children()
|
||||
possible_responses = {gtk.STOCK_OK: on_response_ok,
|
||||
|
@ -1101,15 +1220,47 @@ class ErrorDialog(HigDialog):
|
|||
self.popup()
|
||||
|
||||
class YesNoDialog(HigDialog):
|
||||
def __init__(self, pritext, sectext='', on_response_yes = None,
|
||||
on_response_no = None):
|
||||
def __init__(self, pritext, sectext='', checktext='', on_response_yes=None,
|
||||
on_response_no=None):
|
||||
'''HIG compliant YesNo dialog.'''
|
||||
self.user_response_yes = on_response_yes
|
||||
self.user_response_no = on_response_no
|
||||
HigDialog.__init__( self, None,
|
||||
gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, pritext, sectext,
|
||||
on_response_yes = on_response_yes, on_response_no = on_response_no)
|
||||
on_response_yes=self.on_response_yes,
|
||||
on_response_no=self.on_response_no)
|
||||
|
||||
if checktext:
|
||||
self.checkbutton = gtk.CheckButton(checktext)
|
||||
self.vbox.pack_start(self.checkbutton, expand=False, fill=True)
|
||||
else:
|
||||
self.checkbutton = None
|
||||
self.set_modal(False)
|
||||
self.popup()
|
||||
|
||||
def on_response_yes(self, widget):
|
||||
if self.user_response_yes:
|
||||
if isinstance(self.user_response_yes, tuple):
|
||||
self.user_response_yes[0](self.is_checked(),
|
||||
*self.user_response_yes[1:])
|
||||
else:
|
||||
self.user_response_yes(self.is_checked())
|
||||
self.destroy()
|
||||
|
||||
def on_response_no(self, widget):
|
||||
if self.user_response_no:
|
||||
if isinstance(self.user_response_no, tuple):
|
||||
self.user_response_no[0](*self.user_response_no[1:])
|
||||
else:
|
||||
self.user_response_no()
|
||||
self.destroy()
|
||||
|
||||
def is_checked(self):
|
||||
''' Get active state of the checkbutton '''
|
||||
if not self.checkbutton:
|
||||
return False
|
||||
return self.checkbutton.get_active()
|
||||
|
||||
class ConfirmationDialogCheck(ConfirmationDialog):
|
||||
'''HIG compliant confirmation dialog with checkbutton.'''
|
||||
def __init__(self, pritext, sectext='', checktext = '',
|
||||
|
@ -1145,7 +1296,7 @@ class ConfirmationDialogCheck(ConfirmationDialog):
|
|||
def on_response_cancel(self, widget):
|
||||
if self.user_response_cancel:
|
||||
if isinstance(self.user_response_cancel, tuple):
|
||||
self.user_response_cancel[0](*self.user_response_ok[1:])
|
||||
self.user_response_cancel[0](*self.user_response_cancel[1:])
|
||||
else:
|
||||
self.user_response_cancel()
|
||||
self.destroy()
|
||||
|
@ -1922,14 +2073,14 @@ class SingleMessageWindow:
|
|||
self.completion_dict = {}
|
||||
self.xml.signal_autoconnect(self)
|
||||
|
||||
if gajim.config.get('saveposition'):
|
||||
# get window position and size from config
|
||||
gtkgui_helpers.move_window(self.window,
|
||||
gajim.config.get('single-msg-x-position'),
|
||||
gajim.config.get('single-msg-y-position'))
|
||||
gtkgui_helpers.resize_window(self.window,
|
||||
gajim.config.get('single-msg-width'),
|
||||
gajim.config.get('single-msg-height'))
|
||||
gtkgui_helpers.move_window(self.window,
|
||||
gajim.config.get('single-msg-x-position'),
|
||||
gajim.config.get('single-msg-y-position'))
|
||||
|
||||
self.window.show_all()
|
||||
|
||||
def on_single_message_window_destroy(self, widget):
|
||||
|
@ -1940,7 +2091,6 @@ class SingleMessageWindow:
|
|||
self.message_tv_buffer.place_cursor(end_iter)
|
||||
|
||||
def save_pos(self):
|
||||
if gajim.config.get('saveposition'):
|
||||
# save the window size and position
|
||||
x, y = self.window.get_position()
|
||||
gajim.config.set('single-msg-x-position', x)
|
||||
|
@ -3417,6 +3567,15 @@ class TransformChatToMUC:
|
|||
|
||||
self.guests_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
||||
|
||||
# All contacts beside the following can be invited:
|
||||
# transports, zeroconf contacts, minimized groupchats
|
||||
invitable = lambda contact, contact_transport = None:\
|
||||
contact.jid not in self.auto_jids and\
|
||||
contact.jid != gajim.get_jid_from_account(self.account) and\
|
||||
contact.jid not in gajim.interface.minimized_controls[account] and\
|
||||
not contact.is_transport() and\
|
||||
not contact_transport
|
||||
|
||||
# set jabber id and pseudos
|
||||
for account in gajim.contacts.get_accounts():
|
||||
if gajim.connections[account].is_zeroconf:
|
||||
|
@ -3425,13 +3584,9 @@ class TransformChatToMUC:
|
|||
contact = \
|
||||
gajim.contacts.get_contact_with_highest_priority(account, jid)
|
||||
contact_transport = gajim.get_transport_name_from_jid(jid)
|
||||
# do not add transports, zeroconf contacs, minimized groupchats
|
||||
# and selfjid to list of invitable jids
|
||||
if contact.jid not in self.auto_jids and contact.jid != \
|
||||
gajim.get_jid_from_account(self.account) and not contact_transport \
|
||||
and not contact.is_transport() and contact.jid not in \
|
||||
gajim.interface.minimized_controls[account]:
|
||||
if contact.show not in ('offline', 'error'):
|
||||
# Add contact if it can be invited
|
||||
if invitable(contact, contact_transport) and \
|
||||
contact.show not in ('offline', 'error'):
|
||||
img = gajim.interface.roster.jabber_state_images['16'][
|
||||
contact.show]
|
||||
name = contact.name
|
||||
|
@ -3460,7 +3615,6 @@ class TransformChatToMUC:
|
|||
server = self.server_list_comboboxentry.get_active_text()
|
||||
if server == '':
|
||||
return
|
||||
room_id = gajim.nicks[self.account] + str(randrange(9999999))
|
||||
gajim.connections[self.account].check_unique_room_id_support(server, self)
|
||||
|
||||
def unique_room_id_supported(self, server, room_id):
|
||||
|
|
|
@ -46,7 +46,6 @@ import inspect
|
|||
import weakref
|
||||
import gobject
|
||||
import gtk
|
||||
import gobject
|
||||
import pango
|
||||
|
||||
import dialogs
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
import os
|
||||
import sys
|
||||
import gtk
|
||||
import gobject
|
||||
import gtkgui_helpers
|
||||
|
||||
import dialogs
|
||||
|
@ -53,7 +52,7 @@ class FeaturesWindow:
|
|||
_('Requires python-avahi.'),
|
||||
_('Requires pybonjour (http://o2s.csail.mit.edu/o2s-wiki/pybonjour).')),
|
||||
_('gajim-remote'): (self.dbus_available,
|
||||
_('A script to controle gajim via commandline.'),
|
||||
_('A script to controle Gajim via commandline.'),
|
||||
_('Requires python-dbus.'),
|
||||
_('Feature not available under Windows.')),
|
||||
_('OpenGPG'): (self.gpg_available,
|
||||
|
@ -93,7 +92,7 @@ class FeaturesWindow:
|
|||
_('Requires compilation of the idle module from Gajim sources.'),
|
||||
_('Requires compilation of the idle module from Gajim sources.')),
|
||||
_('LaTeX'): (self.latex_available,
|
||||
_('Transform LaTeX espressions between $$ $$.'),
|
||||
_('Transform LaTeX expressions between $$ $$.'),
|
||||
_('Requires texlive-latex-base, dvips and imagemagick. You have to set \'use_latex\' to True in the Advanced Configuration Editor.'),
|
||||
_('Feature not available under Windows.')),
|
||||
_('End to end encryption'): (self.pycrypto_available,
|
||||
|
@ -141,6 +140,8 @@ class FeaturesWindow:
|
|||
|
||||
def on_features_treeview_cursor_changed(self, widget):
|
||||
selection = widget.get_selection()
|
||||
if not selection:
|
||||
return
|
||||
path = selection.get_selected_rows()[1][0]
|
||||
available = self.model[path][1]
|
||||
feature = self.model[path][0].decode('utf-8')
|
||||
|
@ -178,8 +179,8 @@ class FeaturesWindow:
|
|||
def gpg_available(self):
|
||||
if os.name == 'nt':
|
||||
return False
|
||||
from common import GnuPG
|
||||
return GnuPG.USE_GPG
|
||||
from common import gajim
|
||||
return gajim.HAVE_GPG
|
||||
|
||||
def network_manager_available(self):
|
||||
if os.name == 'nt':
|
||||
|
|
154
src/gajim.py
154
src/gajim.py
|
@ -44,7 +44,6 @@ if os.name == 'nt':
|
|||
# os.environ['GTK_BASEPATH'] = 'gtk'
|
||||
|
||||
import sys
|
||||
import urllib
|
||||
|
||||
import logging
|
||||
consoleloghandler = logging.StreamHandler()
|
||||
|
@ -222,7 +221,6 @@ import gobject
|
|||
|
||||
import re
|
||||
import signal
|
||||
import getopt
|
||||
import time
|
||||
import math
|
||||
|
||||
|
@ -457,10 +455,13 @@ class Interface:
|
|||
|
||||
def handle_event_http_auth(self, account, data):
|
||||
#('HTTP_AUTH', account, (method, url, transaction_id, iq_obj, msg))
|
||||
def response(widget, account, iq_obj, answer):
|
||||
def response(account, iq_obj, answer):
|
||||
self.dialog.destroy()
|
||||
gajim.connections[account].build_http_auth_answer(iq_obj, answer)
|
||||
|
||||
def on_yes(is_checked, account, iq_obj):
|
||||
response(account, iq_obj, 'yes')
|
||||
|
||||
sec_msg = _('Do you accept this request?')
|
||||
if gajim.get_number_of_connected_accounts() > 1:
|
||||
sec_msg = _('Do you accept this request on account %s?') % account
|
||||
|
@ -468,8 +469,8 @@ class Interface:
|
|||
sec_msg = data[4] + '\n' + sec_msg
|
||||
self.dialog = dialogs.YesNoDialog(_('HTTP (%s) Authorization for %s (id: %s)') \
|
||||
% (data[0], data[1], data[2]), sec_msg,
|
||||
on_response_yes = (response, account, data[3], 'yes'),
|
||||
on_response_no = (response, account, data[3], 'no'))
|
||||
on_response_yes=(on_yes, account, data[3]),
|
||||
on_response_no=(response, account, data[3], 'no'))
|
||||
|
||||
def handle_event_error_answer(self, account, array):
|
||||
#('ERROR_ANSWER', account, (id, jid_from, errmsg, errcode))
|
||||
|
@ -581,10 +582,11 @@ class Interface:
|
|||
jid = array[0].split('/')[0]
|
||||
keyID = array[5]
|
||||
contact_nickname = array[7]
|
||||
attached_keys = gajim.config.get_per('accounts', account,
|
||||
'attached_gpg_keys').split()
|
||||
if jid in attached_keys:
|
||||
keyID = attached_keys[attached_keys.index(jid) + 1]
|
||||
|
||||
# Get the proper keyID
|
||||
keyID = helpers.prepare_and_validate_gpg_keyID(account,
|
||||
jid, keyID)
|
||||
|
||||
resource = array[3]
|
||||
if not resource:
|
||||
resource = ''
|
||||
|
@ -723,7 +725,7 @@ class Interface:
|
|||
# remove in 2007
|
||||
# It's maybe a GC_NOTIFY (specialy for MSN gc)
|
||||
self.handle_event_gc_notify(account, (jid, array[1], status_message,
|
||||
array[3], None, None, None, None, None, None, None, None))
|
||||
array[3], None, None, None, None, None, [], None, None))
|
||||
|
||||
|
||||
def handle_event_msg(self, account, array):
|
||||
|
@ -848,8 +850,14 @@ class Interface:
|
|||
msg = message
|
||||
if subject:
|
||||
msg = _('Subject: %s') % subject + '\n' + msg
|
||||
focused = False
|
||||
if chat_control:
|
||||
parent_win = chat_control.parent_win
|
||||
if chat_control == parent_win.get_active_control() and \
|
||||
parent_win.window.has_focus:
|
||||
focused = True
|
||||
notify.notify('new_message', jid_of_control, account, [msg_type,
|
||||
first, nickname, msg], advanced_notif_num)
|
||||
first, nickname, msg, focused], advanced_notif_num)
|
||||
|
||||
if self.remote_ctrl:
|
||||
self.remote_ctrl.raise_signal('NewMessage', (account, array))
|
||||
|
@ -949,13 +957,22 @@ class Interface:
|
|||
self.remote_ctrl.raise_signal('Subscribed', (account, array))
|
||||
|
||||
def handle_event_unsubscribed(self, account, jid):
|
||||
dialogs.InformationDialog(_('Contact "%s" removed subscription from you')\
|
||||
% jid, _('You will always see him or her as offline.'))
|
||||
# FIXME: Per RFC 3921, we can "deny" ack as well, but the GUI does not show deny
|
||||
gajim.connections[account].ack_unsubscribed(jid)
|
||||
if self.remote_ctrl:
|
||||
self.remote_ctrl.raise_signal('Unsubscribed', (account, jid))
|
||||
|
||||
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||
if not contact:
|
||||
return
|
||||
def on_yes(is_checked, list_):
|
||||
self.roster.on_req_usub(None, list_)
|
||||
list_ = [(contact, account)]
|
||||
dialogs.YesNoDialog(
|
||||
_('Contact "%s" removed subscription from you') % jid,
|
||||
_('You will always see him or her as offline.\nDo you want to remove him or her from your contact list?'),
|
||||
on_response_yes=(on_yes, list_))
|
||||
# FIXME: Per RFC 3921, we can "deny" ack as well, but the GUI does not show deny
|
||||
|
||||
def handle_event_agent_info_error(self, account, agent):
|
||||
#('AGENT_ERROR_INFO', account, (agent))
|
||||
try:
|
||||
|
@ -999,6 +1016,11 @@ class Interface:
|
|||
|
||||
def handle_event_agent_info_items(self, account, array):
|
||||
#('AGENT_INFO_ITEMS', account, (agent, node, items))
|
||||
our_jid = gajim.get_jid_from_account(account)
|
||||
if gajim.interface.instances[account].has_key('pep_services') and \
|
||||
array[0] == our_jid:
|
||||
gajim.interface.instances[account]['pep_services'].items_received(
|
||||
array[2])
|
||||
try:
|
||||
gajim.connections[account].services_cache.agent_items(array[0],
|
||||
array[1], array[2])
|
||||
|
@ -1014,11 +1036,11 @@ class Interface:
|
|||
return
|
||||
|
||||
def handle_event_new_acc_connected(self, account, array):
|
||||
#('NEW_ACC_CONNECTED', account, (infos, is_form, ssl_msg, ssl_cert,
|
||||
# ssl_fingerprint))
|
||||
#('NEW_ACC_CONNECTED', account, (infos, is_form, ssl_msg, ssl_err,
|
||||
# ssl_cert, ssl_fingerprint))
|
||||
if self.instances.has_key('account_creation_wizard'):
|
||||
self.instances['account_creation_wizard'].new_acc_connected(array[0],
|
||||
array[1], array[2], array[3], array[4])
|
||||
array[1], array[2], array[3], array[4], array[5])
|
||||
|
||||
def handle_event_new_acc_not_connected(self, account, array):
|
||||
#('NEW_ACC_NOT_CONNECTED', account, (reason))
|
||||
|
@ -1407,14 +1429,19 @@ class Interface:
|
|||
gajim.connections[account].gpg_passphrase(self.gpg_passphrase[keyid])
|
||||
callback()
|
||||
return
|
||||
if self.gpg_dialog:
|
||||
# A GPG dialog is already open, retry in 0.5 second
|
||||
gobject.timeout_add(500, self.handle_event_gpg_password_required,
|
||||
account, array)
|
||||
return
|
||||
password_ok = False
|
||||
count = 0
|
||||
title = _('Passphrase Required')
|
||||
second = _('Enter GPG key passphrase for account %s.') % account
|
||||
while not password_ok and count < 3:
|
||||
count += 1
|
||||
w = dialogs.PassphraseDialog(title, second, '')
|
||||
passphrase, save = w.run()
|
||||
self.gpg_dialog = dialogs.PassphraseDialog(title, second, '')
|
||||
passphrase, save = self.gpg_dialog.run()
|
||||
if passphrase == -1:
|
||||
# User pressed cancel
|
||||
passphrase = None
|
||||
|
@ -1424,6 +1451,7 @@ class Interface:
|
|||
test_gpg_passphrase(passphrase)
|
||||
title = _('Wrong Passphrase')
|
||||
second = _('Please retype your GPG passphrase or press Cancel.')
|
||||
self.gpg_dialog = None
|
||||
if passphrase != None:
|
||||
self.gpg_passphrase[keyid] = passphrase
|
||||
gobject.timeout_add(30000, self.forget_gpg_passphrase, keyid)
|
||||
|
@ -1857,6 +1885,7 @@ class Interface:
|
|||
# block signed in notifications for 30 seconds
|
||||
gajim.block_signed_in_notifications[account] = True
|
||||
self.roster.set_actions_menu_needs_rebuild()
|
||||
self.roster.draw_account(account)
|
||||
if self.sleeper.getState() != common.sleepy.STATE_UNKNOWN and \
|
||||
gajim.connections[account].connected in (2, 3):
|
||||
# we go online or free for chat, so we activate auto status
|
||||
|
@ -1922,12 +1951,12 @@ class Interface:
|
|||
negotiated, not_acceptable, ask_user = session.verify_options_bob(form)
|
||||
|
||||
if ask_user:
|
||||
def accept_nondefault_options(widget):
|
||||
def accept_nondefault_options(is_checked):
|
||||
self.dialog.destroy()
|
||||
negotiated.update(ask_user)
|
||||
session.respond_e2e_bob(form, negotiated, not_acceptable)
|
||||
|
||||
def reject_nondefault_options(widget):
|
||||
def reject_nondefault_options():
|
||||
self.dialog.destroy()
|
||||
for key in ask_user.keys():
|
||||
not_acceptable.append(key)
|
||||
|
@ -1939,8 +1968,8 @@ class Interface:
|
|||
%s
|
||||
|
||||
Are these options acceptable?''') % (negotiation.describe_features(ask_user)),
|
||||
on_response_yes = accept_nondefault_options,
|
||||
on_response_no = reject_nondefault_options)
|
||||
on_response_yes=accept_nondefault_options,
|
||||
on_response_no=reject_nondefault_options)
|
||||
else:
|
||||
session.respond_e2e_bob(form, negotiated, not_acceptable)
|
||||
|
||||
|
@ -1963,7 +1992,7 @@ class Interface:
|
|||
session.check_identity = _cb
|
||||
|
||||
if ask_user:
|
||||
def accept_nondefault_options(widget):
|
||||
def accept_nondefault_options(is_checked):
|
||||
dialog.destroy()
|
||||
|
||||
negotiated.update(ask_user)
|
||||
|
@ -1973,7 +2002,7 @@ class Interface:
|
|||
except exceptions.NegotiationError, details:
|
||||
session.fail_bad_negotiation(details)
|
||||
|
||||
def reject_nondefault_options(widget):
|
||||
def reject_nondefault_options():
|
||||
session.reject_negotiation()
|
||||
dialog.destroy()
|
||||
|
||||
|
@ -2169,6 +2198,11 @@ class Interface:
|
|||
_('You are already connected to this account with the same resource. Please type a new one'), input_str = gajim.connections[account].server_resource,
|
||||
is_modal = False, ok_handler = on_ok)
|
||||
|
||||
def handle_event_pep_access_model(self, account, data):
|
||||
# ('PEP_ACCESS_MODEL', account, (node, model))
|
||||
if self.instances[account].has_key('pep_services'):
|
||||
self.instances[account]['pep_services'].new_service(data[0], data[1])
|
||||
|
||||
def handle_event_unique_room_id_supported(self, account, data):
|
||||
'''Receive confirmation that unique_room_id are supported'''
|
||||
# ('UNIQUE_ROOM_ID_SUPPORTED', server, instance, room_id)
|
||||
|
@ -2181,44 +2215,76 @@ class Interface:
|
|||
instance.unique_room_id_error(data[0])
|
||||
|
||||
def handle_event_ssl_error(self, account, data):
|
||||
# ('SSL_ERROR', account, (text, cert, sha1_fingerprint))
|
||||
# ('SSL_ERROR', account, (text, errnum, cert, sha1_fingerprint))
|
||||
server = gajim.config.get_per('accounts', account, 'hostname')
|
||||
def on_ok(is_checked):
|
||||
def on_ok(is_checked=False):
|
||||
if is_checked:
|
||||
# Check if cert is already in file
|
||||
certs = ''
|
||||
if os.path.isfile(gajim.MY_CACERTS):
|
||||
f = open(gajim.MY_CACERTS)
|
||||
certs = f.read()
|
||||
f.close()
|
||||
if data[2] in certs:
|
||||
dialogs.ErrorDialog(_('Certificate Already in File'),
|
||||
_('This certificate is already in file %s, so it\'s not added again.') % gajim.MY_CACERTS)
|
||||
else:
|
||||
f = open(gajim.MY_CACERTS, 'a')
|
||||
f.write(server + '\n')
|
||||
f.write(data[1] + '\n\n')
|
||||
f.write(data[2] + '\n\n')
|
||||
f.close()
|
||||
gajim.config.set_per('accounts', account, 'ssl_fingerprint_sha1',
|
||||
data[2])
|
||||
data[3])
|
||||
gajim.connections[account].ssl_certificate_accepted()
|
||||
def on_cancel():
|
||||
gajim.connections[account].disconnect(on_purpose=True)
|
||||
self.handle_event_status(account, 'offline')
|
||||
pritext = _('Error verifying SSL certificate')
|
||||
sectext = _('There was an error verifying the SSL certificate of your jabber server: %(error)s\nDo you still want to connect to this server?') % {'error': data[0]}
|
||||
checktext = _('Add this certificate to the list of trusted certificates.\nSHA1 fingerprint of the certificate:\n%s') % data[2]
|
||||
if data[1] in (18, 27):
|
||||
checktext = _('Add this certificate to the list of trusted certificates.\nSHA1 fingerprint of the certificate:\n%s') % data[3]
|
||||
dialogs.ConfirmationDialogCheck(pritext, sectext, checktext,
|
||||
on_response_ok=on_ok, on_response_cancel=on_cancel)
|
||||
else:
|
||||
dialogs.ConfirmationDialog(pritext, sectext,
|
||||
on_response_ok=on_ok, on_response_cancel=on_cancel)
|
||||
|
||||
def handle_event_fingerprint_error(self, account, data):
|
||||
# ('FINGERPRINT_ERROR', account, (fingerprint,))
|
||||
def on_yes(widget):
|
||||
dialog.destroy()
|
||||
# ('FINGERPRINT_ERROR', account, (new_fingerprint,))
|
||||
def on_yes(is_checked):
|
||||
gajim.config.set_per('accounts', account, 'ssl_fingerprint_sha1',
|
||||
data[0])
|
||||
gajim.connections[account].ssl_certificate_accepted()
|
||||
def on_no(widget):
|
||||
dialog.destroy()
|
||||
def on_no():
|
||||
gajim.connections[account].disconnect(on_purpose=True)
|
||||
self.handle_event_status(account, 'offline')
|
||||
pritext = _('SSL certificate error')
|
||||
sectext = _('It seems SSL certificate has changed or your connection is '
|
||||
'being hacked. Do you still want to connect and update the fingerprint'
|
||||
'of the certificate?')
|
||||
sectext = _('It seems the SSL certificate has changed or your connection '
|
||||
'is being hacked.\nOld fingerprint: %s\nNew fingerprint: %s\n\nDo you '
|
||||
'still want to connect and update the fingerprint of the certificate?'\
|
||||
) % (gajim.config.get_per('accounts', account, 'ssl_fingerprint_sha1'),
|
||||
data[0])
|
||||
dialog = dialogs.YesNoDialog(pritext, sectext, on_response_yes=on_yes,
|
||||
on_response_no=on_no)
|
||||
|
||||
def handle_event_plain_connection(self, account, data):
|
||||
# ('PLAIN_CONNECTION', account, (connection))
|
||||
server = gajim.config.get_per('accounts', account, 'hostname')
|
||||
def on_yes(is_checked):
|
||||
if is_checked:
|
||||
gajim.config.set_per('accounts', account,
|
||||
'warn_when_insecure_connection', False)
|
||||
gajim.connections[account].connection_accepted(data[0], 'tcp')
|
||||
def on_no():
|
||||
gajim.connections[account].disconnect(on_purpose=True)
|
||||
self.handle_event_status(account, 'offline')
|
||||
pritext = _('Insecure connection')
|
||||
sectext = _('You are about to send your password on an insecure '
|
||||
'conection. Are you sure you want to do that?')
|
||||
checktext = _('Do _not ask me again')
|
||||
dialog = dialogs.YesNoDialog(pritext, sectext, checktext,
|
||||
on_response_yes=on_yes, on_response_no=on_no)
|
||||
|
||||
def read_sleepy(self):
|
||||
'''Check idle status and change that status if needed'''
|
||||
if not self.sleeper.poll():
|
||||
|
@ -2328,7 +2394,7 @@ class Interface:
|
|||
|
||||
#FIXME: recognize xmpp: and treat it specially
|
||||
|
||||
links = r'\b(%s)\S*[\w\/\=]|' % prefixes
|
||||
links = r"(www\.(?!\.)|[a-z][a-z0-9+.-]*://)[^\s<>'\"]+[^!,\.\s<>\)'\"\]]"
|
||||
#2nd one: at_least_one_char@at_least_one_char.at_least_one_char
|
||||
mail = r'\bmailto:\S*[^\s\W]|' r'\b\S+@\S+\.\S*[^\s\W]'
|
||||
|
||||
|
@ -2340,7 +2406,7 @@ class Interface:
|
|||
|
||||
latex = r'|\$\$[^$\\]*?([\]\[0-9A-Za-z()|+*/-]|[\\][\]\[0-9A-Za-z()|{}$])(.*?[^\\])?\$\$'
|
||||
|
||||
basic_pattern = links + mail
|
||||
basic_pattern = links + '|' + mail
|
||||
|
||||
if gajim.config.get('use_latex'):
|
||||
basic_pattern += latex
|
||||
|
@ -2551,6 +2617,7 @@ class Interface:
|
|||
'SEARCH_FORM': self.handle_event_search_form,
|
||||
'SEARCH_RESULT': self.handle_event_search_result,
|
||||
'RESOURCE_CONFLICT': self.handle_event_resource_conflict,
|
||||
'PEP_ACCESS_MODEL': self.handle_event_pep_access_model,
|
||||
'UNIQUE_ROOM_ID_UNSUPPORTED': \
|
||||
self.handle_event_unique_room_id_unsupported,
|
||||
'UNIQUE_ROOM_ID_SUPPORTED': self.handle_event_unique_room_id_supported,
|
||||
|
@ -2558,6 +2625,7 @@ class Interface:
|
|||
'GPG_PASSWORD_REQUIRED': self.handle_event_gpg_password_required,
|
||||
'SSL_ERROR': self.handle_event_ssl_error,
|
||||
'FINGERPRINT_ERROR': self.handle_event_fingerprint_error,
|
||||
'PLAIN_CONNECTION': self.handle_event_plain_connection,
|
||||
}
|
||||
gajim.handlers = self.handlers
|
||||
|
||||
|
@ -2674,6 +2742,7 @@ class Interface:
|
|||
self.status_sent_to_users = {}
|
||||
self.status_sent_to_groups = {}
|
||||
self.gpg_passphrase = {}
|
||||
self.gpg_dialog = None
|
||||
self.default_colors = {
|
||||
'inmsgcolor': gajim.config.get('inmsgcolor'),
|
||||
'outmsgcolor': gajim.config.get('outmsgcolor'),
|
||||
|
@ -2903,7 +2972,7 @@ if __name__ == '__main__':
|
|||
print >> sys.stderr, _('Session Management support not available (missing gnome.ui module)')
|
||||
else:
|
||||
def die_cb(cli):
|
||||
gtk.main_quit()
|
||||
gajim.interface.roster.quit_gtkgui_interface()
|
||||
gnome.program_init('gajim', gajim.version)
|
||||
cli = gnome.ui.master_client()
|
||||
cli.connect('die', die_cb)
|
||||
|
@ -2928,4 +2997,7 @@ if __name__ == '__main__':
|
|||
osx.init()
|
||||
|
||||
Interface()
|
||||
try:
|
||||
gtk.main()
|
||||
except KeyboardInterrupt:
|
||||
print >> sys.stderr, 'KeyboardInterrupt'
|
||||
|
|
|
@ -72,12 +72,19 @@ def tree_cell_data_func(column, renderer, model, iter, tv=None):
|
|||
# reference to GroupchatControl instance (self)
|
||||
theme = gajim.config.get('roster_theme')
|
||||
# allocate space for avatar only if needed
|
||||
parent_iter = model.iter_parent(iter)
|
||||
if isinstance(renderer, gtk.CellRendererPixbuf):
|
||||
if model[iter][C_AVATAR]:
|
||||
avatar_position = gajim.config.get('avatar_position_in_roster')
|
||||
if avatar_position == 'right':
|
||||
renderer.set_property('xalign', 1) # align pixbuf to the right
|
||||
else:
|
||||
renderer.set_property('xalign', 0.5)
|
||||
if parent_iter and (model[iter][C_AVATAR] or avatar_position == 'left'):
|
||||
renderer.set_property('visible', True)
|
||||
renderer.set_property('width', gajim.config.get('roster_avatar_width'))
|
||||
else:
|
||||
renderer.set_property('visible', False)
|
||||
if model.iter_parent(iter):
|
||||
if parent_iter:
|
||||
bgcolor = gajim.config.get_per('themes', theme, 'contactbgcolor')
|
||||
if bgcolor:
|
||||
renderer.set_property('cell-background', bgcolor)
|
||||
|
@ -228,6 +235,12 @@ class GroupchatControl(ChatControlBase):
|
|||
|
||||
self.tooltip = tooltips.GCTooltip()
|
||||
|
||||
# nickname coloring
|
||||
self.gc_count_nicknames_colors = 0
|
||||
self.gc_custom_colors = {}
|
||||
self.number_of_colors = len(gajim.config.get('gc_nicknames_colors').\
|
||||
split(':'))
|
||||
|
||||
# connect the menuitems to their respective functions
|
||||
xm = gtkgui_helpers.get_glade('gc_control_popup_menu.glade')
|
||||
|
||||
|
@ -301,6 +314,16 @@ class GroupchatControl(ChatControlBase):
|
|||
# first one img, second one text, third is sec pixbuf
|
||||
column = gtk.TreeViewColumn()
|
||||
|
||||
def add_avatar_renderer():
|
||||
renderer_pixbuf = gtk.CellRendererPixbuf() # avatar image
|
||||
column.pack_start(renderer_pixbuf, expand = False)
|
||||
column.add_attribute(renderer_pixbuf, 'pixbuf', C_AVATAR)
|
||||
column.set_cell_data_func(renderer_pixbuf, tree_cell_data_func,
|
||||
self.list_treeview)
|
||||
|
||||
if gajim.config.get('avatar_position_in_roster') == 'left':
|
||||
add_avatar_renderer()
|
||||
|
||||
renderer_image = cell_renderer_image.CellRendererImage(0, 0) # status img
|
||||
renderer_image.set_property('width', 26)
|
||||
column.pack_start(renderer_image, expand = False)
|
||||
|
@ -315,12 +338,8 @@ class GroupchatControl(ChatControlBase):
|
|||
column.set_cell_data_func(renderer_text, tree_cell_data_func,
|
||||
self.list_treeview)
|
||||
|
||||
renderer_pixbuf = gtk.CellRendererPixbuf() # avatar image
|
||||
column.pack_start(renderer_pixbuf, expand = False)
|
||||
column.add_attribute(renderer_pixbuf, 'pixbuf', C_AVATAR)
|
||||
column.set_cell_data_func(renderer_pixbuf, tree_cell_data_func,
|
||||
self.list_treeview)
|
||||
renderer_pixbuf.set_property('xalign', 1) # align pixbuf to the right
|
||||
if gajim.config.get('avatar_position_in_roster') == 'right':
|
||||
add_avatar_renderer()
|
||||
|
||||
self.list_treeview.append_column(column)
|
||||
|
||||
|
@ -639,9 +658,6 @@ class GroupchatControl(ChatControlBase):
|
|||
fin = True
|
||||
return None
|
||||
|
||||
gc_count_nicknames_colors = 0
|
||||
gc_custom_colors = {}
|
||||
|
||||
def print_old_conversation(self, text, contact = '', tim = None,
|
||||
xhtml = None):
|
||||
if isinstance(text, str):
|
||||
|
@ -692,9 +708,7 @@ class GroupchatControl(ChatControlBase):
|
|||
str(self.gc_custom_colors[contact]))
|
||||
else:
|
||||
self.gc_count_nicknames_colors += 1
|
||||
number_of_colors = len(gajim.config.get('gc_nicknames_colors').\
|
||||
split(':'))
|
||||
if self.gc_count_nicknames_colors == number_of_colors:
|
||||
if self.gc_count_nicknames_colors == self.number_of_colors:
|
||||
self.gc_count_nicknames_colors = 0
|
||||
self.gc_custom_colors[contact] = \
|
||||
self.gc_count_nicknames_colors
|
||||
|
@ -813,6 +827,13 @@ class GroupchatControl(ChatControlBase):
|
|||
return False
|
||||
else: # Special word == word, no char after in word
|
||||
return True
|
||||
for special_word in special_words:
|
||||
if special_word.find(' ') > -1:
|
||||
# There is a space in this special word, do a global search
|
||||
# without splitting by words as previously
|
||||
# We don't search this in all cases so we don't loose time
|
||||
if text.find(special_word) > -1:
|
||||
return True
|
||||
return False
|
||||
|
||||
def set_subject(self, subject):
|
||||
|
@ -1979,7 +2000,8 @@ class GroupchatControl(ChatControlBase):
|
|||
self.handlers[id] = item
|
||||
|
||||
item = xml.get_widget('add_to_roster_menuitem')
|
||||
if not jid:
|
||||
our_jid = gajim.get_jid_from_account(self.account)
|
||||
if not jid or jid == our_jid:
|
||||
item.set_sensitive(False)
|
||||
else:
|
||||
id = item.connect('activate', self.on_add_to_roster, jid)
|
||||
|
@ -2079,12 +2101,7 @@ class GroupchatControl(ChatControlBase):
|
|||
if not nick in gajim.contacts.get_nick_list(self.account,
|
||||
self.room_jid):
|
||||
# it's a group
|
||||
col = widget.get_column(0)
|
||||
avatar_cell = col.get_cell_renderers()[0]
|
||||
(pos, avatar_size) = col.cell_get_position(avatar_cell)
|
||||
status_cell = col.get_cell_renderers()[1]
|
||||
(pos, status_size) = col.cell_get_position(status_cell)
|
||||
if x > avatar_size and x < avatar_size + status_size:
|
||||
if x < 27:
|
||||
if (widget.row_expanded(path)):
|
||||
widget.collapse_row(path)
|
||||
else:
|
||||
|
@ -2142,6 +2159,9 @@ class GroupchatControl(ChatControlBase):
|
|||
self.tooltip.hide_tooltip()
|
||||
|
||||
def show_tooltip(self, contact):
|
||||
if not self.list_treeview.window:
|
||||
# control has been destroyed since tooltip was requested
|
||||
return
|
||||
pointer = self.list_treeview.get_pointer()
|
||||
props = self.list_treeview.get_path_at_pos(pointer[0], pointer[1])
|
||||
# check if the current pointer is at the same path
|
||||
|
|
|
@ -247,6 +247,11 @@ def move_window(window, x, y):
|
|||
x = 0
|
||||
if y < 0:
|
||||
y = 0
|
||||
w, h = window.get_size()
|
||||
if x + w > screen_w:
|
||||
x = screen_w - w
|
||||
if y + h > screen_h:
|
||||
y = screen_h - h
|
||||
window.move(x, y)
|
||||
|
||||
def resize_window(window, w, h):
|
||||
|
|
|
@ -100,7 +100,7 @@ class HistoryManager:
|
|||
self.logs_scrolledwindow = xml.get_widget('logs_scrolledwindow')
|
||||
self.search_results_scrolledwindow = xml.get_widget(
|
||||
'search_results_scrolledwindow')
|
||||
self.welcome_label = xml.get_widget('welcome_label')
|
||||
self.welcome_vbox = xml.get_widget('welcome_vbox')
|
||||
|
||||
self.jids_already_in = [] # holds jids that we already have in DB
|
||||
self.AT_LEAST_ONE_DELETION_DONE = False
|
||||
|
@ -236,7 +236,7 @@ class HistoryManager:
|
|||
|
||||
self.logs_liststore.clear() # clear the store
|
||||
|
||||
self.welcome_label.hide()
|
||||
self.welcome_vbox.hide()
|
||||
self.search_results_scrolledwindow.hide()
|
||||
self.logs_scrolledwindow.show()
|
||||
|
||||
|
@ -579,7 +579,7 @@ class HistoryManager:
|
|||
if text == '':
|
||||
return
|
||||
|
||||
self.welcome_label.hide()
|
||||
self.welcome_vbox.hide()
|
||||
self.logs_scrolledwindow.hide()
|
||||
self.search_results_scrolledwindow.show()
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ __version__ = '$Revision: 64 $'
|
|||
|
||||
from urllib import urlopen
|
||||
from xml.dom import minidom
|
||||
from time import time, strftime
|
||||
from time import time
|
||||
|
||||
class LastFM:
|
||||
# Where to fetch the played song information
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## message_control.py
|
||||
##
|
||||
## Copyright (C) 2006 Travis Shirk <travis@pobox.com>
|
||||
## Copyright (C) 2006-2007 Travis Shirk <travis@pobox.com>
|
||||
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
|
||||
##
|
||||
## This file is part of Gajim.
|
||||
|
@ -86,7 +86,7 @@ class MessageControl:
|
|||
pass # NOTE: Derived classes SHOULD implement this
|
||||
|
||||
def get_tab_label(self, chatstate):
|
||||
'''Return a suitable the tab label string. Returns a tuple such as:
|
||||
'''Return a suitable tab label string. Returns a tuple such as:
|
||||
(label_str, color) either of which can be None
|
||||
if chatstate is given that means we have HE SENT US a chatstate and
|
||||
we want it displayed'''
|
||||
|
@ -126,8 +126,8 @@ class MessageControl:
|
|||
if self.session.enable_encryption:
|
||||
was_encrypted = True
|
||||
|
||||
print "starting a new session, dropping the old one!"
|
||||
gajim.connections[self.account].delete_session(self.session.jid, self.session.thread_id)
|
||||
gajim.connections[self.account].delete_session(self.session.jid,
|
||||
self.session.thread_id)
|
||||
|
||||
self.session = session
|
||||
|
||||
|
|
|
@ -6,10 +6,9 @@
|
|||
## Vincent Hanquez <tab@snarc.org>
|
||||
## Nikos Kouremenos <kourem@gmail.com>
|
||||
## Dimitur Kirov <dkirov@gmail.com>
|
||||
## Travis Shirk <travis@pobox.com>
|
||||
## Norman Rasmussen <norman@rasmussen.co.za>
|
||||
## Copyright (C) 2006 Travis Shirk <travis@pobox.com>
|
||||
## Geobert Quach <geobert@gmail.com>
|
||||
## Copyright (C) 2005-2007 Travis Shirk <travis@pobox.com>
|
||||
## Copyright (C) 2006 Geobert Quach <geobert@gmail.com>
|
||||
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
|
||||
##
|
||||
## This file is part of Gajim.
|
||||
|
@ -39,7 +38,7 @@ from common import gajim
|
|||
|
||||
####################
|
||||
|
||||
class MessageWindow:
|
||||
class MessageWindow(object):
|
||||
'''Class for windows which contain message like things; chats,
|
||||
groupchats, etc.'''
|
||||
|
||||
|
@ -54,7 +53,7 @@ class MessageWindow:
|
|||
CLOSE_CTRL_KEY
|
||||
) = range(5)
|
||||
|
||||
def __init__(self, acct, type):
|
||||
def __init__(self, acct, type, parent_window=None, parent_paned=None):
|
||||
# A dictionary of dictionaries where _contacts[account][jid] == A MessageControl
|
||||
self._controls = {}
|
||||
# If None, the window is not tied to any specific account
|
||||
|
@ -68,6 +67,18 @@ class MessageWindow:
|
|||
self.widget_name = 'message_window'
|
||||
self.xml = gtkgui_helpers.get_glade('%s.glade' % self.widget_name)
|
||||
self.window = self.xml.get_widget(self.widget_name)
|
||||
self.notebook = self.xml.get_widget('notebook')
|
||||
self.parent_paned = None
|
||||
|
||||
if parent_window:
|
||||
orig_window = self.window
|
||||
self.window = parent_window
|
||||
self.parent_paned = parent_paned
|
||||
self.notebook.reparent(self.parent_paned)
|
||||
self.parent_paned.pack2(self.notebook, resize=True, shrink=True)
|
||||
orig_window.destroy()
|
||||
del orig_window
|
||||
|
||||
id = self.window.connect('delete-event', self._on_window_delete)
|
||||
self.handlers[id] = self.window
|
||||
id = self.window.connect('destroy', self._on_window_destroy)
|
||||
|
@ -91,7 +102,6 @@ class MessageWindow:
|
|||
self.window.add_events(gtk.gdk.POINTER_MOTION_MASK)
|
||||
self.alignment = self.xml.get_widget('alignment')
|
||||
|
||||
self.notebook = self.xml.get_widget('notebook')
|
||||
id = self.notebook.connect('switch-page',
|
||||
self._on_notebook_switch_page)
|
||||
self.handlers[id] = self.notebook
|
||||
|
@ -144,6 +154,9 @@ class MessageWindow:
|
|||
n += len(dict)
|
||||
return n
|
||||
|
||||
def resize(self, width, height):
|
||||
gtkgui_helpers.resize_window(self.window, width, height)
|
||||
|
||||
def _on_window_focus(self, widget, event):
|
||||
# window received focus, so if we had urgency REMOVE IT
|
||||
# NOTE: we do not have to read the message (it maybe in a bg tab)
|
||||
|
@ -179,6 +192,8 @@ class MessageWindow:
|
|||
for ctrl in self.controls():
|
||||
ctrl.shutdown()
|
||||
self._controls.clear()
|
||||
# Clean up handlers connected to the parent window, this is important since
|
||||
# self.window may be the RosterWindow
|
||||
for i in self.handlers.keys():
|
||||
if self.handlers[i].handler_is_connected(i):
|
||||
self.handlers[i].disconnect(i)
|
||||
|
@ -211,7 +226,8 @@ class MessageWindow:
|
|||
id = widget.connect('clicked', self._on_close_button_clicked, control)
|
||||
control.handlers[id] = widget
|
||||
|
||||
id = tab_label_box.connect('button-press-event', self.on_tab_eventbox_button_press_event, control.widget)
|
||||
id = tab_label_box.connect('button-press-event', self.on_tab_eventbox_button_press_event,
|
||||
control.widget)
|
||||
control.handlers[id] = tab_label_box
|
||||
self.notebook.append_page(control.widget, tab_label_box)
|
||||
|
||||
|
@ -222,6 +238,9 @@ class MessageWindow:
|
|||
self.setup_tab_dnd(control.widget)
|
||||
|
||||
self.redraw_tab(control)
|
||||
if self.parent_paned:
|
||||
self.notebook.show_all()
|
||||
else:
|
||||
self.window.show_all()
|
||||
# NOTE: we do not call set_control_active(True) since we don't know whether
|
||||
# the tab is the active one.
|
||||
|
@ -307,7 +326,7 @@ class MessageWindow:
|
|||
'''When close button is pressed: close a tab'''
|
||||
self.remove_tab(control, self.CLOSE_CLOSE_BUTTON)
|
||||
|
||||
def show_title(self, urgent = True, control = None):
|
||||
def show_title(self, urgent=True, control=None):
|
||||
'''redraw the window's title'''
|
||||
if not control:
|
||||
control = self.get_active_control()
|
||||
|
@ -341,10 +360,7 @@ class MessageWindow:
|
|||
name += '/' + control.resource
|
||||
|
||||
window_mode = gajim.interface.msg_win_mgr.mode
|
||||
|
||||
if self.get_num_controls() == 1:
|
||||
label = name
|
||||
elif window_mode == MessageWindowMgr.ONE_MSG_WINDOW_PERTYPE:
|
||||
if window_mode == MessageWindowMgr.ONE_MSG_WINDOW_PERTYPE:
|
||||
# Show the plural form since number of tabs > 1
|
||||
if self.type == 'chat':
|
||||
label = _('Chats')
|
||||
|
@ -352,9 +368,16 @@ class MessageWindow:
|
|||
label = _('Group Chats')
|
||||
else:
|
||||
label = _('Private Chats')
|
||||
elif window_mode == MessageWindowMgr.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER:
|
||||
label = None
|
||||
elif self.get_num_controls() == 1:
|
||||
label = name
|
||||
else:
|
||||
label = _('Messages')
|
||||
title = _('%s - Gajim') % label
|
||||
|
||||
title = 'Gajim'
|
||||
if label:
|
||||
title = _('%s - %s') % (label, title)
|
||||
|
||||
if window_mode == MessageWindowMgr.ONE_MSG_WINDOW_PERACCT:
|
||||
title = title + ": " + control.account
|
||||
|
@ -413,6 +436,11 @@ class MessageWindow:
|
|||
gajim.interface.msg_win_mgr._on_window_destroy(self.window)
|
||||
# dnd clean up
|
||||
self.notebook.drag_dest_unset()
|
||||
if self.parent_paned:
|
||||
# Don't close parent window, just remove the child
|
||||
child = self.parent_paned.get_child2()
|
||||
self.parent_paned.remove(child)
|
||||
else:
|
||||
self.window.destroy()
|
||||
return # don't show_title, we are dead
|
||||
elif self.get_num_controls() == 1: # we are going from two tabs to one
|
||||
|
@ -598,8 +626,8 @@ class MessageWindow:
|
|||
def _on_notebook_key_press(self, widget, event):
|
||||
control = self.get_active_control()
|
||||
# Ctrl+PageUP / DOWN has to be handled by notebook
|
||||
if event.state & gtk.gdk.CONTROL_MASK and event.keyval in (
|
||||
gtk.keysyms.Page_Down, gtk.keysyms.Page_Up):
|
||||
if (event.state & gtk.gdk.CONTROL_MASK and
|
||||
event.keyval in (gtk.keysyms.Page_Down, gtk.keysyms.Page_Up)):
|
||||
return False
|
||||
if isinstance(control, ChatControlBase):
|
||||
# we forwarded it to message textview
|
||||
|
@ -679,36 +707,53 @@ class MessageWindow:
|
|||
tab_label.disconnect(tab_label.dnd_handler)
|
||||
|
||||
################################################################################
|
||||
class MessageWindowMgr:
|
||||
class MessageWindowMgr(gobject.GObject):
|
||||
'''A manager and factory for MessageWindow objects'''
|
||||
__gsignals__ = {
|
||||
'window-delete': (gobject.SIGNAL_RUN_LAST, None, (object,)),
|
||||
}
|
||||
|
||||
# These constants map to common.config.opt_one_window_types indices
|
||||
(
|
||||
ONE_MSG_WINDOW_NEVER,
|
||||
ONE_MSG_WINDOW_ALWAYS,
|
||||
ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER,
|
||||
ONE_MSG_WINDOW_PERACCT,
|
||||
ONE_MSG_WINDOW_PERTYPE
|
||||
) = range(4)
|
||||
# A key constant for the main window for all messages
|
||||
ONE_MSG_WINDOW_PERTYPE,
|
||||
) = range(5)
|
||||
# A key constant for the main window in ONE_MSG_WINDOW_ALWAYS mode
|
||||
MAIN_WIN = 'main'
|
||||
# A key constant for the main window in ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER mode
|
||||
ROSTER_MAIN_WIN = 'roster'
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, parent_window, parent_paned):
|
||||
''' A dictionary of windows; the key depends on the config:
|
||||
ONE_MSG_WINDOW_NEVER: The key is the contact JID
|
||||
ONE_MSG_WINDOW_ALWAYS: The key is MessageWindowMgr.MAIN_WIN
|
||||
ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER: The key is MessageWindowMgr.MAIN_WIN
|
||||
ONE_MSG_WINDOW_PERACCT: The key is the account name
|
||||
ONE_MSG_WINDOW_PERTYPE: The key is a message type constant'''
|
||||
gobject.GObject.__init__(self)
|
||||
self._windows = {}
|
||||
|
||||
# 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)
|
||||
|
||||
self.parent_win = parent_window
|
||||
self.parent_paned = parent_paned
|
||||
|
||||
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)
|
||||
parent_win = None
|
||||
parent_paned = None
|
||||
if self.mode == self.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER:
|
||||
parent_win = self.parent_win
|
||||
parent_paned = self.parent_paned
|
||||
win = MessageWindow(acct, type, parent_win, parent_paned)
|
||||
# we track the lifetime of this window
|
||||
win.window.connect('delete-event', self._on_window_delete)
|
||||
win.window.connect('destroy', self._on_window_destroy)
|
||||
|
@ -729,7 +774,7 @@ class MessageWindowMgr:
|
|||
def has_window(self, jid, acct):
|
||||
return self.get_window(jid, acct) != None
|
||||
|
||||
def one_window_opened(self, contact, acct, type):
|
||||
def one_window_opened(self, contact=None, acct=None, type=None):
|
||||
try:
|
||||
return self._windows[self._mode_to_key(contact, acct, type)] != None
|
||||
except KeyError:
|
||||
|
@ -737,12 +782,13 @@ class MessageWindowMgr:
|
|||
|
||||
def _resize_window(self, win, acct, type):
|
||||
'''Resizes window according to config settings'''
|
||||
if not gajim.config.get('saveposition'):
|
||||
return
|
||||
|
||||
if self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
||||
if self.mode in (self.ONE_MSG_WINDOW_ALWAYS,
|
||||
self.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER):
|
||||
size = (gajim.config.get('msgwin-width'),
|
||||
gajim.config.get('msgwin-height'))
|
||||
if self.mode == self.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER:
|
||||
parent_size = win.window.get_size()
|
||||
size = (parent_size[0] + size[0], size[1])
|
||||
elif self.mode == self.ONE_MSG_WINDOW_PERACCT:
|
||||
size = (gajim.config.get_per('accounts', acct, 'msgwin-width'),
|
||||
gajim.config.get_per('accounts', acct, 'msgwin-height'))
|
||||
|
@ -754,13 +800,12 @@ class MessageWindowMgr:
|
|||
size = (gajim.config.get(opt_width), gajim.config.get(opt_height))
|
||||
else:
|
||||
return
|
||||
|
||||
gtkgui_helpers.resize_window(win.window, size[0], size[1])
|
||||
win.resize(size[0], size[1])
|
||||
|
||||
def _position_window(self, win, acct, type):
|
||||
'''Moves window according to config settings'''
|
||||
if not gajim.config.get('saveposition') or\
|
||||
self.mode == self.ONE_MSG_WINDOW_NEVER:
|
||||
if (self.mode in [self.ONE_MSG_WINDOW_NEVER,
|
||||
self.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER]):
|
||||
return
|
||||
|
||||
if self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
||||
|
@ -782,21 +827,22 @@ class MessageWindowMgr:
|
|||
key = acct + contact.jid
|
||||
if resource:
|
||||
key += '/' + resource
|
||||
elif self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
||||
key = self.MAIN_WIN
|
||||
elif self.mode == self.ONE_MSG_WINDOW_PERACCT:
|
||||
key = acct
|
||||
elif self.mode == self.ONE_MSG_WINDOW_PERTYPE:
|
||||
key = type
|
||||
return key
|
||||
elif self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
||||
return self.MAIN_WIN
|
||||
elif self.mode == self.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER:
|
||||
return self.ROSTER_MAIN_WIN
|
||||
elif self.mode == self.ONE_MSG_WINDOW_PERACCT:
|
||||
return acct
|
||||
elif self.mode == self.ONE_MSG_WINDOW_PERTYPE:
|
||||
return type
|
||||
|
||||
def create_window(self, contact, acct, type, resource = None):
|
||||
key = None
|
||||
win_acct = None
|
||||
win_type = None
|
||||
win_role = 'messages'
|
||||
win_role = None # X11 window role
|
||||
|
||||
key = self._mode_to_key(contact, acct, type, resource)
|
||||
win_key = self._mode_to_key(contact, acct, type, resource)
|
||||
if self.mode == self.ONE_MSG_WINDOW_PERACCT:
|
||||
win_acct = acct
|
||||
win_role = acct
|
||||
|
@ -806,21 +852,24 @@ class MessageWindowMgr:
|
|||
elif self.mode == self.ONE_MSG_WINDOW_NEVER:
|
||||
win_type = type
|
||||
win_role = contact.jid
|
||||
elif self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
||||
win_role = 'messages'
|
||||
|
||||
win = None
|
||||
try:
|
||||
win = self._windows[key]
|
||||
win = self._windows[win_key]
|
||||
except KeyError:
|
||||
win = self._new_window(win_acct, win_type)
|
||||
|
||||
if win_role:
|
||||
win.window.set_role(win_role)
|
||||
|
||||
# Position and size window based on saved state and window mode
|
||||
if not self.one_window_opened(contact, acct, type):
|
||||
self._position_window(win, acct, type)
|
||||
self._resize_window(win, acct, type)
|
||||
self._position_window(win, acct, type)
|
||||
|
||||
self._windows[key] = win
|
||||
self._windows[win_key] = win
|
||||
return win
|
||||
|
||||
def change_key(self, old_jid, new_jid, acct):
|
||||
|
@ -842,6 +891,7 @@ class MessageWindowMgr:
|
|||
def _on_window_destroy(self, win):
|
||||
for k in self._windows.keys():
|
||||
if self._windows[k].window == win:
|
||||
self.emit('window-delete', self._windows[k])
|
||||
del self._windows[k]
|
||||
return
|
||||
|
||||
|
@ -870,17 +920,16 @@ class MessageWindowMgr:
|
|||
for c in w.controls():
|
||||
yield c
|
||||
|
||||
def shutdown(self):
|
||||
def shutdown(self, width_adjust=0):
|
||||
for w in self.windows():
|
||||
self.save_state(w)
|
||||
self.save_state(w, width_adjust)
|
||||
if not w.parent_paned:
|
||||
w.window.hide()
|
||||
w.window.destroy()
|
||||
|
||||
gajim.interface.save_config()
|
||||
|
||||
def save_state(self, msg_win):
|
||||
if not gajim.config.get('saveposition'):
|
||||
return
|
||||
|
||||
def save_state(self, msg_win, width_adjust=0):
|
||||
# Save window size and position
|
||||
pos_x_key = 'msgwin-x-position'
|
||||
pos_y_key = 'msgwin-y-position'
|
||||
|
@ -907,6 +956,9 @@ class MessageWindowMgr:
|
|||
type = msg_win.type
|
||||
size_width_key = type + '-msgwin-width'
|
||||
size_height_key = type + '-msgwin-height'
|
||||
elif self.mode == self.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER:
|
||||
# Ignore any hpaned width
|
||||
width = msg_win.notebook.allocation.width
|
||||
|
||||
if acct:
|
||||
gajim.config.set_per('accounts', acct, size_width_key, width)
|
||||
|
@ -917,6 +969,7 @@ class MessageWindowMgr:
|
|||
gajim.config.set_per('accounts', acct, pos_y_key, y)
|
||||
|
||||
else:
|
||||
width += width_adjust
|
||||
gajim.config.set(size_width_key, width)
|
||||
gajim.config.set(size_height_key, height)
|
||||
|
||||
|
@ -937,6 +990,9 @@ class MessageWindowMgr:
|
|||
|
||||
controls = []
|
||||
for w in self.windows():
|
||||
# Note, we are taking care not to hide/delete the roster window when the
|
||||
# MessageWindow is embedded.
|
||||
if not w.parent_paned:
|
||||
w.window.hide()
|
||||
while w.notebook.get_n_pages():
|
||||
page = w.notebook.get_nth_page(0)
|
||||
|
@ -944,10 +1000,14 @@ class MessageWindowMgr:
|
|||
w.notebook.remove_page(0)
|
||||
page.unparent()
|
||||
controls.append(ctrl)
|
||||
# Must clear _controls from window to prevent
|
||||
# MessageControl.shutdown calls
|
||||
# Must clear _controls from window to prevent MessageControl.shutdown calls
|
||||
w._controls = {}
|
||||
if not w.parent_paned:
|
||||
w.window.destroy()
|
||||
else:
|
||||
# Don't close parent window, just remove the child
|
||||
child = w.parent_paned.get_child2()
|
||||
w.parent_paned.remove(child)
|
||||
|
||||
self._windows = {}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
## You should have received a copy of the GNU General Public License
|
||||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
import os
|
||||
import gobject
|
||||
if __name__ == '__main__':
|
||||
# install _() func before importing dbus_support
|
||||
|
@ -51,6 +52,13 @@ class MusicTrackListener(gobject.GObject):
|
|||
|
||||
bus = dbus.SessionBus()
|
||||
|
||||
## MPRIS
|
||||
bus.add_signal_receiver(self._mpris_music_track_change_cb, 'TrackChange',
|
||||
'org.freedesktop.MediaPlayer')
|
||||
bus.add_signal_receiver(self._mpris_playing_changed_cb, 'StatusChange',
|
||||
'org.freedesktop.MediaPlayer')
|
||||
|
||||
|
||||
## Muine
|
||||
bus.add_signal_receiver(self._muine_music_track_change_cb, 'SongChanged',
|
||||
'org.gnome.Muine.Player')
|
||||
|
@ -60,16 +68,18 @@ class MusicTrackListener(gobject.GObject):
|
|||
'org.gnome.Muine.Player')
|
||||
|
||||
## Rhythmbox
|
||||
bus.add_signal_receiver(self._rhythmbox_music_track_change_cb,
|
||||
'playingUriChanged', 'org.gnome.Rhythmbox.Player')
|
||||
bus.add_signal_receiver(self._player_name_owner_changed,
|
||||
'NameOwnerChanged', 'org.freedesktop.DBus', arg0='org.gnome.Rhythmbox')
|
||||
bus.add_signal_receiver(self._player_playing_changed_cb,
|
||||
bus.add_signal_receiver(self._rhythmbox_playing_changed_cb,
|
||||
'playingChanged', 'org.gnome.Rhythmbox.Player')
|
||||
bus.add_signal_receiver(self._player_playing_song_property_changed_cb,
|
||||
'playingSongPropertyChanged', 'org.gnome.Rhythmbox.Player')
|
||||
|
||||
## Banshee
|
||||
# Banshee sucks because it only supports polling.
|
||||
# Thus, we only register this is we are very sure that it's
|
||||
# installed.
|
||||
if os.name == 'posix' and os.system('which banshee >/dev/null 2>&1') == 0:
|
||||
banshee_bus = dbus.SessionBus()
|
||||
dubus = banshee_bus.get_object('org.freedesktop.DBus',
|
||||
'/org/freedesktop/dbus')
|
||||
|
@ -116,6 +126,40 @@ class MusicTrackListener(gobject.GObject):
|
|||
if b == 'rb:stream-song-title':
|
||||
self.emit('music-track-changed', self._last_playing_music)
|
||||
|
||||
def _mpris_properties_extract(self, song):
|
||||
info = MusicTrackInfo()
|
||||
|
||||
if song.has_key('title'):
|
||||
info.title = song['title']
|
||||
else:
|
||||
info.title = ''
|
||||
|
||||
if song.has_key('album'):
|
||||
info.album = song['album']
|
||||
else:
|
||||
info.album = ''
|
||||
|
||||
if song.has_key('artist'):
|
||||
info.artist = song['artist']
|
||||
else:
|
||||
info.artist = ''
|
||||
|
||||
if song.has_key('length'):
|
||||
info.duration = int(song['length'])
|
||||
else:
|
||||
info.duration = 0
|
||||
|
||||
return info
|
||||
|
||||
def _mpris_playing_changed_cb(self, playing):
|
||||
if playing == 0:
|
||||
self.emit('music-track-changed', self._last_playing_music)
|
||||
else:
|
||||
self.emit('music-track-changed', None)
|
||||
|
||||
def _mpris_music_track_change_cb(self, arg):
|
||||
self._last_playing_music = self._mpris_properties_extract(arg)
|
||||
|
||||
def _muine_properties_extract(self, song_string):
|
||||
d = dict((x.strip() for x in s1.split(':', 1)) for s1 in \
|
||||
song_string.split('\n'))
|
||||
|
@ -131,6 +175,13 @@ class MusicTrackListener(gobject.GObject):
|
|||
info = self._muine_properties_extract(arg)
|
||||
self.emit('music-track-changed', info)
|
||||
|
||||
def _rhythmbox_playing_changed_cb(self, playing):
|
||||
if playing:
|
||||
info = self.get_playing_track()
|
||||
self.emit('music-track-changed', info)
|
||||
else:
|
||||
self.emit('music-track-changed', None)
|
||||
|
||||
def _rhythmbox_properties_extract(self, props):
|
||||
info = MusicTrackInfo()
|
||||
info.title = props['title']
|
||||
|
@ -140,17 +191,6 @@ class MusicTrackListener(gobject.GObject):
|
|||
info.track_number = int(props['track-number'])
|
||||
return info
|
||||
|
||||
def _rhythmbox_music_track_change_cb(self, uri):
|
||||
if not uri:
|
||||
return
|
||||
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 _banshee_check_track_status(self):
|
||||
if self.dubus_methods.NameHasOwner('org.gnome.Banshee') and \
|
||||
not hasattr(self, 'banshee_methods'):
|
||||
|
|
|
@ -170,17 +170,25 @@ def notify(event, jid, account, parameters, advanced_notif_num = None):
|
|||
nickname = parameters[2]
|
||||
if gajim.config.get('notification_preview_message'):
|
||||
message = parameters[3]
|
||||
if message.startswith('/me ') or message.startswith('/me\n'):
|
||||
message = '* ' + nickname + message[3:]
|
||||
else:
|
||||
# We don't want message preview, do_preview = False
|
||||
message = ''
|
||||
focused = parameters[4]
|
||||
if helpers.allow_showing_notification(account, 'notify_on_new_message',
|
||||
advanced_notif_num, is_first_message):
|
||||
do_popup = True
|
||||
if is_first_message and helpers.allow_sound_notification(
|
||||
'first_message_received', advanced_notif_num):
|
||||
do_sound = True
|
||||
elif not is_first_message and helpers.allow_sound_notification(
|
||||
'next_message_received', advanced_notif_num):
|
||||
elif not is_first_message and focused and \
|
||||
helpers.allow_sound_notification('next_message_received_focused',
|
||||
advanced_notif_num):
|
||||
do_sound = True
|
||||
elif not is_first_message and not focused and \
|
||||
helpers.allow_sound_notification('next_message_received_unfocused',
|
||||
advanced_notif_num):
|
||||
do_sound = True
|
||||
else:
|
||||
print '*Event not implemeted yet*'
|
||||
|
@ -283,8 +291,10 @@ def notify(event, jid, account, parameters, advanced_notif_num = None):
|
|||
pass # do not set snd_event
|
||||
elif is_first_message:
|
||||
snd_event = 'first_message_received'
|
||||
elif focused:
|
||||
snd_event = 'next_message_received_focused'
|
||||
else:
|
||||
snd_event = 'next_message_received'
|
||||
snd_event = 'next_message_received_unfocused'
|
||||
elif event in ('contact_connected', 'contact_disconnected'):
|
||||
snd_event = event
|
||||
if snd_file:
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# dummy
|
|
@ -1 +0,0 @@
|
|||
# dummy
|
|
@ -1 +0,0 @@
|
|||
# dummy
|
|
@ -1 +0,0 @@
|
|||
# dummy
|
|
@ -114,6 +114,7 @@ static PyObject * idle_getIdleSec(PyObject *self, PyObject *args)
|
|||
else
|
||||
{
|
||||
printf("Couldn't grab properties of system\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (obj)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# dummy
|
|
@ -1 +0,0 @@
|
|||
# dummy
|
|
@ -6,6 +6,7 @@
|
|||
## Copyright (C) 2005-2006 Andrew Sayman <lorien420@myrealbox.com>
|
||||
## Copyright (C) 2007 Lukas Petrovicky <lukas@petrovicky.net>
|
||||
## Copyright (C) 2007 Julien Pivotto <roidelapluie@gmail.com>
|
||||
## Copyright (C) 2007 Travis Shirk <travis@pobox.com>
|
||||
##
|
||||
## This file is part of Gajim.
|
||||
##
|
||||
|
@ -373,7 +374,6 @@ class SignalObject(dbus.service.Object):
|
|||
if not specified status is changed for all accounts. '''
|
||||
if status not in ('offline', 'online', 'chat',
|
||||
'away', 'xa', 'dnd', 'invisible'):
|
||||
raise InvalidArgument
|
||||
return DBUS_BOOLEAN(False)
|
||||
if account:
|
||||
gobject.idle_add(gajim.interface.roster.send_status, account,
|
||||
|
@ -616,6 +616,9 @@ class SignalObject(dbus.service.Object):
|
|||
resource_props = dbus.Struct((DBUS_STRING(contact.resource),
|
||||
dbus.Int32(contact.priority), DBUS_STRING(contact.status)))
|
||||
contact_dict['resources'].append(resource_props)
|
||||
contact_dict['groups'] = dbus.Array([], signature='s')
|
||||
for group in prim_contact.groups:
|
||||
contact_dict['groups'].append(DBUS_STRING(group))
|
||||
return contact_dict
|
||||
|
||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s')
|
||||
|
@ -654,4 +657,4 @@ class SignalObject(dbus.service.Object):
|
|||
gajim.interface.instances[account]['join_gc'] = \
|
||||
JoinGroupchatWindow(account, room_jid, nick)
|
||||
else:
|
||||
gajim.connections[account].join_gc(nick, room_jid, password)
|
||||
gajim.interface.roster.join_gc_room(account, room_jid, nick, password)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,7 +22,6 @@
|
|||
import sys
|
||||
import gtk
|
||||
import systray
|
||||
import gobject
|
||||
|
||||
from common import gajim
|
||||
from common import helpers
|
||||
|
@ -60,7 +59,7 @@ class StatusIcon(systray.Systray):
|
|||
self.unsubscribe_events()
|
||||
|
||||
def on_status_icon_left_clicked(self, widget):
|
||||
gobject.idle_add(self.on_left_click)
|
||||
self.on_left_click()
|
||||
|
||||
def set_img(self):
|
||||
'''apart from image, we also update tooltip text here'''
|
||||
|
|
|
@ -254,14 +254,10 @@ class Systray:
|
|||
item = gtk.MenuItem(_('Hide this menu'))
|
||||
self.systray_context_menu.prepend(item)
|
||||
self.added_hide_menuitem = True
|
||||
self.systray_context_menu.popup(None, None,
|
||||
gtk.status_icon_position_menu, event_button,
|
||||
event_time, self.status_icon)
|
||||
|
||||
else: # GNU and Unices
|
||||
self.systray_context_menu.show_all()
|
||||
self.systray_context_menu.popup(None, None, None, event_button,
|
||||
event_time)
|
||||
self.systray_context_menu.show_all()
|
||||
|
||||
def on_show_all_events_menuitem_activate(self, widget):
|
||||
events = gajim.events.get_systray_events()
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
## tooltips.py
|
||||
##
|
||||
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov@gmail.com>
|
||||
|
@ -463,6 +464,10 @@ class RosterTooltip(NotificationAreaTooltip):
|
|||
contact.last_status_time)
|
||||
properties.append((self.table, None))
|
||||
else: # only one resource
|
||||
|
||||
#FIXME: User {Mood, Activity, Tune} not shown if there are
|
||||
#multiple resources
|
||||
#FIXME: User {Mood, Activity, Tune} not shown for self
|
||||
if contact.show:
|
||||
show = helpers.get_uf_show(contact.show)
|
||||
if contact.last_status_time:
|
||||
|
@ -494,6 +499,52 @@ class RosterTooltip(NotificationAreaTooltip):
|
|||
show = '<i>' + show + '</i>'
|
||||
# we append show below
|
||||
|
||||
if contact.mood.has_key('mood'):
|
||||
mood = contact.mood['mood'].strip()
|
||||
mood = gobject.markup_escape_text(mood)
|
||||
mood_string = _('Mood:') + ' <b>%s</b>' % mood
|
||||
if contact.mood.has_key('text') and contact.mood['text'] != '':
|
||||
mood_text = contact.mood['text'].strip()
|
||||
mood_text = gobject.markup_escape_text(mood_text)
|
||||
mood_string += ' (%s)' % mood_text
|
||||
properties.append((mood_string, None))
|
||||
|
||||
if contact.activity.has_key('activity'):
|
||||
activity = contact.activity['activity'].strip()
|
||||
activity = gobject.markup_escape_text(activity)
|
||||
activity_string = _('Activity:') + ' <b>%s' % activity
|
||||
if contact.activity.has_key('subactivity'):
|
||||
activity_sub = contact.activity['subactivity'].strip()
|
||||
activity_sub = gobject.markup_escape_text(activity_sub)
|
||||
activity_string += ' (%s)</b>' % activity_sub
|
||||
else:
|
||||
activity_string += '</b>'
|
||||
if contact.activity.has_key('text'):
|
||||
activity_text = contact.activity['text'].strip()
|
||||
activity_text = gobject.markup_escape_text(activity_text)
|
||||
activity_string += ' (%s)' % activity_text
|
||||
properties.append((activity_string, None))
|
||||
|
||||
if contact.tune.has_key('artist') or contact.tune.has_key('title'):
|
||||
if contact.tune.has_key('artist'):
|
||||
artist = contact.tune['artist'].strip()
|
||||
artist = gobject.markup_escape_text(artist)
|
||||
else:
|
||||
artist = _('Unknown Artist')
|
||||
if contact.tune.has_key('title'):
|
||||
title = contact.tune['title'].strip()
|
||||
title = gobject.markup_escape_text(title)
|
||||
else:
|
||||
title = _('Unknown Title')
|
||||
if contact.tune.has_key('source'):
|
||||
source = contact.tune['source'].strip()
|
||||
source = gobject.markup_escape_text(source)
|
||||
else:
|
||||
source = _('Unknown Source')
|
||||
tune_string = _('Tune:') + ' ' + _('<b>"%(title)s"</b> by <i>%(artist)s</i>\nfrom <i>%(source)s</i>' %\
|
||||
{'title': title, 'artist': artist, 'source': source})
|
||||
properties.append((tune_string, None))
|
||||
|
||||
if contact.status:
|
||||
status = contact.status.strip()
|
||||
if status:
|
||||
|
|
|
@ -178,8 +178,6 @@ class VcardWindow:
|
|||
pass
|
||||
|
||||
def set_values(self, vcard):
|
||||
if not 'PHOTO' in vcard:
|
||||
self.xml.get_widget('no_user_avatar_label').show()
|
||||
for i in vcard.keys():
|
||||
if i == 'PHOTO' and self.xml.get_widget('information_notebook').\
|
||||
get_n_pages() > 4:
|
||||
|
@ -187,6 +185,7 @@ class VcardWindow:
|
|||
get_avatar_pixbuf_encoded_mime(vcard[i])
|
||||
image = self.xml.get_widget('PHOTO_image')
|
||||
image.show()
|
||||
self.xml.get_widget('user_avatar_label').show()
|
||||
if not pixbuf:
|
||||
image.set_from_icon_name('stock_person',
|
||||
gtk.ICON_SIZE_DIALOG)
|
||||
|
|
Loading…
Add table
Reference in a new issue