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 \
|
echo "[encoding: UTF-8]" > po/POTFILES.in \
|
||||||
&& ls -1 -U data/gajim.desktop.in.in data/glade/*.glade \
|
&& 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
|
po/POTFILES.in || exit 1
|
||||||
if test -z `which pkg-config 2>/dev/null`;then
|
if test -z `which pkg-config 2>/dev/null`;then
|
||||||
echo "***Error: pkg-config not found***"
|
echo "***Error: pkg-config not found***"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
AC_INIT([Gajim - A Jabber Instant Messager],
|
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])
|
AC_PREREQ([2.59])
|
||||||
AM_INIT_AUTOMAKE([1.8])
|
AM_INIT_AUTOMAKE([1.8])
|
||||||
AC_CONFIG_HEADER(config.h)
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
|
@ -14,7 +14,13 @@ sounds_DATA = $(srcdir)/sounds/*.wav
|
||||||
otherdir = $(pkgdatadir)/data/other
|
otherdir = $(pkgdatadir)/data/other
|
||||||
other_DATA = other/servers.xml other/cacerts.pem
|
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) \
|
EXTRA_DIST = $(desktop_in_files) \
|
||||||
|
|
|
@ -17,6 +17,20 @@
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
|
@ -117,7 +117,7 @@ to the Jabber network.</property>
|
||||||
<widget class="GtkLabel" id="label270">
|
<widget class="GtkLabel" id="label270">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="xalign">0</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>
|
<property name="use_markup">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<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="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="label" translatable="yes">gtk-add</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_add_button_clicked"/>
|
<signal name="clicked" handler="on_add_button_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<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="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="label" translatable="yes">gtk-remove</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_remove_button_clicked"/>
|
<signal name="clicked" handler="on_remove_button_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
|
@ -79,6 +81,7 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">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="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"/>
|
<signal name="clicked" handler="on_rename_button_clicked"/>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkHBox" id="hbox8">
|
<widget class="GtkHBox" id="hbox8">
|
||||||
|
@ -138,6 +141,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="resize">False</property>
|
<property name="resize">False</property>
|
||||||
|
<property name="shrink">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -152,9 +156,6 @@
|
||||||
<property name="visible">True</property>
|
<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="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
|
@ -175,34 +176,135 @@
|
||||||
<property name="column_spacing">6</property>
|
<property name="column_spacing">6</property>
|
||||||
<property name="row_spacing">6</property>
|
<property name="row_spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkEntry" id="resource_entry1">
|
<widget class="GtkLabel" id="label2">
|
||||||
<property name="visible">True</property>
|
<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="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="invisible_char">*</property>
|
||||||
<property name="text" translatable="yes">Gajim</property>
|
<property name="activates_default">True</property>
|
||||||
<signal name="focus_out_event" handler="on_resource_entry1_focus_out_event"/>
|
<signal name="changed" handler="on_password_entry1_changed"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
<property name="right_attach">3</property>
|
<property name="right_attach">2</property>
|
||||||
<property name="top_attach">2</property>
|
<property name="top_attach">1</property>
|
||||||
<property name="bottom_attach">3</property>
|
<property name="bottom_attach">2</property>
|
||||||
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
<property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||||
<property name="y_options"></property>
|
<property name="y_options"></property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkEntry" id="jid_entry1">
|
<widget class="GtkCheckButton" id="save_password_checkbutton1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="invisible_char">*</property>
|
<property name="tooltip" translatable="yes">If checked, Gajim will remember the password for this account</property>
|
||||||
<property name="activates_default">True</property>
|
<property name="label" translatable="yes">Save pass_word</property>
|
||||||
<signal name="focus_out_event" handler="on_jid_entry1_focus_out_event"/>
|
<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>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<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="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>
|
<property name="y_options"></property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -222,6 +324,7 @@
|
||||||
<property name="tooltip" translatable="yes">Click to request authorization to all contacts of another account</property>
|
<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="label" translatable="yes">Synchronise contacts</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_synchronise_contacts_button1_clicked"/>
|
<signal name="clicked" handler="on_synchronise_contacts_button1_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
|
@ -235,6 +338,7 @@
|
||||||
<property name="tooltip" translatable="yes">Click to change account's password</property>
|
<property name="tooltip" translatable="yes">Click to change account's password</property>
|
||||||
<property name="label" translatable="yes">Chan_ge Password</property>
|
<property name="label" translatable="yes">Chan_ge Password</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_change_password_button1_clicked"/>
|
<signal name="clicked" handler="on_change_password_button1_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
|
@ -263,140 +367,38 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkSpinButton" id="priority_spinbutton1">
|
<widget class="GtkEntry" id="jid_entry1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">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="invisible_char">*</property>
|
||||||
<property name="activates_default">True</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>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
<property name="right_attach">2</property>
|
<property name="right_attach">3</property>
|
||||||
<property name="top_attach">1</property>
|
<property name="y_options"></property>
|
||||||
<property name="bottom_attach">2</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="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
|
||||||
<property name="y_options"></property>
|
<property name="y_options"></property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
</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>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label7">
|
<widget class="GtkLabel" id="label7">
|
||||||
|
@ -405,7 +407,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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="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="label" translatable="yes">C_onnect on Gajim startup</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_autoconnect_checkbutton_toggled"/>
|
<signal name="toggled" handler="on_autoconnect_checkbutton_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -435,6 +437,7 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Auto-reconnect when connection is lost</property>
|
<property name="label" translatable="yes">Auto-reconnect when connection is lost</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_autoreconnect_checkbutton_toggled"/>
|
<signal name="toggled" handler="on_autoreconnect_checkbutton_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -450,6 +453,7 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Save conversation _logs for all contacts</property>
|
<property name="label" translatable="yes">Save conversation _logs for all contacts</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="active">True</property>
|
<property name="active">True</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_log_history_checkbutton_toggled"/>
|
<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="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="label" translatable="yes">Synch_ronize account status with global status</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_sync_with_global_status_checkbutton_toggled"/>
|
<signal name="toggled" handler="on_sync_with_global_status_checkbutton_toggled"/>
|
||||||
</widget>
|
</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="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="label" translatable="yes">Use file transfer proxies</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_use_ft_proxies_checkbutton1_toggled"/>
|
<signal name="toggled" handler="on_use_ft_proxies_checkbutton1_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -495,7 +501,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -507,7 +512,6 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -517,29 +521,46 @@
|
||||||
<property name="border_width">6</property>
|
<property name="border_width">6</property>
|
||||||
<property name="spacing">12</property>
|
<property name="spacing">12</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkHBox" id="hbox2">
|
<widget class="GtkFrame" id="frame3">
|
||||||
<property name="visible">True</property>
|
<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="border_width">6</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label9">
|
<widget class="GtkCheckButton" id="use_env_http_proxy_checkbutton1">
|
||||||
<property name="visible">True</property>
|
<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>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="proxy_hbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkComboBox" id="proxies_combobox1">
|
<widget class="GtkComboBox" id="proxies_combobox1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="items" translatable="yes" comments="None means no proxy profile selected">None</property>
|
<property name="items" translatable="yes" comments="None means no proxy profile selected">None</property>
|
||||||
<signal name="changed" handler="on_proxies_combobox1_changed"/>
|
<signal name="changed" handler="on_proxies_combobox1_changed"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="manage_proxies_button1">
|
<widget class="GtkButton" id="manage_proxies_button1">
|
||||||
|
@ -547,19 +568,38 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Manage...</property>
|
<property name="label" translatable="yes">Manage...</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_manage_proxies_button1_clicked"/>
|
<signal name="clicked" handler="on_manage_proxies_button1_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="position">2</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<widget class="GtkFrame" id="misc_frame1">
|
<widget class="GtkFrame" id="misc_frame1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -575,14 +615,15 @@
|
||||||
<property name="border_width">6</property>
|
<property name="border_width">6</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkCheckButton" id="use_ssl_checkbutton1">
|
<widget class="GtkCheckButton" id="warn_when_insecure_connection_checkbutton1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">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="tooltip" translatable="yes">Check this so Gajim will ask you before sending your password over an insecure connection.</property>
|
||||||
<property name="label" translatable="yes">Use _SSL (legacy)</property>
|
<property name="label" translatable="yes">_Warn before using an insecure connection</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</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>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<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="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="label" translatable="yes">Send keep-alive packets</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="active">True</property>
|
<property name="active">True</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_send_keepalive_checkbutton1_toggled"/>
|
<signal name="toggled" handler="on_send_keepalive_checkbutton1_toggled"/>
|
||||||
|
@ -612,6 +654,7 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Use custom hostname/port</property>
|
<property name="label" translatable="yes">Use custom hostname/port</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_custom_host_port_checkbutton1_toggled"/>
|
<signal name="toggled" handler="on_custom_host_port_checkbutton1_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -700,7 +743,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -711,7 +753,6 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -766,6 +807,7 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Choose _Key...</property>
|
<property name="label" translatable="yes">Choose _Key...</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_gpg_choose_button_clicked"/>
|
<signal name="clicked" handler="on_gpg_choose_button_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<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="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="label" translatable="yes">Use GPG _Agent</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_use_gpg_agent_checkbutton_toggled"/>
|
<signal name="toggled" handler="on_use_gpg_agent_checkbutton_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -831,6 +875,7 @@
|
||||||
<property name="tooltip" translatable="yes">Information about you, as stored in the server</property>
|
<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="label" translatable="yes">Edit Personal Information...</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_edit_details_button1_clicked"/>
|
<signal name="clicked" handler="on_edit_details_button1_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
@ -855,7 +900,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -866,14 +910,12 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -892,6 +934,7 @@
|
||||||
<property name="can_focus">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="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="label" translatable="yes">Enable</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_enable_zeroconf_checkbutton2_toggled"/>
|
<signal name="toggled" handler="on_enable_zeroconf_checkbutton2_toggled"/>
|
||||||
</widget>
|
</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="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="label" translatable="yes">C_onnect on Gajim startup</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_autoconnect_checkbutton_toggled"/>
|
<signal name="toggled" handler="on_autoconnect_checkbutton_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -929,6 +973,7 @@
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Save conversation _logs for all contacts</property>
|
<property name="label" translatable="yes">Save conversation _logs for all contacts</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_log_history_checkbutton_toggled"/>
|
<signal name="toggled" handler="on_log_history_checkbutton_toggled"/>
|
||||||
</widget>
|
</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="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="label" translatable="yes">Synch_ronize account status with global status</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_sync_with_global_status_checkbutton_toggled"/>
|
<signal name="toggled" handler="on_sync_with_global_status_checkbutton_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -965,6 +1011,7 @@
|
||||||
You might consider to change possible firewall settings.</property>
|
You might consider to change possible firewall settings.</property>
|
||||||
<property name="label" translatable="yes">Use custom port:</property>
|
<property name="label" translatable="yes">Use custom port:</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_custom_port_checkbutton2_toggled"/>
|
<signal name="toggled" handler="on_custom_port_checkbutton2_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -994,9 +1041,6 @@ You might consider to change possible firewall settings.</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label11">
|
<widget class="GtkLabel" id="label11">
|
||||||
|
@ -1006,7 +1050,6 @@ You might consider to change possible firewall settings.</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -1018,125 +1061,6 @@ You might consider to change possible firewall settings.</property>
|
||||||
<property name="n_columns">2</property>
|
<property name="n_columns">2</property>
|
||||||
<property name="column_spacing">2</property>
|
<property name="column_spacing">2</property>
|
||||||
<property name="row_spacing">5</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>
|
<child>
|
||||||
<widget class="GtkVBox" id="vbox10">
|
<widget class="GtkVBox" id="vbox10">
|
||||||
<property name="visible">True</property>
|
<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="can_focus">True</property>
|
||||||
<property name="label" translatable="yes">Choose _Key...</property>
|
<property name="label" translatable="yes">Choose _Key...</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_gpg_choose_button_clicked"/>
|
<signal name="clicked" handler="on_gpg_choose_button_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<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="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="label" translatable="yes">Use GPG _Agent</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_use_gpg_agent_checkbutton_toggled"/>
|
<signal name="toggled" handler="on_use_gpg_agent_checkbutton_toggled"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -1215,10 +1142,128 @@ You might consider to change possible firewall settings.</property>
|
||||||
<property name="x_options">GTK_FILL</property>
|
<property name="x_options">GTK_FILL</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -1229,7 +1274,6 @@ You might consider to change possible firewall settings.</property>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -1241,7 +1285,6 @@ You might consider to change possible firewall settings.</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -1251,6 +1294,10 @@ You might consider to change possible firewall settings.</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="resize">True</property>
|
||||||
|
<property name="shrink">True</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</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="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="label" translatable="yes">Mer_ge accounts</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
<signal name="toggled" handler="on_merge_checkbutton_toggled"/>
|
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
||||||
<property name="visible">True</property>
|
<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="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="label" translatable="yes">gtk-close</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
<signal name="clicked" handler="on_close_button_clicked"/>
|
<signal name="clicked" handler="on_close_button_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</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">
|
<widget class="GtkVBox" id="vbox1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkVBox" id="vbox2">
|
<widget class="GtkVBox" id="welcome_vbox">
|
||||||
<property name="visible">True</property>
|
<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="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
<child>
|
<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>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<widget class="GtkScrolledWindow" id="message_scrolledwindow">
|
<widget class="GtkScrolledWindow" id="message_scrolledwindow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -119,6 +133,11 @@
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
|
@ -136,38 +155,6 @@
|
||||||
<widget class="GtkHBox" id="hbox3006">
|
<widget class="GtkHBox" id="hbox3006">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="spacing">1</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>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -399,6 +386,7 @@
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkVBox" id="muc_child_vbox">
|
<widget class="GtkVBox" id="muc_child_vbox">
|
||||||
|
<property name="can_focus">True</property>
|
||||||
<property name="border_width">3</property>
|
<property name="border_width">3</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkAlignment" id="alignment103">
|
<widget class="GtkAlignment" id="alignment103">
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -193,6 +193,14 @@
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</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>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -222,6 +230,17 @@
|
||||||
<signal name="activate" handler="on_show_transports_menuitem_activate"/>
|
<signal name="activate" handler="on_show_transports_menuitem_activate"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<widget class="GtkSeparatorMenuItem" id="separator3">
|
<widget class="GtkSeparatorMenuItem" id="separator3">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -343,6 +362,15 @@
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<widget class="GtkScrolledWindow" id="scrolledwindow">
|
<widget class="GtkScrolledWindow" id="scrolledwindow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -369,9 +397,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkComboBox" id="status_combobox">
|
<widget class="GtkComboBox" id="status_combobox">
|
||||||
|
@ -380,7 +405,21 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<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>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
<property name="xpad">5</property>
|
<property name="xpad">5</property>
|
||||||
<property name="ypad">5</property>
|
<property name="ypad">5</property>
|
||||||
<property name="selectable">True</property>
|
<property name="selectable">True</property>
|
||||||
|
<property name="ellipsize">PANGO_ELLIPSIZE_END</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -94,6 +95,7 @@
|
||||||
<property name="xpad">5</property>
|
<property name="xpad">5</property>
|
||||||
<property name="ypad">5</property>
|
<property name="ypad">5</property>
|
||||||
<property name="selectable">True</property>
|
<property name="selectable">True</property>
|
||||||
|
<property name="ellipsize">PANGO_ELLIPSIZE_END</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
|
@ -218,8 +220,8 @@
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="spacing">6</property>
|
<property name="spacing">6</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label59">
|
<widget class="GtkLabel" id="user_avatar_label">
|
||||||
<property name="visible">True</property>
|
<property name="no_show_all">True</property>
|
||||||
<property name="label" translatable="yes">User avatar:</property>
|
<property name="label" translatable="yes">User avatar:</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
|
@ -227,17 +229,6 @@
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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>
|
<child>
|
||||||
<widget class="GtkEventBox" id="PHOTO_eventbox">
|
<widget class="GtkEventBox" id="PHOTO_eventbox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -254,7 +245,7 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="position">2</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -265,7 +256,7 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="position">3</property>
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -277,11 +268,12 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">False</property>
|
||||||
<property name="position">4</property>
|
<property name="position">3</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -384,9 +376,6 @@
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label3">
|
<widget class="GtkLabel" id="label3">
|
||||||
|
@ -397,7 +386,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -1014,7 +1002,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -1027,7 +1014,6 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -1459,7 +1445,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -1472,7 +1457,6 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -1497,7 +1481,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -1510,7 +1493,6 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -1533,7 +1515,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">4</property>
|
<property name="position">4</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -1544,7 +1525,6 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">4</property>
|
<property name="position">4</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -1588,6 +1568,7 @@
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</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
|
#: ../src/filetransfers_window.py:87
|
||||||
msgid "Time"
|
msgid "Time"
|
||||||
msgstr "Moment"
|
msgstr "Durée"
|
||||||
|
|
||||||
#: ../src/filetransfers_window.py:99
|
#: ../src/filetransfers_window.py:99
|
||||||
msgid "Progress"
|
msgid "Progress"
|
||||||
|
@ -6537,6 +6537,406 @@ msgstr "Connecté"
|
||||||
msgid "Disconnected"
|
msgid "Disconnected"
|
||||||
msgstr "Déconnecté"
|
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"
|
#~ msgid "2003-12-13T18:30:02Z"
|
||||||
#~ msgstr "2003-12-13T18:30:02Z"
|
#~ msgstr "2003-12-13T18:30:02Z"
|
||||||
#~ msgid "<small>Romeo and Juliet</small>"
|
#~ msgid "<small>Romeo and Juliet</small>"
|
||||||
|
|
|
@ -44,26 +44,26 @@ trayicon.c:
|
||||||
$(srcdir)/trayicon.defs > $@
|
$(srcdir)/trayicon.defs > $@
|
||||||
endif
|
endif
|
||||||
gajimsrcdir = $(pkgdatadir)/src
|
gajimsrcdir = $(pkgdatadir)/src
|
||||||
gajimsrc_DATA = $(srcdir)/*.py
|
gajimsrc_PYTHON = $(srcdir)/*.py
|
||||||
|
|
||||||
gajimsrc1dir = $(pkgdatadir)/src/common
|
gajimsrc1dir = $(pkgdatadir)/src/common
|
||||||
gajimsrc1_DATA = \
|
gajimsrc1_PYTHON = \
|
||||||
$(srcdir)/common/*.py
|
$(srcdir)/common/*.py
|
||||||
|
|
||||||
gajimsrc2dir = $(pkgdatadir)/src/common/xmpp
|
gajimsrc2dir = $(pkgdatadir)/src/common/xmpp
|
||||||
gajimsrc2_DATA = \
|
gajimsrc2_PYTHON = \
|
||||||
$(srcdir)/common/xmpp/*.py
|
$(srcdir)/common/xmpp/*.py
|
||||||
|
|
||||||
gajimsrc3dir = $(pkgdatadir)/src/common/zeroconf
|
gajimsrc3dir = $(pkgdatadir)/src/common/zeroconf
|
||||||
gajimsrc3_DATA = \
|
gajimsrc3_PYTHON = \
|
||||||
$(srcdir)/common/zeroconf/*.py
|
$(srcdir)/common/zeroconf/*.py
|
||||||
|
|
||||||
DISTCLEANFILES =
|
DISTCLEANFILES =
|
||||||
|
|
||||||
EXTRA_DIST = $(gajimsrc_DATA) \
|
EXTRA_DIST = $(gajimsrc_PYTHON) \
|
||||||
$(gajimsrc1_DATA) \
|
$(gajimsrc1_PYTHON) \
|
||||||
$(gajimsrc2_DATA) \
|
$(gajimsrc2_PYTHON) \
|
||||||
$(gajimsrc3_DATA) \
|
$(gajimsrc3_PYTHON) \
|
||||||
gtkspellmodule.c \
|
gtkspellmodule.c \
|
||||||
eggtrayicon.c \
|
eggtrayicon.c \
|
||||||
trayiconmodule.c \
|
trayiconmodule.c \
|
||||||
|
|
|
@ -151,7 +151,7 @@ class ChatControlBase(MessageControl):
|
||||||
self._on_banner_eventbox_button_press_event)
|
self._on_banner_eventbox_button_press_event)
|
||||||
self.handlers[id] = widget
|
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:
|
if gajim.HAVE_PYSEXY:
|
||||||
import sexy
|
import sexy
|
||||||
|
@ -1018,6 +1018,10 @@ class ChatControl(ChatControlBase):
|
||||||
self.widget_set_visible(self.xml.get_widget('banner_eventbox'),
|
self.widget_set_visible(self.xml.get_widget('banner_eventbox'),
|
||||||
gajim.config.get('hide_chat_banner'))
|
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
|
# 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
|
# it is on enter-notify and leave-notify so no need to be per jid
|
||||||
self.show_bigger_avatar_timeout_id = None
|
self.show_bigger_avatar_timeout_id = None
|
||||||
|
@ -1050,15 +1054,25 @@ class ChatControl(ChatControlBase):
|
||||||
self.on_avatar_eventbox_button_press_event)
|
self.on_avatar_eventbox_button_press_event)
|
||||||
self.handlers[id] = widget
|
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)
|
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.status_tooltip = gtk.Tooltips()
|
||||||
self.update_ui()
|
self.update_ui()
|
||||||
# restore previous conversation
|
# restore previous conversation
|
||||||
|
@ -1164,8 +1178,6 @@ class ChatControl(ChatControlBase):
|
||||||
gtk.gdk.INTERP_BILINEAR)
|
gtk.gdk.INTERP_BILINEAR)
|
||||||
banner_status_img.set_from_pixbuf(scaled_pix)
|
banner_status_img.set_from_pixbuf(scaled_pix)
|
||||||
|
|
||||||
self._update_gpg()
|
|
||||||
|
|
||||||
def draw_banner_text(self):
|
def draw_banner_text(self):
|
||||||
'''Draw the text in the fat line at the top of the window that
|
'''Draw the text in the fat line at the top of the window that
|
||||||
houses the name, jid.
|
houses the name, jid.
|
||||||
|
@ -1254,34 +1266,52 @@ class ChatControl(ChatControlBase):
|
||||||
# setup the label that holds name and jid
|
# setup the label that holds name and jid
|
||||||
banner_name_label.set_markup(label_text)
|
banner_name_label.set_markup(label_text)
|
||||||
|
|
||||||
def on_toggle_gpg_togglebutton(self, widget):
|
def _toggle_gpg(self):
|
||||||
gajim.config.set_per('contacts', self.contact.jid, 'gpg_enabled',
|
ec = gajim.encrypted_chats[self.account]
|
||||||
widget.get_active())
|
if self.gpg_is_active:
|
||||||
|
# Disable encryption
|
||||||
def _update_gpg(self):
|
ec.remove(self.contact.jid)
|
||||||
tb = self.xml.get_widget('gpg_togglebutton')
|
self.gpg_is_active = False
|
||||||
# we can do gpg
|
msg = _('GPG encryption disabled')
|
||||||
# if self.contact is our own contact info (transports),
|
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||||
# don't enable pgp
|
if self.session:
|
||||||
if self.contact.keyID and not gajim.jid_is_transport(self.contact.jid):
|
self.session.loggable = True
|
||||||
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)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
tb.set_sensitive(False)
|
# Enable encryption
|
||||||
#we talk about a contact here
|
ec.append(self.contact.jid)
|
||||||
tt = _('%s has not broadcast an OpenPGP key, nor has one been assigned') %\
|
self.gpg_is_active = True
|
||||||
self.contact.get_shown_name()
|
msg = _('GPG encryption enabled')
|
||||||
gtk.Tooltips().set_tip(self.xml.get_widget('gpg_eventbox'), tt)
|
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):
|
def _process_command(self, message):
|
||||||
if message[0] != '/':
|
if message[0] != '/':
|
||||||
|
@ -1369,9 +1399,11 @@ class ChatControl(ChatControlBase):
|
||||||
encrypted = bool(self.session) and self.session.enable_encryption
|
encrypted = bool(self.session) and self.session.enable_encryption
|
||||||
|
|
||||||
keyID = ''
|
keyID = ''
|
||||||
if self.xml.get_widget('gpg_togglebutton').get_active():
|
if self.gpg_is_active:
|
||||||
keyID = contact.keyID
|
keyID = contact.keyID
|
||||||
encrypted = True
|
encrypted = True
|
||||||
|
if not keyID:
|
||||||
|
keyID = 'UNKNOWN'
|
||||||
|
|
||||||
chatstates_on = gajim.config.get('outgoing_chat_state_notifications') != \
|
chatstates_on = gajim.config.get('outgoing_chat_state_notifications') != \
|
||||||
'disabled'
|
'disabled'
|
||||||
|
@ -1468,13 +1500,14 @@ class ChatControl(ChatControlBase):
|
||||||
msg = _('Session negotiation cancelled')
|
msg = _('Session negotiation cancelled')
|
||||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||||
|
|
||||||
# print esession settings to textview
|
|
||||||
def print_esession_details(self):
|
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')
|
msg = _('E2E encryption enabled')
|
||||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
||||||
|
|
||||||
if self.session.loggable:
|
if self.session.is_loggable():
|
||||||
msg = _('Session WILL be logged')
|
msg = _('Session WILL be logged')
|
||||||
else:
|
else:
|
||||||
msg = _('Session WILL NOT be logged')
|
msg = _('Session WILL NOT be logged')
|
||||||
|
@ -1483,6 +1516,8 @@ class ChatControl(ChatControlBase):
|
||||||
else:
|
else:
|
||||||
msg = _('E2E encryption disabled')
|
msg = _('E2E encryption disabled')
|
||||||
ChatControlBase.print_conversation_line(self, msg, 'status', '', None)
|
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,
|
def print_conversation(self, text, frm = '', tim = None,
|
||||||
encrypted = False, subject = None, xhtml = None):
|
encrypted = False, subject = None, xhtml = None):
|
||||||
|
@ -1510,19 +1545,15 @@ class ChatControl(ChatControlBase):
|
||||||
'status', '', tim)
|
'status', '', tim)
|
||||||
else:
|
else:
|
||||||
# GPG encryption
|
# GPG encryption
|
||||||
ec = gajim.encrypted_chats[self.account]
|
if encrypted and not self.gpg_is_active:
|
||||||
if encrypted and jid not in ec:
|
msg = _('The following message was encrypted')
|
||||||
msg = _('OpenPGP Encryption enabled')
|
|
||||||
ChatControlBase.print_conversation_line(self, msg,
|
ChatControlBase.print_conversation_line(self, msg,
|
||||||
'status', '', tim)
|
'status', '', tim)
|
||||||
ec.append(jid)
|
self._toggle_gpg()
|
||||||
elif not encrypted and jid in ec:
|
elif not encrypted and self.gpg_is_active:
|
||||||
msg = _('OpenPGP Encryption disabled')
|
msg = _('The following message was NOT encrypted')
|
||||||
ChatControlBase.print_conversation_line(self, msg,
|
ChatControlBase.print_conversation_line(self, msg,
|
||||||
'status', '', tim)
|
'status', '', tim)
|
||||||
ec.remove(jid)
|
|
||||||
self.xml.get_widget('gpg_togglebutton').set_active(encrypted)
|
|
||||||
|
|
||||||
if not frm:
|
if not frm:
|
||||||
kind = 'incoming'
|
kind = 'incoming'
|
||||||
name = contact.get_shown_name()
|
name = contact.get_shown_name()
|
||||||
|
@ -1650,12 +1681,15 @@ class ChatControl(ChatControlBase):
|
||||||
contact = self.parent_win.get_active_contact()
|
contact = self.parent_win.get_active_contact()
|
||||||
jid = contact.jid
|
jid = contact.jid
|
||||||
|
|
||||||
# check if gpg capabitlies or else make gpg toggle insensitive
|
# check if we support and use gpg
|
||||||
gpg_btn = self.xml.get_widget('gpg_togglebutton')
|
if not gajim.config.get_per('accounts', self.account, 'keyid') or\
|
||||||
isactive = gpg_btn.get_active()
|
not gajim.connections[self.account].USE_GPG or\
|
||||||
is_sensitive = gpg_btn.get_property('sensitive')
|
gajim.jid_is_transport(jid):
|
||||||
toggle_gpg_menuitem.set_active(isactive)
|
toggle_gpg_menuitem.set_sensitive(False)
|
||||||
toggle_gpg_menuitem.set_property('sensitive', is_sensitive)
|
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
|
# TODO: check that the remote client supports e2e
|
||||||
if not gajim.HAVE_PYCRYPTO:
|
if not gajim.HAVE_PYCRYPTO:
|
||||||
|
@ -1663,6 +1697,7 @@ class ChatControl(ChatControlBase):
|
||||||
else:
|
else:
|
||||||
isactive = int(self.session != None and self.session.enable_encryption)
|
isactive = int(self.session != None and self.session.enable_encryption)
|
||||||
toggle_e2e_menuitem.set_active(isactive)
|
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
|
# If we don't have resource, we can't do file transfer
|
||||||
# in transports, contact holds our info we need to disable it too
|
# 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
|
self.handlers[id] = add_to_roster_menuitem
|
||||||
id = toggle_gpg_menuitem.connect('activate',
|
id = toggle_gpg_menuitem.connect('activate',
|
||||||
self._on_toggle_gpg_menuitem_activate)
|
self._on_toggle_gpg_menuitem_activate)
|
||||||
|
self.handlers[id] = toggle_gpg_menuitem
|
||||||
id = toggle_e2e_menuitem.connect('activate',
|
id = toggle_e2e_menuitem.connect('activate',
|
||||||
self._on_toggle_e2e_menuitem_activate)
|
self._on_toggle_e2e_menuitem_activate)
|
||||||
self.handlers[id] = toggle_gpg_menuitem
|
self.handlers[id] = toggle_e2e_menuitem
|
||||||
id = information_menuitem.connect('activate',
|
id = information_menuitem.connect('activate',
|
||||||
self._on_contact_information_menuitem_activate)
|
self._on_contact_information_menuitem_activate)
|
||||||
self.handlers[id] = information_menuitem
|
self.handlers[id] = information_menuitem
|
||||||
|
@ -2154,10 +2190,7 @@ class ChatControl(ChatControlBase):
|
||||||
gajim.interface.roster.on_info(widget, self.contact, self.account)
|
gajim.interface.roster.on_info(widget, self.contact, self.account)
|
||||||
|
|
||||||
def _on_toggle_gpg_menuitem_activate(self, widget):
|
def _on_toggle_gpg_menuitem_activate(self, widget):
|
||||||
# update the button
|
self._toggle_gpg()
|
||||||
# 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())
|
|
||||||
|
|
||||||
def _on_convert_to_gc_menuitem_activate(self, widget):
|
def _on_convert_to_gc_menuitem_activate(self, widget):
|
||||||
'''user want to invite some friends to chat'''
|
'''user want to invite some friends to chat'''
|
||||||
|
|
|
@ -28,24 +28,12 @@
|
||||||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
##
|
##
|
||||||
|
|
||||||
import os
|
import gajim
|
||||||
from os import tmpfile
|
from os import tmpfile
|
||||||
from common import helpers
|
from common import helpers
|
||||||
|
|
||||||
USE_GPG = True
|
if gajim.HAVE_GPG:
|
||||||
|
import GnuPGInterface
|
||||||
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
|
|
||||||
|
|
||||||
class GnuPG(GnuPGInterface.GnuPG):
|
class GnuPG(GnuPGInterface.GnuPG):
|
||||||
def __init__(self, use_agent = False):
|
def __init__(self, use_agent = False):
|
||||||
|
@ -57,8 +45,6 @@ else:
|
||||||
self.options.armor = 1
|
self.options.armor = 1
|
||||||
self.options.meta_interactive = 0
|
self.options.meta_interactive = 0
|
||||||
self.options.extra_args.append('--no-secmem-warning')
|
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:
|
if self.use_agent:
|
||||||
self.options.extra_args.append('--use-agent')
|
self.options.extra_args.append('--use-agent')
|
||||||
|
|
||||||
|
@ -88,8 +74,6 @@ else:
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def encrypt(self, str, recipients):
|
def encrypt(self, str, recipients):
|
||||||
if not USE_GPG:
|
|
||||||
return str, 'GnuPG not usable'
|
|
||||||
self.options.recipients = recipients # a list!
|
self.options.recipients = recipients # a list!
|
||||||
|
|
||||||
proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout', 'status',
|
proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout', 'status',
|
||||||
|
@ -125,8 +109,6 @@ else:
|
||||||
return self._stripHeaderFooter(output), error
|
return self._stripHeaderFooter(output), error
|
||||||
|
|
||||||
def decrypt(self, str, keyID):
|
def decrypt(self, str, keyID):
|
||||||
if not USE_GPG:
|
|
||||||
return str
|
|
||||||
proc = self.run(['--decrypt', '-q', '-u %s'%keyID], create_fhs=['stdin', 'stdout'])
|
proc = self.run(['--decrypt', '-q', '-u %s'%keyID], create_fhs=['stdin', 'stdout'])
|
||||||
enc = self._addHeaderFooter(str, 'MESSAGE')
|
enc = self._addHeaderFooter(str, 'MESSAGE')
|
||||||
proc.handles['stdin'].write(enc)
|
proc.handles['stdin'].write(enc)
|
||||||
|
@ -140,8 +122,6 @@ else:
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def sign(self, str, keyID):
|
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 = self.run(['-b', '-u %s'%keyID], create_fhs=['stdin', 'stdout', 'status', 'stderr'])
|
||||||
proc.handles['stdin'].write(str)
|
proc.handles['stdin'].write(str)
|
||||||
try:
|
try:
|
||||||
|
@ -170,8 +150,6 @@ else:
|
||||||
return 'BAD_PASSPHRASE'
|
return 'BAD_PASSPHRASE'
|
||||||
|
|
||||||
def verify(self, str, sign):
|
def verify(self, str, sign):
|
||||||
if not USE_GPG:
|
|
||||||
return str
|
|
||||||
if str == None:
|
if str == None:
|
||||||
return ''
|
return ''
|
||||||
f = tmpfile()
|
f = tmpfile()
|
||||||
|
@ -200,8 +178,6 @@ else:
|
||||||
return keyid
|
return keyid
|
||||||
|
|
||||||
def get_keys(self, secret = False):
|
def get_keys(self, secret = False):
|
||||||
if not USE_GPG:
|
|
||||||
return {}
|
|
||||||
if secret:
|
if secret:
|
||||||
opt = '--list-secret-keys'
|
opt = '--list-secret-keys'
|
||||||
else:
|
else:
|
||||||
|
@ -217,8 +193,10 @@ else:
|
||||||
sline = line.split(':')
|
sline = line.split(':')
|
||||||
if (sline[0] == 'sec' and secret) or \
|
if (sline[0] == 'sec' and secret) or \
|
||||||
(sline[0] == 'pub' and not secret):
|
(sline[0] == 'pub' and not secret):
|
||||||
|
# decode escaped chars
|
||||||
|
name = eval('"' + sline[9].replace('"', '\\"') + '"')
|
||||||
# make it unicode instance
|
# make it unicode instance
|
||||||
keys[sline[4][8:]] = helpers.decode_string(sline[9])
|
keys[sline[4][8:]] = helpers.decode_string(name)
|
||||||
return keys
|
return keys
|
||||||
try: proc.wait()
|
try: proc.wait()
|
||||||
except IOError: pass
|
except IOError: pass
|
||||||
|
|
|
@ -45,7 +45,7 @@ opt_int = [ 'integer', 0 ]
|
||||||
opt_str = [ 'string', 0 ]
|
opt_str = [ 'string', 0 ]
|
||||||
opt_bool = [ 'boolean', 0 ]
|
opt_bool = [ 'boolean', 0 ]
|
||||||
opt_color = [ 'color', '^(#[0-9a-fA-F]{6})|()$' ]
|
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']
|
opt_treat_incoming_messages = ['', 'chat', 'normal']
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
@ -100,7 +100,6 @@ class Config:
|
||||||
'urlmsgcolor': [ opt_color, '#0000ff', '', True ],
|
'urlmsgcolor': [ opt_color, '#0000ff', '', True ],
|
||||||
'collapsed_rows': [ opt_str, '', _('List (space separated) of rows (accounts and groups) that are collapsed.'), True ],
|
'collapsed_rows': [ opt_str, '', _('List (space separated) of rows (accounts and groups) that are collapsed.'), True ],
|
||||||
'roster_theme': [ opt_str, _('default'), '', True ],
|
'roster_theme': [ opt_str, _('default'), '', True ],
|
||||||
'saveposition': [ opt_bool, True ],
|
|
||||||
'mergeaccounts': [ opt_bool, False, '', True ],
|
'mergeaccounts': [ opt_bool, False, '', True ],
|
||||||
'sort_by_show': [ opt_bool, True, '', True ],
|
'sort_by_show': [ opt_bool, True, '', True ],
|
||||||
'enable_zeroconf': [opt_bool, False, _('Enable link-local/zeroconf messaging')],
|
'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_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_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],
|
'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.')],
|
'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_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.')],
|
'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.')],
|
'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',
|
'one_message_window': [opt_str, 'always',
|
||||||
#always, never, peracct, pertype should not be translated
|
#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.')],
|
'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.')],
|
'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.')],
|
'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.')],
|
'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.')],
|
'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.')],
|
'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.')],
|
'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 = {
|
__options_per_key = {
|
||||||
|
@ -275,7 +282,8 @@ class Config:
|
||||||
'keyid': [ opt_str, '', '', True ],
|
'keyid': [ opt_str, '', '', True ],
|
||||||
'gpg_sign_presence': [ opt_bool, True, _('If disabled, don\'t sign presences with GPG key, even if GPG is configured.') ],
|
'gpg_sign_presence': [ opt_bool, True, _('If disabled, don\'t sign presences with GPG key, even if GPG is configured.') ],
|
||||||
'keyname': [ opt_str, '', '', True ],
|
'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 ],
|
'ssl_fingerprint_sha1': [ opt_str, '', '', True ],
|
||||||
'use_srv': [ opt_bool, True, '', True ],
|
'use_srv': [ opt_bool, True, '', True ],
|
||||||
'use_custom_host': [ opt_bool, False, '', True ],
|
'use_custom_host': [ opt_bool, False, '', True ],
|
||||||
|
@ -306,6 +314,7 @@ class Config:
|
||||||
'zeroconf_last_name': [ opt_str, '', '', True ],
|
'zeroconf_last_name': [ opt_str, '', '', True ],
|
||||||
'zeroconf_jabber_id': [ opt_str, '', '', True ],
|
'zeroconf_jabber_id': [ opt_str, '', '', True ],
|
||||||
'zeroconf_email': [ opt_str, '', '', True ],
|
'zeroconf_email': [ opt_str, '', '', True ],
|
||||||
|
'use_env_http_proxy' : [opt_bool, False],
|
||||||
}, {}),
|
}, {}),
|
||||||
'statusmsg': ({
|
'statusmsg': ({
|
||||||
'message': [ opt_str, '' ],
|
'message': [ opt_str, '' ],
|
||||||
|
@ -354,7 +363,7 @@ class Config:
|
||||||
'state_muc_directed_msg_color': [ opt_color, 'red2' ],
|
'state_muc_directed_msg_color': [ opt_color, 'red2' ],
|
||||||
}, {}),
|
}, {}),
|
||||||
'contacts': ({
|
'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')],
|
'speller_language': [ opt_str, '', _('Language for which we want to check misspelled words')],
|
||||||
}, {}),
|
}, {}),
|
||||||
'rooms': ({
|
'rooms': ({
|
||||||
|
@ -400,7 +409,8 @@ class Config:
|
||||||
|
|
||||||
soundevents_default = {
|
soundevents_default = {
|
||||||
'first_message_received': [ True, '../data/sounds/message1.wav' ],
|
'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_connected': [ True, '../data/sounds/connected.wav' ],
|
||||||
'contact_disconnected': [ True, '../data/sounds/disconnected.wav' ],
|
'contact_disconnected': [ True, '../data/sounds/disconnected.wav' ],
|
||||||
'message_sent': [ True, '../data/sounds/sent.wav' ],
|
'message_sent': [ True, '../data/sounds/sent.wav' ],
|
||||||
|
|
|
@ -48,7 +48,6 @@ from common import passwords
|
||||||
from common import exceptions
|
from common import exceptions
|
||||||
|
|
||||||
from connection_handlers import *
|
from connection_handlers import *
|
||||||
USE_GPG = GnuPG.USE_GPG
|
|
||||||
|
|
||||||
from common.rst_xhtml_generator import create_xhtml
|
from common.rst_xhtml_generator import create_xhtml
|
||||||
|
|
||||||
|
@ -56,8 +55,6 @@ from string import Template
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger('gajim.c.connection')
|
log = logging.getLogger('gajim.c.connection')
|
||||||
|
|
||||||
import gtkgui_helpers
|
|
||||||
|
|
||||||
ssl_error = {
|
ssl_error = {
|
||||||
2: _("Unable to get issuer certificate"),
|
2: _("Unable to get issuer certificate"),
|
||||||
3: _("Unable to get certificate CRL"),
|
3: _("Unable to get certificate CRL"),
|
||||||
|
@ -75,9 +72,9 @@ ssl_error = {
|
||||||
15: _("Format error in CRL's lastUpdate field"),
|
15: _("Format error in CRL's lastUpdate field"),
|
||||||
16: _("Format error in CRL's nextUpdate field"),
|
16: _("Format error in CRL's nextUpdate field"),
|
||||||
17: _("Out of memory"),
|
17: _("Out of memory"),
|
||||||
18: _("Self signed certificate in certificate chain"),
|
18: _("Self signed certificate"),
|
||||||
19: _("Unable to get local issuer certificate"),
|
19: _("Self signed certificate in certificate chain"),
|
||||||
20: _("Unable to verify the first certificate"),
|
20: _("Unable to get local issuer certificate"),
|
||||||
21: _("Unable to verify the first certificate"),
|
21: _("Unable to verify the first certificate"),
|
||||||
22: _("Certificate chain too long"),
|
22: _("Certificate chain too long"),
|
||||||
23: _("Certificate revoked"),
|
23: _("Certificate revoked"),
|
||||||
|
@ -107,7 +104,9 @@ class Connection(ConnectionHandlers):
|
||||||
self.last_connection = None # last ClientCommon instance
|
self.last_connection = None # last ClientCommon instance
|
||||||
self.is_zeroconf = False
|
self.is_zeroconf = False
|
||||||
self.gpg = 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.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||||
self.status = ''
|
self.status = ''
|
||||||
self.priority = gajim.get_priority(name, 'offline')
|
self.priority = gajim.get_priority(name, 'offline')
|
||||||
|
@ -142,6 +141,9 @@ class Connection(ConnectionHandlers):
|
||||||
self.blocked_contacts = []
|
self.blocked_contacts = []
|
||||||
self.blocked_groups = []
|
self.blocked_groups = []
|
||||||
self.pep_supported = False
|
self.pep_supported = False
|
||||||
|
self.mood = {}
|
||||||
|
self.tune = {}
|
||||||
|
self.activity = {}
|
||||||
# Do we continue connection when we get roster (send presence,get vcard..)
|
# Do we continue connection when we get roster (send presence,get vcard..)
|
||||||
self.continue_connect_info = None
|
self.continue_connect_info = None
|
||||||
# To know the groupchat jid associated with a sranza ID. Useful to
|
# To know the groupchat jid associated with a sranza ID. Useful to
|
||||||
|
@ -178,7 +180,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.dispatch('STATUS', 'connecting')
|
self.dispatch('STATUS', 'connecting')
|
||||||
self.retrycount += 1
|
self.retrycount += 1
|
||||||
self.on_connect_auth = self._init_roster
|
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:
|
else:
|
||||||
# reconnect succeeded
|
# reconnect succeeded
|
||||||
self.time_to_reconnect = None
|
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
|
# We are doing disconnect at so many places, better use one function in all
|
||||||
def disconnect(self, on_purpose=False):
|
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.on_purpose = on_purpose
|
||||||
self.connected = 0
|
self.connected = 0
|
||||||
self.time_to_reconnect = None
|
self.time_to_reconnect = None
|
||||||
|
@ -265,7 +269,8 @@ class Connection(ConnectionHandlers):
|
||||||
if not common.xmpp.isResultNode(result):
|
if not common.xmpp.isResultNode(result):
|
||||||
self.dispatch('ACC_NOT_OK', (result.getError()))
|
self.dispatch('ACC_NOT_OK', (result.getError()))
|
||||||
return
|
return
|
||||||
if USE_GPG:
|
if gajim.HAVE_GPG:
|
||||||
|
self.USE_GPG = True
|
||||||
self.gpg = GnuPG.GnuPG(gajim.config.get(
|
self.gpg = GnuPG.GnuPG(gajim.config.get(
|
||||||
'use_gpg_agent'))
|
'use_gpg_agent'))
|
||||||
self.dispatch('ACC_OK', (self.new_account_info))
|
self.dispatch('ACC_OK', (self.new_account_info))
|
||||||
|
@ -279,7 +284,7 @@ class Connection(ConnectionHandlers):
|
||||||
# typed, so send them
|
# typed, so send them
|
||||||
if is_form:
|
if is_form:
|
||||||
#TODO: Check if form has changed
|
#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)
|
iq.setTag('query').addChild(node=self.new_account_form)
|
||||||
self.connection.SendAndCallForResponse(iq,
|
self.connection.SendAndCallForResponse(iq,
|
||||||
_on_register_result)
|
_on_register_result)
|
||||||
|
@ -313,7 +318,7 @@ class Connection(ConnectionHandlers):
|
||||||
ssl_fingerprint = \
|
ssl_fingerprint = \
|
||||||
self.connection.Connection.ssl_fingerprint_sha1
|
self.connection.Connection.ssl_fingerprint_sha1
|
||||||
self.dispatch('NEW_ACC_CONNECTED', (conf, is_form, ssl_msg,
|
self.dispatch('NEW_ACC_CONNECTED', (conf, is_form, ssl_msg,
|
||||||
ssl_cert, ssl_fingerprint))
|
errnum, ssl_cert, ssl_fingerprint))
|
||||||
self.connection.UnregisterDisconnectHandler(
|
self.connection.UnregisterDisconnectHandler(
|
||||||
self._on_new_account)
|
self._on_new_account)
|
||||||
self.disconnect(on_purpose=True)
|
self.disconnect(on_purpose=True)
|
||||||
|
@ -423,27 +428,56 @@ class Connection(ConnectionHandlers):
|
||||||
proxy['user'] = gajim.config.get_per('proxies', p, 'user')
|
proxy['user'] = gajim.config.get_per('proxies', p, 'user')
|
||||||
proxy['password'] = gajim.config.get_per('proxies', p, 'pass')
|
proxy['password'] = gajim.config.get_per('proxies', p, 'pass')
|
||||||
proxy['type'] = gajim.config.get_per('proxies', p, 'type')
|
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:
|
else:
|
||||||
proxy = None
|
proxy = None
|
||||||
|
|
||||||
h = hostname
|
h = hostname
|
||||||
p = 5222
|
p = 5222
|
||||||
# autodetect [for SSL in 5223/443 and for TLS if broadcasted]
|
ssl_p = 5223
|
||||||
secur = None
|
# use_srv = False # wants ssl? disable srv lookup
|
||||||
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
|
|
||||||
if use_custom:
|
if use_custom:
|
||||||
h = custom_h
|
h = custom_h
|
||||||
p = custom_p
|
p = custom_p
|
||||||
|
ssl_p = custom_p
|
||||||
use_srv = False
|
use_srv = False
|
||||||
|
|
||||||
hosts = []
|
|
||||||
# SRV resolver
|
# SRV resolver
|
||||||
self._proxy = proxy
|
self._proxy = proxy
|
||||||
self._secure = secur
|
self._hosts = [ {'host': h, 'port': p, 'ssl_port': ssl_p, 'prio': 10,
|
||||||
self._hosts = [ {'host': h, 'port': p, 'prio': 10, 'weight': 10} ]
|
'weight': 10} ]
|
||||||
self._hostname = hostname
|
self._hostname = hostname
|
||||||
if use_srv:
|
if use_srv:
|
||||||
# add request for srv query to the resolve, on result '_on_resolve'
|
# 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
|
# SRV query returned at least one valid result, we put it in hosts dict
|
||||||
if len(result_array) != 0:
|
if len(result_array) != 0:
|
||||||
self._hosts = [i for i in result_array]
|
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()
|
self.connect_to_next_host()
|
||||||
|
|
||||||
def on_proxy_failure(self, reason):
|
def on_proxy_failure(self, reason):
|
||||||
|
@ -468,8 +508,9 @@ class Connection(ConnectionHandlers):
|
||||||
self.dispatch('CONNECTION_LOST',
|
self.dispatch('CONNECTION_LOST',
|
||||||
(_('Connection to proxy failed'), reason))
|
(_('Connection to proxy failed'), reason))
|
||||||
|
|
||||||
def connect_to_next_host(self, retry = False):
|
def connect_to_next_type(self, retry=False):
|
||||||
if len(self._hosts):
|
if len(self._connection_types):
|
||||||
|
self._current_type = self._connection_types.pop(0)
|
||||||
if self.last_connection:
|
if self.last_connection:
|
||||||
self.last_connection.socket.disconnect()
|
self.last_connection.socket.disconnect()
|
||||||
self.last_connection = None
|
self.last_connection = None
|
||||||
|
@ -478,27 +519,49 @@ class Connection(ConnectionHandlers):
|
||||||
con = common.xmpp.NonBlockingClient(self._hostname, caller = self,
|
con = common.xmpp.NonBlockingClient(self._hostname, caller = self,
|
||||||
on_connect = self.on_connect_success,
|
on_connect = self.on_connect_success,
|
||||||
on_proxy_failure = self.on_proxy_failure,
|
on_proxy_failure = self.on_proxy_failure,
|
||||||
on_connect_failure = self.connect_to_next_host)
|
on_connect_failure = self.connect_to_next_type)
|
||||||
else:
|
else:
|
||||||
con = common.xmpp.NonBlockingClient(self._hostname, debug = [], caller = self,
|
con = common.xmpp.NonBlockingClient(self._hostname, debug = [],
|
||||||
on_connect = self.on_connect_success,
|
caller = self, on_connect = self.on_connect_success,
|
||||||
on_proxy_failure = self.on_proxy_failure,
|
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
|
self.last_connection = con
|
||||||
# increase default timeout for server responses
|
# increase default timeout for server responses
|
||||||
common.xmpp.dispatcher_nb.DEFAULT_TIMEOUT_SECONDS = self.try_connecting_for_foo_secs
|
common.xmpp.dispatcher_nb.DEFAULT_TIMEOUT_SECONDS = self.try_connecting_for_foo_secs
|
||||||
con.set_idlequeue(gajim.idlequeue)
|
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
|
# FIXME: this is a hack; need a better way
|
||||||
if self.on_connect_success == self._on_new_account:
|
if self.on_connect_success == self._on_new_account:
|
||||||
con.RegisterDisconnectHandler(self._on_new_account)
|
con.RegisterDisconnectHandler(self._on_new_account)
|
||||||
|
|
||||||
log.info("Connecting to %s: [%s:%d]", self.name, host['host'], host['port'])
|
if self._current_type == 'ssl':
|
||||||
con.connect((host['host'], host['port']), proxy = self._proxy,
|
port = self._current_host['ssl_port']
|
||||||
secure = self._secure)
|
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:
|
else:
|
||||||
if not retry and self.retrycount == 0:
|
if not retry and self.retrycount == 0:
|
||||||
log.debug("Out of hosts, giving up connecting to %s", self.name)
|
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
|
if not self.connected: # We went offline during connecting process
|
||||||
# FIXME - not possible, maybe it was when we used threads
|
# FIXME - not possible, maybe it was when we used threads
|
||||||
return
|
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 = []
|
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.connected_hostname = self._current_host['host']
|
||||||
self.on_connect_failure = None
|
self.on_connect_failure = None
|
||||||
con.RegisterDisconnectHandler(self._disconnectedReconnCB)
|
con.RegisterDisconnectHandler(self._disconnectedReconnCB)
|
||||||
log.debug(_('Connected to server %s:%s with %s') % (self._current_host['host'],
|
log.debug('Connected to server %s:%s with %s' % (
|
||||||
self._current_host['port'], con_type))
|
self._current_host['host'], self._current_host['port'], con_type))
|
||||||
|
|
||||||
name = gajim.config.get_per('accounts', self.name, 'name')
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
||||||
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
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.') %\
|
text = _('The authenticity of the %s certificate could be invalid.') %\
|
||||||
hostname
|
hostname
|
||||||
if errnum in ssl_error:
|
if errnum in ssl_error:
|
||||||
text += _('\nSSL Error: %s') % ssl_error[errnum]
|
text += _('\nSSL Error: <b>%s</b>') % ssl_error[errnum]
|
||||||
else:
|
else:
|
||||||
text += _('\nUnknown SSL error: %d') % errnum
|
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))
|
con.Connection.ssl_fingerprint_sha1))
|
||||||
return True
|
return True
|
||||||
if hasattr(con.Connection, 'ssl_fingerprint_sha1'):
|
if hasattr(con.Connection, 'ssl_fingerprint_sha1'):
|
||||||
|
@ -565,11 +639,17 @@ class Connection(ConnectionHandlers):
|
||||||
self._register_handlers(con, con_type)
|
self._register_handlers(con, con_type)
|
||||||
con.auth(name, self.password, self.server_resource, 1, self.__on_auth)
|
con.auth(name, self.password, self.server_resource, 1, self.__on_auth)
|
||||||
|
|
||||||
|
|
||||||
def ssl_certificate_accepted(self):
|
def ssl_certificate_accepted(self):
|
||||||
name = gajim.config.get_per('accounts', self.name, 'name')
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
||||||
self._register_handlers(self.connection, 'ssl')
|
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):
|
def _register_handlers(self, con, con_type):
|
||||||
self.peerhost = con.get_peerhost()
|
self.peerhost = con.get_peerhost()
|
||||||
|
@ -699,6 +779,17 @@ class Connection(ConnectionHandlers):
|
||||||
def send_invisible_presence(self, msg, signed, initial = False):
|
def send_invisible_presence(self, msg, signed, initial = False):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
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
|
# try to set the privacy rule
|
||||||
iq = self.build_privacy_rule('invisible', 'deny')
|
iq = self.build_privacy_rule('invisible', 'deny')
|
||||||
self.connection.SendAndCallForResponse(iq, self._continue_invisible,
|
self.connection.SendAndCallForResponse(iq, self._continue_invisible,
|
||||||
|
@ -707,8 +798,7 @@ class Connection(ConnectionHandlers):
|
||||||
def _continue_invisible(self, con, iq_obj, msg, signed, initial):
|
def _continue_invisible(self, con, iq_obj, msg, signed, initial):
|
||||||
ptype = ''
|
ptype = ''
|
||||||
show = ''
|
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 iq_obj.getType() == 'error': # server doesn't support privacy lists
|
||||||
if 1 or iq_obj.getType() == 'error': #server doesn't support privacy lists
|
|
||||||
# We use the old way which is not xmpp complient
|
# We use the old way which is not xmpp complient
|
||||||
ptype = 'invisible'
|
ptype = 'invisible'
|
||||||
show = 'invisible'
|
show = 'invisible'
|
||||||
|
@ -760,7 +850,7 @@ class Connection(ConnectionHandlers):
|
||||||
callback is the function to call when user give the passphrase'''
|
callback is the function to call when user give the passphrase'''
|
||||||
signed = ''
|
signed = ''
|
||||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
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')
|
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||||
if self.gpg.passphrase is None and not use_gpg_agent:
|
if self.gpg.passphrase is None and not use_gpg_agent:
|
||||||
# We didn't set a passphrase
|
# We didn't set a passphrase
|
||||||
|
@ -768,7 +858,7 @@ class Connection(ConnectionHandlers):
|
||||||
if self.gpg.passphrase is not None or use_gpg_agent:
|
if self.gpg.passphrase is not None or use_gpg_agent:
|
||||||
signed = self.gpg.sign(msg, keyID)
|
signed = self.gpg.sign(msg, keyID)
|
||||||
if signed == 'BAD_PASSPHRASE':
|
if signed == 'BAD_PASSPHRASE':
|
||||||
self.gpg = None
|
self.USE_GPG = False
|
||||||
signed = ''
|
signed = ''
|
||||||
self.dispatch('BAD_PASSPHRASE', ())
|
self.dispatch('BAD_PASSPHRASE', ())
|
||||||
return signed
|
return signed
|
||||||
|
@ -845,7 +935,8 @@ class Connection(ConnectionHandlers):
|
||||||
safe_substitute({
|
safe_substitute({
|
||||||
'hostname': socket.gethostname()
|
'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.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||||
self.connect_and_init(show, msg, sign_msg)
|
self.connect_and_init(show, msg, sign_msg)
|
||||||
|
|
||||||
|
@ -922,7 +1013,13 @@ class Connection(ConnectionHandlers):
|
||||||
fjid += '/' + resource
|
fjid += '/' + resource
|
||||||
msgtxt = msg
|
msgtxt = msg
|
||||||
msgenc = ''
|
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
|
#encrypt
|
||||||
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
||||||
if msgenc and not error:
|
if msgenc and not error:
|
||||||
|
@ -1109,7 +1206,7 @@ class Connection(ConnectionHandlers):
|
||||||
def send_new_account_infos(self, form, is_form):
|
def send_new_account_infos(self, form, is_form):
|
||||||
if is_form:
|
if is_form:
|
||||||
# Get username and password and put them in new_account_info
|
# 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':
|
if field.var == 'username':
|
||||||
self.new_account_info['name'] = field.value
|
self.new_account_info['name'] = field.value
|
||||||
if field.var == 'password':
|
if field.var == 'password':
|
||||||
|
|
|
@ -35,15 +35,20 @@ from calendar import timegm
|
||||||
import socks5
|
import socks5
|
||||||
import common.xmpp
|
import common.xmpp
|
||||||
|
|
||||||
from common import GnuPG
|
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import atom
|
from common import atom
|
||||||
|
from common import pep
|
||||||
from common import exceptions
|
from common import exceptions
|
||||||
from common.commands import ConnectionCommands
|
from common.commands import ConnectionCommands
|
||||||
from common.pubsub import ConnectionPubSub
|
from common.pubsub import ConnectionPubSub
|
||||||
from common.caps import ConnectionCaps
|
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
|
from common.stanza_session import EncryptedStanzaSession
|
||||||
|
|
||||||
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
STATUS_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||||
|
@ -54,6 +59,7 @@ VCARD_ARRIVED = 'vcard_arrived'
|
||||||
AGENT_REMOVED = 'agent_removed'
|
AGENT_REMOVED = 'agent_removed'
|
||||||
METACONTACTS_ARRIVED = 'metacontacts_arrived'
|
METACONTACTS_ARRIVED = 'metacontacts_arrived'
|
||||||
PRIVACY_ARRIVED = 'privacy_arrived'
|
PRIVACY_ARRIVED = 'privacy_arrived'
|
||||||
|
PEP_ACCESS_MODEL = 'pep_access_model'
|
||||||
HAS_IDLE = True
|
HAS_IDLE = True
|
||||||
try:
|
try:
|
||||||
import idle
|
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_MUC})
|
||||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_COMMANDS})
|
q.addChild('feature', attrs = {'var': common.xmpp.NS_COMMANDS})
|
||||||
q.addChild('feature', attrs = {'var': common.xmpp.NS_DISCO_INFO})
|
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})
|
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':
|
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'] == \
|
if identity['category'] == 'pubsub' and identity['type'] == \
|
||||||
'pep':
|
'pep':
|
||||||
self.pep_supported = True
|
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
|
break
|
||||||
if features.__contains__(common.xmpp.NS_BYTESTREAM):
|
if features.__contains__(common.xmpp.NS_BYTESTREAM):
|
||||||
gajim.proxy65_manager.resolve(jid, self.connection, self.name)
|
gajim.proxy65_manager.resolve(jid, self.connection, self.name)
|
||||||
|
@ -1099,6 +1118,16 @@ class ConnectionVcard:
|
||||||
self.get_privacy_list('block')
|
self.get_privacy_list('block')
|
||||||
# Ask metacontacts before roster
|
# Ask metacontacts before roster
|
||||||
self.get_metacontacts()
|
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]
|
del self.awaiting_answers[id]
|
||||||
|
|
||||||
|
@ -1251,7 +1280,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
reply.setType('error')
|
reply.setType('error')
|
||||||
|
|
||||||
reply.addChild(feature)
|
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)
|
con.send(reply)
|
||||||
|
|
||||||
|
@ -1419,7 +1448,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
iq_obj = iq_obj.buildReply('result')
|
iq_obj = iq_obj.buildReply('result')
|
||||||
qp = iq_obj.getTag('query')
|
qp = iq_obj.getTag('query')
|
||||||
qp.setTagData('utc', strftime('%Y%m%dT%T', gmtime()))
|
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',
|
qp.setTagData('display', helpers.decode_string(strftime('%c',
|
||||||
localtime())))
|
localtime())))
|
||||||
self.connection.send(iq_obj)
|
self.connection.send(iq_obj)
|
||||||
|
@ -1599,7 +1628,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
if not user_nick:
|
if not user_nick:
|
||||||
user_nick = ''
|
user_nick = ''
|
||||||
|
|
||||||
if encTag and GnuPG.USE_GPG:
|
if encTag and self.USE_GPG:
|
||||||
#decrypt
|
#decrypt
|
||||||
encmsg = encTag.getData()
|
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. '''
|
''' Called when we receive <message/> with pubsub event. '''
|
||||||
# TODO: Logging? (actually services where logging would be useful, should
|
# TODO: Logging? (actually services where logging would be useful, should
|
||||||
# TODO: allow to access archives remotely...)
|
# TODO: allow to access archives remotely...)
|
||||||
|
jid = helpers.get_full_jid_from_iq(msg)
|
||||||
event = msg.getTag('event')
|
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')
|
items = event.getTag('items')
|
||||||
if items is None: return
|
if items is None: return
|
||||||
|
|
||||||
|
@ -1857,7 +1900,7 @@ returns the session that we last sent a message to.'''
|
||||||
except:
|
except:
|
||||||
prio = 0
|
prio = 0
|
||||||
keyID = ''
|
keyID = ''
|
||||||
if sigTag and self.gpg:
|
if sigTag and self.USE_GPG:
|
||||||
# verify
|
# verify
|
||||||
sigmsg = sigTag.getData()
|
sigmsg = sigTag.getData()
|
||||||
keyID = self.gpg.verify(status, sigmsg)
|
keyID = self.gpg.verify(status, sigmsg)
|
||||||
|
@ -2109,6 +2152,21 @@ returns the session that we last sent a message to.'''
|
||||||
raw_roster = roster.getRaw()
|
raw_roster = roster.getRaw()
|
||||||
roster = {}
|
roster = {}
|
||||||
our_jid = helpers.parse_jid(gajim.get_jid_from_account(self.name))
|
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:
|
for jid in raw_roster:
|
||||||
try:
|
try:
|
||||||
j = helpers.parse_jid(jid)
|
j = helpers.parse_jid(jid)
|
||||||
|
@ -2131,20 +2189,6 @@ returns the session that we last sent a message to.'''
|
||||||
|
|
||||||
self.dispatch('ROSTER', roster)
|
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 = ''):
|
def _send_first_presence(self, signed = ''):
|
||||||
show = self.continue_connect_info[0]
|
show = self.continue_connect_info[0]
|
||||||
msg = self.continue_connect_info[1]
|
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'),
|
self.dispatch('ERROR', (_('OpenPGP passphrase was not given'),
|
||||||
#%s is the account name here
|
#%s is the account name here
|
||||||
_('You will be connected to %s without OpenPGP.') % self.name))
|
_('You will be connected to %s without OpenPGP.') % self.name))
|
||||||
|
self.USE_GPG = False
|
||||||
signed = ''
|
signed = ''
|
||||||
self.connected = STATUS_LIST.index(show)
|
self.connected = STATUS_LIST.index(show)
|
||||||
sshow = helpers.get_xmpp_show(show)
|
sshow = helpers.get_xmpp_show(show)
|
||||||
|
|
|
@ -27,7 +27,8 @@ class Contact:
|
||||||
'''Information concerning each contact'''
|
'''Information concerning each contact'''
|
||||||
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
|
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
|
||||||
ask='', resource='', priority=0, keyID='', our_chatstate=None,
|
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.jid = jid
|
||||||
self.name = name
|
self.name = name
|
||||||
self.contact_name = '' # nick choosen by contact
|
self.contact_name = '' # nick choosen by contact
|
||||||
|
@ -63,6 +64,10 @@ class Contact:
|
||||||
self.chatstate = chatstate
|
self.chatstate = chatstate
|
||||||
self.last_status_time = last_status_time
|
self.last_status_time = last_status_time
|
||||||
|
|
||||||
|
self.mood = mood.copy()
|
||||||
|
self.tune = tune.copy()
|
||||||
|
self.activity = activity.copy()
|
||||||
|
|
||||||
def get_full_jid(self):
|
def get_full_jid(self):
|
||||||
if self.resource:
|
if self.resource:
|
||||||
return self.jid + '/' + self.resource
|
return self.jid + '/' + self.resource
|
||||||
|
@ -162,15 +167,16 @@ class Contacts:
|
||||||
|
|
||||||
def create_contact(self, jid='', name='', groups=[], show='', status='',
|
def create_contact(self, jid='', name='', groups=[], show='', status='',
|
||||||
sub='', ask='', resource='', priority=0, keyID='', our_chatstate=None,
|
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,
|
return Contact(jid, name, groups, show, status, sub, ask, resource,
|
||||||
priority, keyID, our_chatstate, chatstate, last_status_time,
|
priority, keyID, our_chatstate, chatstate, last_status_time,
|
||||||
composing_xep)
|
None, composing_xep, mood, tune, activity)
|
||||||
|
|
||||||
def copy_contact(self, contact):
|
def copy_contact(self, contact):
|
||||||
return self.create_contact(jid = contact.jid, name = contact.name,
|
return self.create_contact(jid = contact.jid, name = contact.name,
|
||||||
groups = contact.groups, show = contact.show, status = contact.status,
|
groups = contact.groups, show = contact.show, status =
|
||||||
sub = contact.sub, ask = contact.ask, resource = contact.resource,
|
contact.status, sub = contact.sub, ask = contact.ask, resource = contact.resource,
|
||||||
priority = contact.priority, keyID = contact.keyID,
|
priority = contact.priority, keyID = contact.keyID,
|
||||||
our_chatstate = contact.our_chatstate, chatstate = contact.chatstate,
|
our_chatstate = contact.our_chatstate, chatstate = contact.chatstate,
|
||||||
last_status_time = contact.last_status_time)
|
last_status_time = contact.last_status_time)
|
||||||
|
@ -469,6 +475,15 @@ class Contacts:
|
||||||
return 1
|
return 1
|
||||||
if show2 > show1:
|
if show2 > show1:
|
||||||
return -1
|
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:
|
if jid1 > jid2:
|
||||||
return 1
|
return 1
|
||||||
if jid2 > jid1:
|
if jid2 > jid1:
|
||||||
|
|
|
@ -2,7 +2,7 @@ docdir = '../'
|
||||||
|
|
||||||
datadir = '../'
|
datadir = '../'
|
||||||
|
|
||||||
version = '0.11.4.0-svn'
|
version = '0.11.4.2-svn'
|
||||||
|
|
||||||
import sys, os.path
|
import sys, os.path
|
||||||
for base in ('.', 'common'):
|
for base in ('.', 'common'):
|
||||||
|
|
|
@ -138,9 +138,6 @@ SHOW_LIST = ['offline', 'connecting', 'online', 'chat', 'away', 'xa', 'dnd',
|
||||||
|
|
||||||
# zeroconf account name
|
# zeroconf account name
|
||||||
ZEROCONF_ACC_NAME = 'Local'
|
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
|
HAVE_PYCRYPTO = True
|
||||||
try:
|
try:
|
||||||
|
@ -154,6 +151,17 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAVE_PYSEXY = False
|
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):
|
def get_nick_from_jid(jid):
|
||||||
pos = jid.find('@')
|
pos = jid.find('@')
|
||||||
return jid[:pos]
|
return jid[:pos]
|
||||||
|
@ -260,13 +268,14 @@ def account_is_disconnected(account):
|
||||||
def get_number_of_securely_connected_accounts():
|
def get_number_of_securely_connected_accounts():
|
||||||
'''returns the number of the accounts that are SSL/TLS connected'''
|
'''returns the number of the accounts that are SSL/TLS connected'''
|
||||||
num_of_secured = 0
|
num_of_secured = 0
|
||||||
for account in connections:
|
for account in connections.keys():
|
||||||
if account_is_securely_connected(account):
|
if account_is_securely_connected(account):
|
||||||
num_of_secured += 1
|
num_of_secured += 1
|
||||||
return num_of_secured
|
return num_of_secured
|
||||||
|
|
||||||
def account_is_securely_connected(account):
|
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
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -429,7 +429,7 @@ def launch_browser_mailer(kind, uri):
|
||||||
command = 'kfmclient exec'
|
command = 'kfmclient exec'
|
||||||
elif gajim.config.get('openwith') == 'exo-open':
|
elif gajim.config.get('openwith') == 'exo-open':
|
||||||
command = 'exo-open'
|
command = 'exo-open'
|
||||||
elif ((sys.platform == 'darwin') and
|
elif ((sys.platform == 'darwin') and\
|
||||||
(gajim.config.get('openwith') == 'open')):
|
(gajim.config.get('openwith') == 'open')):
|
||||||
command = 'open'
|
command = 'open'
|
||||||
elif gajim.config.get('openwith') == 'custom':
|
elif gajim.config.get('openwith') == 'custom':
|
||||||
|
@ -459,7 +459,7 @@ def launch_file_manager(path_to_open):
|
||||||
command = 'kfmclient exec'
|
command = 'kfmclient exec'
|
||||||
elif gajim.config.get('openwith') == 'exo-open':
|
elif gajim.config.get('openwith') == 'exo-open':
|
||||||
command = 'exo-open'
|
command = 'exo-open'
|
||||||
elif ((sys.platform == 'darwin') and
|
elif ((sys.platform == 'darwin') and\
|
||||||
(gajim.config.get('openwith') == 'open')):
|
(gajim.config.get('openwith') == 'open')):
|
||||||
command = 'open'
|
command = 'open'
|
||||||
elif gajim.config.get('openwith') == 'custom':
|
elif gajim.config.get('openwith') == 'custom':
|
||||||
|
@ -784,7 +784,8 @@ def get_os_info():
|
||||||
'sourcemage') or not\
|
'sourcemage') or not\
|
||||||
os.path.basename(path_to_file).startswith('slackware'):
|
os.path.basename(path_to_file).startswith('slackware'):
|
||||||
text = distro_name + ' ' + text
|
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
|
# file doesn't have version
|
||||||
text = distro_name
|
text = distro_name
|
||||||
elif path_to_file.endswith('lfs-release'): # file just has version
|
elif path_to_file.endswith('lfs-release'): # file just has version
|
||||||
|
@ -792,7 +793,7 @@ def get_os_info():
|
||||||
return text
|
return text
|
||||||
|
|
||||||
# our last chance, ask uname and strip it
|
# 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:
|
if uname_output is not None:
|
||||||
return uname_output[0] # only first line
|
return uname_output[0] # only first line
|
||||||
return 'N/A'
|
return 'N/A'
|
||||||
|
@ -1092,3 +1093,38 @@ def get_transport_path(transport):
|
||||||
elif os.path.isdir(os.path.join(gajim.MY_ICONSETS_PATH, 'transports',
|
elif os.path.isdir(os.path.join(gajim.MY_ICONSETS_PATH, 'transports',
|
||||||
transport)):
|
transport)):
|
||||||
return 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()
|
self.update_config_to_01115()
|
||||||
if old < [0, 11, 2, 1] and new >= [0, 11, 2, 1]:
|
if old < [0, 11, 2, 1] and new >= [0, 11, 2, 1]:
|
||||||
self.update_config_to_01121()
|
self.update_config_to_01121()
|
||||||
if old < [0, 11, 2, 2] and new >= [0, 11, 2, 2]:
|
if old < [0, 11, 4, 1] and new >= [0, 11, 4, 1]:
|
||||||
self.update_config_to_01122()
|
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.logger.init_vars()
|
||||||
gajim.config.set('version', new_version)
|
gajim.config.set('version', new_version)
|
||||||
|
@ -503,7 +505,7 @@ class OptionsParser:
|
||||||
|
|
||||||
gajim.config.set('version', '0.11.2.1')
|
gajim.config.set('version', '0.11.2.1')
|
||||||
|
|
||||||
def update_config_to_01122(self):
|
def update_config_to_01141(self):
|
||||||
back = os.getcwd()
|
back = os.getcwd()
|
||||||
os.chdir(logger.LOG_DB_FOLDER)
|
os.chdir(logger.LOG_DB_FOLDER)
|
||||||
con = sqlite.connect(logger.LOG_DB_FILE)
|
con = sqlite.connect(logger.LOG_DB_FILE)
|
||||||
|
@ -524,5 +526,20 @@ class OptionsParser:
|
||||||
except sqlite.OperationalError, e:
|
except sqlite.OperationalError, e:
|
||||||
pass
|
pass
|
||||||
con.close()
|
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 xmpp
|
||||||
import gajim
|
import gajim
|
||||||
|
import connection_handlers
|
||||||
|
|
||||||
class ConnectionPubSub:
|
class ConnectionPubSub:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -43,9 +44,61 @@ class ConnectionPubSub:
|
||||||
|
|
||||||
self.connection.send(query)
|
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):
|
def _PubSubCB(self, conn, stanza):
|
||||||
try:
|
try:
|
||||||
cb, args, kwargs = self.__callbacks.pop(stanza.getID())
|
cb, args, kwargs = self.__callbacks.pop(stanza.getID())
|
||||||
cb(conn, stanza, *args, **kwargs)
|
cb(conn, stanza, *args, **kwargs)
|
||||||
except:
|
except:
|
||||||
pass
|
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
|
elif self.state == 3: # send 'connect' request
|
||||||
self.send_raw(self._get_request_buff(self._get_sha1_auth()))
|
self.send_raw(self._get_request_buff(self._get_sha1_auth()))
|
||||||
elif self.file_props['type'] != 'r':
|
elif self.file_props['type'] != 'r':
|
||||||
if self.file_props['paused'] == True:
|
if self.file_props['paused']:
|
||||||
self.idlequeue.plug_idle(self, False, False)
|
self.idlequeue.plug_idle(self, False, False)
|
||||||
return
|
return
|
||||||
result = self.write_next()
|
result = self.write_next()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from common import gajim
|
from common import gajim
|
||||||
|
|
||||||
from common import xmpp
|
from common import xmpp
|
||||||
from common import helpers
|
|
||||||
from common import exceptions
|
from common import exceptions
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
|
@ -27,11 +27,14 @@ NS_AGENTS ='jabber:iq:agents'
|
||||||
NS_AMP ='http://jabber.org/protocol/amp'
|
NS_AMP ='http://jabber.org/protocol/amp'
|
||||||
NS_AMP_ERRORS =NS_AMP+'#errors'
|
NS_AMP_ERRORS =NS_AMP+'#errors'
|
||||||
NS_AUTH ='jabber:iq:auth'
|
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_BIND ='urn:ietf:params:xml:ns:xmpp-bind'
|
||||||
NS_BROWSE ='jabber:iq:browse'
|
NS_BROWSE ='jabber:iq:browse'
|
||||||
NS_BYTESTREAM ='http://jabber.org/protocol/bytestreams' # XEP-0065
|
NS_BROWSING ='http://jabber.org/protocol/browsing' # XEP-0195
|
||||||
NS_CAPS ='http://jabber.org/protocol/caps' # XEP-0115
|
NS_BYTESTREAM ='http://jabber.org/protocol/bytestreams' # JEP-0065
|
||||||
NS_CHATSTATES ='http://jabber.org/protocol/chatstates' # XEP-0085
|
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_CLIENT ='jabber:client'
|
||||||
NS_COMMANDS ='http://jabber.org/protocol/commands'
|
NS_COMMANDS ='http://jabber.org/protocol/commands'
|
||||||
NS_COMPONENT_ACCEPT='jabber:component:accept'
|
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_ESESSION_INIT='http://www.xmpp.org/extensions/xep-0116.html#ns-init' # XEP-0116
|
||||||
NS_EVENT ='jabber:x:event' # XEP-0022
|
NS_EVENT ='jabber:x:event' # XEP-0022
|
||||||
NS_FEATURE ='http://jabber.org/protocol/feature-neg'
|
NS_FEATURE ='http://jabber.org/protocol/feature-neg'
|
||||||
NS_FILE ='http://jabber.org/protocol/si/profile/file-transfer' # XEP-0096
|
NS_FILE ='http://jabber.org/protocol/si/profile/file-transfer' # JEP-0096
|
||||||
NS_GEOLOC ='http://jabber.org/protocol/geoloc' # XEP-0080
|
NS_GAMING ='http://jabber.org/protocol/gaming' # XEP-0196
|
||||||
|
NS_GEOLOC ='http://jabber.org/protocol/geoloc' # JEP-0080
|
||||||
NS_GROUPCHAT ='gc-1.0'
|
NS_GROUPCHAT ='gc-1.0'
|
||||||
NS_HTTP_AUTH ='http://jabber.org/protocol/http-auth' # XEP-0070
|
NS_HTTP_AUTH ='http://jabber.org/protocol/http-auth' # XEP-0070
|
||||||
NS_HTTP_BIND ='http://jabber.org/protocol/httpbind' # XEP-0124
|
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_PRIVATE ='jabber:iq:private'
|
||||||
NS_PROFILE ='http://jabber.org/protocol/profile' # XEP-0154
|
NS_PROFILE ='http://jabber.org/protocol/profile' # XEP-0154
|
||||||
NS_PUBSUB ='http://jabber.org/protocol/pubsub' # XEP-0060
|
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_REGISTER ='jabber:iq:register'
|
||||||
NS_ROSTER ='jabber:iq:roster'
|
NS_ROSTER ='jabber:iq:roster'
|
||||||
NS_ROSTERX ='http://jabber.org/protocol/rosterx' # XEP-0144
|
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 ='jabber:iq:time' # XEP-0900
|
||||||
NS_TIME_REVISED ='urn:xmpp:time' # XEP-0202
|
NS_TIME_REVISED ='urn:xmpp:time' # XEP-0202
|
||||||
NS_TLS ='urn:ietf:params:xml:ns:xmpp-tls'
|
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_VACATION ='http://jabber.org/protocol/vacation'
|
||||||
NS_VCARD ='vcard-temp'
|
NS_VCARD ='vcard-temp'
|
||||||
NS_GMAILNOTIFY ='google:mail:notify'
|
NS_GMAILNOTIFY ='google:mail:notify'
|
||||||
NS_GTALKSETTING ='google:setting'
|
NS_GTALKSETTING ='google:setting'
|
||||||
NS_VCARD_UPDATE =NS_VCARD+':x:update'
|
NS_VCARD_UPDATE =NS_VCARD+':x:update'
|
||||||
NS_VERSION ='jabber:iq:version'
|
NS_VERSION ='jabber:iq:version'
|
||||||
|
NS_VIEWING ='http://jabber.org/protocol/viewing' # XEP--197
|
||||||
NS_PING ='urn:xmpp:ping' # XEP-0199
|
NS_PING ='urn:xmpp:ping' # XEP-0199
|
||||||
NS_WAITINGLIST ='http://jabber.org/protocol/waitinglist' # XEP-0130
|
NS_WAITINGLIST ='http://jabber.org/protocol/waitinglist' # XEP-0130
|
||||||
NS_XHTML_IM ='http://jabber.org/protocol/xhtml-im' # XEP-0071
|
NS_XHTML_IM ='http://jabber.org/protocol/xhtml-im' # XEP-0071
|
||||||
|
|
|
@ -87,7 +87,11 @@ class Roster(PlugIn):
|
||||||
def PresenceHandler(self,dis,pres):
|
def PresenceHandler(self,dis,pres):
|
||||||
""" Presence tracker. Used internally for setting items' resources state in
|
""" Presence tracker. Used internally for setting items' resources state in
|
||||||
internal roster representation. """
|
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 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()):
|
if type(self._data[jid.getStripped()]['resources'])!=type(dict()):
|
||||||
self._data[jid.getStripped()]['resources']={}
|
self._data[jid.getStripped()]['resources']={}
|
||||||
|
|
|
@ -761,15 +761,18 @@ class NonBlockingTLS(PlugIn):
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if 'BEGIN CERTIFICATE' in line:
|
if 'BEGIN CERTIFICATE' in line:
|
||||||
begin = i
|
begin = i
|
||||||
continue
|
|
||||||
elif 'END CERTIFICATE' in line and begin > -1:
|
elif 'END CERTIFICATE' in line and begin > -1:
|
||||||
cert = ''.join(lines[begin:i+2])
|
cert = ''.join(lines[begin:i+2])
|
||||||
try:
|
try:
|
||||||
X509cert = OpenSSL.crypto.load_certificate(
|
X509cert = OpenSSL.crypto.load_certificate(
|
||||||
OpenSSL.crypto.FILETYPE_PEM, cert)
|
OpenSSL.crypto.FILETYPE_PEM, cert)
|
||||||
store.add_cert(X509cert)
|
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:
|
except:
|
||||||
log.warning('Unable to load a certificate from file %s' % \
|
log.warning(
|
||||||
|
'Unknown error while loading certificate from file %s' % \
|
||||||
gajim.MY_CACERTS)
|
gajim.MY_CACERTS)
|
||||||
begin = -1
|
begin = -1
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -787,7 +790,8 @@ class NonBlockingTLS(PlugIn):
|
||||||
try:
|
try:
|
||||||
self.starttls='in progress'
|
self.starttls='in progress'
|
||||||
tcpsock._sslObj.do_handshake()
|
tcpsock._sslObj.do_handshake()
|
||||||
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantWriteError), e:
|
# Errors are handeled in _do_receive function
|
||||||
|
except:
|
||||||
pass
|
pass
|
||||||
tcpsock._sslObj.setblocking(False)
|
tcpsock._sslObj.setblocking(False)
|
||||||
log.debug("Synchronous handshake completed")
|
log.debug("Synchronous handshake completed")
|
||||||
|
@ -1027,7 +1031,7 @@ class NBSOCKS5PROXYsocket(NonBlockingTcp):
|
||||||
# use the IPv4 address request even if remote resolving was specified.
|
# use the IPv4 address request even if remote resolving was specified.
|
||||||
try:
|
try:
|
||||||
self.ipaddr = socket.inet_aton(self.server[0])
|
self.ipaddr = socket.inet_aton(self.server[0])
|
||||||
req = req + "\x01" + ipaddr
|
req = req + "\x01" + self.ipaddr
|
||||||
except socket.error:
|
except socket.error:
|
||||||
# Well it's not an IP number, so it's probably a DNS name.
|
# Well it's not an IP number, so it's probably a DNS name.
|
||||||
# if self.__proxy[3]==True:
|
# if self.__proxy[3]==True:
|
||||||
|
|
|
@ -32,7 +32,6 @@ from calendar import timegm
|
||||||
from common import socks5
|
from common import socks5
|
||||||
import common.xmpp
|
import common.xmpp
|
||||||
|
|
||||||
from common import GnuPG
|
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common.zeroconf import zeroconf
|
from common.zeroconf import zeroconf
|
||||||
|
@ -726,13 +725,15 @@ class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream):
|
||||||
if not user_nick:
|
if not user_nick:
|
||||||
user_nick = ''
|
user_nick = ''
|
||||||
|
|
||||||
if encTag and GnuPG.USE_GPG:
|
if encTag and self.USE_GPG:
|
||||||
#decrypt
|
#decrypt
|
||||||
encmsg = encTag.getData()
|
encmsg = encTag.getData()
|
||||||
|
|
||||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||||
if keyID:
|
if keyID:
|
||||||
decmsg = self.gpg.decrypt(encmsg, keyID)
|
decmsg = self.gpg.decrypt(encmsg, keyID)
|
||||||
|
# \x00 chars are not allowed in C (so in GTK)
|
||||||
|
decmsg = decmsg.replace('\x00', '')
|
||||||
if decmsg:
|
if decmsg:
|
||||||
msgtxt = decmsg
|
msgtxt = decmsg
|
||||||
encrypted = True
|
encrypted = True
|
||||||
|
|
|
@ -49,8 +49,6 @@ from common.zeroconf import client_zeroconf
|
||||||
from common.zeroconf import zeroconf
|
from common.zeroconf import zeroconf
|
||||||
from connection_handlers_zeroconf import *
|
from connection_handlers_zeroconf import *
|
||||||
|
|
||||||
USE_GPG = GnuPG.USE_GPG
|
|
||||||
|
|
||||||
class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
'''Connection class'''
|
'''Connection class'''
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
|
@ -62,7 +60,9 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.connected = 0 # offline
|
self.connected = 0 # offline
|
||||||
self.connection = None
|
self.connection = None
|
||||||
self.gpg = 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.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||||
self.is_zeroconf = True
|
self.is_zeroconf = True
|
||||||
self.privacy_rules_supported = False
|
self.privacy_rules_supported = False
|
||||||
|
@ -86,9 +86,13 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.no_log_for = False
|
self.no_log_for = False
|
||||||
|
|
||||||
self.pep_supported = False
|
self.pep_supported = False
|
||||||
|
self.mood = {}
|
||||||
|
self.tune = {}
|
||||||
|
self.activity = {}
|
||||||
# Do we continue connection when we get roster (send presence,get vcard...)
|
# Do we continue connection when we get roster (send presence,get vcard...)
|
||||||
self.continue_connect_info = None
|
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.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||||
|
|
||||||
self.get_config_values_or_default()
|
self.get_config_values_or_default()
|
||||||
|
@ -160,7 +164,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
def get_signed_msg(self, msg):
|
def get_signed_msg(self, msg):
|
||||||
signed = ''
|
signed = ''
|
||||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
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')
|
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||||
if self.connected < 2 and self.gpg.passphrase is None and \
|
if self.connected < 2 and self.gpg.passphrase is None and \
|
||||||
not use_gpg_agent:
|
not use_gpg_agent:
|
||||||
|
@ -168,9 +172,11 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.dispatch('ERROR', (_('OpenPGP passphrase was not given'),
|
self.dispatch('ERROR', (_('OpenPGP passphrase was not given'),
|
||||||
#%s is the account name here
|
#%s is the account name here
|
||||||
_('You will be connected to %s without OpenPGP.') % self.name))
|
_('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:
|
elif self.gpg.passphrase is not None or use_gpg_agent:
|
||||||
signed = self.gpg.sign(msg, keyID)
|
signed = self.gpg.sign(msg, keyID)
|
||||||
if signed == 'BAD_PASSPHRASE':
|
if signed == 'BAD_PASSPHRASE':
|
||||||
|
self.USE_GPG = False
|
||||||
signed = ''
|
signed = ''
|
||||||
if self.connected < 2:
|
if self.connected < 2:
|
||||||
self.dispatch('BAD_PASSPHRASE', ())
|
self.dispatch('BAD_PASSPHRASE', ())
|
||||||
|
@ -370,7 +376,12 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
|
|
||||||
msgtxt = msg
|
msgtxt = msg
|
||||||
msgenc = ''
|
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
|
# encrypt
|
||||||
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
||||||
if msgenc and not error:
|
if msgenc and not error:
|
||||||
|
@ -507,7 +518,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
gajim.log.debug('This should not happen (send_agent_status)')
|
gajim.log.debug('This should not happen (send_agent_status)')
|
||||||
|
|
||||||
def gpg_passphrase(self, passphrase):
|
def gpg_passphrase(self, passphrase):
|
||||||
if USE_GPG:
|
if self.gpg:
|
||||||
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||||
if use_gpg_agent:
|
if use_gpg_agent:
|
||||||
self.gpg.passphrase = None
|
self.gpg.passphrase = None
|
||||||
|
@ -515,13 +526,13 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.gpg.passphrase = passphrase
|
self.gpg.passphrase = passphrase
|
||||||
|
|
||||||
def ask_gpg_keys(self):
|
def ask_gpg_keys(self):
|
||||||
if USE_GPG:
|
if self.gpg:
|
||||||
keys = self.gpg.get_keys()
|
keys = self.gpg.get_keys()
|
||||||
return keys
|
return keys
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def ask_gpg_secrete_keys(self):
|
def ask_gpg_secrete_keys(self):
|
||||||
if USE_GPG:
|
if self.gpg:
|
||||||
keys = self.gpg.get_secret_keys()
|
keys = self.gpg.get_secret_keys()
|
||||||
return keys
|
return keys
|
||||||
return None
|
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) 2003-2005 Vincent Hanquez <tab@snarc.org>
|
||||||
## Copyright (C) 2006 Stefan Bethge <stefan@lanpartei.de>
|
## Copyright (C) 2006 Stefan Bethge <stefan@lanpartei.de>
|
||||||
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
|
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
|
||||||
|
## Copyright (C) 2007 Travis Shirk <travis@pobox.com>
|
||||||
##
|
##
|
||||||
## This file is part of Gajim.
|
## This file is part of Gajim.
|
||||||
##
|
##
|
||||||
|
@ -49,6 +50,7 @@ from common import passwords
|
||||||
from common import zeroconf
|
from common import zeroconf
|
||||||
from common import dbus_support
|
from common import dbus_support
|
||||||
from common import dataforms
|
from common import dataforms
|
||||||
|
from common import pep
|
||||||
|
|
||||||
from common.exceptions import GajimGeneralException
|
from common.exceptions import GajimGeneralException
|
||||||
|
|
||||||
|
@ -69,8 +71,6 @@ class PreferencesWindow:
|
||||||
self.window = self.xml.get_widget('preferences_window')
|
self.window = self.xml.get_widget('preferences_window')
|
||||||
self.window.set_transient_for(gajim.interface.roster.window)
|
self.window.set_transient_for(gajim.interface.roster.window)
|
||||||
self.notebook = self.xml.get_widget('preferences_notebook')
|
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.one_window_type_combobox =\
|
||||||
self.xml.get_widget('one_window_type_combobox')
|
self.xml.get_widget('one_window_type_combobox')
|
||||||
self.iconset_combobox = self.xml.get_widget('iconset_combobox')
|
self.iconset_combobox = self.xml.get_widget('iconset_combobox')
|
||||||
|
@ -90,8 +90,6 @@ class PreferencesWindow:
|
||||||
'auto_xa_time_spinbutton')
|
'auto_xa_time_spinbutton')
|
||||||
self.auto_xa_message_entry = self.xml.get_widget('auto_xa_message_entry')
|
self.auto_xa_message_entry = self.xml.get_widget('auto_xa_message_entry')
|
||||||
|
|
||||||
w = self.xml.get_widget('anc_hbox')
|
|
||||||
|
|
||||||
### General tab ###
|
### General tab ###
|
||||||
# Display avatars in roster
|
# Display avatars in roster
|
||||||
st = gajim.config.get('show_avatars_in_roster')
|
st = gajim.config.get('show_avatars_in_roster')
|
||||||
|
@ -132,14 +130,6 @@ class PreferencesWindow:
|
||||||
if not gajim.config.get('emoticons_theme'):
|
if not gajim.config.get('emoticons_theme'):
|
||||||
emoticons_combobox.set_active(len(l)-1)
|
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
|
# Set default for single window type
|
||||||
choices = common.config.opt_one_window_types
|
choices = common.config.opt_one_window_types
|
||||||
type = gajim.config.get('one_message_window')
|
type = gajim.config.get('one_message_window')
|
||||||
|
@ -163,6 +153,7 @@ class PreferencesWindow:
|
||||||
else:
|
else:
|
||||||
self.xml.get_widget('speller_checkbutton').set_sensitive(False)
|
self.xml.get_widget('speller_checkbutton').set_sensitive(False)
|
||||||
|
|
||||||
|
### Style tab ###
|
||||||
# Themes
|
# Themes
|
||||||
theme_combobox = self.xml.get_widget('theme_combobox')
|
theme_combobox = self.xml.get_widget('theme_combobox')
|
||||||
cell = gtk.CellRendererText()
|
cell = gtk.CellRendererText()
|
||||||
|
@ -211,7 +202,37 @@ class PreferencesWindow:
|
||||||
st = gajim.config.get('use_transports_iconsets')
|
st = gajim.config.get('use_transports_iconsets')
|
||||||
self.xml.get_widget('transports_iconsets_checkbutton').set_active(st)
|
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
|
# outgoing send chat state notifications
|
||||||
st = gajim.config.get('outgoing_chat_state_notifications')
|
st = gajim.config.get('outgoing_chat_state_notifications')
|
||||||
combo = self.xml.get_widget('outgoing_chat_states_combobox')
|
combo = self.xml.get_widget('outgoing_chat_states_combobox')
|
||||||
|
@ -232,11 +253,29 @@ class PreferencesWindow:
|
||||||
else: # disabled
|
else: # disabled
|
||||||
combo.set_active(2)
|
combo.set_active(2)
|
||||||
|
|
||||||
# Ignore messages from unknown contacts
|
# PEP
|
||||||
self.xml.get_widget('ignore_events_from_unknown_contacts_checkbutton').\
|
st = gajim.config.get('publish_mood')
|
||||||
set_active(gajim.config.get('ignore_unknown_contacts'))
|
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 new event
|
||||||
on_event_combobox = self.xml.get_widget('on_event_combobox')
|
on_event_combobox = self.xml.get_widget('on_event_combobox')
|
||||||
if gajim.config.get('autopopup'):
|
if gajim.config.get('autopopup'):
|
||||||
|
@ -306,6 +345,24 @@ class PreferencesWindow:
|
||||||
|
|
||||||
self.fill_sound_treeview()
|
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
|
# Autoaway
|
||||||
st = gajim.config.get('autoaway')
|
st = gajim.config.get('autoaway')
|
||||||
self.auto_away_checkbutton.set_active(st)
|
self.auto_away_checkbutton.set_active(st)
|
||||||
|
@ -356,7 +413,7 @@ class PreferencesWindow:
|
||||||
renderer = gtk.CellRendererText()
|
renderer = gtk.CellRendererText()
|
||||||
col.pack_start(renderer, False)
|
col.pack_start(renderer, False)
|
||||||
col.set_attributes(renderer, text = 1)
|
col.set_attributes(renderer, text = 1)
|
||||||
col = gtk.TreeViewColumn('Message')
|
col = gtk.TreeViewColumn('Default Message')
|
||||||
self.default_msg_tree.append_column(col)
|
self.default_msg_tree.append_column(col)
|
||||||
renderer = gtk.CellRendererText()
|
renderer = gtk.CellRendererText()
|
||||||
col.pack_start(renderer, True)
|
col.pack_start(renderer, True)
|
||||||
|
@ -387,6 +444,7 @@ class PreferencesWindow:
|
||||||
buf = self.xml.get_widget('msg_textview').get_buffer()
|
buf = self.xml.get_widget('msg_textview').get_buffer()
|
||||||
buf.connect('changed', self.on_msg_textview_changed)
|
buf.connect('changed', self.on_msg_textview_changed)
|
||||||
|
|
||||||
|
### Advanced tab ###
|
||||||
# open links with
|
# open links with
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
applications_frame = self.xml.get_widget('applications_frame')
|
applications_frame = self.xml.get_widget('applications_frame')
|
||||||
|
@ -417,7 +475,7 @@ class PreferencesWindow:
|
||||||
self.applications_combobox.set_active(2)
|
self.applications_combobox.set_active(2)
|
||||||
elif gajim.config.get('openwith') == 'exo-open':
|
elif gajim.config.get('openwith') == 'exo-open':
|
||||||
self.applications_combobox.set_active(3)
|
self.applications_combobox.set_active(3)
|
||||||
elif ((sys.platform == 'darwin') and
|
elif ((sys.platform == 'darwin') and\
|
||||||
(gajim.config.get('openwith') == 'open')):
|
(gajim.config.get('openwith') == 'open')):
|
||||||
self.applications_combobox.set_active(1)
|
self.applications_combobox.set_active(1)
|
||||||
elif gajim.config.get('openwith') == 'custom':
|
elif gajim.config.get('openwith') == 'custom':
|
||||||
|
@ -438,74 +496,21 @@ class PreferencesWindow:
|
||||||
st = gajim.config.get('log_contact_status_changes')
|
st = gajim.config.get('log_contact_status_changes')
|
||||||
self.xml.get_widget('log_show_changes_checkbutton').set_active(st)
|
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
|
# send os info
|
||||||
st = gajim.config.get('send_os_info')
|
st = gajim.config.get('send_os_info')
|
||||||
self.xml.get_widget('send_os_info_checkbutton').set_active(st)
|
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')
|
st = gajim.config.get('check_if_gajim_is_default')
|
||||||
self.xml.get_widget('check_default_client_checkbutton').set_active(st)
|
self.xml.get_widget('check_default_client_checkbutton').set_active(st)
|
||||||
|
|
||||||
# set status msg from currently playing music track
|
# Ignore messages from unknown contacts
|
||||||
widget = self.xml.get_widget(
|
self.xml.get_widget('ignore_events_from_unknown_contacts_checkbutton').\
|
||||||
'set_status_msg_from_current_music_track_checkbutton')
|
set_active(gajim.config.get('ignore_unknown_contacts'))
|
||||||
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)
|
|
||||||
|
|
||||||
self.xml.signal_autoconnect(self)
|
self.xml.signal_autoconnect(self)
|
||||||
|
|
||||||
|
@ -521,6 +526,7 @@ class PreferencesWindow:
|
||||||
self.theme_preferences = None
|
self.theme_preferences = None
|
||||||
|
|
||||||
self.notebook.set_current_page(0)
|
self.notebook.set_current_page(0)
|
||||||
|
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
gtkgui_helpers.possibly_move_window_in_current_desktop(self.window)
|
gtkgui_helpers.possibly_move_window_in_current_desktop(self.window)
|
||||||
|
|
||||||
|
@ -536,6 +542,42 @@ class PreferencesWindow:
|
||||||
w.set_sensitive(widget.get_active())
|
w.set_sensitive(widget.get_active())
|
||||||
gajim.interface.save_config()
|
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):
|
def on_show_avatars_in_roster_checkbutton_toggled(self, widget):
|
||||||
self.on_checkbutton_toggled(widget, 'show_avatars_in_roster')
|
self.on_checkbutton_toggled(widget, 'show_avatars_in_roster')
|
||||||
gajim.interface.roster.draw_roster()
|
gajim.interface.roster.draw_roster()
|
||||||
|
@ -576,11 +618,6 @@ class PreferencesWindow:
|
||||||
for win in gajim.interface.msg_win_mgr.windows():
|
for win in gajim.interface.msg_win_mgr.windows():
|
||||||
win.toggle_emoticons()
|
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):
|
def on_one_window_type_combo_changed(self, widget):
|
||||||
active = widget.get_active()
|
active = widget.get_active()
|
||||||
config_type = common.config.opt_one_window_types[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):
|
def on_log_show_changes_checkbutton_toggled(self, widget):
|
||||||
self.on_checkbutton_toggled(widget, 'log_contact_status_changes')
|
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):
|
def on_send_os_info_checkbutton_toggled(self, widget):
|
||||||
self.on_checkbutton_toggled(widget, 'send_os_info')
|
self.on_checkbutton_toggled(widget, 'send_os_info')
|
||||||
|
|
||||||
|
@ -1030,26 +1070,23 @@ class PreferencesWindow:
|
||||||
def fill_sound_treeview(self):
|
def fill_sound_treeview(self):
|
||||||
model = self.sound_tree.get_model()
|
model = self.sound_tree.get_model()
|
||||||
model.clear()
|
model.clear()
|
||||||
|
model.set_sort_column_id(1, gtk.SORT_ASCENDING)
|
||||||
|
|
||||||
# NOTE: sounds_ui_names MUST have all items of
|
# NOTE: sounds_ui_names MUST have all items of
|
||||||
# sounds = gajim.config.get_per('soundevents') as keys
|
# sounds = gajim.config.get_per('soundevents') as keys
|
||||||
sounds_dict = {
|
sounds_dict = {
|
||||||
'first_message_received': _('First Message Received'),
|
'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_connected': _('Contact Connected'),
|
||||||
'contact_disconnected': _('Contact Disconnected'),
|
'contact_disconnected': _('Contact Disconnected'),
|
||||||
'message_sent': _('Message Sent'),
|
'message_sent': _('Message Sent'),
|
||||||
'muc_message_highlight': _('Group Chat Message Highlight'),
|
'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():
|
for sound_event_config_name, sound_ui_name in sounds_dict.items():
|
||||||
enabled = gajim.config.get_per('soundevents',
|
enabled = gajim.config.get_per('soundevents',
|
||||||
sound_event_config_name, 'enabled')
|
sound_event_config_name, 'enabled')
|
||||||
|
@ -1290,6 +1327,7 @@ class AccountsWindow:
|
||||||
del gajim.interface.instances['accounts']
|
del gajim.interface.instances['accounts']
|
||||||
|
|
||||||
def on_close_button_clicked(self, widget):
|
def on_close_button_clicked(self, widget):
|
||||||
|
self.check_resend_relog()
|
||||||
self.window.destroy()
|
self.window.destroy()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -1299,8 +1337,6 @@ class AccountsWindow:
|
||||||
self.accounts_treeview = self.xml.get_widget('accounts_treeview')
|
self.accounts_treeview = self.xml.get_widget('accounts_treeview')
|
||||||
self.remove_button = self.xml.get_widget('remove_button')
|
self.remove_button = self.xml.get_widget('remove_button')
|
||||||
self.rename_button = self.xml.get_widget('rename_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',
|
path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
|
||||||
'kbd_input.png')
|
'kbd_input.png')
|
||||||
img = self.xml.get_widget('rename_image')
|
img = self.xml.get_widget('rename_image')
|
||||||
|
@ -1327,7 +1363,10 @@ class AccountsWindow:
|
||||||
|
|
||||||
# Merge accounts
|
# Merge accounts
|
||||||
st = gajim.config.get('mergeaccounts')
|
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
|
self.avahi_available = True
|
||||||
try:
|
try:
|
||||||
|
@ -1337,6 +1376,7 @@ class AccountsWindow:
|
||||||
|
|
||||||
def on_accounts_window_key_press_event(self, widget, event):
|
def on_accounts_window_key_press_event(self, widget, event):
|
||||||
if event.keyval == gtk.keysyms.Escape:
|
if event.keyval == gtk.keysyms.Escape:
|
||||||
|
self.check_resend_relog()
|
||||||
self.window.destroy()
|
self.window.destroy()
|
||||||
|
|
||||||
def select_account(self, account):
|
def select_account(self, account):
|
||||||
|
@ -1354,7 +1394,6 @@ class AccountsWindow:
|
||||||
self.remove_button.set_sensitive(False)
|
self.remove_button.set_sensitive(False)
|
||||||
self.rename_button.set_sensitive(False)
|
self.rename_button.set_sensitive(False)
|
||||||
self.current_account = None
|
self.current_account = None
|
||||||
self.init_account()
|
|
||||||
model = self.accounts_treeview.get_model()
|
model = self.accounts_treeview.get_model()
|
||||||
model.clear()
|
model.clear()
|
||||||
for account in gajim.config.get_per('accounts'):
|
for account in gajim.config.get_per('accounts'):
|
||||||
|
@ -1366,37 +1405,7 @@ class AccountsWindow:
|
||||||
status = gajim.connections[self.current_account].status
|
status = gajim.connections[self.current_account].status
|
||||||
gajim.connections[self.current_account].change_status(show, status)
|
gajim.connections[self.current_account].change_status(show, status)
|
||||||
|
|
||||||
def on_accounts_treeview_cursor_changed(self, widget):
|
def check_resend_relog(self):
|
||||||
'''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)
|
|
||||||
|
|
||||||
if self.need_relogin and self.current_account == gajim.ZEROCONF_ACC_NAME:
|
if self.need_relogin and self.current_account == gajim.ZEROCONF_ACC_NAME:
|
||||||
if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
|
if gajim.connections.has_key(gajim.ZEROCONF_ACC_NAME):
|
||||||
gajim.connections[gajim.ZEROCONF_ACC_NAME].update_details()
|
gajim.connections[gajim.ZEROCONF_ACC_NAME].update_details()
|
||||||
|
@ -1435,6 +1444,40 @@ class AccountsWindow:
|
||||||
|
|
||||||
self.need_relogin = False
|
self.need_relogin = False
|
||||||
self.resend_presence = 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.remove_button.set_sensitive(True)
|
||||||
self.rename_button.set_sensitive(True)
|
self.rename_button.set_sensitive(True)
|
||||||
if iter:
|
if iter:
|
||||||
|
@ -1585,8 +1628,16 @@ class AccountsWindow:
|
||||||
'priority'))
|
'priority'))
|
||||||
|
|
||||||
# Connection tab
|
# Connection tab
|
||||||
usessl = gajim.config.get_per('accounts', account, 'usessl')
|
use_env_http_proxy = gajim.config.get_per('accounts', account,
|
||||||
self.xml.get_widget('use_ssl_checkbutton1').set_active(usessl)
|
'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(
|
self.xml.get_widget('send_keepalive_checkbutton1').set_active(
|
||||||
gajim.config.get_per('accounts', account, 'keep_alives_enabled'))
|
gajim.config.get_per('accounts', account, 'keep_alives_enabled'))
|
||||||
|
@ -1899,7 +1950,8 @@ class AccountsWindow:
|
||||||
'no_log_for').split()
|
'no_log_for').split()
|
||||||
if self.current_account in list_no_log_for:
|
if self.current_account in list_no_log_for:
|
||||||
list_no_log_for.remove(self.current_account)
|
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)
|
list_no_log_for.append(self.current_account)
|
||||||
gajim.config.set_per('accounts', self.current_account, 'no_log_for',
|
gajim.config.set_per('accounts', self.current_account, 'no_log_for',
|
||||||
' '.join(list_no_log_for))
|
' '.join(list_no_log_for))
|
||||||
|
@ -1917,6 +1969,14 @@ class AccountsWindow:
|
||||||
self.on_checkbutton_toggled(widget, 'use_ft_proxies',
|
self.on_checkbutton_toggled(widget, 'use_ft_proxies',
|
||||||
account=self.current_account)
|
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):
|
def on_proxies_combobox1_changed(self, widget):
|
||||||
active = widget.get_active()
|
active = widget.get_active()
|
||||||
proxy = widget.get_model()[active][0].decode('utf-8')
|
proxy = widget.get_model()[active][0].decode('utf-8')
|
||||||
|
@ -1934,20 +1994,11 @@ class AccountsWindow:
|
||||||
else:
|
else:
|
||||||
gajim.interface.instances['manage_proxies'] = ManageProxiesWindow()
|
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:
|
if self.ignore_events:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.option_changed('usessl', widget.get_active()):
|
self.on_checkbutton_toggled(widget, 'warn_when_insecure_connection',
|
||||||
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',
|
|
||||||
account=self.current_account)
|
account=self.current_account)
|
||||||
|
|
||||||
def on_send_keepalive_checkbutton1_toggled(self, widget):
|
def on_send_keepalive_checkbutton1_toggled(self, widget):
|
||||||
|
@ -1992,14 +2043,14 @@ class AccountsWindow:
|
||||||
custom_port)
|
custom_port)
|
||||||
|
|
||||||
def on_gpg_choose_button_clicked(self, widget, data = None):
|
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].\
|
secret_keys = gajim.connections[self.current_account].\
|
||||||
ask_gpg_secrete_keys()
|
ask_gpg_secrete_keys()
|
||||||
|
|
||||||
# self.current_account is None and/or gajim.connections is {}
|
# self.current_account is None and/or gajim.connections is {}
|
||||||
else:
|
else:
|
||||||
from common import GnuPG
|
if gajim.HAVE_GPG:
|
||||||
if GnuPG.USE_GPG:
|
|
||||||
secret_keys = GnuPG.GnuPG().get_secret_keys()
|
secret_keys = GnuPG.GnuPG().get_secret_keys()
|
||||||
else:
|
else:
|
||||||
secret_keys = []
|
secret_keys = []
|
||||||
|
@ -3030,7 +3081,7 @@ class AccountCreationWizardWindow:
|
||||||
elif cur_page == 1:
|
elif cur_page == 1:
|
||||||
# We are adding an existing account
|
# We are adding an existing account
|
||||||
username = self.xml.get_widget('username_entry').get_text().decode(
|
username = self.xml.get_widget('username_entry').get_text().decode(
|
||||||
'utf-8')
|
'utf-8').strip()
|
||||||
if not username:
|
if not username:
|
||||||
pritext = _('Invalid username')
|
pritext = _('Invalid username')
|
||||||
sectext = _(
|
sectext = _(
|
||||||
|
@ -3038,7 +3089,7 @@ class AccountCreationWizardWindow:
|
||||||
dialogs.ErrorDialog(pritext, sectext)
|
dialogs.ErrorDialog(pritext, sectext)
|
||||||
return
|
return
|
||||||
server = self.xml.get_widget('server_comboboxentry').child.get_text().\
|
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').\
|
savepass = self.xml.get_widget('save_password_checkbutton').\
|
||||||
get_active()
|
get_active()
|
||||||
password = self.xml.get_widget('password_entry').get_text().decode(
|
password = self.xml.get_widget('password_entry').get_text().decode(
|
||||||
|
@ -3142,6 +3193,16 @@ class AccountCreationWizardWindow:
|
||||||
if checked:
|
if checked:
|
||||||
hostname = gajim.connections[self.account].new_account_info[
|
hostname = gajim.connections[self.account].new_account_info[
|
||||||
'hostname']
|
'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 = open(gajim.MY_CACERTS, 'a')
|
||||||
f.write(hostname + '\n')
|
f.write(hostname + '\n')
|
||||||
f.write(self.ssl_cert + '\n\n')
|
f.write(self.ssl_cert + '\n\n')
|
||||||
|
@ -3188,7 +3249,7 @@ class AccountCreationWizardWindow:
|
||||||
self.progressbar.pulse()
|
self.progressbar.pulse()
|
||||||
return True # loop forever
|
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):
|
ssl_fingerprint):
|
||||||
'''connection to server succeded, present the form to the user.'''
|
'''connection to server succeded, present the form to the user.'''
|
||||||
if self.update_progressbar_timeout_id is not None:
|
if self.update_progressbar_timeout_id is not None:
|
||||||
|
@ -3213,8 +3274,12 @@ class AccountCreationWizardWindow:
|
||||||
'SSL Error: %s\n'
|
'SSL Error: %s\n'
|
||||||
'Do you still want to connect to this server?') % (hostname,
|
'Do you still want to connect to this server?') % (hostname,
|
||||||
ssl_msg))
|
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
|
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)
|
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
|
self.notebook.set_current_page(3) # show SSL page
|
||||||
else:
|
else:
|
||||||
self.notebook.set_current_page(4) # show form page
|
self.notebook.set_current_page(4) # show form page
|
||||||
|
@ -3406,3 +3471,277 @@ class AccountCreationWizardWindow:
|
||||||
gajim.interface.roster.draw_roster()
|
gajim.interface.roster.draw_roster()
|
||||||
gajim.interface.roster.set_actions_menu_needs_rebuild()
|
gajim.interface.roster.set_actions_menu_needs_rebuild()
|
||||||
gajim.interface.save_config()
|
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.anchor = anchor
|
||||||
self._selected = False
|
self._selected = False
|
||||||
self._disconnect_funcs = []
|
self._disconnect_funcs = []
|
||||||
self.connect("parent-set", self.on_parent_set)
|
self.connect('parent-set', self.on_parent_set)
|
||||||
self.connect("expose-event", self.on_expose)
|
self.connect('expose-event', self.on_expose)
|
||||||
|
|
||||||
def _get_selected(self):
|
def _get_selected(self):
|
||||||
parent = self.get_parent()
|
parent = self.get_parent()
|
||||||
|
@ -110,13 +110,13 @@ class TextViewImage(gtk.Image):
|
||||||
self._disconnect_signals()
|
self._disconnect_signals()
|
||||||
return
|
return
|
||||||
|
|
||||||
self._do_connect(parent, "style-set", 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-in-event', self.do_queue_draw)
|
||||||
self._do_connect(parent, "focus-out-event", self.do_queue_draw)
|
self._do_connect(parent, 'focus-out-event', self.do_queue_draw)
|
||||||
|
|
||||||
textbuf = parent.get_buffer()
|
textbuf = parent.get_buffer()
|
||||||
self._do_connect(textbuf, "mark-set", self.on_mark_set)
|
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-deleted', self.on_mark_deleted)
|
||||||
|
|
||||||
def do_queue_draw(self, *args):
|
def do_queue_draw(self, *args):
|
||||||
self.queue_draw()
|
self.queue_draw()
|
||||||
|
@ -186,7 +186,7 @@ class ConversationTextview:
|
||||||
self.on_textview_button_press_event)
|
self.on_textview_button_press_event)
|
||||||
self.handlers[id] = self.tv
|
self.handlers[id] = self.tv
|
||||||
|
|
||||||
id = self.tv.connect("expose-event",
|
id = self.tv.connect('expose-event',
|
||||||
self.on_textview_expose_event)
|
self.on_textview_expose_event)
|
||||||
self.handlers[id] = self.tv
|
self.handlers[id] = self.tv
|
||||||
|
|
||||||
|
@ -213,10 +213,9 @@ class ConversationTextview:
|
||||||
|
|
||||||
colors = gajim.config.get('gc_nicknames_colors')
|
colors = gajim.config.get('gc_nicknames_colors')
|
||||||
colors = colors.split(':')
|
colors = colors.split(':')
|
||||||
for color in xrange(len(colors)):
|
for i,color in enumerate(colors):
|
||||||
tagname = 'gc_nickname_color_' + str(color)
|
tagname = 'gc_nickname_color_' + str(i)
|
||||||
tag = buffer.create_tag(tagname)
|
tag = buffer.create_tag(tagname)
|
||||||
color = colors[color]
|
|
||||||
tag.set_property('foreground', color)
|
tag.set_property('foreground', color)
|
||||||
|
|
||||||
tag = buffer.create_tag('marked')
|
tag = buffer.create_tag('marked')
|
||||||
|
@ -353,9 +352,8 @@ class ConversationTextview:
|
||||||
adjustment.set_value(0)
|
adjustment.set_value(0)
|
||||||
return False # when called in an idle_add, just do it once
|
return False # when called in an idle_add, just do it once
|
||||||
|
|
||||||
def bring_scroll_to_end(self, diff_y = 0,\
|
def bring_scroll_to_end(self, diff_y = 0,
|
||||||
use_smooth =\
|
use_smooth=gajim.config.get('use_smooth_scrolling')):
|
||||||
gajim.config.get('use_smooth_scrolling')):
|
|
||||||
''' scrolls to the end of textview if end is not visible '''
|
''' scrolls to the end of textview if end is not visible '''
|
||||||
buffer = self.tv.get_buffer()
|
buffer = self.tv.get_buffer()
|
||||||
end_iter = buffer.get_end_iter()
|
end_iter = buffer.get_end_iter()
|
||||||
|
@ -423,7 +421,8 @@ class ConversationTextview:
|
||||||
|
|
||||||
end_iter = buffer.get_end_iter()
|
end_iter = buffer.get_end_iter()
|
||||||
before_img_iter = end_iter.copy()
|
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)
|
buffer.apply_tag_by_name('focus-out-line', before_img_iter, end_iter)
|
||||||
|
|
||||||
self.allow_focus_out_line = False
|
self.allow_focus_out_line = False
|
||||||
|
@ -452,7 +451,8 @@ class ConversationTextview:
|
||||||
# check if the current pointer is still over the line
|
# check if the current pointer is still over the line
|
||||||
position = self.tv.window.get_origin()
|
position = self.tv.window.get_origin()
|
||||||
self.line_tooltip.show_tooltip(_('Text below this line is what has '
|
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):
|
def on_textview_expose_event(self, widget, event):
|
||||||
expalloc = event.area
|
expalloc = event.area
|
||||||
|
@ -582,7 +582,8 @@ class ConversationTextview:
|
||||||
else:
|
else:
|
||||||
if dict_link.find('%s') == -1:
|
if dict_link.find('%s') == -1:
|
||||||
# we must have %s in the url if not WIKTIONARY
|
# 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)
|
item.set_property('sensitive', False)
|
||||||
else:
|
else:
|
||||||
link = dict_link % self.selected_phrase
|
link = dict_link % self.selected_phrase
|
||||||
|
@ -639,7 +640,8 @@ class ConversationTextview:
|
||||||
if return_val: # if sth was selected when we right-clicked
|
if return_val: # if sth was selected when we right-clicked
|
||||||
# get the selected text
|
# get the selected text
|
||||||
start_sel, finish_sel = return_val[0], return_val[1]
|
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):
|
def on_open_link_activate(self, widget, kind, text):
|
||||||
helpers.launch_browser_mailer(kind, text)
|
helpers.launch_browser_mailer(kind, text)
|
||||||
|
@ -673,7 +675,8 @@ class ConversationTextview:
|
||||||
if kind == 'url':
|
if kind == 'url':
|
||||||
id = childs[0].connect('activate', self.on_copy_link_activate, text)
|
id = childs[0].connect('activate', self.on_copy_link_activate, text)
|
||||||
self.handlers[id] = childs[0]
|
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]
|
self.handlers[id] = childs[1]
|
||||||
childs[2].hide() # copy mail address
|
childs[2].hide() # copy mail address
|
||||||
childs[3].hide() # open mail composer
|
childs[3].hide() # open mail composer
|
||||||
|
@ -691,7 +694,8 @@ class ConversationTextview:
|
||||||
text = text.lower()
|
text = text.lower()
|
||||||
id = childs[2].connect('activate', self.on_copy_link_activate, text)
|
id = childs[2].connect('activate', self.on_copy_link_activate, text)
|
||||||
self.handlers[id] = childs[2]
|
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]
|
self.handlers[id] = childs[3]
|
||||||
id = childs[5].connect('activate', self.on_start_chat_activate, text)
|
id = childs[5].connect('activate', self.on_start_chat_activate, text)
|
||||||
self.handlers[id] = childs[5]
|
self.handlers[id] = childs[5]
|
||||||
|
@ -708,7 +712,8 @@ class ConversationTextview:
|
||||||
allow_add = True
|
allow_add = True
|
||||||
|
|
||||||
if allow_add:
|
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]
|
self.handlers[id] = childs[7]
|
||||||
childs[7].show() # show add to roster menuitem
|
childs[7].show() # show add to roster menuitem
|
||||||
else:
|
else:
|
||||||
|
@ -729,7 +734,8 @@ class ConversationTextview:
|
||||||
# we get the end of the tag
|
# we get the end of the tag
|
||||||
while not end_iter.ends_tag(texttag):
|
while not end_iter.ends_tag(texttag):
|
||||||
end_iter.forward_char()
|
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
|
if event.button == 3: # right click
|
||||||
self.make_link_menu(event, kind, word)
|
self.make_link_menu(event, kind, word)
|
||||||
else:
|
else:
|
||||||
|
@ -786,16 +792,16 @@ class ConversationTextview:
|
||||||
exitcode = 0
|
exitcode = 0
|
||||||
|
|
||||||
# some latex commands are really bad
|
# some latex commands are really bad
|
||||||
blacklist = ["\\def", "\\let", "\\futurelet",
|
blacklist = ['\\def', '\\let', '\\futurelet',
|
||||||
"\\newcommand", "\\renewcomment", "\\else", "\\fi", "\\write",
|
'\\newcommand', '\\renewcomment', '\\else', '\\fi', '\\write',
|
||||||
"\\input", "\\include", "\\chardef", "\\catcode", "\\makeatletter",
|
'\\input', '\\include', '\\chardef', '\\catcode', '\\makeatletter',
|
||||||
"\\noexpand", "\\toksdef", "\\every", "\\errhelp", "\\errorstopmode",
|
'\\noexpand', '\\toksdef', '\\every', '\\errhelp', '\\errorstopmode',
|
||||||
"\\scrollmode", "\\nonstopmode", "\\batchmode", "\\read", "\\csname",
|
'\\scrollmode', '\\nonstopmode', '\\batchmode', '\\read', '\\csname',
|
||||||
"\\newhelp", "\\relax", "\\afterground", "\\afterassignment",
|
'\\newhelp', '\\relax', '\\afterground', '\\afterassignment',
|
||||||
"\\expandafter", "\\noexpand", "\\special", "\\command", "\\loop",
|
'\\expandafter', '\\noexpand', '\\special', '\\command', '\\loop',
|
||||||
"\\repeat", "\\toks", "\\output", "\\line", "\\mathcode", "\\name",
|
'\\repeat', '\\toks', '\\output', '\\line', '\\mathcode', '\\name',
|
||||||
"\\item", "\\section", "\\mbox", "\\DeclareRobustCommand", "\\[",
|
'\\item', '\\section', '\\mbox', '\\DeclareRobustCommand', '\\[',
|
||||||
"\\]"]
|
'\\]']
|
||||||
|
|
||||||
str = str[2:len(str)-2]
|
str = str[2:len(str)-2]
|
||||||
|
|
||||||
|
@ -807,16 +813,18 @@ class ConversationTextview:
|
||||||
|
|
||||||
if exitcode == 0:
|
if exitcode == 0:
|
||||||
random.seed()
|
random.seed()
|
||||||
tmpfile = os.path.join(gettempdir(), "gajimtex_" + random.randint(0,
|
tmpfile = os.path.join(gettempdir(), 'gajimtex_' + random.randint(0,
|
||||||
100).__str__())
|
100).__str__())
|
||||||
|
|
||||||
# build latex string
|
# build latex string
|
||||||
texstr = "\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}\\usepackage{amsmath}\\usepackage{amssymb}\\pagestyle{empty}"
|
texstr = '\\documentclass[12pt]{article}\\usepackage[dvips]{graphicx}'
|
||||||
texstr += "\\begin{document}\\begin{large}\\begin{gather*}"
|
texstr += '\\usepackage{amsmath}\\usepackage{amssymb}'
|
||||||
|
texstr += '\\pagestyle{empty}'
|
||||||
|
texstr += '\\begin{document}\\begin{large}\\begin{gather*}'
|
||||||
texstr += str
|
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.write(texstr)
|
||||||
file.flush()
|
file.flush()
|
||||||
file.close()
|
file.close()
|
||||||
|
@ -831,11 +839,11 @@ class ConversationTextview:
|
||||||
exitcode = p.wait()
|
exitcode = p.wait()
|
||||||
|
|
||||||
if exitcode == 0:
|
if exitcode == 0:
|
||||||
p = Popen(['convert', tmpfile + '.ps', tmpfile + '.png'],
|
p = Popen(['convert', '-alpha', 'off', tmpfile + '.ps',
|
||||||
cwd=gettempdir())
|
tmpfile + '.png'], cwd=gettempdir())
|
||||||
exitcode = p.wait()
|
exitcode = p.wait()
|
||||||
|
|
||||||
extensions = [".tex", ".log", ".aux", ".dvi", ".ps"]
|
extensions = ['.tex', '.log', '.aux', '.dvi', '.ps']
|
||||||
for ext in extensions:
|
for ext in extensions:
|
||||||
try:
|
try:
|
||||||
os.remove(tmpfile + ext)
|
os.remove(tmpfile + ext)
|
||||||
|
@ -895,11 +903,13 @@ class ConversationTextview:
|
||||||
use_other_tags = False
|
use_other_tags = False
|
||||||
elif special_text.startswith('*'): # it's a bold text
|
elif special_text.startswith('*'): # it's a bold text
|
||||||
tags.append('bold')
|
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')
|
tags.append('italic')
|
||||||
if not show_ascii_formatting_chars:
|
if not show_ascii_formatting_chars:
|
||||||
special_text = special_text[2:-2] # remove */ /*
|
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')
|
tags.append('underline')
|
||||||
if not show_ascii_formatting_chars:
|
if not show_ascii_formatting_chars:
|
||||||
special_text = special_text[2:-2] # remove *_ _*
|
special_text = special_text[2:-2] # remove *_ _*
|
||||||
|
@ -908,11 +918,13 @@ class ConversationTextview:
|
||||||
special_text = special_text[1:-1] # remove * *
|
special_text = special_text[1:-1] # remove * *
|
||||||
elif special_text.startswith('/'): # it's an italic text
|
elif special_text.startswith('/'): # it's an italic text
|
||||||
tags.append('italic')
|
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')
|
tags.append('bold')
|
||||||
if not show_ascii_formatting_chars:
|
if not show_ascii_formatting_chars:
|
||||||
special_text = special_text[2:-2] # remove /* */
|
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')
|
tags.append('underline')
|
||||||
if not show_ascii_formatting_chars:
|
if not show_ascii_formatting_chars:
|
||||||
special_text = special_text[2:-2] # remove /_ _/
|
special_text = special_text[2:-2] # remove /_ _/
|
||||||
|
@ -921,11 +933,13 @@ class ConversationTextview:
|
||||||
special_text = special_text[1:-1] # remove / /
|
special_text = special_text[1:-1] # remove / /
|
||||||
elif special_text.startswith('_'): # it's an underlined text
|
elif special_text.startswith('_'): # it's an underlined text
|
||||||
tags.append('underline')
|
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')
|
tags.append('bold')
|
||||||
if not show_ascii_formatting_chars:
|
if not show_ascii_formatting_chars:
|
||||||
special_text = special_text[2:-2] # remove _* *_
|
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')
|
tags.append('italic')
|
||||||
if not show_ascii_formatting_chars:
|
if not show_ascii_formatting_chars:
|
||||||
special_text = special_text[2:-2] # remove _/ /_
|
special_text = special_text[2:-2] # remove _/ /_
|
||||||
|
@ -1123,8 +1137,8 @@ class ConversationTextview:
|
||||||
self.tv.display_html(xhtml.encode('utf-8'))
|
self.tv.display_html(xhtml.encode('utf-8'))
|
||||||
return
|
return
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
gajim.log.debug(str("Error processing xhtml")+str(e))
|
gajim.log.debug(str('Error processing xhtml')+str(e))
|
||||||
gajim.log.debug(str("with |"+xhtml+"|"))
|
gajim.log.debug(str('with |'+xhtml+'|'))
|
||||||
|
|
||||||
buffer = self.tv.get_buffer()
|
buffer = self.tv.get_buffer()
|
||||||
# /me is replaced by name if name is given
|
# /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
|
# add the rest of text located in the index and after
|
||||||
end_iter = buffer.get_end_iter()
|
end_iter = buffer.get_end_iter()
|
||||||
buffer.insert_with_tags_by_name(end_iter, text[index:], *text_tags)
|
buffer.insert_with_tags_by_name(end_iter, text[index:], *text_tags)
|
||||||
|
|
||||||
|
|
190
src/dialogs.py
190
src/dialogs.py
|
@ -351,9 +351,9 @@ class ChooseGPGKeyDialog:
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
rep = self.window.run()
|
rep = self.window.run()
|
||||||
if rep == gtk.RESPONSE_OK:
|
|
||||||
selection = self.keys_treeview.get_selection()
|
selection = self.keys_treeview.get_selection()
|
||||||
(model, iter) = selection.get_selected()
|
(model, iter) = selection.get_selected()
|
||||||
|
if iter and rep == gtk.RESPONSE_OK:
|
||||||
keyID = [ model[iter][0].decode('utf-8'),
|
keyID = [ model[iter][0].decode('utf-8'),
|
||||||
model[iter][1].decode('utf-8') ]
|
model[iter][1].decode('utf-8') ]
|
||||||
else:
|
else:
|
||||||
|
@ -370,6 +370,125 @@ class ChooseGPGKeyDialog:
|
||||||
self.keys_treeview.set_cursor(path)
|
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:
|
class ChangeStatusMessageDialog:
|
||||||
def __init__(self, show = None):
|
def __init__(self, show = None):
|
||||||
self.show = show
|
self.show = show
|
||||||
|
@ -922,7 +1041,7 @@ class HigDialog(gtk.MessageDialog):
|
||||||
gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL,
|
gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL,
|
||||||
type, buttons, message_format = pritext)
|
type, buttons, message_format = pritext)
|
||||||
|
|
||||||
self.format_secondary_text(sectext)
|
self.format_secondary_markup(sectext)
|
||||||
|
|
||||||
buttons = self.action_area.get_children()
|
buttons = self.action_area.get_children()
|
||||||
possible_responses = {gtk.STOCK_OK: on_response_ok,
|
possible_responses = {gtk.STOCK_OK: on_response_ok,
|
||||||
|
@ -1101,15 +1220,47 @@ class ErrorDialog(HigDialog):
|
||||||
self.popup()
|
self.popup()
|
||||||
|
|
||||||
class YesNoDialog(HigDialog):
|
class YesNoDialog(HigDialog):
|
||||||
def __init__(self, pritext, sectext='', on_response_yes = None,
|
def __init__(self, pritext, sectext='', checktext='', on_response_yes=None,
|
||||||
on_response_no=None):
|
on_response_no=None):
|
||||||
'''HIG compliant YesNo dialog.'''
|
'''HIG compliant YesNo dialog.'''
|
||||||
|
self.user_response_yes = on_response_yes
|
||||||
|
self.user_response_no = on_response_no
|
||||||
HigDialog.__init__( self, None,
|
HigDialog.__init__( self, None,
|
||||||
gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, pritext, sectext,
|
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.set_modal(False)
|
||||||
self.popup()
|
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):
|
class ConfirmationDialogCheck(ConfirmationDialog):
|
||||||
'''HIG compliant confirmation dialog with checkbutton.'''
|
'''HIG compliant confirmation dialog with checkbutton.'''
|
||||||
def __init__(self, pritext, sectext='', checktext = '',
|
def __init__(self, pritext, sectext='', checktext = '',
|
||||||
|
@ -1145,7 +1296,7 @@ class ConfirmationDialogCheck(ConfirmationDialog):
|
||||||
def on_response_cancel(self, widget):
|
def on_response_cancel(self, widget):
|
||||||
if self.user_response_cancel:
|
if self.user_response_cancel:
|
||||||
if isinstance(self.user_response_cancel, tuple):
|
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:
|
else:
|
||||||
self.user_response_cancel()
|
self.user_response_cancel()
|
||||||
self.destroy()
|
self.destroy()
|
||||||
|
@ -1922,14 +2073,14 @@ class SingleMessageWindow:
|
||||||
self.completion_dict = {}
|
self.completion_dict = {}
|
||||||
self.xml.signal_autoconnect(self)
|
self.xml.signal_autoconnect(self)
|
||||||
|
|
||||||
if gajim.config.get('saveposition'):
|
|
||||||
# get window position and size from config
|
# 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,
|
gtkgui_helpers.resize_window(self.window,
|
||||||
gajim.config.get('single-msg-width'),
|
gajim.config.get('single-msg-width'),
|
||||||
gajim.config.get('single-msg-height'))
|
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()
|
self.window.show_all()
|
||||||
|
|
||||||
def on_single_message_window_destroy(self, widget):
|
def on_single_message_window_destroy(self, widget):
|
||||||
|
@ -1940,7 +2091,6 @@ class SingleMessageWindow:
|
||||||
self.message_tv_buffer.place_cursor(end_iter)
|
self.message_tv_buffer.place_cursor(end_iter)
|
||||||
|
|
||||||
def save_pos(self):
|
def save_pos(self):
|
||||||
if gajim.config.get('saveposition'):
|
|
||||||
# save the window size and position
|
# save the window size and position
|
||||||
x, y = self.window.get_position()
|
x, y = self.window.get_position()
|
||||||
gajim.config.set('single-msg-x-position', x)
|
gajim.config.set('single-msg-x-position', x)
|
||||||
|
@ -3417,6 +3567,15 @@ class TransformChatToMUC:
|
||||||
|
|
||||||
self.guests_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
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
|
# set jabber id and pseudos
|
||||||
for account in gajim.contacts.get_accounts():
|
for account in gajim.contacts.get_accounts():
|
||||||
if gajim.connections[account].is_zeroconf:
|
if gajim.connections[account].is_zeroconf:
|
||||||
|
@ -3425,13 +3584,9 @@ class TransformChatToMUC:
|
||||||
contact = \
|
contact = \
|
||||||
gajim.contacts.get_contact_with_highest_priority(account, jid)
|
gajim.contacts.get_contact_with_highest_priority(account, jid)
|
||||||
contact_transport = gajim.get_transport_name_from_jid(jid)
|
contact_transport = gajim.get_transport_name_from_jid(jid)
|
||||||
# do not add transports, zeroconf contacs, minimized groupchats
|
# Add contact if it can be invited
|
||||||
# and selfjid to list of invitable jids
|
if invitable(contact, contact_transport) and \
|
||||||
if contact.jid not in self.auto_jids and contact.jid != \
|
contact.show not in ('offline', 'error'):
|
||||||
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'):
|
|
||||||
img = gajim.interface.roster.jabber_state_images['16'][
|
img = gajim.interface.roster.jabber_state_images['16'][
|
||||||
contact.show]
|
contact.show]
|
||||||
name = contact.name
|
name = contact.name
|
||||||
|
@ -3460,7 +3615,6 @@ class TransformChatToMUC:
|
||||||
server = self.server_list_comboboxentry.get_active_text()
|
server = self.server_list_comboboxentry.get_active_text()
|
||||||
if server == '':
|
if server == '':
|
||||||
return
|
return
|
||||||
room_id = gajim.nicks[self.account] + str(randrange(9999999))
|
|
||||||
gajim.connections[self.account].check_unique_room_id_support(server, self)
|
gajim.connections[self.account].check_unique_room_id_support(server, self)
|
||||||
|
|
||||||
def unique_room_id_supported(self, server, room_id):
|
def unique_room_id_supported(self, server, room_id):
|
||||||
|
|
|
@ -46,7 +46,6 @@ import inspect
|
||||||
import weakref
|
import weakref
|
||||||
import gobject
|
import gobject
|
||||||
import gtk
|
import gtk
|
||||||
import gobject
|
|
||||||
import pango
|
import pango
|
||||||
|
|
||||||
import dialogs
|
import dialogs
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import gtk
|
import gtk
|
||||||
import gobject
|
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
|
|
||||||
import dialogs
|
import dialogs
|
||||||
|
@ -53,7 +52,7 @@ class FeaturesWindow:
|
||||||
_('Requires python-avahi.'),
|
_('Requires python-avahi.'),
|
||||||
_('Requires pybonjour (http://o2s.csail.mit.edu/o2s-wiki/pybonjour).')),
|
_('Requires pybonjour (http://o2s.csail.mit.edu/o2s-wiki/pybonjour).')),
|
||||||
_('gajim-remote'): (self.dbus_available,
|
_('gajim-remote'): (self.dbus_available,
|
||||||
_('A script to controle gajim via commandline.'),
|
_('A script to controle Gajim via commandline.'),
|
||||||
_('Requires python-dbus.'),
|
_('Requires python-dbus.'),
|
||||||
_('Feature not available under Windows.')),
|
_('Feature not available under Windows.')),
|
||||||
_('OpenGPG'): (self.gpg_available,
|
_('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.'),
|
||||||
_('Requires compilation of the idle module from Gajim sources.')),
|
_('Requires compilation of the idle module from Gajim sources.')),
|
||||||
_('LaTeX'): (self.latex_available,
|
_('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.'),
|
_('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.')),
|
_('Feature not available under Windows.')),
|
||||||
_('End to end encryption'): (self.pycrypto_available,
|
_('End to end encryption'): (self.pycrypto_available,
|
||||||
|
@ -141,6 +140,8 @@ class FeaturesWindow:
|
||||||
|
|
||||||
def on_features_treeview_cursor_changed(self, widget):
|
def on_features_treeview_cursor_changed(self, widget):
|
||||||
selection = widget.get_selection()
|
selection = widget.get_selection()
|
||||||
|
if not selection:
|
||||||
|
return
|
||||||
path = selection.get_selected_rows()[1][0]
|
path = selection.get_selected_rows()[1][0]
|
||||||
available = self.model[path][1]
|
available = self.model[path][1]
|
||||||
feature = self.model[path][0].decode('utf-8')
|
feature = self.model[path][0].decode('utf-8')
|
||||||
|
@ -178,8 +179,8 @@ class FeaturesWindow:
|
||||||
def gpg_available(self):
|
def gpg_available(self):
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
return False
|
return False
|
||||||
from common import GnuPG
|
from common import gajim
|
||||||
return GnuPG.USE_GPG
|
return gajim.HAVE_GPG
|
||||||
|
|
||||||
def network_manager_available(self):
|
def network_manager_available(self):
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
|
|
148
src/gajim.py
148
src/gajim.py
|
@ -44,7 +44,6 @@ if os.name == 'nt':
|
||||||
# os.environ['GTK_BASEPATH'] = 'gtk'
|
# os.environ['GTK_BASEPATH'] = 'gtk'
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import urllib
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
consoleloghandler = logging.StreamHandler()
|
consoleloghandler = logging.StreamHandler()
|
||||||
|
@ -222,7 +221,6 @@ import gobject
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
import getopt
|
|
||||||
import time
|
import time
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
@ -457,10 +455,13 @@ class Interface:
|
||||||
|
|
||||||
def handle_event_http_auth(self, account, data):
|
def handle_event_http_auth(self, account, data):
|
||||||
#('HTTP_AUTH', account, (method, url, transaction_id, iq_obj, msg))
|
#('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()
|
self.dialog.destroy()
|
||||||
gajim.connections[account].build_http_auth_answer(iq_obj, answer)
|
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?')
|
sec_msg = _('Do you accept this request?')
|
||||||
if gajim.get_number_of_connected_accounts() > 1:
|
if gajim.get_number_of_connected_accounts() > 1:
|
||||||
sec_msg = _('Do you accept this request on account %s?') % account
|
sec_msg = _('Do you accept this request on account %s?') % account
|
||||||
|
@ -468,7 +469,7 @@ class Interface:
|
||||||
sec_msg = data[4] + '\n' + sec_msg
|
sec_msg = data[4] + '\n' + sec_msg
|
||||||
self.dialog = dialogs.YesNoDialog(_('HTTP (%s) Authorization for %s (id: %s)') \
|
self.dialog = dialogs.YesNoDialog(_('HTTP (%s) Authorization for %s (id: %s)') \
|
||||||
% (data[0], data[1], data[2]), sec_msg,
|
% (data[0], data[1], data[2]), sec_msg,
|
||||||
on_response_yes = (response, account, data[3], 'yes'),
|
on_response_yes=(on_yes, account, data[3]),
|
||||||
on_response_no=(response, account, data[3], 'no'))
|
on_response_no=(response, account, data[3], 'no'))
|
||||||
|
|
||||||
def handle_event_error_answer(self, account, array):
|
def handle_event_error_answer(self, account, array):
|
||||||
|
@ -581,10 +582,11 @@ class Interface:
|
||||||
jid = array[0].split('/')[0]
|
jid = array[0].split('/')[0]
|
||||||
keyID = array[5]
|
keyID = array[5]
|
||||||
contact_nickname = array[7]
|
contact_nickname = array[7]
|
||||||
attached_keys = gajim.config.get_per('accounts', account,
|
|
||||||
'attached_gpg_keys').split()
|
# Get the proper keyID
|
||||||
if jid in attached_keys:
|
keyID = helpers.prepare_and_validate_gpg_keyID(account,
|
||||||
keyID = attached_keys[attached_keys.index(jid) + 1]
|
jid, keyID)
|
||||||
|
|
||||||
resource = array[3]
|
resource = array[3]
|
||||||
if not resource:
|
if not resource:
|
||||||
resource = ''
|
resource = ''
|
||||||
|
@ -723,7 +725,7 @@ class Interface:
|
||||||
# remove in 2007
|
# remove in 2007
|
||||||
# It's maybe a GC_NOTIFY (specialy for MSN gc)
|
# It's maybe a GC_NOTIFY (specialy for MSN gc)
|
||||||
self.handle_event_gc_notify(account, (jid, array[1], status_message,
|
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):
|
def handle_event_msg(self, account, array):
|
||||||
|
@ -848,8 +850,14 @@ class Interface:
|
||||||
msg = message
|
msg = message
|
||||||
if subject:
|
if subject:
|
||||||
msg = _('Subject: %s') % subject + '\n' + msg
|
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,
|
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:
|
if self.remote_ctrl:
|
||||||
self.remote_ctrl.raise_signal('NewMessage', (account, array))
|
self.remote_ctrl.raise_signal('NewMessage', (account, array))
|
||||||
|
@ -949,13 +957,22 @@ class Interface:
|
||||||
self.remote_ctrl.raise_signal('Subscribed', (account, array))
|
self.remote_ctrl.raise_signal('Subscribed', (account, array))
|
||||||
|
|
||||||
def handle_event_unsubscribed(self, account, jid):
|
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)
|
gajim.connections[account].ack_unsubscribed(jid)
|
||||||
if self.remote_ctrl:
|
if self.remote_ctrl:
|
||||||
self.remote_ctrl.raise_signal('Unsubscribed', (account, jid))
|
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):
|
def handle_event_agent_info_error(self, account, agent):
|
||||||
#('AGENT_ERROR_INFO', account, (agent))
|
#('AGENT_ERROR_INFO', account, (agent))
|
||||||
try:
|
try:
|
||||||
|
@ -999,6 +1016,11 @@ class Interface:
|
||||||
|
|
||||||
def handle_event_agent_info_items(self, account, array):
|
def handle_event_agent_info_items(self, account, array):
|
||||||
#('AGENT_INFO_ITEMS', account, (agent, node, items))
|
#('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:
|
try:
|
||||||
gajim.connections[account].services_cache.agent_items(array[0],
|
gajim.connections[account].services_cache.agent_items(array[0],
|
||||||
array[1], array[2])
|
array[1], array[2])
|
||||||
|
@ -1014,11 +1036,11 @@ class Interface:
|
||||||
return
|
return
|
||||||
|
|
||||||
def handle_event_new_acc_connected(self, account, array):
|
def handle_event_new_acc_connected(self, account, array):
|
||||||
#('NEW_ACC_CONNECTED', account, (infos, is_form, ssl_msg, ssl_cert,
|
#('NEW_ACC_CONNECTED', account, (infos, is_form, ssl_msg, ssl_err,
|
||||||
# ssl_fingerprint))
|
# ssl_cert, ssl_fingerprint))
|
||||||
if self.instances.has_key('account_creation_wizard'):
|
if self.instances.has_key('account_creation_wizard'):
|
||||||
self.instances['account_creation_wizard'].new_acc_connected(array[0],
|
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):
|
def handle_event_new_acc_not_connected(self, account, array):
|
||||||
#('NEW_ACC_NOT_CONNECTED', account, (reason))
|
#('NEW_ACC_NOT_CONNECTED', account, (reason))
|
||||||
|
@ -1407,14 +1429,19 @@ class Interface:
|
||||||
gajim.connections[account].gpg_passphrase(self.gpg_passphrase[keyid])
|
gajim.connections[account].gpg_passphrase(self.gpg_passphrase[keyid])
|
||||||
callback()
|
callback()
|
||||||
return
|
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
|
password_ok = False
|
||||||
count = 0
|
count = 0
|
||||||
title = _('Passphrase Required')
|
title = _('Passphrase Required')
|
||||||
second = _('Enter GPG key passphrase for account %s.') % account
|
second = _('Enter GPG key passphrase for account %s.') % account
|
||||||
while not password_ok and count < 3:
|
while not password_ok and count < 3:
|
||||||
count += 1
|
count += 1
|
||||||
w = dialogs.PassphraseDialog(title, second, '')
|
self.gpg_dialog = dialogs.PassphraseDialog(title, second, '')
|
||||||
passphrase, save = w.run()
|
passphrase, save = self.gpg_dialog.run()
|
||||||
if passphrase == -1:
|
if passphrase == -1:
|
||||||
# User pressed cancel
|
# User pressed cancel
|
||||||
passphrase = None
|
passphrase = None
|
||||||
|
@ -1424,6 +1451,7 @@ class Interface:
|
||||||
test_gpg_passphrase(passphrase)
|
test_gpg_passphrase(passphrase)
|
||||||
title = _('Wrong Passphrase')
|
title = _('Wrong Passphrase')
|
||||||
second = _('Please retype your GPG passphrase or press Cancel.')
|
second = _('Please retype your GPG passphrase or press Cancel.')
|
||||||
|
self.gpg_dialog = None
|
||||||
if passphrase != None:
|
if passphrase != None:
|
||||||
self.gpg_passphrase[keyid] = passphrase
|
self.gpg_passphrase[keyid] = passphrase
|
||||||
gobject.timeout_add(30000, self.forget_gpg_passphrase, keyid)
|
gobject.timeout_add(30000, self.forget_gpg_passphrase, keyid)
|
||||||
|
@ -1857,6 +1885,7 @@ class Interface:
|
||||||
# block signed in notifications for 30 seconds
|
# block signed in notifications for 30 seconds
|
||||||
gajim.block_signed_in_notifications[account] = True
|
gajim.block_signed_in_notifications[account] = True
|
||||||
self.roster.set_actions_menu_needs_rebuild()
|
self.roster.set_actions_menu_needs_rebuild()
|
||||||
|
self.roster.draw_account(account)
|
||||||
if self.sleeper.getState() != common.sleepy.STATE_UNKNOWN and \
|
if self.sleeper.getState() != common.sleepy.STATE_UNKNOWN and \
|
||||||
gajim.connections[account].connected in (2, 3):
|
gajim.connections[account].connected in (2, 3):
|
||||||
# we go online or free for chat, so we activate auto status
|
# 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)
|
negotiated, not_acceptable, ask_user = session.verify_options_bob(form)
|
||||||
|
|
||||||
if ask_user:
|
if ask_user:
|
||||||
def accept_nondefault_options(widget):
|
def accept_nondefault_options(is_checked):
|
||||||
self.dialog.destroy()
|
self.dialog.destroy()
|
||||||
negotiated.update(ask_user)
|
negotiated.update(ask_user)
|
||||||
session.respond_e2e_bob(form, negotiated, not_acceptable)
|
session.respond_e2e_bob(form, negotiated, not_acceptable)
|
||||||
|
|
||||||
def reject_nondefault_options(widget):
|
def reject_nondefault_options():
|
||||||
self.dialog.destroy()
|
self.dialog.destroy()
|
||||||
for key in ask_user.keys():
|
for key in ask_user.keys():
|
||||||
not_acceptable.append(key)
|
not_acceptable.append(key)
|
||||||
|
@ -1963,7 +1992,7 @@ class Interface:
|
||||||
session.check_identity = _cb
|
session.check_identity = _cb
|
||||||
|
|
||||||
if ask_user:
|
if ask_user:
|
||||||
def accept_nondefault_options(widget):
|
def accept_nondefault_options(is_checked):
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
|
|
||||||
negotiated.update(ask_user)
|
negotiated.update(ask_user)
|
||||||
|
@ -1973,7 +2002,7 @@ class Interface:
|
||||||
except exceptions.NegotiationError, details:
|
except exceptions.NegotiationError, details:
|
||||||
session.fail_bad_negotiation(details)
|
session.fail_bad_negotiation(details)
|
||||||
|
|
||||||
def reject_nondefault_options(widget):
|
def reject_nondefault_options():
|
||||||
session.reject_negotiation()
|
session.reject_negotiation()
|
||||||
dialog.destroy()
|
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,
|
_('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)
|
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):
|
def handle_event_unique_room_id_supported(self, account, data):
|
||||||
'''Receive confirmation that unique_room_id are supported'''
|
'''Receive confirmation that unique_room_id are supported'''
|
||||||
# ('UNIQUE_ROOM_ID_SUPPORTED', server, instance, room_id)
|
# ('UNIQUE_ROOM_ID_SUPPORTED', server, instance, room_id)
|
||||||
|
@ -2181,44 +2215,76 @@ class Interface:
|
||||||
instance.unique_room_id_error(data[0])
|
instance.unique_room_id_error(data[0])
|
||||||
|
|
||||||
def handle_event_ssl_error(self, account, data):
|
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')
|
server = gajim.config.get_per('accounts', account, 'hostname')
|
||||||
def on_ok(is_checked):
|
def on_ok(is_checked=False):
|
||||||
if is_checked:
|
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 = open(gajim.MY_CACERTS, 'a')
|
||||||
f.write(server + '\n')
|
f.write(server + '\n')
|
||||||
f.write(data[1] + '\n\n')
|
f.write(data[2] + '\n\n')
|
||||||
f.close()
|
f.close()
|
||||||
gajim.config.set_per('accounts', account, 'ssl_fingerprint_sha1',
|
gajim.config.set_per('accounts', account, 'ssl_fingerprint_sha1',
|
||||||
data[2])
|
data[3])
|
||||||
gajim.connections[account].ssl_certificate_accepted()
|
gajim.connections[account].ssl_certificate_accepted()
|
||||||
def on_cancel():
|
def on_cancel():
|
||||||
gajim.connections[account].disconnect(on_purpose=True)
|
gajim.connections[account].disconnect(on_purpose=True)
|
||||||
self.handle_event_status(account, 'offline')
|
self.handle_event_status(account, 'offline')
|
||||||
pritext = _('Error verifying SSL certificate')
|
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]}
|
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,
|
dialogs.ConfirmationDialogCheck(pritext, sectext, checktext,
|
||||||
on_response_ok=on_ok, on_response_cancel=on_cancel)
|
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):
|
def handle_event_fingerprint_error(self, account, data):
|
||||||
# ('FINGERPRINT_ERROR', account, (fingerprint,))
|
# ('FINGERPRINT_ERROR', account, (new_fingerprint,))
|
||||||
def on_yes(widget):
|
def on_yes(is_checked):
|
||||||
dialog.destroy()
|
|
||||||
gajim.config.set_per('accounts', account, 'ssl_fingerprint_sha1',
|
gajim.config.set_per('accounts', account, 'ssl_fingerprint_sha1',
|
||||||
data[0])
|
data[0])
|
||||||
gajim.connections[account].ssl_certificate_accepted()
|
gajim.connections[account].ssl_certificate_accepted()
|
||||||
def on_no(widget):
|
def on_no():
|
||||||
dialog.destroy()
|
|
||||||
gajim.connections[account].disconnect(on_purpose=True)
|
gajim.connections[account].disconnect(on_purpose=True)
|
||||||
self.handle_event_status(account, 'offline')
|
self.handle_event_status(account, 'offline')
|
||||||
pritext = _('SSL certificate error')
|
pritext = _('SSL certificate error')
|
||||||
sectext = _('It seems SSL certificate has changed or your connection is '
|
sectext = _('It seems the SSL certificate has changed or your connection '
|
||||||
'being hacked. Do you still want to connect and update the fingerprint'
|
'is being hacked.\nOld fingerprint: %s\nNew fingerprint: %s\n\nDo you '
|
||||||
'of the certificate?')
|
'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,
|
dialog = dialogs.YesNoDialog(pritext, sectext, on_response_yes=on_yes,
|
||||||
on_response_no=on_no)
|
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):
|
def read_sleepy(self):
|
||||||
'''Check idle status and change that status if needed'''
|
'''Check idle status and change that status if needed'''
|
||||||
if not self.sleeper.poll():
|
if not self.sleeper.poll():
|
||||||
|
@ -2328,7 +2394,7 @@ class Interface:
|
||||||
|
|
||||||
#FIXME: recognize xmpp: and treat it specially
|
#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
|
#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]'
|
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()|{}$])(.*?[^\\])?\$\$'
|
latex = r'|\$\$[^$\\]*?([\]\[0-9A-Za-z()|+*/-]|[\\][\]\[0-9A-Za-z()|{}$])(.*?[^\\])?\$\$'
|
||||||
|
|
||||||
basic_pattern = links + mail
|
basic_pattern = links + '|' + mail
|
||||||
|
|
||||||
if gajim.config.get('use_latex'):
|
if gajim.config.get('use_latex'):
|
||||||
basic_pattern += latex
|
basic_pattern += latex
|
||||||
|
@ -2551,6 +2617,7 @@ class Interface:
|
||||||
'SEARCH_FORM': self.handle_event_search_form,
|
'SEARCH_FORM': self.handle_event_search_form,
|
||||||
'SEARCH_RESULT': self.handle_event_search_result,
|
'SEARCH_RESULT': self.handle_event_search_result,
|
||||||
'RESOURCE_CONFLICT': self.handle_event_resource_conflict,
|
'RESOURCE_CONFLICT': self.handle_event_resource_conflict,
|
||||||
|
'PEP_ACCESS_MODEL': self.handle_event_pep_access_model,
|
||||||
'UNIQUE_ROOM_ID_UNSUPPORTED': \
|
'UNIQUE_ROOM_ID_UNSUPPORTED': \
|
||||||
self.handle_event_unique_room_id_unsupported,
|
self.handle_event_unique_room_id_unsupported,
|
||||||
'UNIQUE_ROOM_ID_SUPPORTED': self.handle_event_unique_room_id_supported,
|
'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,
|
'GPG_PASSWORD_REQUIRED': self.handle_event_gpg_password_required,
|
||||||
'SSL_ERROR': self.handle_event_ssl_error,
|
'SSL_ERROR': self.handle_event_ssl_error,
|
||||||
'FINGERPRINT_ERROR': self.handle_event_fingerprint_error,
|
'FINGERPRINT_ERROR': self.handle_event_fingerprint_error,
|
||||||
|
'PLAIN_CONNECTION': self.handle_event_plain_connection,
|
||||||
}
|
}
|
||||||
gajim.handlers = self.handlers
|
gajim.handlers = self.handlers
|
||||||
|
|
||||||
|
@ -2674,6 +2742,7 @@ class Interface:
|
||||||
self.status_sent_to_users = {}
|
self.status_sent_to_users = {}
|
||||||
self.status_sent_to_groups = {}
|
self.status_sent_to_groups = {}
|
||||||
self.gpg_passphrase = {}
|
self.gpg_passphrase = {}
|
||||||
|
self.gpg_dialog = None
|
||||||
self.default_colors = {
|
self.default_colors = {
|
||||||
'inmsgcolor': gajim.config.get('inmsgcolor'),
|
'inmsgcolor': gajim.config.get('inmsgcolor'),
|
||||||
'outmsgcolor': gajim.config.get('outmsgcolor'),
|
'outmsgcolor': gajim.config.get('outmsgcolor'),
|
||||||
|
@ -2903,7 +2972,7 @@ if __name__ == '__main__':
|
||||||
print >> sys.stderr, _('Session Management support not available (missing gnome.ui module)')
|
print >> sys.stderr, _('Session Management support not available (missing gnome.ui module)')
|
||||||
else:
|
else:
|
||||||
def die_cb(cli):
|
def die_cb(cli):
|
||||||
gtk.main_quit()
|
gajim.interface.roster.quit_gtkgui_interface()
|
||||||
gnome.program_init('gajim', gajim.version)
|
gnome.program_init('gajim', gajim.version)
|
||||||
cli = gnome.ui.master_client()
|
cli = gnome.ui.master_client()
|
||||||
cli.connect('die', die_cb)
|
cli.connect('die', die_cb)
|
||||||
|
@ -2928,4 +2997,7 @@ if __name__ == '__main__':
|
||||||
osx.init()
|
osx.init()
|
||||||
|
|
||||||
Interface()
|
Interface()
|
||||||
|
try:
|
||||||
gtk.main()
|
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)
|
# reference to GroupchatControl instance (self)
|
||||||
theme = gajim.config.get('roster_theme')
|
theme = gajim.config.get('roster_theme')
|
||||||
# allocate space for avatar only if needed
|
# allocate space for avatar only if needed
|
||||||
|
parent_iter = model.iter_parent(iter)
|
||||||
if isinstance(renderer, gtk.CellRendererPixbuf):
|
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('visible', True)
|
||||||
|
renderer.set_property('width', gajim.config.get('roster_avatar_width'))
|
||||||
else:
|
else:
|
||||||
renderer.set_property('visible', False)
|
renderer.set_property('visible', False)
|
||||||
if model.iter_parent(iter):
|
if parent_iter:
|
||||||
bgcolor = gajim.config.get_per('themes', theme, 'contactbgcolor')
|
bgcolor = gajim.config.get_per('themes', theme, 'contactbgcolor')
|
||||||
if bgcolor:
|
if bgcolor:
|
||||||
renderer.set_property('cell-background', bgcolor)
|
renderer.set_property('cell-background', bgcolor)
|
||||||
|
@ -228,6 +235,12 @@ class GroupchatControl(ChatControlBase):
|
||||||
|
|
||||||
self.tooltip = tooltips.GCTooltip()
|
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
|
# connect the menuitems to their respective functions
|
||||||
xm = gtkgui_helpers.get_glade('gc_control_popup_menu.glade')
|
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
|
# first one img, second one text, third is sec pixbuf
|
||||||
column = gtk.TreeViewColumn()
|
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 = cell_renderer_image.CellRendererImage(0, 0) # status img
|
||||||
renderer_image.set_property('width', 26)
|
renderer_image.set_property('width', 26)
|
||||||
column.pack_start(renderer_image, expand = False)
|
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,
|
column.set_cell_data_func(renderer_text, tree_cell_data_func,
|
||||||
self.list_treeview)
|
self.list_treeview)
|
||||||
|
|
||||||
renderer_pixbuf = gtk.CellRendererPixbuf() # avatar image
|
if gajim.config.get('avatar_position_in_roster') == 'right':
|
||||||
column.pack_start(renderer_pixbuf, expand = False)
|
add_avatar_renderer()
|
||||||
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
|
|
||||||
|
|
||||||
self.list_treeview.append_column(column)
|
self.list_treeview.append_column(column)
|
||||||
|
|
||||||
|
@ -639,9 +658,6 @@ class GroupchatControl(ChatControlBase):
|
||||||
fin = True
|
fin = True
|
||||||
return None
|
return None
|
||||||
|
|
||||||
gc_count_nicknames_colors = 0
|
|
||||||
gc_custom_colors = {}
|
|
||||||
|
|
||||||
def print_old_conversation(self, text, contact = '', tim = None,
|
def print_old_conversation(self, text, contact = '', tim = None,
|
||||||
xhtml = None):
|
xhtml = None):
|
||||||
if isinstance(text, str):
|
if isinstance(text, str):
|
||||||
|
@ -692,9 +708,7 @@ class GroupchatControl(ChatControlBase):
|
||||||
str(self.gc_custom_colors[contact]))
|
str(self.gc_custom_colors[contact]))
|
||||||
else:
|
else:
|
||||||
self.gc_count_nicknames_colors += 1
|
self.gc_count_nicknames_colors += 1
|
||||||
number_of_colors = len(gajim.config.get('gc_nicknames_colors').\
|
if self.gc_count_nicknames_colors == self.number_of_colors:
|
||||||
split(':'))
|
|
||||||
if self.gc_count_nicknames_colors == number_of_colors:
|
|
||||||
self.gc_count_nicknames_colors = 0
|
self.gc_count_nicknames_colors = 0
|
||||||
self.gc_custom_colors[contact] = \
|
self.gc_custom_colors[contact] = \
|
||||||
self.gc_count_nicknames_colors
|
self.gc_count_nicknames_colors
|
||||||
|
@ -813,6 +827,13 @@ class GroupchatControl(ChatControlBase):
|
||||||
return False
|
return False
|
||||||
else: # Special word == word, no char after in word
|
else: # Special word == word, no char after in word
|
||||||
return True
|
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
|
return False
|
||||||
|
|
||||||
def set_subject(self, subject):
|
def set_subject(self, subject):
|
||||||
|
@ -1979,7 +2000,8 @@ class GroupchatControl(ChatControlBase):
|
||||||
self.handlers[id] = item
|
self.handlers[id] = item
|
||||||
|
|
||||||
item = xml.get_widget('add_to_roster_menuitem')
|
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)
|
item.set_sensitive(False)
|
||||||
else:
|
else:
|
||||||
id = item.connect('activate', self.on_add_to_roster, jid)
|
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,
|
if not nick in gajim.contacts.get_nick_list(self.account,
|
||||||
self.room_jid):
|
self.room_jid):
|
||||||
# it's a group
|
# it's a group
|
||||||
col = widget.get_column(0)
|
if x < 27:
|
||||||
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 (widget.row_expanded(path)):
|
if (widget.row_expanded(path)):
|
||||||
widget.collapse_row(path)
|
widget.collapse_row(path)
|
||||||
else:
|
else:
|
||||||
|
@ -2142,6 +2159,9 @@ class GroupchatControl(ChatControlBase):
|
||||||
self.tooltip.hide_tooltip()
|
self.tooltip.hide_tooltip()
|
||||||
|
|
||||||
def show_tooltip(self, contact):
|
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()
|
pointer = self.list_treeview.get_pointer()
|
||||||
props = self.list_treeview.get_path_at_pos(pointer[0], pointer[1])
|
props = self.list_treeview.get_path_at_pos(pointer[0], pointer[1])
|
||||||
# check if the current pointer is at the same path
|
# check if the current pointer is at the same path
|
||||||
|
|
|
@ -247,6 +247,11 @@ def move_window(window, x, y):
|
||||||
x = 0
|
x = 0
|
||||||
if y < 0:
|
if y < 0:
|
||||||
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)
|
window.move(x, y)
|
||||||
|
|
||||||
def resize_window(window, w, h):
|
def resize_window(window, w, h):
|
||||||
|
|
|
@ -100,7 +100,7 @@ class HistoryManager:
|
||||||
self.logs_scrolledwindow = xml.get_widget('logs_scrolledwindow')
|
self.logs_scrolledwindow = xml.get_widget('logs_scrolledwindow')
|
||||||
self.search_results_scrolledwindow = xml.get_widget(
|
self.search_results_scrolledwindow = xml.get_widget(
|
||||||
'search_results_scrolledwindow')
|
'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.jids_already_in = [] # holds jids that we already have in DB
|
||||||
self.AT_LEAST_ONE_DELETION_DONE = False
|
self.AT_LEAST_ONE_DELETION_DONE = False
|
||||||
|
@ -236,7 +236,7 @@ class HistoryManager:
|
||||||
|
|
||||||
self.logs_liststore.clear() # clear the store
|
self.logs_liststore.clear() # clear the store
|
||||||
|
|
||||||
self.welcome_label.hide()
|
self.welcome_vbox.hide()
|
||||||
self.search_results_scrolledwindow.hide()
|
self.search_results_scrolledwindow.hide()
|
||||||
self.logs_scrolledwindow.show()
|
self.logs_scrolledwindow.show()
|
||||||
|
|
||||||
|
@ -579,7 +579,7 @@ class HistoryManager:
|
||||||
if text == '':
|
if text == '':
|
||||||
return
|
return
|
||||||
|
|
||||||
self.welcome_label.hide()
|
self.welcome_vbox.hide()
|
||||||
self.logs_scrolledwindow.hide()
|
self.logs_scrolledwindow.hide()
|
||||||
self.search_results_scrolledwindow.show()
|
self.search_results_scrolledwindow.show()
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ __version__ = '$Revision: 64 $'
|
||||||
|
|
||||||
from urllib import urlopen
|
from urllib import urlopen
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from time import time, strftime
|
from time import time
|
||||||
|
|
||||||
class LastFM:
|
class LastFM:
|
||||||
# Where to fetch the played song information
|
# Where to fetch the played song information
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
## message_control.py
|
## 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>
|
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
|
||||||
##
|
##
|
||||||
## This file is part of Gajim.
|
## This file is part of Gajim.
|
||||||
|
@ -86,7 +86,7 @@ class MessageControl:
|
||||||
pass # NOTE: Derived classes SHOULD implement this
|
pass # NOTE: Derived classes SHOULD implement this
|
||||||
|
|
||||||
def get_tab_label(self, chatstate):
|
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
|
(label_str, color) either of which can be None
|
||||||
if chatstate is given that means we have HE SENT US a chatstate and
|
if chatstate is given that means we have HE SENT US a chatstate and
|
||||||
we want it displayed'''
|
we want it displayed'''
|
||||||
|
@ -126,8 +126,8 @@ class MessageControl:
|
||||||
if self.session.enable_encryption:
|
if self.session.enable_encryption:
|
||||||
was_encrypted = True
|
was_encrypted = True
|
||||||
|
|
||||||
print "starting a new session, dropping the old one!"
|
gajim.connections[self.account].delete_session(self.session.jid,
|
||||||
gajim.connections[self.account].delete_session(self.session.jid, self.session.thread_id)
|
self.session.thread_id)
|
||||||
|
|
||||||
self.session = session
|
self.session = session
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,9 @@
|
||||||
## Vincent Hanquez <tab@snarc.org>
|
## Vincent Hanquez <tab@snarc.org>
|
||||||
## Nikos Kouremenos <kourem@gmail.com>
|
## Nikos Kouremenos <kourem@gmail.com>
|
||||||
## Dimitur Kirov <dkirov@gmail.com>
|
## Dimitur Kirov <dkirov@gmail.com>
|
||||||
## Travis Shirk <travis@pobox.com>
|
|
||||||
## Norman Rasmussen <norman@rasmussen.co.za>
|
## Norman Rasmussen <norman@rasmussen.co.za>
|
||||||
## Copyright (C) 2006 Travis Shirk <travis@pobox.com>
|
## Copyright (C) 2005-2007 Travis Shirk <travis@pobox.com>
|
||||||
## Geobert Quach <geobert@gmail.com>
|
## Copyright (C) 2006 Geobert Quach <geobert@gmail.com>
|
||||||
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
|
## Copyright (C) 2007 Stephan Erb <steve-e@h3c.de>
|
||||||
##
|
##
|
||||||
## This file is part of Gajim.
|
## 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,
|
'''Class for windows which contain message like things; chats,
|
||||||
groupchats, etc.'''
|
groupchats, etc.'''
|
||||||
|
|
||||||
|
@ -54,7 +53,7 @@ class MessageWindow:
|
||||||
CLOSE_CTRL_KEY
|
CLOSE_CTRL_KEY
|
||||||
) = range(5)
|
) = 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
|
# A dictionary of dictionaries where _contacts[account][jid] == A MessageControl
|
||||||
self._controls = {}
|
self._controls = {}
|
||||||
# If None, the window is not tied to any specific account
|
# If None, the window is not tied to any specific account
|
||||||
|
@ -68,6 +67,18 @@ class MessageWindow:
|
||||||
self.widget_name = 'message_window'
|
self.widget_name = 'message_window'
|
||||||
self.xml = gtkgui_helpers.get_glade('%s.glade' % self.widget_name)
|
self.xml = gtkgui_helpers.get_glade('%s.glade' % self.widget_name)
|
||||||
self.window = self.xml.get_widget(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)
|
id = self.window.connect('delete-event', self._on_window_delete)
|
||||||
self.handlers[id] = self.window
|
self.handlers[id] = self.window
|
||||||
id = self.window.connect('destroy', self._on_window_destroy)
|
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.window.add_events(gtk.gdk.POINTER_MOTION_MASK)
|
||||||
self.alignment = self.xml.get_widget('alignment')
|
self.alignment = self.xml.get_widget('alignment')
|
||||||
|
|
||||||
self.notebook = self.xml.get_widget('notebook')
|
|
||||||
id = self.notebook.connect('switch-page',
|
id = self.notebook.connect('switch-page',
|
||||||
self._on_notebook_switch_page)
|
self._on_notebook_switch_page)
|
||||||
self.handlers[id] = self.notebook
|
self.handlers[id] = self.notebook
|
||||||
|
@ -144,6 +154,9 @@ class MessageWindow:
|
||||||
n += len(dict)
|
n += len(dict)
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
def resize(self, width, height):
|
||||||
|
gtkgui_helpers.resize_window(self.window, width, height)
|
||||||
|
|
||||||
def _on_window_focus(self, widget, event):
|
def _on_window_focus(self, widget, event):
|
||||||
# window received focus, so if we had urgency REMOVE IT
|
# 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)
|
# 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():
|
for ctrl in self.controls():
|
||||||
ctrl.shutdown()
|
ctrl.shutdown()
|
||||||
self._controls.clear()
|
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():
|
for i in self.handlers.keys():
|
||||||
if self.handlers[i].handler_is_connected(i):
|
if self.handlers[i].handler_is_connected(i):
|
||||||
self.handlers[i].disconnect(i)
|
self.handlers[i].disconnect(i)
|
||||||
|
@ -211,7 +226,8 @@ class MessageWindow:
|
||||||
id = widget.connect('clicked', self._on_close_button_clicked, control)
|
id = widget.connect('clicked', self._on_close_button_clicked, control)
|
||||||
control.handlers[id] = widget
|
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
|
control.handlers[id] = tab_label_box
|
||||||
self.notebook.append_page(control.widget, 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.setup_tab_dnd(control.widget)
|
||||||
|
|
||||||
self.redraw_tab(control)
|
self.redraw_tab(control)
|
||||||
|
if self.parent_paned:
|
||||||
|
self.notebook.show_all()
|
||||||
|
else:
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
# NOTE: we do not call set_control_active(True) since we don't know whether
|
# NOTE: we do not call set_control_active(True) since we don't know whether
|
||||||
# the tab is the active one.
|
# the tab is the active one.
|
||||||
|
@ -341,10 +360,7 @@ class MessageWindow:
|
||||||
name += '/' + control.resource
|
name += '/' + control.resource
|
||||||
|
|
||||||
window_mode = gajim.interface.msg_win_mgr.mode
|
window_mode = gajim.interface.msg_win_mgr.mode
|
||||||
|
if window_mode == MessageWindowMgr.ONE_MSG_WINDOW_PERTYPE:
|
||||||
if self.get_num_controls() == 1:
|
|
||||||
label = name
|
|
||||||
elif window_mode == MessageWindowMgr.ONE_MSG_WINDOW_PERTYPE:
|
|
||||||
# Show the plural form since number of tabs > 1
|
# Show the plural form since number of tabs > 1
|
||||||
if self.type == 'chat':
|
if self.type == 'chat':
|
||||||
label = _('Chats')
|
label = _('Chats')
|
||||||
|
@ -352,9 +368,16 @@ class MessageWindow:
|
||||||
label = _('Group Chats')
|
label = _('Group Chats')
|
||||||
else:
|
else:
|
||||||
label = _('Private Chats')
|
label = _('Private Chats')
|
||||||
|
elif window_mode == MessageWindowMgr.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER:
|
||||||
|
label = None
|
||||||
|
elif self.get_num_controls() == 1:
|
||||||
|
label = name
|
||||||
else:
|
else:
|
||||||
label = _('Messages')
|
label = _('Messages')
|
||||||
title = _('%s - Gajim') % label
|
|
||||||
|
title = 'Gajim'
|
||||||
|
if label:
|
||||||
|
title = _('%s - %s') % (label, title)
|
||||||
|
|
||||||
if window_mode == MessageWindowMgr.ONE_MSG_WINDOW_PERACCT:
|
if window_mode == MessageWindowMgr.ONE_MSG_WINDOW_PERACCT:
|
||||||
title = title + ": " + control.account
|
title = title + ": " + control.account
|
||||||
|
@ -413,6 +436,11 @@ class MessageWindow:
|
||||||
gajim.interface.msg_win_mgr._on_window_destroy(self.window)
|
gajim.interface.msg_win_mgr._on_window_destroy(self.window)
|
||||||
# dnd clean up
|
# dnd clean up
|
||||||
self.notebook.drag_dest_unset()
|
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()
|
self.window.destroy()
|
||||||
return # don't show_title, we are dead
|
return # don't show_title, we are dead
|
||||||
elif self.get_num_controls() == 1: # we are going from two tabs to one
|
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):
|
def _on_notebook_key_press(self, widget, event):
|
||||||
control = self.get_active_control()
|
control = self.get_active_control()
|
||||||
# Ctrl+PageUP / DOWN has to be handled by notebook
|
# Ctrl+PageUP / DOWN has to be handled by notebook
|
||||||
if event.state & gtk.gdk.CONTROL_MASK and event.keyval in (
|
if (event.state & gtk.gdk.CONTROL_MASK and
|
||||||
gtk.keysyms.Page_Down, gtk.keysyms.Page_Up):
|
event.keyval in (gtk.keysyms.Page_Down, gtk.keysyms.Page_Up)):
|
||||||
return False
|
return False
|
||||||
if isinstance(control, ChatControlBase):
|
if isinstance(control, ChatControlBase):
|
||||||
# we forwarded it to message textview
|
# we forwarded it to message textview
|
||||||
|
@ -679,36 +707,53 @@ class MessageWindow:
|
||||||
tab_label.disconnect(tab_label.dnd_handler)
|
tab_label.disconnect(tab_label.dnd_handler)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
class MessageWindowMgr:
|
class MessageWindowMgr(gobject.GObject):
|
||||||
'''A manager and factory for MessageWindow objects'''
|
'''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
|
# These constants map to common.config.opt_one_window_types indices
|
||||||
(
|
(
|
||||||
ONE_MSG_WINDOW_NEVER,
|
ONE_MSG_WINDOW_NEVER,
|
||||||
ONE_MSG_WINDOW_ALWAYS,
|
ONE_MSG_WINDOW_ALWAYS,
|
||||||
|
ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER,
|
||||||
ONE_MSG_WINDOW_PERACCT,
|
ONE_MSG_WINDOW_PERACCT,
|
||||||
ONE_MSG_WINDOW_PERTYPE
|
ONE_MSG_WINDOW_PERTYPE,
|
||||||
) = range(4)
|
) = range(5)
|
||||||
# A key constant for the main window for all messages
|
# A key constant for the main window in ONE_MSG_WINDOW_ALWAYS mode
|
||||||
MAIN_WIN = 'main'
|
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:
|
''' A dictionary of windows; the key depends on the config:
|
||||||
ONE_MSG_WINDOW_NEVER: The key is the contact JID
|
ONE_MSG_WINDOW_NEVER: The key is the contact JID
|
||||||
ONE_MSG_WINDOW_ALWAYS: The key is MessageWindowMgr.MAIN_WIN
|
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_PERACCT: The key is the account name
|
||||||
ONE_MSG_WINDOW_PERTYPE: The key is a message type constant'''
|
ONE_MSG_WINDOW_PERTYPE: The key is a message type constant'''
|
||||||
|
gobject.GObject.__init__(self)
|
||||||
self._windows = {}
|
self._windows = {}
|
||||||
|
|
||||||
# Map the mode to a int constant for frequent compares
|
# Map the mode to a int constant for frequent compares
|
||||||
mode = gajim.config.get('one_message_window')
|
mode = gajim.config.get('one_message_window')
|
||||||
self.mode = common.config.opt_one_window_types.index(mode)
|
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):
|
def change_account_name(self, old_name, new_name):
|
||||||
for win in self.windows():
|
for win in self.windows():
|
||||||
win.change_account_name(old_name, new_name)
|
win.change_account_name(old_name, new_name)
|
||||||
|
|
||||||
def _new_window(self, acct, type):
|
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
|
# we track the lifetime of this window
|
||||||
win.window.connect('delete-event', self._on_window_delete)
|
win.window.connect('delete-event', self._on_window_delete)
|
||||||
win.window.connect('destroy', self._on_window_destroy)
|
win.window.connect('destroy', self._on_window_destroy)
|
||||||
|
@ -729,7 +774,7 @@ class MessageWindowMgr:
|
||||||
def has_window(self, jid, acct):
|
def has_window(self, jid, acct):
|
||||||
return self.get_window(jid, acct) != None
|
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:
|
try:
|
||||||
return self._windows[self._mode_to_key(contact, acct, type)] != None
|
return self._windows[self._mode_to_key(contact, acct, type)] != None
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -737,12 +782,13 @@ class MessageWindowMgr:
|
||||||
|
|
||||||
def _resize_window(self, win, acct, type):
|
def _resize_window(self, win, acct, type):
|
||||||
'''Resizes window according to config settings'''
|
'''Resizes window according to config settings'''
|
||||||
if not gajim.config.get('saveposition'):
|
if self.mode in (self.ONE_MSG_WINDOW_ALWAYS,
|
||||||
return
|
self.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER):
|
||||||
|
|
||||||
if self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
|
||||||
size = (gajim.config.get('msgwin-width'),
|
size = (gajim.config.get('msgwin-width'),
|
||||||
gajim.config.get('msgwin-height'))
|
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:
|
elif self.mode == self.ONE_MSG_WINDOW_PERACCT:
|
||||||
size = (gajim.config.get_per('accounts', acct, 'msgwin-width'),
|
size = (gajim.config.get_per('accounts', acct, 'msgwin-width'),
|
||||||
gajim.config.get_per('accounts', acct, 'msgwin-height'))
|
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))
|
size = (gajim.config.get(opt_width), gajim.config.get(opt_height))
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
win.resize(size[0], size[1])
|
||||||
gtkgui_helpers.resize_window(win.window, size[0], size[1])
|
|
||||||
|
|
||||||
def _position_window(self, win, acct, type):
|
def _position_window(self, win, acct, type):
|
||||||
'''Moves window according to config settings'''
|
'''Moves window according to config settings'''
|
||||||
if not gajim.config.get('saveposition') or\
|
if (self.mode in [self.ONE_MSG_WINDOW_NEVER,
|
||||||
self.mode == self.ONE_MSG_WINDOW_NEVER:
|
self.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER]):
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
if self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
||||||
|
@ -782,21 +827,22 @@ class MessageWindowMgr:
|
||||||
key = acct + contact.jid
|
key = acct + contact.jid
|
||||||
if resource:
|
if resource:
|
||||||
key += '/' + 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
|
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):
|
def create_window(self, contact, acct, type, resource = None):
|
||||||
key = None
|
|
||||||
win_acct = None
|
win_acct = None
|
||||||
win_type = 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:
|
if self.mode == self.ONE_MSG_WINDOW_PERACCT:
|
||||||
win_acct = acct
|
win_acct = acct
|
||||||
win_role = acct
|
win_role = acct
|
||||||
|
@ -806,21 +852,24 @@ class MessageWindowMgr:
|
||||||
elif self.mode == self.ONE_MSG_WINDOW_NEVER:
|
elif self.mode == self.ONE_MSG_WINDOW_NEVER:
|
||||||
win_type = type
|
win_type = type
|
||||||
win_role = contact.jid
|
win_role = contact.jid
|
||||||
|
elif self.mode == self.ONE_MSG_WINDOW_ALWAYS:
|
||||||
|
win_role = 'messages'
|
||||||
|
|
||||||
win = None
|
win = None
|
||||||
try:
|
try:
|
||||||
win = self._windows[key]
|
win = self._windows[win_key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
win = self._new_window(win_acct, win_type)
|
win = self._new_window(win_acct, win_type)
|
||||||
|
|
||||||
|
if win_role:
|
||||||
win.window.set_role(win_role)
|
win.window.set_role(win_role)
|
||||||
|
|
||||||
# Position and size window based on saved state and window mode
|
# Position and size window based on saved state and window mode
|
||||||
if not self.one_window_opened(contact, acct, type):
|
if not self.one_window_opened(contact, acct, type):
|
||||||
self._position_window(win, acct, type)
|
|
||||||
self._resize_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
|
return win
|
||||||
|
|
||||||
def change_key(self, old_jid, new_jid, acct):
|
def change_key(self, old_jid, new_jid, acct):
|
||||||
|
@ -842,6 +891,7 @@ class MessageWindowMgr:
|
||||||
def _on_window_destroy(self, win):
|
def _on_window_destroy(self, win):
|
||||||
for k in self._windows.keys():
|
for k in self._windows.keys():
|
||||||
if self._windows[k].window == win:
|
if self._windows[k].window == win:
|
||||||
|
self.emit('window-delete', self._windows[k])
|
||||||
del self._windows[k]
|
del self._windows[k]
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -870,17 +920,16 @@ class MessageWindowMgr:
|
||||||
for c in w.controls():
|
for c in w.controls():
|
||||||
yield c
|
yield c
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self, width_adjust=0):
|
||||||
for w in self.windows():
|
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.hide()
|
||||||
w.window.destroy()
|
w.window.destroy()
|
||||||
|
|
||||||
gajim.interface.save_config()
|
gajim.interface.save_config()
|
||||||
|
|
||||||
def save_state(self, msg_win):
|
def save_state(self, msg_win, width_adjust=0):
|
||||||
if not gajim.config.get('saveposition'):
|
|
||||||
return
|
|
||||||
|
|
||||||
# Save window size and position
|
# Save window size and position
|
||||||
pos_x_key = 'msgwin-x-position'
|
pos_x_key = 'msgwin-x-position'
|
||||||
pos_y_key = 'msgwin-y-position'
|
pos_y_key = 'msgwin-y-position'
|
||||||
|
@ -907,6 +956,9 @@ class MessageWindowMgr:
|
||||||
type = msg_win.type
|
type = msg_win.type
|
||||||
size_width_key = type + '-msgwin-width'
|
size_width_key = type + '-msgwin-width'
|
||||||
size_height_key = type + '-msgwin-height'
|
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:
|
if acct:
|
||||||
gajim.config.set_per('accounts', acct, size_width_key, width)
|
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)
|
gajim.config.set_per('accounts', acct, pos_y_key, y)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
width += width_adjust
|
||||||
gajim.config.set(size_width_key, width)
|
gajim.config.set(size_width_key, width)
|
||||||
gajim.config.set(size_height_key, height)
|
gajim.config.set(size_height_key, height)
|
||||||
|
|
||||||
|
@ -937,6 +990,9 @@ class MessageWindowMgr:
|
||||||
|
|
||||||
controls = []
|
controls = []
|
||||||
for w in self.windows():
|
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()
|
w.window.hide()
|
||||||
while w.notebook.get_n_pages():
|
while w.notebook.get_n_pages():
|
||||||
page = w.notebook.get_nth_page(0)
|
page = w.notebook.get_nth_page(0)
|
||||||
|
@ -944,10 +1000,14 @@ class MessageWindowMgr:
|
||||||
w.notebook.remove_page(0)
|
w.notebook.remove_page(0)
|
||||||
page.unparent()
|
page.unparent()
|
||||||
controls.append(ctrl)
|
controls.append(ctrl)
|
||||||
# Must clear _controls from window to prevent
|
# Must clear _controls from window to prevent MessageControl.shutdown calls
|
||||||
# MessageControl.shutdown calls
|
|
||||||
w._controls = {}
|
w._controls = {}
|
||||||
|
if not w.parent_paned:
|
||||||
w.window.destroy()
|
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 = {}
|
self._windows = {}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
## You should have received a copy of the GNU General Public License
|
## You should have received a copy of the GNU General Public License
|
||||||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
##
|
##
|
||||||
|
import os
|
||||||
import gobject
|
import gobject
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# install _() func before importing dbus_support
|
# install _() func before importing dbus_support
|
||||||
|
@ -51,6 +52,13 @@ class MusicTrackListener(gobject.GObject):
|
||||||
|
|
||||||
bus = dbus.SessionBus()
|
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
|
## Muine
|
||||||
bus.add_signal_receiver(self._muine_music_track_change_cb, 'SongChanged',
|
bus.add_signal_receiver(self._muine_music_track_change_cb, 'SongChanged',
|
||||||
'org.gnome.Muine.Player')
|
'org.gnome.Muine.Player')
|
||||||
|
@ -60,16 +68,18 @@ class MusicTrackListener(gobject.GObject):
|
||||||
'org.gnome.Muine.Player')
|
'org.gnome.Muine.Player')
|
||||||
|
|
||||||
## Rhythmbox
|
## 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,
|
bus.add_signal_receiver(self._player_name_owner_changed,
|
||||||
'NameOwnerChanged', 'org.freedesktop.DBus', arg0='org.gnome.Rhythmbox')
|
'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')
|
'playingChanged', 'org.gnome.Rhythmbox.Player')
|
||||||
bus.add_signal_receiver(self._player_playing_song_property_changed_cb,
|
bus.add_signal_receiver(self._player_playing_song_property_changed_cb,
|
||||||
'playingSongPropertyChanged', 'org.gnome.Rhythmbox.Player')
|
'playingSongPropertyChanged', 'org.gnome.Rhythmbox.Player')
|
||||||
|
|
||||||
## Banshee
|
## 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()
|
banshee_bus = dbus.SessionBus()
|
||||||
dubus = banshee_bus.get_object('org.freedesktop.DBus',
|
dubus = banshee_bus.get_object('org.freedesktop.DBus',
|
||||||
'/org/freedesktop/dbus')
|
'/org/freedesktop/dbus')
|
||||||
|
@ -116,6 +126,40 @@ class MusicTrackListener(gobject.GObject):
|
||||||
if b == 'rb:stream-song-title':
|
if b == 'rb:stream-song-title':
|
||||||
self.emit('music-track-changed', self._last_playing_music)
|
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):
|
def _muine_properties_extract(self, song_string):
|
||||||
d = dict((x.strip() for x in s1.split(':', 1)) for s1 in \
|
d = dict((x.strip() for x in s1.split(':', 1)) for s1 in \
|
||||||
song_string.split('\n'))
|
song_string.split('\n'))
|
||||||
|
@ -131,6 +175,13 @@ class MusicTrackListener(gobject.GObject):
|
||||||
info = self._muine_properties_extract(arg)
|
info = self._muine_properties_extract(arg)
|
||||||
self.emit('music-track-changed', info)
|
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):
|
def _rhythmbox_properties_extract(self, props):
|
||||||
info = MusicTrackInfo()
|
info = MusicTrackInfo()
|
||||||
info.title = props['title']
|
info.title = props['title']
|
||||||
|
@ -140,17 +191,6 @@ class MusicTrackListener(gobject.GObject):
|
||||||
info.track_number = int(props['track-number'])
|
info.track_number = int(props['track-number'])
|
||||||
return info
|
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):
|
def _banshee_check_track_status(self):
|
||||||
if self.dubus_methods.NameHasOwner('org.gnome.Banshee') and \
|
if self.dubus_methods.NameHasOwner('org.gnome.Banshee') and \
|
||||||
not hasattr(self, 'banshee_methods'):
|
not hasattr(self, 'banshee_methods'):
|
||||||
|
|
|
@ -170,17 +170,25 @@ def notify(event, jid, account, parameters, advanced_notif_num = None):
|
||||||
nickname = parameters[2]
|
nickname = parameters[2]
|
||||||
if gajim.config.get('notification_preview_message'):
|
if gajim.config.get('notification_preview_message'):
|
||||||
message = parameters[3]
|
message = parameters[3]
|
||||||
|
if message.startswith('/me ') or message.startswith('/me\n'):
|
||||||
|
message = '* ' + nickname + message[3:]
|
||||||
else:
|
else:
|
||||||
# We don't want message preview, do_preview = False
|
# We don't want message preview, do_preview = False
|
||||||
message = ''
|
message = ''
|
||||||
|
focused = parameters[4]
|
||||||
if helpers.allow_showing_notification(account, 'notify_on_new_message',
|
if helpers.allow_showing_notification(account, 'notify_on_new_message',
|
||||||
advanced_notif_num, is_first_message):
|
advanced_notif_num, is_first_message):
|
||||||
do_popup = True
|
do_popup = True
|
||||||
if is_first_message and helpers.allow_sound_notification(
|
if is_first_message and helpers.allow_sound_notification(
|
||||||
'first_message_received', advanced_notif_num):
|
'first_message_received', advanced_notif_num):
|
||||||
do_sound = True
|
do_sound = True
|
||||||
elif not is_first_message and helpers.allow_sound_notification(
|
elif not is_first_message and focused and \
|
||||||
'next_message_received', advanced_notif_num):
|
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
|
do_sound = True
|
||||||
else:
|
else:
|
||||||
print '*Event not implemeted yet*'
|
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
|
pass # do not set snd_event
|
||||||
elif is_first_message:
|
elif is_first_message:
|
||||||
snd_event = 'first_message_received'
|
snd_event = 'first_message_received'
|
||||||
|
elif focused:
|
||||||
|
snd_event = 'next_message_received_focused'
|
||||||
else:
|
else:
|
||||||
snd_event = 'next_message_received'
|
snd_event = 'next_message_received_unfocused'
|
||||||
elif event in ('contact_connected', 'contact_disconnected'):
|
elif event in ('contact_connected', 'contact_disconnected'):
|
||||||
snd_event = event
|
snd_event = event
|
||||||
if snd_file:
|
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
|
else
|
||||||
{
|
{
|
||||||
printf("Couldn't grab properties of system\n");
|
printf("Couldn't grab properties of system\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj)
|
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) 2005-2006 Andrew Sayman <lorien420@myrealbox.com>
|
||||||
## Copyright (C) 2007 Lukas Petrovicky <lukas@petrovicky.net>
|
## Copyright (C) 2007 Lukas Petrovicky <lukas@petrovicky.net>
|
||||||
## Copyright (C) 2007 Julien Pivotto <roidelapluie@gmail.com>
|
## Copyright (C) 2007 Julien Pivotto <roidelapluie@gmail.com>
|
||||||
|
## Copyright (C) 2007 Travis Shirk <travis@pobox.com>
|
||||||
##
|
##
|
||||||
## This file is part of Gajim.
|
## 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 not specified status is changed for all accounts. '''
|
||||||
if status not in ('offline', 'online', 'chat',
|
if status not in ('offline', 'online', 'chat',
|
||||||
'away', 'xa', 'dnd', 'invisible'):
|
'away', 'xa', 'dnd', 'invisible'):
|
||||||
raise InvalidArgument
|
|
||||||
return DBUS_BOOLEAN(False)
|
return DBUS_BOOLEAN(False)
|
||||||
if account:
|
if account:
|
||||||
gobject.idle_add(gajim.interface.roster.send_status, 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),
|
resource_props = dbus.Struct((DBUS_STRING(contact.resource),
|
||||||
dbus.Int32(contact.priority), DBUS_STRING(contact.status)))
|
dbus.Int32(contact.priority), DBUS_STRING(contact.status)))
|
||||||
contact_dict['resources'].append(resource_props)
|
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
|
return contact_dict
|
||||||
|
|
||||||
@dbus.service.method(INTERFACE, in_signature='', out_signature='s')
|
@dbus.service.method(INTERFACE, in_signature='', out_signature='s')
|
||||||
|
@ -654,4 +657,4 @@ class SignalObject(dbus.service.Object):
|
||||||
gajim.interface.instances[account]['join_gc'] = \
|
gajim.interface.instances[account]['join_gc'] = \
|
||||||
JoinGroupchatWindow(account, room_jid, nick)
|
JoinGroupchatWindow(account, room_jid, nick)
|
||||||
else:
|
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 sys
|
||||||
import gtk
|
import gtk
|
||||||
import systray
|
import systray
|
||||||
import gobject
|
|
||||||
|
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import helpers
|
from common import helpers
|
||||||
|
@ -60,7 +59,7 @@ class StatusIcon(systray.Systray):
|
||||||
self.unsubscribe_events()
|
self.unsubscribe_events()
|
||||||
|
|
||||||
def on_status_icon_left_clicked(self, widget):
|
def on_status_icon_left_clicked(self, widget):
|
||||||
gobject.idle_add(self.on_left_click)
|
self.on_left_click()
|
||||||
|
|
||||||
def set_img(self):
|
def set_img(self):
|
||||||
'''apart from image, we also update tooltip text here'''
|
'''apart from image, we also update tooltip text here'''
|
||||||
|
|
|
@ -254,14 +254,10 @@ class Systray:
|
||||||
item = gtk.MenuItem(_('Hide this menu'))
|
item = gtk.MenuItem(_('Hide this menu'))
|
||||||
self.systray_context_menu.prepend(item)
|
self.systray_context_menu.prepend(item)
|
||||||
self.added_hide_menuitem = True
|
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,
|
self.systray_context_menu.popup(None, None, None, event_button,
|
||||||
event_time)
|
event_time)
|
||||||
self.systray_context_menu.show_all()
|
|
||||||
|
|
||||||
def on_show_all_events_menuitem_activate(self, widget):
|
def on_show_all_events_menuitem_activate(self, widget):
|
||||||
events = gajim.events.get_systray_events()
|
events = gajim.events.get_systray_events()
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
## tooltips.py
|
## tooltips.py
|
||||||
##
|
##
|
||||||
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov@gmail.com>
|
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov@gmail.com>
|
||||||
|
@ -463,6 +464,10 @@ class RosterTooltip(NotificationAreaTooltip):
|
||||||
contact.last_status_time)
|
contact.last_status_time)
|
||||||
properties.append((self.table, None))
|
properties.append((self.table, None))
|
||||||
else: # only one resource
|
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:
|
if contact.show:
|
||||||
show = helpers.get_uf_show(contact.show)
|
show = helpers.get_uf_show(contact.show)
|
||||||
if contact.last_status_time:
|
if contact.last_status_time:
|
||||||
|
@ -494,6 +499,52 @@ class RosterTooltip(NotificationAreaTooltip):
|
||||||
show = '<i>' + show + '</i>'
|
show = '<i>' + show + '</i>'
|
||||||
# we append show below
|
# 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:
|
if contact.status:
|
||||||
status = contact.status.strip()
|
status = contact.status.strip()
|
||||||
if status:
|
if status:
|
||||||
|
|
|
@ -178,8 +178,6 @@ class VcardWindow:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_values(self, vcard):
|
def set_values(self, vcard):
|
||||||
if not 'PHOTO' in vcard:
|
|
||||||
self.xml.get_widget('no_user_avatar_label').show()
|
|
||||||
for i in vcard.keys():
|
for i in vcard.keys():
|
||||||
if i == 'PHOTO' and self.xml.get_widget('information_notebook').\
|
if i == 'PHOTO' and self.xml.get_widget('information_notebook').\
|
||||||
get_n_pages() > 4:
|
get_n_pages() > 4:
|
||||||
|
@ -187,6 +185,7 @@ class VcardWindow:
|
||||||
get_avatar_pixbuf_encoded_mime(vcard[i])
|
get_avatar_pixbuf_encoded_mime(vcard[i])
|
||||||
image = self.xml.get_widget('PHOTO_image')
|
image = self.xml.get_widget('PHOTO_image')
|
||||||
image.show()
|
image.show()
|
||||||
|
self.xml.get_widget('user_avatar_label').show()
|
||||||
if not pixbuf:
|
if not pixbuf:
|
||||||
image.set_from_icon_name('stock_person',
|
image.set_from_icon_name('stock_person',
|
||||||
gtk.ICON_SIZE_DIALOG)
|
gtk.ICON_SIZE_DIALOG)
|
||||||
|
|
Loading…
Add table
Reference in a new issue