merge with trunk
This commit is contained in:
commit
796213c9cb
10
AUTHORS
10
AUTHORS
|
@ -1,13 +1,8 @@
|
|||
CURRENT DEVELOPERS:
|
||||
|
||||
Alexander Cherniuk (ts33kr AT gmail.com)
|
||||
Nikos Kouremenos (kourem AT gmail.com)
|
||||
Yann Leboulanger (asterix AT lagaule.org)
|
||||
Julien Pivotto (roidelapluie AT gmail.com)
|
||||
Jonathan Schleifer (js-gajim AT webkeks.org)
|
||||
Travis Shirk (travis AT pobox.com)
|
||||
Brendan Taylor (whateley AT gmail.com)
|
||||
Jean-Marie Traissard (jim AT lapin.org)
|
||||
|
||||
PAST DEVELOPERS:
|
||||
|
||||
|
@ -15,3 +10,8 @@ Stefan Bethge (stefan AT lanpartei.de)
|
|||
Stephan Erb (steve-e AT h3c.de)
|
||||
Vincent Hanquez (tab AT snarc.org)
|
||||
Dimitur Kirov (dkirov AT gmail.com)
|
||||
Nikos Kouremenos (kourem AT gmail.com)
|
||||
Julien Pivotto (roidelapluie AT gmail.com)
|
||||
Travis Shirk (travis AT pobox.com)
|
||||
Brendan Taylor (whateley AT gmail.com)
|
||||
Jean-Marie Traissard (jim AT lapin.org)
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<h2>Optional Runtime Requirements</h2>
|
||||
<ul>
|
||||
<li><a href="http://pyopenssl.sourceforge.net/">PyOpenSSL</a> (python-pyopenssl package in Debian) for <em>secure</em> SSL/TLS. Python's default SSL is insecure, so this package is highly recommended!</li>
|
||||
<li><a href="http://pyopenssl.sourceforge.net/">PyOpenSSL</a> (python-pyopenssl package in Debian) (>=0.9) for <em>secure</em> SSL/TLS. Python's default SSL is insecure, so this package is highly recommended!</li>
|
||||
<li>python-crypto to enable End to end encryption</li>
|
||||
<li>For idle module, libxss library</li>
|
||||
<li>For zeroconf (bonjour), the "enable link-local messaging" checkbox, you need dbus-glib, python-avahi</li>
|
||||
|
@ -63,7 +63,7 @@
|
|||
|
||||
<p>To specify where to install do:</p>
|
||||
<pre>
|
||||
su -c make PREFIX=custom_path install
|
||||
./configure --prefix=custom_path
|
||||
</pre>
|
||||
|
||||
<h2>Running Gajim</h2>
|
||||
|
@ -98,7 +98,8 @@ or if you didn't 'make install' you can also run from gajim folder with<em>./lau
|
|||
If you want to remove it from custom directory provide it as:
|
||||
</p>
|
||||
<pre>
|
||||
make PREFIX=custom_path uninstall
|
||||
./configure --prefix=custom_path
|
||||
make uninstall
|
||||
</pre>
|
||||
|
||||
<h2>Miscellaneous</h2>
|
||||
|
@ -119,7 +120,7 @@ Wiki can be found at <a href="http://trac.gajim.org/wiki">http://trac.gajim.org/
|
|||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
(C) 2003-200888888888<br/>
|
||||
(C) 2003-2010<br/>
|
||||
The Gajim Team<br/>
|
||||
http://gajim.org<br/>
|
||||
<br/>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
Transifex.net Token Verification
|
||||
=================================
|
||||
|
||||
The list of tokens bellow guarantee the respective users to be able to enable
|
||||
submission on components using the following repository url:
|
||||
|
||||
ssh://hg.gajim.org/gajim
|
||||
|
||||
Tokens:
|
||||
|
||||
JzQjKFEfvEhybB3vKxvsNYfusnpxWth3 / asterix
|
|
@ -8,7 +8,9 @@
|
|||
fi
|
||||
|
||||
echo "[encoding: UTF-8]" > po/POTFILES.in \
|
||||
&& ls -1 data/gajim.desktop.in.in data/gui/*.ui \
|
||||
&& for p in `ls data/gui/*.ui`; do echo "[type: gettext/glade]$p" >> \
|
||||
po/POTFILES.in; done \
|
||||
&& ls -1 data/gajim.desktop.in.in \
|
||||
src/*py src/common/*py src/common/zeroconf/*.py | grep -v ipython_view.py >> \
|
||||
po/POTFILES.in || exit 1
|
||||
if test -z `which pkg-config 2>/dev/null`;then
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<object class="GtkMenu" id="account_context_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="status_menuitem">
|
||||
<property name="label">_Status</property>
|
||||
<property name="label" translatable="yes">_Status</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
@ -14,7 +14,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="pep_menuitem">
|
||||
<property name="label">_Personal Events</property>
|
||||
<property name="label" translatable="yes">_Personal Events</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="use_underline">True</property>
|
||||
|
@ -30,7 +30,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="start_chat_menuitem">
|
||||
<property name="label">_Start Chat...</property>
|
||||
<property name="label" translatable="yes">_Start Chat...</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="use_underline">True</property>
|
||||
|
@ -40,7 +40,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="join_group_chat_menuitem">
|
||||
<property name="label">Join _Group Chat...</property>
|
||||
<property name="label" translatable="yes">Join _Group Chat...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image4</property>
|
||||
|
@ -54,7 +54,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="add_contact_menuitem">
|
||||
<property name="label">_Add Contact...</property>
|
||||
<property name="label" translatable="yes">_Add Contact...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image5</property>
|
||||
|
@ -63,7 +63,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="service_discovery_menuitem">
|
||||
<property name="label">_Discover Services</property>
|
||||
<property name="label" translatable="yes">_Discover Services</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image6</property>
|
||||
|
@ -72,7 +72,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="execute_command_menuitem">
|
||||
<property name="label">_Execute Command...</property>
|
||||
<property name="label" translatable="yes">_Execute Command...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image7</property>
|
||||
|
@ -93,7 +93,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="edit_account_menuitem">
|
||||
<property name="label">_Modify Account</property>
|
||||
<property name="label" translatable="yes">_Modify Account</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image8</property>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
<columns>
|
||||
<!-- column-name item text -->
|
||||
<!-- column-name item -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
<data>
|
||||
|
@ -203,7 +203,7 @@
|
|||
<object class="GtkTable" id="table1">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">6</property>
|
||||
<property name="n_rows">5</property>
|
||||
<property name="n_rows">6</property>
|
||||
<property name="n_columns">3</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">6</property>
|
||||
|
@ -445,6 +445,68 @@
|
|||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander" id="expander2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label28">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">_Client Cert File:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="mnemonic_widget">cert_entry1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="cert_entry1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">The path to the client certificate and key in PKCS#12 format</property>
|
||||
<property name="invisible_char">●</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="browse_for_client_cert_button">
|
||||
<property name="label" translatable="yes">Browse...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Choose Client Cert</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Client certificate</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="right_attach">3</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="y_options">GTK_FILL</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="tab">
|
||||
|
|
|
@ -358,6 +358,22 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="spacing">12</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="restart_button">
|
||||
<property name="label">gtk-goto-first</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_restart_button_clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="back_button">
|
||||
<property name="label">gtk-go-back</property>
|
||||
|
@ -371,7 +387,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -387,7 +403,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -403,7 +419,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -419,7 +435,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<object class="GtkMenu" id="administrator_menuitem_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="send_server_message_menuitem">
|
||||
<property name="label">_Send Server Message...</property>
|
||||
<property name="label" translatable="yes">_Send Server Message...</property>
|
||||
<property name="tooltip_text" translatable="yes">Sends a message to users currently connected to this server</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
@ -54,7 +54,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="delete_motd_menuitem">
|
||||
<property name="label">Delete MOTD</property>
|
||||
<property name="label" translatable="yes">Delete MOTD</property>
|
||||
<property name="tooltip_text" translatable="yes">Deletes Message of the Day</property>
|
||||
<property name="image">image2</property>
|
||||
<property name="use_stock">False</property>
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">_Unblock</property>
|
||||
<property name="label" translatable="yes">_Unblock</property>
|
||||
<property name="use_underline">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<object class="GtkMenu" id="chat_context_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="copy_link_location_menuitem">
|
||||
<property name="label">_Copy Link Location</property>
|
||||
<property name="label" translatable="yes">_Copy Link Location</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
@ -14,7 +14,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="open_link_in_browser_menuitem">
|
||||
<property name="label">_Open Link in Browser</property>
|
||||
<property name="label" translatable="yes">_Open Link in Browser</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image2</property>
|
||||
|
@ -23,7 +23,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="copy_email_address_menuitem">
|
||||
<property name="label">_Copy JID/Email Address</property>
|
||||
<property name="label" translatable="yes">_Copy JID/Email Address</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image3</property>
|
||||
|
@ -32,7 +32,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="open_email_composer_menuitem">
|
||||
<property name="label">_Open Email Composer</property>
|
||||
<property name="label" translatable="yes">_Open Email Composer</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image4</property>
|
||||
|
@ -46,7 +46,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="start_chat_menuitem">
|
||||
<property name="label">_Start Chat</property>
|
||||
<property name="label" translatable="yes">_Start Chat</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image5</property>
|
||||
|
@ -55,7 +55,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="join_group_chat_menuitem">
|
||||
<property name="label">Join _Group Chat</property>
|
||||
<property name="label" translatable="yes">Join _Group Chat</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image6</property>
|
||||
|
@ -65,7 +65,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="add_to_roster_menuitem">
|
||||
<property name="label">_Add to Roster...</property>
|
||||
<property name="label" translatable="yes">_Add to Roster...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image7</property>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -41,9 +41,6 @@ Select the contacts you want to invite</property>
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<signal name="drag_end" handler="on_guests_treeview_drag_end"/>
|
||||
<signal name="drag_data_get" handler="on_guests_treeview_drag_data_get"/>
|
||||
<signal name="drag_data_received" handler="on_guests_treeview_drag_data_received"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -251,7 +251,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="continue_menuitem">
|
||||
<property name="label">_Continue</property>
|
||||
<property name="label" translatable="yes">_Continue</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
|
@ -261,7 +261,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="pause_menuitem">
|
||||
<property name="label">_Pause</property>
|
||||
<property name="label" translatable="yes">_Pause</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="accel_group">accelgroup1</property>
|
||||
|
@ -284,7 +284,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="open_folder_menuitem">
|
||||
<property name="label">_Open Containing Folder</property>
|
||||
<property name="label" translatable="yes">_Open Containing Folder</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="accel_group">accelgroup1</property>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<object class="GtkMenu" id="gc_control_popup_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="change_nick_menuitem">
|
||||
<property name="label">Change _Nickname...</property>
|
||||
<property name="label" translatable="yes">Change _Nickname...</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
@ -14,7 +14,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="manage_room_menuitem">
|
||||
<property name="label">_Manage Room</property>
|
||||
<property name="label" translatable="yes">_Manage Room</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="use_underline">True</property>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="change_subject_menuitem">
|
||||
<property name="label">Change _Subject...</property>
|
||||
<property name="label" translatable="yes">Change _Subject...</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image2</property>
|
||||
|
@ -35,7 +35,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="configure_room_menuitem">
|
||||
<property name="label">Configure _Room...</property>
|
||||
<property name="label" translatable="yes">Configure _Room...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image3</property>
|
||||
<property name="use_stock">False</property>
|
||||
|
@ -48,7 +48,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="destroy_room_menuitem">
|
||||
<property name="label">_Destroy Room</property>
|
||||
<property name="label" translatable="yes">_Destroy Room</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image4</property>
|
||||
|
@ -73,7 +73,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="bookmark_room_menuitem">
|
||||
<property name="label">_Bookmark</property>
|
||||
<property name="label" translatable="yes">_Bookmark</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image6</property>
|
||||
|
@ -87,7 +87,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="history_menuitem">
|
||||
<property name="label">_History</property>
|
||||
<property name="label" translatable="yes">_History</property>
|
||||
<property name="no_show_all">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image7</property>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<object class="GtkMenu" id="gc_occupants_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="send_private_message_menuitem">
|
||||
<property name="label">_Send Private Message</property>
|
||||
<property name="label" translatable="yes">_Send Private Message</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
@ -15,7 +15,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="send_file_menuitem">
|
||||
<property name="label">Send _File</property>
|
||||
<property name="label" translatable="yes">Send _File</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="use_underline">True</property>
|
||||
|
@ -101,7 +101,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="add_to_roster_menuitem">
|
||||
<property name="label">_Add to Roster</property>
|
||||
<property name="label" translatable="yes">_Add to Roster</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image3</property>
|
||||
|
@ -111,7 +111,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="block_menuitem">
|
||||
<property name="label">_Block</property>
|
||||
<property name="label" translatable="yes">_Block</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image4</property>
|
||||
|
@ -121,7 +121,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="unblock_menuitem">
|
||||
<property name="label">_Unblock</property>
|
||||
<property name="label" translatable="yes">_Unblock</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image5</property>
|
||||
|
@ -145,7 +145,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="history_menuitem">
|
||||
<property name="label">_History</property>
|
||||
<property name="label" translatable="yes">_History</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image6</property>
|
||||
|
|
|
@ -75,6 +75,85 @@
|
|||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHPaned" id="hpaned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="position">495</property>
|
||||
<property name="position_set">True</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="gc_textviews_vbox">
|
||||
<property name="width_request">0</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="conversation_scrolledwindow">
|
||||
<property name="width_request">200</property>
|
||||
<property name="height_request">60</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="message_scrolledwindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="list_scrolledwindow">
|
||||
<property name="width_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="list_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">1</property>
|
||||
<property name="headers_visible">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="actions_hbox">
|
||||
<property name="visible">True</property>
|
||||
|
@ -133,7 +212,6 @@
|
|||
<object class="GtkVSeparator" id="vseparator2">
|
||||
<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="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -233,7 +311,6 @@
|
|||
<object class="GtkVSeparator" id="vseparator4">
|
||||
<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="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -269,6 +346,14 @@
|
|||
<property name="position">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="label_selector">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">9</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment2">
|
||||
<property name="visible">True</property>
|
||||
|
@ -278,7 +363,7 @@
|
|||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">9</property>
|
||||
<property name="position">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -326,7 +411,7 @@
|
|||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">10</property>
|
||||
<property name="position">11</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -335,94 +420,5 @@
|
|||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHPaned" id="hpaned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">3</property>
|
||||
<property name="position">495</property>
|
||||
<property name="position_set">True</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox108">
|
||||
<property name="width_request">0</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox109">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="conversation_scrolledwindow">
|
||||
<property name="width_request">200</property>
|
||||
<property name="height_request">60</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">automatic</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="message_scrolledwindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">never</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="list_scrolledwindow">
|
||||
<property name="width_request">100</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">never</property>
|
||||
<property name="vscrollbar_policy">automatic</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="list_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="border_width">1</property>
|
||||
<property name="headers_visible">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">False</property>
|
||||
<property name="shrink">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
|
@ -281,7 +281,7 @@ If you plan to do massive deletions, please make sure Gajim is not running. Gene
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="delete_menuitem">
|
||||
<property name="label">Delete</property>
|
||||
<property name="label" translatable="yes">Delete</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<property name="type_hint">dialog</property>
|
||||
<property name="has_separator">False</property>
|
||||
<signal name="destroy" handler="on_input_dialog_destroy"/>
|
||||
<signal name="delete_event" handler="on_input_dialog_delete_event"/>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox10">
|
||||
<property name="visible">True</property>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<child>
|
||||
<object class="GtkTable" id="table15">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">7</property>
|
||||
<property name="n_rows">8</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">12</property>
|
||||
<property name="row_spacing">6</property>
|
||||
|
@ -110,8 +110,8 @@
|
|||
<property name="label" translatable="yes">Password:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
<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>
|
||||
|
@ -126,14 +126,14 @@
|
|||
<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="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="auto_join_checkbutton">
|
||||
<property name="label" translatable="yes">Join this room automatically when I connect</property>
|
||||
<property name="label" translatable="yes">Join this room _automatically when I connect</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">True</property>
|
||||
|
@ -143,8 +143,8 @@
|
|||
</object>
|
||||
<packing>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">6</property>
|
||||
<property name="bottom_attach">7</property>
|
||||
<property name="top_attach">7</property>
|
||||
<property name="bottom_attach">8</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
|
@ -174,21 +174,69 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="bookmark_checkbutton">
|
||||
<property name="label" translatable="yes">Bookmark this room</property>
|
||||
<property name="label" translatable="yes">_Bookmark this room</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<signal name="toggled" handler="on_bookmark_checkbutton_toggled"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">5</property>
|
||||
<property name="bottom_attach">6</property>
|
||||
<property name="top_attach">6</property>
|
||||
<property name="bottom_attach">7</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Server:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">4</property>
|
||||
<property name="bottom_attach">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkComboBoxEntry" id="server_comboboxentry">
|
||||
<property name="visible">True</property>
|
||||
<property name="model">liststore1</property>
|
||||
<property name="text_column">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="browse_rooms_button">
|
||||
<property name="label" translatable="yes">Bro_wse Rooms</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="image">image1</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="clicked" handler="on_browse_rooms_button_clicked"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<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>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
|
@ -275,4 +323,14 @@
|
|||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
<columns>
|
||||
<!-- column-name gchararray1 -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-find</property>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
<columns>
|
||||
<!-- column-name item text -->
|
||||
<!-- column-name item -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
|
@ -13,7 +13,6 @@
|
|||
<property name="title" translatable="yes">Manage Bookmarks</property>
|
||||
<property name="default_width">550</property>
|
||||
<property name="default_height">300</property>
|
||||
<signal name="button_press_event" handler="on_manage_bookmarks_window_button_press_event"/>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox86">
|
||||
<property name="visible">True</property>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="scrollable">True</property>
|
||||
<property name="tab_border">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -43,6 +44,7 @@
|
|||
<property name="xalign">0</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="ellipsize">end</property>
|
||||
<property name="max_width_chars">9</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
|
@ -59,7 +61,6 @@
|
|||
<child>
|
||||
<object class="GtkImage" id="image1329">
|
||||
<property name="visible">True</property>
|
||||
<property name="ypad">6</property>
|
||||
<property name="stock">gtk-close</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<object class="GtkLabel" id="event_type_label">
|
||||
<property name="width_request">196</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label">Event Type</property>
|
||||
<property name="label" translatable="yes">Event Type</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
|
@ -85,7 +85,7 @@
|
|||
<property name="width_request">218</property>
|
||||
<property name="height_request">64</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label">Event desc</property>
|
||||
<property name="label" translatable="yes">Event desc</property>
|
||||
<property name="wrap">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
|
|
|
@ -2136,7 +2136,7 @@ $T will be replaced by auto-not-available timeout</property>
|
|||
<child>
|
||||
<object class="GtkTable" id="table8">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">6</property>
|
||||
<property name="row_spacing">6</property>
|
||||
|
@ -2184,6 +2184,52 @@ $T will be replaced by auto-not-available timeout</property>
|
|||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label26">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Video framerate</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label27">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Video size</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="video_framerate_combobox">
|
||||
<property name="visible">True</property>
|
||||
<signal name="changed" handler="on_video_framerate_combobox_changed"/>
|
||||
</object>
|
||||
<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>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="video_size_combobox">
|
||||
<property name="visible">True</property>
|
||||
<signal name="changed" handler="on_video_size_combobox_changed"/>
|
||||
</object>
|
||||
<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>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -432,6 +432,7 @@
|
|||
<object class="GtkEntry" id="BDAY_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<signal name="focus_out_event" handler="on_BDAY_entry_focus_out_event"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<object class="GtkMenu" id="actions_menu_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="new_chat_menuitem">
|
||||
<property name="label">_Start Chat...</property>
|
||||
<property name="label" translatable="yes">_Start Chat...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
@ -44,7 +44,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="send_single_message_menuitem">
|
||||
<property name="label">_Send Single Message...</property>
|
||||
<property name="label" translatable="yes">_Send Single Message...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image2</property>
|
||||
<property name="use_stock">False</property>
|
||||
|
@ -53,9 +53,9 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="join_gc_menuitem">
|
||||
<property name="label">Join _Group Chat...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Join _Group Chat...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="image">image3</property>
|
||||
<property name="use_stock">False</property>
|
||||
<property name="accel_group">accelgroup1</property>
|
||||
|
@ -68,9 +68,9 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="add_new_contact_menuitem">
|
||||
<property name="label">Add _Contact...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Add _Contact...</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="image">image4</property>
|
||||
<property name="use_stock">False</property>
|
||||
<property name="accel_group">accelgroup1</property>
|
||||
|
@ -78,7 +78,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="service_disco_menuitem">
|
||||
<property name="label">_Discover Services</property>
|
||||
<property name="label" translatable="yes">_Discover Services</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image5</property>
|
||||
|
@ -123,7 +123,7 @@
|
|||
<object class="GtkMenu" id="edit_menu_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="accounts_menuitem">
|
||||
<property name="label">_Accounts</property>
|
||||
<property name="label" translatable="yes">_Accounts</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image6</property>
|
||||
|
@ -135,7 +135,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="profile_avatar_menuitem">
|
||||
<property name="label">Profile, A_vatar</property>
|
||||
<property name="label" translatable="yes">Profile, A_vatar</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image7</property>
|
||||
|
@ -159,16 +159,6 @@
|
|||
<signal name="activate" handler="on_preferences_menuitem_activate"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="plugins_menuitem">
|
||||
<property name="label" translatable="yes">P_lugins</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image13</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_plugins_menuitem_activate"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -225,7 +215,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="file_transfers_menuitem">
|
||||
<property name="label">File _Transfers</property>
|
||||
<property name="label" translatable="yes">File _Transfers</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image8</property>
|
||||
|
@ -237,7 +227,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="history_menuitem">
|
||||
<property name="label">_History</property>
|
||||
<property name="label" translatable="yes">_History</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="use_underline">True</property>
|
||||
|
@ -260,7 +250,7 @@
|
|||
<object class="GtkMenu" id="help_menu_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="contents_menuitem">
|
||||
<property name="label">_Contents</property>
|
||||
<property name="label" translatable="yes">_Contents</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Help online</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
@ -272,7 +262,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="faq_menuitem">
|
||||
<property name="label">_FAQ</property>
|
||||
<property name="label" translatable="yes">_FAQ</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Frequently Asked Questions (online)</property>
|
||||
<property name="use_underline">True</property>
|
||||
|
@ -289,7 +279,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="features_menuitem">
|
||||
<property name="label">Fea_tures</property>
|
||||
<property name="label" translatable="yes">Fea_tures</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="use_underline">True</property>
|
||||
|
@ -447,9 +437,4 @@
|
|||
<property name="stock">gtk-properties</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="image13">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-disconnect</property>
|
||||
<property name="icon-size">1</property>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
<columns>
|
||||
<!-- column-name item text -->
|
||||
<!-- column-name item -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
|
@ -70,14 +70,8 @@ Agent JID - node</property>
|
|||
<object class="GtkComboBoxEntry" id="address_comboboxentry">
|
||||
<property name="visible">True</property>
|
||||
<property name="model">liststore1</property>
|
||||
<property name="text_column">0</property>
|
||||
<signal name="changed" handler="on_address_comboboxentry_changed"/>
|
||||
<signal name="key_press_event" handler="on_address_comboboxentry_key_press_event"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext1"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<object class="GtkMenu" id="subscription_request_popup_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="start_chat_menuitem">
|
||||
<property name="label">_Start Chat</property>
|
||||
<property name="label" translatable="yes">_Start Chat</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<object class="GtkMenu" id="systray_context_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="status_menu">
|
||||
<property name="label">Sta_tus</property>
|
||||
<property name="label" translatable="yes">Sta_tus</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
@ -15,7 +15,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="chat_with_menuitem">
|
||||
<property name="label">_Start Chat</property>
|
||||
<property name="label" translatable="yes">_Start Chat</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image2</property>
|
||||
|
@ -25,7 +25,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="join_gc_menuitem">
|
||||
<property name="label">_Group Chat</property>
|
||||
<property name="label" translatable="yes">_Group Chat</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image3</property>
|
||||
|
@ -35,7 +35,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="single_message_menuitem">
|
||||
<property name="label">Send Single _Message</property>
|
||||
<property name="label" translatable="yes">Send Single _Message</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image4</property>
|
||||
|
@ -66,13 +66,11 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="show_roster_menuitem">
|
||||
<property name="label">Show _Roster</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image5</property>
|
||||
<property name="use_stock">False</property>
|
||||
<property name="accel_group">accelgroup1</property>
|
||||
<signal name="activate" handler="on_show_roster_menuitem_activate"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<property name="border_width">12</property>
|
||||
<property name="default_width">550</property>
|
||||
<property name="default_height">450</property>
|
||||
<signal name="delete_event" handler="on_xml_console_window_delete_event"/>
|
||||
<signal name="destroy" handler="on_xml_console_window_destroy"/>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox">
|
||||
<property name="visible">True</property>
|
||||
|
@ -50,7 +50,7 @@
|
|||
<property name="visible">True</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="enable_checkbutton">
|
||||
<property name="label" translatable="yes" comments="XML Console enable checkbutton">Enable</property>
|
||||
<property name="label" translatable="yes" comments="XML Console enable checkbutton">_Enable</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<object class="GtkMenu" id="zeroconf_context_menu">
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="status_menuitem">
|
||||
<property name="label">_Status</property>
|
||||
<property name="label" translatable="yes">_Status</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image1</property>
|
||||
|
@ -20,7 +20,7 @@
|
|||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="zeroconf_properties_menuitem">
|
||||
<property name="label">_Modify Account...</property>
|
||||
<property name="label" translatable="yes">_Modify Account...</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="image">image2</property>
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
gajim (0.13.4-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Fix flood when trying to join a full MUC. Closes: #575688
|
||||
|
||||
-- Yann Leboulanger <asterix@lagaule.org> Fri, 02 Apr 2010 10:19:59 +0200
|
||||
|
||||
gajim (0.13.3-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Fix connection to facebook. Closes: #569767
|
||||
|
||||
-- Yann Leboulanger <asterix@lagaule.org> Tue, 23 Feb 2010 21:00:41 +0100
|
||||
|
||||
gajim (0.13.2-1) unstable; urgency=low
|
||||
|
||||
* New upstream release.
|
||||
* Fix gnomekeyring usage. Closes: #562913
|
||||
* Fix completion. Closes: #563930
|
||||
* Fix typo in suggests list. Closes: #564754
|
||||
|
||||
-- Yann Leboulanger <asterix@lagaule.org> Thu, 14 Jan 2010 21:23:36 +0100
|
||||
|
||||
gajim (0.13.1-1) unstable; urgency=low
|
||||
|
||||
* New upstream release. Closes: #559905
|
||||
|
|
|
@ -2,9 +2,9 @@ Source: gajim
|
|||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Yann Leboulanger <asterix@lagaule.org>
|
||||
Build-Depends: debhelper (>= 7), cdbs (>= 0.4.43), python-support (>= 0.7.1), python-dev, libgtk2.0-dev, python-gtk2-dev, gettext (>= 0.17-4), intltool (>= 0.40.1), imagemagick, python-central (>= 0.5)
|
||||
Build-Depends: debhelper (>= 7), cdbs (>= 0.4.43), python-support (>= 0.7.1), python-dev, libgtk2.0-dev, python-gtk2-dev, gettext (>= 0.17-4), intltool (>= 0.40.1), imagemagick
|
||||
Build-Conflicts: python2.3
|
||||
XS-Python-Version: >= 2.4
|
||||
XS-Python-Version: >= 2.5
|
||||
Standards-Version: 3.8.3
|
||||
Homepage: http://www.gajim.org
|
||||
Vcs-Hg: http://hg.gajim.org/gajim/
|
||||
|
@ -15,7 +15,7 @@ Architecture: any
|
|||
XB-Python-Version: ${python:Versions}
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}, ${python:Depends}, python-support (>= 0.7.1), python-glade2 (>= 2.12.0), python-gtk2 (>= 2.12.0), dnsutils
|
||||
Recommends: dbus, python-dbus, notification-daemon, python-gnupginterface, python-openssl, python-crypto
|
||||
Suggests: python-gconf, python-gnome2, nautilus-sendto, avahi-daemon, python-avahi, network-manager, libgtkspell0, aspell-en, python-gnomekeyring, gnome-keyring, python-kerberos (>= 1.1), texlive-latex-base, dvipng
|
||||
Suggests: python-gconf, python-gnome2, nautilus-sendto, avahi-daemon, python-avahi, network-manager, libgtkspell0, aspell-en, python-gnomekeyring, gnome-keyring, python-sexy, python-kerberos (>= 1.1), texlive-latex-base, dvipng
|
||||
Description: Jabber client written in PyGTK
|
||||
Gajim is a Jabber client. It has a tabbed user interface with normal chats,
|
||||
group chats, and has many features such as, TLS, GPG, SSL, multiple accounts,
|
||||
|
|
|
@ -5,12 +5,12 @@ It was downloaded from:
|
|||
http://www.gajim.org/downloads/
|
||||
|
||||
Upstream Authors:
|
||||
- Alexander Cherniuk <ts33kr@gmail.com>
|
||||
- Yann Le Boulanger <asterix@lagaule.org>
|
||||
- Jean-Marie Traissard <jim@lapin.org>
|
||||
- Stephan Erb <steve-e@h3c.de>
|
||||
- Jonathan Schleifer <js-gajim@webkeks.org>
|
||||
|
||||
|
||||
Copyright: (c) 2003-2009 Gajim Team
|
||||
Copyright: (c) 2003-2010 Gajim Team
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
2
|
|
@ -1 +1 @@
|
|||
2.4
|
||||
2.5-
|
||||
|
|
|
@ -7,10 +7,9 @@ include /usr/share/cdbs/1/rules/debhelper.mk
|
|||
include /usr/share/cdbs/1/rules/simple-patchsys.mk
|
||||
include /usr/share/cdbs/1/class/autotools.mk
|
||||
|
||||
PYTHONVER = 2.5
|
||||
DEB_CONFIGURE_EXTRA_FLAGS := --prefix=/usr
|
||||
DEB_MAKE_BUILD_TARGET := all PYTHON=python$(PYTHONVER)
|
||||
DEB_MAKE_INSTALL_TARGET = install PYTHON=python$(PYTHONVER) DESTDIR=$(DEB_DESTDIR)
|
||||
DEB_MAKE_BUILD_TARGET := all
|
||||
DEB_MAKE_INSTALL_TARGET = install DESTDIR=$(DEB_DESTDIR)
|
||||
|
||||
binary-install/gajim::
|
||||
rm $(DEB_DESTDIR)/usr/share/gajim/src/common/GnuPGInterface.py*
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# Control file for uscan
|
||||
# Run the "uscan" command to check for upstream updates and more.
|
||||
# See uscan(1) for format
|
||||
|
||||
# Compulsory line, this is a version 3 file
|
||||
version=3
|
||||
|
||||
http://www.gajim.org/downloads/([\d.]*)/gajim-([\d\.]*)\.tar\.gz
|
Binary file not shown.
After Width: | Height: | Size: 828 B |
Binary file not shown.
After Width: | Height: | Size: 706 B |
Binary file not shown.
After Width: | Height: | Size: 767 B |
Binary file not shown.
After Width: | Height: | Size: 760 B |
|
@ -29,3 +29,5 @@ gl
|
|||
lt
|
||||
da
|
||||
uk
|
||||
ja
|
||||
kk
|
||||
|
|
4774
po/be@latin.po
4774
po/be@latin.po
File diff suppressed because it is too large
Load Diff
8229
po/en_GB.po
8229
po/en_GB.po
File diff suppressed because it is too large
Load Diff
4419
po/pt_BR.po
4419
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
4816
po/sr@Latn.po
4816
po/sr@Latn.po
File diff suppressed because it is too large
Load Diff
4783
po/zh_CN.po
4783
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
|
@ -7,4 +7,4 @@ import sys
|
|||
if os.getcwd().endswith('dev'):
|
||||
os.chdir('../../src/') # we were in scripts/dev
|
||||
|
||||
os.system("pylint --indent-string='\t' --additional-builtins='_' --disable-msg=C0111,C0103,C0111,C0112 --disable-checker=design " + "".join(sys.argv[1:]))
|
||||
os.system("pylint --include-ids=y --additional-builtins='_' --disable-msg=C0103,C0111,W0703,W0511,W0142,W0613,R0201 --disable-checker=design " + "".join(sys.argv[1:]))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## setup_win32.py (run me as python setup_win32.py py2exe -O2)
|
||||
##
|
||||
## Copyright (C) 2003-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2003-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
||||
##
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
##
|
||||
## Copyright (C) 2006 Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2006-2007 Tomasz Melcer <liori AT exroot.org>
|
||||
## Copyright (C) 2006-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2006-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
||||
## Stephan Erb <steve-e AT h3c.de>
|
||||
##
|
||||
|
@ -55,21 +55,15 @@ class CommandWindow:
|
|||
# an account object
|
||||
self.account = gajim.connections[account]
|
||||
self.jid = jid
|
||||
|
||||
self.pulse_id=None # to satisfy self.setup_pulsing()
|
||||
self.commandlist=None # a list of (commandname, commanddescription)
|
||||
|
||||
# command's data
|
||||
self.commandnode = commandnode
|
||||
self.sessionid = None
|
||||
self.dataform = None
|
||||
self.allow_stage3_close = False
|
||||
self.data_form_widget = None
|
||||
|
||||
# retrieving widgets from xml
|
||||
self.xml = gtkgui_helpers.get_gtk_builder('adhoc_commands_window.ui')
|
||||
self.window = self.xml.get_object('adhoc_commands_window')
|
||||
self.window.connect('delete-event', self.on_adhoc_commands_window_delete_event)
|
||||
for name in ('back_button', 'forward_button',
|
||||
self.window.connect('delete-event',
|
||||
self.on_adhoc_commands_window_delete_event)
|
||||
for name in ('restart_button', 'back_button', 'forward_button',
|
||||
'execute_button', 'close_button', 'stages_notebook',
|
||||
'retrieving_commands_stage_vbox',
|
||||
'command_list_stage_vbox', 'command_list_vbox',
|
||||
|
@ -78,7 +72,22 @@ class CommandWindow:
|
|||
'error_description_label'):
|
||||
self.__dict__[name] = self.xml.get_object(name)
|
||||
|
||||
self.initiate()
|
||||
|
||||
def initiate(self):
|
||||
|
||||
self.pulse_id = None # to satisfy self.setup_pulsing()
|
||||
self.commandlist = None # a list of (commandname, commanddescription)
|
||||
|
||||
# command's data
|
||||
self.sessionid = None
|
||||
self.dataform = None
|
||||
self.allow_stage3_close = False
|
||||
|
||||
# creating data forms widget
|
||||
if self.data_form_widget:
|
||||
self.sending_form_stage_vbox.remove(self.data_form_widget)
|
||||
self.data_form_widget.destroy()
|
||||
self.data_form_widget = dataforms_widget.DataFormWidget()
|
||||
self.data_form_widget.show()
|
||||
self.sending_form_stage_vbox.pack_start(self.data_form_widget)
|
||||
|
@ -94,6 +103,8 @@ class CommandWindow:
|
|||
self.xml.connect_signals(self)
|
||||
self.window.show_all()
|
||||
|
||||
self.restart_button.set_sensitive(False)
|
||||
|
||||
# These functions are set up by appropriate stageX methods.
|
||||
def stage_finish(self, *anything):
|
||||
pass
|
||||
|
@ -130,7 +141,7 @@ class CommandWindow:
|
|||
return self.stage_close_button_clicked(*anything)
|
||||
|
||||
def on_adhoc_commands_window_destroy(self, *anything):
|
||||
# TODO: do all actions that are needed to remove this object from memory...
|
||||
# TODO: do all actions that are needed to remove this object from memory
|
||||
self.remove_pulsing()
|
||||
|
||||
def on_adhoc_commands_window_delete_event(self, *anything):
|
||||
|
@ -167,7 +178,8 @@ class CommandWindow:
|
|||
# setup the callbacks
|
||||
self.stage_finish = self.stage1_finish
|
||||
self.stage_close_button_clicked = self.stage1_close_button_clicked
|
||||
self.stage_adhoc_commands_window_delete_event = self.stage1_adhoc_commands_window_delete_event
|
||||
self.stage_adhoc_commands_window_delete_event = \
|
||||
self.stage1_adhoc_commands_window_delete_event
|
||||
|
||||
def stage1_finish(self):
|
||||
self.remove_pulsing()
|
||||
|
@ -196,8 +208,7 @@ class CommandWindow:
|
|||
assert len(self.commandlist)>0
|
||||
|
||||
self.stages_notebook.set_current_page(
|
||||
self.stages_notebook.page_num(
|
||||
self.command_list_stage_vbox))
|
||||
self.stages_notebook.page_num(self.command_list_stage_vbox))
|
||||
|
||||
self.close_button.set_sensitive(True)
|
||||
self.back_button.set_sensitive(False)
|
||||
|
@ -208,7 +219,8 @@ class CommandWindow:
|
|||
first_radio = None
|
||||
for (commandnode, commandname) in self.commandlist:
|
||||
radio = gtk.RadioButton(first_radio, label=commandname)
|
||||
radio.connect("toggled", self.on_command_radiobutton_toggled, commandnode)
|
||||
radio.connect("toggled", self.on_command_radiobutton_toggled,
|
||||
commandnode)
|
||||
if not first_radio:
|
||||
first_radio = radio
|
||||
self.commandnode = commandnode
|
||||
|
@ -266,7 +278,8 @@ class CommandWindow:
|
|||
self.stage_forward_button_clicked = self.stage3_forward_button_clicked
|
||||
self.stage_execute_button_clicked = self.stage3_execute_button_clicked
|
||||
self.stage_close_button_clicked = self.stage3_close_button_clicked
|
||||
self.stage_adhoc_commands_window_delete_event = self.stage3_close_button_clicked
|
||||
self.stage_adhoc_commands_window_delete_event = \
|
||||
self.stage3_close_button_clicked
|
||||
|
||||
def stage3_finish(self):
|
||||
pass
|
||||
|
@ -276,10 +289,10 @@ class CommandWindow:
|
|||
We are in the middle of executing command. Ask user if he really want to
|
||||
cancel the process, then cancel it
|
||||
"""
|
||||
# this works also as a handler for window_delete_event, so we have to return appropriate
|
||||
# values
|
||||
# this works also as a handler for window_delete_event, so we have to
|
||||
# return appropriate values
|
||||
if self.form_status == 'completed':
|
||||
if widget!=self.window:
|
||||
if widget != self.window:
|
||||
self.window.destroy()
|
||||
return False
|
||||
|
||||
|
@ -291,10 +304,10 @@ class CommandWindow:
|
|||
self.allow_stage3_close = True
|
||||
self.window.destroy()
|
||||
|
||||
dialog = dialogs.HigDialog(self.window, gtk.DIALOG_DESTROY_WITH_PARENT | \
|
||||
gtk.DIALOG_MODAL, gtk.BUTTONS_YES_NO, _('Cancel confirmation'),
|
||||
_('You are in process of executing command. Do you really want to '
|
||||
'cancel it?'), on_response_yes=on_yes)
|
||||
dialog = dialogs.HigDialog(self.window, gtk.DIALOG_DESTROY_WITH_PARENT \
|
||||
| gtk.DIALOG_MODAL, gtk.BUTTONS_YES_NO, _('Cancel confirmation'),
|
||||
_('You are in process of executing command. Do you really want to '
|
||||
'cancel it?'), on_response_yes=on_yes)
|
||||
dialog.popup()
|
||||
return True # Block event, don't close window
|
||||
|
||||
|
@ -310,7 +323,7 @@ class CommandWindow:
|
|||
def stage3_submit_form(self, action='execute'):
|
||||
self.data_form_widget.set_sensitive(False)
|
||||
if self.data_form_widget.get_data_form():
|
||||
self.data_form_widget.data_form.type='submit'
|
||||
self.data_form_widget.data_form.type = 'submit'
|
||||
else:
|
||||
self.data_form_widget.hide()
|
||||
|
||||
|
@ -346,9 +359,10 @@ class CommandWindow:
|
|||
|
||||
self.data_form_widget.set_sensitive(True)
|
||||
try:
|
||||
self.data_form_widget.data_form=self.dataform
|
||||
self.data_form_widget.data_form = self.dataform
|
||||
except dataforms.Error:
|
||||
self.stage5(error=_('Service sent malformed data'), senderror=True)
|
||||
self.stage5(error=_('Service sent malformed data'),
|
||||
senderror=True)
|
||||
return
|
||||
self.data_form_widget.show()
|
||||
if self.data_form_widget.title:
|
||||
|
@ -362,7 +376,8 @@ class CommandWindow:
|
|||
# actions, actions, actions...
|
||||
self.close_button.set_sensitive(True)
|
||||
self.back_button.set_sensitive(actions.getTag('prev') is not None)
|
||||
self.forward_button.set_sensitive(actions.getTag('next') is not None)
|
||||
self.forward_button.set_sensitive(
|
||||
actions.getTag('next') is not None)
|
||||
self.execute_button.set_sensitive(True)
|
||||
else:
|
||||
self.close_button.set_sensitive(True)
|
||||
|
@ -372,11 +387,13 @@ class CommandWindow:
|
|||
|
||||
if self.form_status == 'completed':
|
||||
self.close_button.set_sensitive(True)
|
||||
self.restart_button.set_sensitive(True)
|
||||
self.back_button.hide()
|
||||
self.forward_button.hide()
|
||||
self.execute_button.hide()
|
||||
self.close_button.show()
|
||||
self.stage_adhoc_commands_window_delete_event = self.stage3_close_button_clicked
|
||||
self.stage_adhoc_commands_window_delete_event = \
|
||||
self.stage3_close_button_clicked
|
||||
|
||||
note = command.getTag('note')
|
||||
if note:
|
||||
|
@ -387,6 +404,10 @@ class CommandWindow:
|
|||
self.notes_label.set_no_show_all(True)
|
||||
self.notes_label.hide()
|
||||
|
||||
def on_restart_button_clicked(self, widget):
|
||||
self.commandnode = None
|
||||
self.initiate()
|
||||
|
||||
# stage 4: no commands are exposed
|
||||
def stage4(self):
|
||||
"""
|
||||
|
@ -396,8 +417,7 @@ class CommandWindow:
|
|||
self.stage_finish()
|
||||
|
||||
self.stages_notebook.set_current_page(
|
||||
self.stages_notebook.page_num(
|
||||
self.no_commands_stage_vbox))
|
||||
self.stages_notebook.page_num(self.no_commands_stage_vbox))
|
||||
|
||||
self.close_button.set_sensitive(True)
|
||||
self.back_button.set_sensitive(False)
|
||||
|
@ -442,8 +462,7 @@ class CommandWindow:
|
|||
assert False
|
||||
|
||||
self.stages_notebook.set_current_page(
|
||||
self.stages_notebook.page_num(
|
||||
self.error_stage_vbox))
|
||||
self.stages_notebook.page_num(self.error_stage_vbox))
|
||||
|
||||
self.close_button.set_sensitive(True)
|
||||
self.back_button.hide()
|
||||
|
@ -481,14 +500,15 @@ class CommandWindow:
|
|||
"""
|
||||
if self.pulse_id:
|
||||
gobject.source_remove(self.pulse_id)
|
||||
self.pulse_id=None
|
||||
self.pulse_id = None
|
||||
|
||||
# handling xml stanzas
|
||||
def request_command_list(self):
|
||||
"""
|
||||
Request the command list. Change stage on delivery
|
||||
"""
|
||||
query = xmpp.Iq(typ='get', to=xmpp.JID(self.jid), queryNS=xmpp.NS_DISCO_ITEMS)
|
||||
query = xmpp.Iq(typ='get', to=xmpp.JID(self.jid),
|
||||
queryNS=xmpp.NS_DISCO_ITEMS)
|
||||
query.setQuerynode(xmpp.NS_COMMANDS)
|
||||
|
||||
def callback(response):
|
||||
|
@ -512,7 +532,8 @@ class CommandWindow:
|
|||
self.commandlist = []
|
||||
self.stage4()
|
||||
else:
|
||||
self.commandlist = [(t.getAttr('node'), t.getAttr('name')) for t in items]
|
||||
self.commandlist = [(t.getAttr('node'), t.getAttr('name')) \
|
||||
for t in items]
|
||||
self.stage2()
|
||||
|
||||
self.account.connection.SendAndCallForResponse(query, callback)
|
||||
|
@ -533,9 +554,6 @@ class CommandWindow:
|
|||
cmdnode.setAttr('sessionid', self.sessionid)
|
||||
|
||||
if self.data_form_widget.data_form:
|
||||
# cmdnode.addChild(node=dataforms.DataForm(tofill=self.data_form_widget.data_form))
|
||||
# FIXME: simplified form to send
|
||||
|
||||
cmdnode.addChild(node=self.data_form_widget.data_form)
|
||||
|
||||
def callback(response):
|
||||
|
@ -564,6 +582,6 @@ class CommandWindow:
|
|||
|
||||
self.account.connection.send(stanza)
|
||||
else:
|
||||
# we did not received any reply from service; FIXME: we should wait and
|
||||
# then send cancel; for now we do nothing
|
||||
# we did not received any reply from service;
|
||||
# FIXME: we should wait and then send cancel; for now we do nothing
|
||||
pass
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
##
|
||||
## Copyright (C) 2005 Travis Shirk <travis AT pobox.com>
|
||||
## Vincent Hanquez <tab AT snarc.org>
|
||||
## Copyright (C) 2005-2007 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2005-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2005-2007 Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com>
|
||||
## Copyright (C) 2006-2007 Jean-Marie Traissard <jim AT lapin.org>
|
||||
##
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
## src/atom_window.py
|
||||
##
|
||||
## Copyright (C) 2006 Tomasz Melcer <liori AT exroot.org>
|
||||
## Copyright (C) 2006-2007 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2006-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2007 Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
||||
##
|
||||
|
@ -53,15 +53,16 @@ class AtomWindow:
|
|||
"""
|
||||
Create new window... only if we have anything to show
|
||||
"""
|
||||
assert len(self.__class__.entries)>0
|
||||
assert len(self.__class__.entries)
|
||||
|
||||
self.entry = None # the entry actually displayed
|
||||
self.entry = None # the entry actually displayed
|
||||
|
||||
self.xml = gtkgui_helpers.get_gtk_builder('atom_entry_window.ui')
|
||||
self.window = self.xml.get_object('atom_entry_window')
|
||||
for name in ('new_entry_label', 'feed_title_label', 'feed_title_eventbox',
|
||||
'feed_tagline_label', 'entry_title_label', 'entry_title_eventbox',
|
||||
'last_modified_label', 'close_button', 'next_button'):
|
||||
for name in ('new_entry_label', 'feed_title_label',
|
||||
'feed_title_eventbox', 'feed_tagline_label', 'entry_title_label',
|
||||
'entry_title_eventbox', 'last_modified_label', 'close_button',
|
||||
'next_button'):
|
||||
self.__dict__[name] = self.xml.get_object(name)
|
||||
|
||||
self.displayNextEntry()
|
||||
|
@ -83,23 +84,26 @@ class AtomWindow:
|
|||
# fill the fields
|
||||
if newentry.feed_link is not None:
|
||||
self.feed_title_label.set_markup(
|
||||
u'<span foreground="blue" underline="single">%s</span>' % \
|
||||
gobject.markup_escape_text(newentry.feed_title))
|
||||
u'<span foreground="blue" underline="single">%s</span>' % \
|
||||
gobject.markup_escape_text(newentry.feed_title))
|
||||
else:
|
||||
self.feed_title_label.set_markup(
|
||||
gobject.markup_escape_text(newentry.feed_title))
|
||||
gobject.markup_escape_text(newentry.feed_title))
|
||||
|
||||
self.feed_tagline_label.set_markup(
|
||||
u'<small>%s</small>' % \
|
||||
gobject.markup_escape_text(newentry.feed_tagline))
|
||||
u'<small>%s</small>' % \
|
||||
gobject.markup_escape_text(newentry.feed_tagline))
|
||||
|
||||
if newentry.uri is not None:
|
||||
self.entry_title_label.set_markup(
|
||||
if newentry.title:
|
||||
if newentry.uri is not None:
|
||||
self.entry_title_label.set_markup(
|
||||
u'<span foreground="blue" underline="single">%s</span>' % \
|
||||
gobject.markup_escape_text(newentry.title))
|
||||
else:
|
||||
self.entry_title_label.set_markup(
|
||||
else:
|
||||
self.entry_title_label.set_markup(
|
||||
gobject.markup_escape_text(newentry.title))
|
||||
else:
|
||||
self.entry_title_label.set_markup('')
|
||||
|
||||
self.last_modified_label.set_text(newentry.updated)
|
||||
|
||||
|
@ -114,11 +118,11 @@ class AtomWindow:
|
|||
changed
|
||||
"""
|
||||
count = len(self.__class__.entries)
|
||||
if count>0:
|
||||
if count:
|
||||
self.new_entry_label.set_text(i18n.ngettext(
|
||||
'You have received new entries (and %d not displayed):',
|
||||
'You have received new entries (and %d not displayed):', count,
|
||||
count, count))
|
||||
'You have received new entries (and %d not displayed):',
|
||||
'You have received new entries (and %d not displayed):', count,
|
||||
count, count))
|
||||
self.next_button.set_sensitive(True)
|
||||
else:
|
||||
self.new_entry_label.set_text(_('You have received new entry:'))
|
||||
|
@ -131,7 +135,7 @@ class AtomWindow:
|
|||
def on_next_button_clicked(self, widget):
|
||||
self.displayNextEntry()
|
||||
|
||||
def on_entry_title_button_press_event(self, widget, event):
|
||||
def on_entry_title_eventbox_button_press_event(self, widget, event):
|
||||
#FIXME: make it using special gtk2.10 widget
|
||||
if event.button == 1: # left click
|
||||
uri = self.entry.uri
|
||||
|
@ -139,7 +143,7 @@ class AtomWindow:
|
|||
helpers.launch_browser_mailer('url', uri)
|
||||
return True
|
||||
|
||||
def on_feed_title_button_press_event(self, widget, event):
|
||||
def on_feed_title_eventbox_button_press_event(self, widget, event):
|
||||
#FIXME: make it using special gtk2.10 widget
|
||||
if event.button == 1: # left click
|
||||
uri = self.entry.feed_uri
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding:utf-8 -*-
|
||||
## src/cell_renderer_image.py
|
||||
##
|
||||
## Copyright (C) 2003-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2003-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2005 Vincent Hanquez <tab AT snarc.org>
|
||||
## Copyright (C) 2005-2007 Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2006 Travis Shirk <travis AT pobox.com>
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
## src/chat_control.py
|
||||
##
|
||||
## Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com>
|
||||
## Copyright (C) 2006-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Jean-Marie Traissard <jim AT lapin.org>
|
||||
## Copyright (C) 2006-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
|
||||
## Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Travis Shirk <travis AT pobox.com>
|
||||
## Copyright (C) 2007 Lukas Petrovicky <lukas AT petrovicky.net>
|
||||
|
@ -94,6 +94,15 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
A base class containing a banner, ConversationTextview, MessageTextView
|
||||
"""
|
||||
|
||||
keymap = gtk.gdk.keymap_get_default()
|
||||
try:
|
||||
keycode_c = keymap.get_entries_for_keyval(gtk.keysyms.c)[0][0]
|
||||
except TypeError:
|
||||
keycode_c = 54
|
||||
try:
|
||||
keycode_ins = keymap.get_entries_for_keyval(gtk.keysyms.Insert)[0][0]
|
||||
except TypeError:
|
||||
keycode_ins = 118
|
||||
def make_href(self, match):
|
||||
url_color = gajim.config.get('urlmsgcolor')
|
||||
url = match.group()
|
||||
|
@ -147,7 +156,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
self.draw_banner_text()
|
||||
self._update_banner_state_image()
|
||||
gajim.plugin_manager.gui_extension_point('chat_control_base_draw_banner',
|
||||
self)
|
||||
self)
|
||||
|
||||
def draw_banner_text(self):
|
||||
"""
|
||||
|
@ -231,6 +240,29 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
def status_url_clicked(self, widget, url):
|
||||
helpers.launch_browser_mailer('url', url)
|
||||
|
||||
def setup_seclabel(self, combo):
|
||||
self.seclabel_combo = combo
|
||||
self.seclabel_combo.hide()
|
||||
self.seclabel_combo.set_no_show_all(True)
|
||||
lb = gtk.ListStore(str)
|
||||
self.seclabel_combo.set_model(lb)
|
||||
cell = gtk.CellRendererText()
|
||||
cell.set_property('xpad', 5) # padding for status text
|
||||
self.seclabel_combo.pack_start(cell, True)
|
||||
# text to show is in in first column of liststore
|
||||
self.seclabel_combo.add_attribute(cell, 'text', 0)
|
||||
if gajim.connections[self.account].seclabel_supported:
|
||||
gajim.connections[self.account].seclabel_catalogue(self.contact.jid, self.on_seclabels_ready)
|
||||
|
||||
def on_seclabels_ready(self):
|
||||
lb = self.seclabel_combo.get_model()
|
||||
lb.clear()
|
||||
for label in gajim.connections[self.account].seclabel_catalogues[self.contact.jid][2]:
|
||||
lb.append([label])
|
||||
self.seclabel_combo.set_active(0)
|
||||
self.seclabel_combo.set_no_show_all(False)
|
||||
self.seclabel_combo.show_all()
|
||||
|
||||
def __init__(self, type_id, parent_win, widget_name, contact, acct,
|
||||
resource=None):
|
||||
# Undo needs this variable to know if space has been pressed.
|
||||
|
@ -383,7 +415,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
# instance object (also subclasses, eg. ChatControl or GroupchatControl)
|
||||
gajim.plugin_manager.gui_extension_point('chat_control_base', self)
|
||||
|
||||
|
||||
def set_speller(self):
|
||||
# now set the one the user selected
|
||||
per_type = 'contacts'
|
||||
|
@ -419,7 +450,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
i += 1
|
||||
menu.show_all()
|
||||
|
||||
|
||||
def shutdown(self):
|
||||
# PluginSystem: removing GUI extension points connected with ChatControlBase
|
||||
# instance object
|
||||
|
@ -568,8 +598,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
self.connect_style_event(widget, opts[0], opts[1])
|
||||
|
||||
def _conv_textview_key_press_event(self, widget, event):
|
||||
if (event.state & gtk.gdk.CONTROL_MASK and event.keyval in (gtk.keysyms.c,
|
||||
gtk.keysyms.Insert)) or (event.state & gtk.gdk.SHIFT_MASK and \
|
||||
# translate any layout to latin_layout
|
||||
keymap = gtk.gdk.keymap_get_default()
|
||||
keycode = keymap.get_entries_for_keyval(event.keyval)[0][0]
|
||||
if (event.state & gtk.gdk.CONTROL_MASK and keycode in (self.keycode_c,
|
||||
self.keycode_ins)) or (event.state & gtk.gdk.SHIFT_MASK and \
|
||||
event.keyval in (gtk.keysyms.Page_Down, gtk.keysyms.Page_Up)):
|
||||
return False
|
||||
self.parent_win.notebook.emit('key_press_event', event)
|
||||
|
@ -729,6 +762,16 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
self.drag_entered_conv = True
|
||||
self.conv_textview.tv.set_editable(True)
|
||||
|
||||
def get_seclabel(self):
|
||||
label = None
|
||||
if self.seclabel_combo is not None:
|
||||
idx = self.seclabel_combo.get_active()
|
||||
if idx != -1:
|
||||
cat = gajim.connections[self.account].seclabel_catalogues[self.contact.jid]
|
||||
lname = cat[2][idx]
|
||||
label = cat[1][lname]
|
||||
return label
|
||||
|
||||
def send_message(self, message, keyID='', type_='chat', chatstate=None,
|
||||
msg_id=None, composing_xep=None, resource=None, xhtml=None,
|
||||
callback=None, callback_args=[], process_commands=True):
|
||||
|
@ -741,9 +784,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
if process_commands and self.process_as_command(message):
|
||||
return
|
||||
|
||||
label = self.get_seclabel()
|
||||
MessageControl.send_message(self, message, keyID, type_=type_,
|
||||
chatstate=chatstate, msg_id=msg_id, composing_xep=composing_xep,
|
||||
resource=resource, user_nick=self.user_nick, xhtml=xhtml,
|
||||
label=label,
|
||||
callback=callback, callback_args=callback_args)
|
||||
|
||||
# Record message history
|
||||
|
@ -777,7 +822,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
other_tags_for_name=[], other_tags_for_time=[],
|
||||
other_tags_for_text=[], count_as_new=True, subject=None,
|
||||
old_kind=None, xhtml=None, simple=False, xep0184_id=None,
|
||||
graphics=True):
|
||||
graphics=True, displaymarking=None):
|
||||
"""
|
||||
Print 'chat' type messages
|
||||
"""
|
||||
|
@ -789,7 +834,8 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
|
|||
end = True
|
||||
textview.print_conversation_line(text, jid, kind, name, tim,
|
||||
other_tags_for_name, other_tags_for_time, other_tags_for_text,
|
||||
subject, old_kind, xhtml, simple=simple, graphics=graphics)
|
||||
subject, old_kind, xhtml, simple=simple, graphics=graphics,
|
||||
displaymarking=displaymarking)
|
||||
|
||||
if xep0184_id is not None:
|
||||
textview.show_xep0184_warning(xep0184_id)
|
||||
|
@ -1267,13 +1313,12 @@ class ChatControl(ChatControlBase):
|
|||
A control for standard 1-1 chat
|
||||
"""
|
||||
(
|
||||
JINGLE_STATE_NOT_AVAILABLE,
|
||||
JINGLE_STATE_AVAILABLE,
|
||||
JINGLE_STATE_NULL,
|
||||
JINGLE_STATE_CONNECTING,
|
||||
JINGLE_STATE_CONNECTION_RECEIVED,
|
||||
JINGLE_STATE_CONNECTED,
|
||||
JINGLE_STATE_ERROR
|
||||
) = range(6)
|
||||
) = range(5)
|
||||
|
||||
TYPE_ID = message_control.TYPE_CHAT
|
||||
old_msg_kind = None # last kind of the printed message
|
||||
|
@ -1360,9 +1405,11 @@ class ChatControl(ChatControlBase):
|
|||
self._audio_banner_image = self.xml.get_object('audio_banner_image')
|
||||
self._video_banner_image = self.xml.get_object('video_banner_image')
|
||||
self.audio_sid = None
|
||||
self.audio_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||
self.audio_state = self.JINGLE_STATE_NULL
|
||||
self.audio_available = False
|
||||
self.video_sid = None
|
||||
self.video_state = self.JINGLE_STATE_NOT_AVAILABLE
|
||||
self.video_state = self.JINGLE_STATE_NULL
|
||||
self.video_available = False
|
||||
|
||||
self.update_toolbar()
|
||||
|
||||
|
@ -1420,6 +1467,15 @@ class ChatControl(ChatControlBase):
|
|||
id_ = widget.connect('released', self.on_num_button_released)
|
||||
self.handlers[id_] = widget
|
||||
|
||||
self.dtmf_window = self.xml.get_object('dtmf_window')
|
||||
id_ = self.dtmf_window.connect('focus-out-event',
|
||||
self.on_dtmf_window_focus_out_event)
|
||||
self.handlers[id_] = self.dtmf_window
|
||||
|
||||
widget = self.xml.get_object('dtmf_button')
|
||||
id_ = widget.connect('clicked', self.on_dtmf_button_clicked)
|
||||
self.handlers[id_] = widget
|
||||
|
||||
widget = self.xml.get_object('mic_hscale')
|
||||
id_ = widget.connect('value_changed', self.on_mic_hscale_value_changed)
|
||||
self.handlers[id_] = widget
|
||||
|
@ -1436,6 +1492,7 @@ class ChatControl(ChatControlBase):
|
|||
session = gajim.connections[self.account].find_controlless_session(
|
||||
self.contact.jid, resource)
|
||||
|
||||
self.setup_seclabel(self.xml.get_object('label_selector'))
|
||||
if session:
|
||||
session.control = self
|
||||
self.session = session
|
||||
|
@ -1488,38 +1545,24 @@ class ChatControl(ChatControlBase):
|
|||
# Jingle detection
|
||||
if self.contact.supports(NS_JINGLE_ICE_UDP) and \
|
||||
gajim.HAVE_FARSIGHT and self.contact.resource:
|
||||
if self.contact.supports(NS_JINGLE_RTP_AUDIO):
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_audio_state('available')
|
||||
else:
|
||||
self.set_audio_state('not_available')
|
||||
|
||||
if self.contact.supports(NS_JINGLE_RTP_VIDEO):
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_video_state('available')
|
||||
else:
|
||||
self.set_video_state('not_available')
|
||||
self.audio_available = self.contact.supports(NS_JINGLE_RTP_AUDIO)
|
||||
self.video_available = self.contact.supports(NS_JINGLE_RTP_VIDEO)
|
||||
else:
|
||||
if self.audio_state != self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_audio_state('not_available')
|
||||
if self.video_state != self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self.set_video_state('not_available')
|
||||
if self.video_available or self.audio_available:
|
||||
self.stop_jingle()
|
||||
self.video_available = False
|
||||
self.audio_available = False
|
||||
|
||||
# Audio buttons
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self._audio_button.set_sensitive(False)
|
||||
else:
|
||||
self._audio_button.set_sensitive(True)
|
||||
self._audio_button.set_sensitive(self.audio_available)
|
||||
|
||||
# Video buttons
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
self._video_button.set_sensitive(False)
|
||||
else:
|
||||
self._video_button.set_sensitive(True)
|
||||
self._video_button.set_sensitive(self.video_available)
|
||||
|
||||
# Send file
|
||||
if self.contact.supports(NS_FILE) and self.contact.resource:
|
||||
self._send_file_button.set_sensitive(True)
|
||||
self._send_file_button.set_tooltip_text('')
|
||||
else:
|
||||
self._send_file_button.set_sensitive(False)
|
||||
if not self.contact.supports(NS_FILE):
|
||||
|
@ -1554,18 +1597,16 @@ class ChatControl(ChatControlBase):
|
|||
else:
|
||||
img.hide()
|
||||
|
||||
# PluginSystem: adding GUI extension point for this ChatControl
|
||||
# PluginSystem: adding GUI extension point for this ChatControl
|
||||
# instance object
|
||||
gajim.plugin_manager.gui_extension_point('chat_control', self)
|
||||
|
||||
|
||||
def _update_jingle(self, jingle_type):
|
||||
if jingle_type not in ('audio', 'video'):
|
||||
return
|
||||
banner_image = getattr(self, '_' + jingle_type + '_banner_image')
|
||||
state = getattr(self, jingle_type + '_state')
|
||||
if state in (self.JINGLE_STATE_NOT_AVAILABLE,
|
||||
self.JINGLE_STATE_AVAILABLE):
|
||||
if state == self.JINGLE_STATE_NULL:
|
||||
banner_image.hide()
|
||||
else:
|
||||
banner_image.show()
|
||||
|
@ -1585,7 +1626,7 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
def update_audio(self):
|
||||
self._update_jingle('audio')
|
||||
vbox = self.xml.get_object('audio_vbox')
|
||||
hbox = self.xml.get_object('audio_buttons_hbox')
|
||||
if self.audio_state == self.JINGLE_STATE_CONNECTED:
|
||||
# Set volume from config
|
||||
input_vol = gajim.config.get('audio_input_volume')
|
||||
|
@ -1595,11 +1636,11 @@ class ChatControl(ChatControlBase):
|
|||
self.xml.get_object('mic_hscale').set_value(input_vol)
|
||||
self.xml.get_object('sound_hscale').set_value(output_vol)
|
||||
# Show vbox
|
||||
vbox.set_no_show_all(False)
|
||||
vbox.show_all()
|
||||
hbox.set_no_show_all(False)
|
||||
hbox.show_all()
|
||||
elif not self.audio_sid:
|
||||
vbox.set_no_show_all(True)
|
||||
vbox.hide()
|
||||
hbox.set_no_show_all(True)
|
||||
hbox.hide()
|
||||
|
||||
def update_video(self):
|
||||
self._update_jingle('video')
|
||||
|
@ -1617,43 +1658,42 @@ class ChatControl(ChatControlBase):
|
|||
# update MessageWindow._controls
|
||||
self.parent_win.change_jid(self.account, old_full_jid, new_full_jid)
|
||||
|
||||
def stop_jingle(self, sid=None, reason=None):
|
||||
if self.audio_sid and sid in (self.audio_sid, None):
|
||||
self.close_jingle_content('audio')
|
||||
if self.video_sid and sid in (self.video_sid, None):
|
||||
self.close_jingle_content('video')
|
||||
|
||||
|
||||
def _set_jingle_state(self, jingle_type, state, sid=None, reason=None):
|
||||
if jingle_type not in ('audio', 'video'):
|
||||
return
|
||||
if state in ('connecting', 'connected', 'stop') and reason:
|
||||
if state in ('connecting', 'connected', 'stop', 'error') and reason:
|
||||
str = _('%(type)s state : %(state)s, reason: %(reason)s') % {
|
||||
'type': jingle_type.capitalize(), 'state': state, 'reason': reason}
|
||||
self.print_conversation(str, 'info')
|
||||
|
||||
states = {'not_available': self.JINGLE_STATE_NOT_AVAILABLE,
|
||||
'available': self.JINGLE_STATE_AVAILABLE,
|
||||
'connecting': self.JINGLE_STATE_CONNECTING,
|
||||
states = {'connecting': self.JINGLE_STATE_CONNECTING,
|
||||
'connection_received': self.JINGLE_STATE_CONNECTION_RECEIVED,
|
||||
'connected': self.JINGLE_STATE_CONNECTED,
|
||||
'stop': self.JINGLE_STATE_AVAILABLE,
|
||||
'stop': self.JINGLE_STATE_NULL,
|
||||
'error': self.JINGLE_STATE_ERROR}
|
||||
|
||||
if state in states:
|
||||
jingle_state = states[state]
|
||||
if getattr(self, jingle_type + '_state') == jingle_state:
|
||||
return
|
||||
setattr(self, jingle_type + '_state', jingle_state)
|
||||
jingle_state = states[state]
|
||||
if getattr(self, jingle_type + '_state') == jingle_state or state == 'error':
|
||||
return
|
||||
|
||||
# Destroy existing session with the user when he signs off
|
||||
# We need to do that before modifying the sid
|
||||
if state == 'not_available':
|
||||
gajim.connections[self.account].delete_jingle_session(
|
||||
self.contact.get_full_jid(), getattr(self, jingle_type + '_sid'))
|
||||
if state == 'stop' and getattr(self, jingle_type + '_sid') not in (None, sid):
|
||||
return
|
||||
|
||||
if state in ('not_available', 'available', 'stop'):
|
||||
setattr(self, jingle_type + '_state', jingle_state)
|
||||
|
||||
if jingle_state == self.JINGLE_STATE_NULL:
|
||||
setattr(self, jingle_type + '_sid', None)
|
||||
if state in ('connection_received', 'connecting'):
|
||||
setattr(self, jingle_type + '_sid', sid)
|
||||
|
||||
if state in ('connecting', 'connected', 'connection_received'):
|
||||
getattr(self, '_' + jingle_type + '_button').set_active(True)
|
||||
elif state in ('not_available', 'stop'):
|
||||
getattr(self, '_' + jingle_type + '_button').set_active(False)
|
||||
getattr(self, '_' + jingle_type + '_button').set_active(jingle_state != self.JINGLE_STATE_NULL)
|
||||
|
||||
getattr(self, 'update_' + jingle_type)()
|
||||
|
||||
|
@ -1674,19 +1714,21 @@ class ChatControl(ChatControlBase):
|
|||
def on_num_button_released(self, released):
|
||||
self._get_audio_content()._stop_dtmf()
|
||||
|
||||
def on_mic_hscale_value_changed(self, widget):
|
||||
value = widget.get_value()
|
||||
def on_dtmf_button_clicked(self, widget):
|
||||
self.dtmf_window.show_all()
|
||||
|
||||
def on_dtmf_window_focus_out_event(self, widget, event):
|
||||
self.dtmf_window.hide()
|
||||
|
||||
def on_mic_hscale_value_changed(self, widget, value):
|
||||
self._get_audio_content().set_mic_volume(value / 100)
|
||||
# Save volume to config
|
||||
# FIXME: Putting it here is maybe not the right thing to do?
|
||||
gajim.config.set('audio_input_volume', value)
|
||||
|
||||
|
||||
def on_sound_hscale_value_changed(self, widget):
|
||||
value = widget.get_value()
|
||||
def on_sound_hscale_value_changed(self, widget, value):
|
||||
self._get_audio_content().set_out_volume(value / 100)
|
||||
# Save volume to config
|
||||
# FIXME: Putting it here is maybe not the right thing to do?
|
||||
gajim.config.set('audio_output_volume', value)
|
||||
|
||||
def on_avatar_eventbox_enter_notify_event(self, widget, event):
|
||||
|
@ -1708,6 +1750,8 @@ class ChatControl(ChatControlBase):
|
|||
# do we have something bigger to show?
|
||||
if avatar_w > scaled_buf_w or avatar_h > scaled_buf_h:
|
||||
# wait for 0.5 sec in case we leave earlier
|
||||
if self.show_bigger_avatar_timeout_id is not None:
|
||||
gobject.source_remove(self.show_bigger_avatar_timeout_id)
|
||||
self.show_bigger_avatar_timeout_id = gobject.timeout_add(500,
|
||||
self.show_bigger_avatar, widget)
|
||||
|
||||
|
@ -1718,6 +1762,7 @@ class ChatControl(ChatControlBase):
|
|||
# did we add a timeout? if yes remove it
|
||||
if self.show_bigger_avatar_timeout_id is not None:
|
||||
gobject.source_remove(self.show_bigger_avatar_timeout_id)
|
||||
self.show_bigger_avatar_timeout_id = None
|
||||
|
||||
def on_avatar_eventbox_button_press_event(self, widget, event):
|
||||
"""
|
||||
|
@ -1727,8 +1772,8 @@ class ChatControl(ChatControlBase):
|
|||
menu = gtk.Menu()
|
||||
menuitem = gtk.ImageMenuItem(gtk.STOCK_SAVE_AS)
|
||||
id_ = menuitem.connect('activate',
|
||||
gtkgui_helpers.on_avatar_save_as_menuitem_activate,
|
||||
self.contact.jid, self.account, self.contact.get_shown_name())
|
||||
gtkgui_helpers.on_avatar_save_as_menuitem_activate,
|
||||
self.contact.jid, self.contact.get_shown_name())
|
||||
self.handlers[id_] = menuitem
|
||||
menu.append(menuitem)
|
||||
menu.show_all()
|
||||
|
@ -1899,12 +1944,16 @@ class ChatControl(ChatControlBase):
|
|||
sid = getattr(self, jingle_type + '_sid')
|
||||
if not sid:
|
||||
return
|
||||
setattr(self, jingle_type + '_sid', None)
|
||||
setattr(self, jingle_type + '_state', self.JINGLE_STATE_NULL)
|
||||
session = gajim.connections[self.account].get_jingle_session(
|
||||
self.contact.get_full_jid(), sid)
|
||||
if session:
|
||||
content = session.get_content(jingle_type)
|
||||
if content:
|
||||
session.remove_content(content.creator, content.name)
|
||||
getattr(self, '_' + jingle_type + '_button').set_active(False)
|
||||
getattr(self, 'update_' + jingle_type)()
|
||||
|
||||
def on_jingle_button_toggled(self, widget, jingle_type):
|
||||
img_name = 'gajim-%s_%s' % ({'audio': 'mic', 'video': 'cam'}[jingle_type],
|
||||
|
@ -1913,7 +1962,7 @@ class ChatControl(ChatControlBase):
|
|||
|
||||
if widget.get_active():
|
||||
if getattr(self, jingle_type + '_state') == \
|
||||
self.JINGLE_STATE_AVAILABLE:
|
||||
self.JINGLE_STATE_NULL:
|
||||
sid = getattr(gajim.connections[self.account],
|
||||
'start_' + jingle_type)(self.contact.get_full_jid())
|
||||
getattr(self, 'set_' + jingle_type + '_state')('connecting', sid)
|
||||
|
@ -2069,20 +2118,23 @@ class ChatControl(ChatControlBase):
|
|||
gobject.source_remove(self.possible_inactive_timeout_id)
|
||||
self._schedule_activity_timers()
|
||||
|
||||
def _on_sent(id_, contact, message, encrypted, xhtml):
|
||||
def _on_sent(id_, contact, message, encrypted, xhtml, label):
|
||||
if contact.supports(NS_RECEIPTS) and gajim.config.get_per('accounts',
|
||||
self.account, 'request_receipt'):
|
||||
xep0184_id = id_
|
||||
else:
|
||||
xep0184_id = None
|
||||
|
||||
if label:
|
||||
displaymarking = label.getTag('displaymarking')
|
||||
else:
|
||||
displaymarking = None
|
||||
self.print_conversation(message, self.contact.jid, encrypted=encrypted,
|
||||
xep0184_id=xep0184_id, xhtml=xhtml)
|
||||
xep0184_id=xep0184_id, xhtml=xhtml, displaymarking=displaymarking)
|
||||
|
||||
ChatControlBase.send_message(self, message, keyID, type_='chat',
|
||||
chatstate=chatstate_to_send, composing_xep=composing_xep,
|
||||
xhtml=xhtml, callback=_on_sent,
|
||||
callback_args=[contact, message, encrypted, xhtml],
|
||||
callback_args=[contact, message, encrypted, xhtml, self.get_seclabel()],
|
||||
process_commands=process_commands)
|
||||
|
||||
def check_for_possible_paused_chatstate(self, arg):
|
||||
|
@ -2171,7 +2223,8 @@ class ChatControl(ChatControlBase):
|
|||
self.session.is_loggable(), self.session and self.session.verified_identity)
|
||||
|
||||
def print_conversation(self, text, frm='', tim=None, encrypted=False,
|
||||
subject=None, xhtml=None, simple=False, xep0184_id=None):
|
||||
subject=None, xhtml=None, simple=False, xep0184_id=None,
|
||||
displaymarking=None):
|
||||
"""
|
||||
Print a line in the conversation
|
||||
|
||||
|
@ -2234,7 +2287,7 @@ class ChatControl(ChatControlBase):
|
|||
xhtml = '<body xmlns="%s">%s</body>' % (NS_XHTML, xhtml)
|
||||
ChatControlBase.print_conversation_line(self, text, kind, name, tim,
|
||||
subject=subject, old_kind=self.old_msg_kind, xhtml=xhtml,
|
||||
simple=simple, xep0184_id=xep0184_id)
|
||||
simple=simple, xep0184_id=xep0184_id, displaymarking=displaymarking)
|
||||
if text.startswith('/me ') or text.startswith('/me\n'):
|
||||
self.old_msg_kind = None
|
||||
else:
|
||||
|
@ -2423,9 +2476,8 @@ class ChatControl(ChatControlBase):
|
|||
super(ChatControl, self).shutdown()
|
||||
# PluginSystem: removing GUI extension points connected with ChatControl
|
||||
# instance object
|
||||
gajim.plugin_manager.remove_gui_extension_point('chat_control', self)
|
||||
gajim.plugin_manager.remove_gui_extension_point('chat_control', self) # Send 'gone' chatstate
|
||||
|
||||
# Send 'gone' chatstate
|
||||
self.send_chatstate('gone', self.contact)
|
||||
self.contact.chatstate = None
|
||||
self.contact.our_chatstate = None
|
||||
|
@ -2688,8 +2740,12 @@ class ChatControl(ChatControlBase):
|
|||
kind = 'info'
|
||||
else:
|
||||
kind = 'print_queue'
|
||||
dm = None
|
||||
if len(data) > 10:
|
||||
dm = data[10]
|
||||
self.print_conversation(data[0], kind, tim = data[3],
|
||||
encrypted = data[4], subject = data[1], xhtml = data[7])
|
||||
encrypted = data[4], subject = data[1], xhtml = data[7],
|
||||
displaymarking=dm)
|
||||
if len(data) > 6 and isinstance(data[6], int):
|
||||
message_ids.append(data[6])
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,7 +14,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
The command system providing scalable, clean and convenient architecture in
|
||||
combination with declarative way of defining commands and a fair amount of
|
||||
automatization for routine processes.
|
||||
The command system providing scalable, clean and convenient architecture
|
||||
in combination with declarative way of defining commands and a fair
|
||||
amount of automatization for routine processes.
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,9 +14,10 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
The backbone of the command system. Provides automatic dispatching which does
|
||||
not require explicit registering commands or containers and remains active even
|
||||
after everything is done, so new commands can be added during the runtime.
|
||||
The backbone of the command system. Provides automatic dispatching which
|
||||
does not require explicit registering commands or containers and remains
|
||||
active even after everything is done, so new commands can be added
|
||||
during the runtime.
|
||||
"""
|
||||
|
||||
from types import NoneType
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -15,8 +15,9 @@
|
|||
|
||||
class BaseError(Exception):
|
||||
"""
|
||||
Common base for errors which relate to a specific command. Encapsulates
|
||||
everything needed to identify a command, by either its object or name.
|
||||
Common base for errors which relate to a specific command.
|
||||
Encapsulates everything needed to identify a command, by either its
|
||||
object or name.
|
||||
"""
|
||||
|
||||
def __init__(self, message, command=None, name=None):
|
||||
|
@ -44,3 +45,9 @@ class CommandError(BaseError):
|
|||
Used to indicate errors occured during command execution.
|
||||
"""
|
||||
pass
|
||||
|
||||
class NoCommandError(BaseError):
|
||||
"""
|
||||
Used to indicate an inability to find the specified command.
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,8 +14,9 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Provides a tiny framework with simple, yet powerful and extensible architecture
|
||||
to implement commands in a streight and flexible, declarative way.
|
||||
Provides a tiny framework with simple, yet powerful and extensible
|
||||
architecture to implement commands in a streight and flexible,
|
||||
declarative way.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
@ -24,46 +25,47 @@ from inspect import getargspec
|
|||
|
||||
from dispatching import Dispatcher, HostDispatcher, ContainerDispatcher
|
||||
from mapping import parse_arguments, adapt_arguments
|
||||
from errors import DefinitionError, CommandError
|
||||
from errors import DefinitionError, CommandError, NoCommandError
|
||||
|
||||
class CommandHost(object):
|
||||
"""
|
||||
Command host is a hub between numerous command processors and command
|
||||
containers. Aimed to participate in a dispatching process in order to
|
||||
provide clean and transparent architecture.
|
||||
Command host is a hub between numerous command processors and
|
||||
command containers. Aimed to participate in a dispatching process in
|
||||
order to provide clean and transparent architecture.
|
||||
"""
|
||||
__metaclass__ = HostDispatcher
|
||||
|
||||
class CommandContainer(object):
|
||||
"""
|
||||
Command container is an entity which holds defined commands, allowing them
|
||||
to be dispatched and proccessed correctly. Each command container may be
|
||||
bound to a one or more command hosts.
|
||||
Command container is an entity which holds defined commands,
|
||||
allowing them to be dispatched and proccessed correctly. Each
|
||||
command container may be bound to a one or more command hosts.
|
||||
|
||||
Bounding is controlled by the HOSTS variable, which must be defined in the
|
||||
body of the command container. This variable should contain a list of hosts
|
||||
to bound to, as a tuple or list.
|
||||
Bounding is controlled by the HOSTS variable, which must be defined
|
||||
in the body of the command container. This variable should contain a
|
||||
list of hosts to bound to, as a tuple or list.
|
||||
"""
|
||||
__metaclass__ = ContainerDispatcher
|
||||
|
||||
class CommandProcessor(object):
|
||||
"""
|
||||
Command processor is an immediate command emitter. It does not participate
|
||||
in the dispatching process directly, but must define a host to bound to.
|
||||
Command processor is an immediate command emitter. It does not
|
||||
participate in the dispatching process directly, but must define a
|
||||
host to bound to.
|
||||
|
||||
Bounding is controlled by the COMMAND_HOST variable, which must be defined
|
||||
in the body of the command processor. This variable should be set to a
|
||||
specific command host.
|
||||
Bounding is controlled by the COMMAND_HOST variable, which must be
|
||||
defined in the body of the command processor. This variable should
|
||||
be set to a specific command host.
|
||||
"""
|
||||
|
||||
# This defines a command prefix (or an initializer), which should preceede a
|
||||
# a text in order it to be processed as a command.
|
||||
# This defines a command prefix (or an initializer), which should
|
||||
# preceede a a text in order it to be processed as a command.
|
||||
COMMAND_PREFIX = '/'
|
||||
|
||||
def process_as_command(self, text):
|
||||
"""
|
||||
Try to process text as a command. Returns True if it has been processed
|
||||
as a command and False otherwise.
|
||||
Try to process text as a command. Returns True if it has been
|
||||
processed as a command and False otherwise.
|
||||
"""
|
||||
prefix = text.startswith(self.COMMAND_PREFIX)
|
||||
length = len(text) > len(self.COMMAND_PREFIX)
|
||||
|
@ -97,28 +99,28 @@ class CommandProcessor(object):
|
|||
|
||||
def command_preprocessor(self, command, name, arguments, args, kwargs):
|
||||
"""
|
||||
Redefine this method in the subclass to execute custom code before
|
||||
command gets executed.
|
||||
Redefine this method in the subclass to execute custom code
|
||||
before command gets executed.
|
||||
|
||||
If returns True then command execution will be interrupted and command
|
||||
will not be executed.
|
||||
If returns True then command execution will be interrupted and
|
||||
command will not be executed.
|
||||
"""
|
||||
pass
|
||||
|
||||
def command_postprocessor(self, command, name, arguments, args, kwargs, value):
|
||||
"""
|
||||
Redefine this method in the subclass to execute custom code after
|
||||
command gets executed.
|
||||
Redefine this method in the subclass to execute custom code
|
||||
after command gets executed.
|
||||
"""
|
||||
pass
|
||||
|
||||
def looks_like_command(self, text, body, name, arguments):
|
||||
"""
|
||||
This hook is being called before any processing, but after it was
|
||||
determined that text looks like a command.
|
||||
This hook is being called before any processing, but after it
|
||||
was determined that text looks like a command.
|
||||
|
||||
If returns value other then None - then further processing will be
|
||||
interrupted and that value will be used to return from
|
||||
If returns value other then None - then further processing will
|
||||
be interrupted and that value will be used to return from
|
||||
process_as_command.
|
||||
"""
|
||||
pass
|
||||
|
@ -126,7 +128,7 @@ class CommandProcessor(object):
|
|||
def get_command(self, name):
|
||||
command = Dispatcher.get_command(self.COMMAND_HOST, name)
|
||||
if not command:
|
||||
raise CommandError("Command does not exist", name=name)
|
||||
raise NoCommandError("Command does not exist", name=name)
|
||||
return command
|
||||
|
||||
def list_commands(self):
|
||||
|
@ -136,8 +138,9 @@ class CommandProcessor(object):
|
|||
|
||||
class Command(object):
|
||||
|
||||
# These two regular expression patterns control how command documentation
|
||||
# will be formatted to be transformed to a normal, readable state.
|
||||
# These two regular expression patterns control how command
|
||||
# documentation will be formatted to be transformed to a normal,
|
||||
# readable state.
|
||||
DOC_STRIP_PATTERN = re.compile(r'(?:^[ \t]+|\A\n)', re.MULTILINE)
|
||||
DOC_FORMAT_PATTERN = re.compile(r'(?<!\n)\n(?!\n)', re.MULTILINE)
|
||||
|
||||
|
@ -145,8 +148,8 @@ class Command(object):
|
|||
self.handler = handler
|
||||
self.names = names
|
||||
|
||||
# Automatically set all the properties passed to a constructor by the
|
||||
# command decorator.
|
||||
# Automatically set all the properties passed to a constructor
|
||||
# by the command decorator.
|
||||
for key, value in properties.iteritems():
|
||||
setattr(self, key, value)
|
||||
|
||||
|
@ -154,18 +157,20 @@ class Command(object):
|
|||
try:
|
||||
return self.handler(*args, **kwargs)
|
||||
|
||||
# This allows to use a shortcuted way of raising an exception inside a
|
||||
# handler. That is to raise a CommandError without command or name
|
||||
# attributes set. They will be set to a corresponding values right here
|
||||
# in case if they was not set by the one who raised an exception.
|
||||
# This allows to use a shortcuted way of raising an exception
|
||||
# inside a handler. That is to raise a CommandError without
|
||||
# command or name attributes set. They will be set to a
|
||||
# corresponding values right here in case if they was not set by
|
||||
# the one who raised an exception.
|
||||
except CommandError, error:
|
||||
if not error.command and not error.name:
|
||||
raise CommandError(error.message, self)
|
||||
raise
|
||||
|
||||
# This one is a little bit too wide, but as Python does not have
|
||||
# anything more constrained - there is no other choice. Take a look here
|
||||
# if command complains about invalid arguments while they are ok.
|
||||
# anything more constrained - there is no other choice. Take a
|
||||
# look here if command complains about invalid arguments while
|
||||
# they are ok.
|
||||
except TypeError:
|
||||
raise CommandError("Command received invalid arguments", self)
|
||||
|
||||
|
@ -185,8 +190,8 @@ class Command(object):
|
|||
|
||||
def extract_documentation(self):
|
||||
"""
|
||||
Extract handler's documentation which is a doc-string and transform it
|
||||
to a usable format.
|
||||
Extract handler's documentation which is a doc-string and
|
||||
transform it to a usable format.
|
||||
|
||||
Transformation is done based on the DOC_STRIP_PATTERN and
|
||||
DOC_FORMAT_PATTERN regular expression patterns.
|
||||
|
@ -211,19 +216,19 @@ class Command(object):
|
|||
|
||||
def extract_specification(self):
|
||||
"""
|
||||
Extract handler's arguments specification, as it was defined preserving
|
||||
their order.
|
||||
Extract handler's arguments specification, as it was defined
|
||||
preserving their order.
|
||||
"""
|
||||
names, var_args, var_kwargs, defaults = getargspec(self.handler)
|
||||
|
||||
# Behavior of this code need to be checked. Might yield incorrect
|
||||
# results on some rare occasions.
|
||||
# Behavior of this code need to be checked. Might yield
|
||||
# incorrect results on some rare occasions.
|
||||
spec_args = names[:-len(defaults) if defaults else len(names)]
|
||||
spec_kwargs = list(zip(names[-len(defaults):], defaults)) if defaults else {}
|
||||
|
||||
# Removing self from arguments specification. Command handler should
|
||||
# receive the processors as a first argument, which should be self by
|
||||
# the canonical means.
|
||||
# Removing self from arguments specification. Command handler
|
||||
# should receive the processors as a first argument, which
|
||||
# should be self by the canonical means.
|
||||
if spec_args.pop(0) != 'self':
|
||||
raise DefinitionError("First argument must be self", self)
|
||||
|
||||
|
@ -231,44 +236,47 @@ class Command(object):
|
|||
|
||||
def command(*names, **properties):
|
||||
"""
|
||||
A decorator for defining commands in a declarative way. Provides facilities
|
||||
for setting command's names and properties.
|
||||
A decorator for defining commands in a declarative way. Provides
|
||||
facilities for setting command's names and properties.
|
||||
|
||||
Names should contain a set of names (aliases) by which the command can be
|
||||
reached. If no names are given - the the native name (the one extracted from
|
||||
the command handler) will be used.
|
||||
Names should contain a set of names (aliases) by which the command
|
||||
can be reached. If no names are given - the the native name (the one
|
||||
extracted from the command handler) will be used.
|
||||
|
||||
If include_native=True is given (default) and names is non-empty - then the
|
||||
native name of the command will be prepended in addition to the given names.
|
||||
If include_native=True is given (default) and names is non-empty -
|
||||
then the native name of the command will be prepended in addition to
|
||||
the given names.
|
||||
|
||||
If usage=True is given (default) - then command help will be appended with
|
||||
autogenerated usage info, based of the command handler arguments
|
||||
introspection.
|
||||
If usage=True is given (default) - then command help will be
|
||||
appended with autogenerated usage info, based of the command handler
|
||||
arguments introspection.
|
||||
|
||||
If source=True is given - then the first argument of the command will
|
||||
receive the source arguments, as a raw, unprocessed string. The further
|
||||
mapping of arguments and options will not be affected.
|
||||
If source=True is given - then the first argument of the command
|
||||
will receive the source arguments, as a raw, unprocessed string. The
|
||||
further mapping of arguments and options will not be affected.
|
||||
|
||||
If raw=True is given - then command considered to be raw and should define
|
||||
positional arguments only. If it defines only one positional argument - this
|
||||
argument will receive all the raw and unprocessed arguments. If the command
|
||||
defines more then one positional argument - then all the arguments except
|
||||
the last one will be processed normally; the last argument will get what is
|
||||
left after the processing as raw and unprocessed string.
|
||||
If raw=True is given - then command considered to be raw and should
|
||||
define positional arguments only. If it defines only one positional
|
||||
argument - this argument will receive all the raw and unprocessed
|
||||
arguments. If the command defines more then one positional argument
|
||||
- then all the arguments except the last one will be processed
|
||||
normally; the last argument will get what is left after the
|
||||
processing as raw and unprocessed string.
|
||||
|
||||
If empty=True is given - this will allow to call a raw command without
|
||||
arguments.
|
||||
If empty=True is given - this will allow to call a raw command
|
||||
without arguments.
|
||||
|
||||
If extra=True is given - then all the extra arguments passed to a command
|
||||
will be collected into a sequence and given to the last positional argument.
|
||||
If extra=True is given - then all the extra arguments passed to a
|
||||
command will be collected into a sequence and given to the last
|
||||
positional argument.
|
||||
|
||||
If overlap=True is given - then all the extra arguments will be mapped as if
|
||||
they were values for the keyword arguments.
|
||||
If overlap=True is given - then all the extra arguments will be
|
||||
mapped as if they were values for the keyword arguments.
|
||||
|
||||
If expand_short=True is given (default) - then short, one-letter options
|
||||
will be expanded to a verbose ones, based of the comparison of the first
|
||||
letter. If more then one option with the same first letter is given - then
|
||||
only first one will be used in the expansion.
|
||||
If expand_short=True is given (default) - then short, one-letter
|
||||
options will be expanded to a verbose ones, based of the comparison
|
||||
of the first letter. If more then one option with the same first
|
||||
letter is given - then only first one will be used in the expansion.
|
||||
"""
|
||||
names = list(names)
|
||||
|
||||
|
@ -300,34 +308,32 @@ def command(*names, **properties):
|
|||
|
||||
def decorator(handler):
|
||||
"""
|
||||
Decorator which receives handler as a first argument and then wraps it
|
||||
in the command which then returns back.
|
||||
Decorator which receives handler as a first argument and then
|
||||
wraps it in the command which then returns back.
|
||||
"""
|
||||
command = Command(handler, *names, **properties)
|
||||
|
||||
# Extract and inject a native name if either no other names are
|
||||
# specified or include_native property is enabled, while making sure it
|
||||
# is going to be the first one in the list.
|
||||
# specified or include_native property is enabled, while making
|
||||
# sure it is going to be the first one in the list.
|
||||
if not names or include_native:
|
||||
names.insert(0, command.native_name)
|
||||
command.names = tuple(names)
|
||||
|
||||
return command
|
||||
|
||||
# Workaround if we are getting called without parameters. Keep in mind that
|
||||
# in that case - first item in the names will be the handler.
|
||||
# Workaround if we are getting called without parameters. Keep in
|
||||
# mind that in that case - first item in the names will be the
|
||||
# handler.
|
||||
if names and isinstance(names[0], FunctionType):
|
||||
return decorator(names.pop(0))
|
||||
|
||||
return decorator
|
||||
|
||||
def documentation(text):
|
||||
def doc(text):
|
||||
"""
|
||||
This decorator is used to bind a documentation (a help) to a command.
|
||||
|
||||
Though this can be done easily by using doc-strings in a declarative and
|
||||
Pythonic way - some of Gajim's developers are against it because of the
|
||||
scaffolding needed to support the tranlation of such documentation.
|
||||
This decorator is used to bind a documentation (a help) to a
|
||||
command.
|
||||
"""
|
||||
def decorator(target):
|
||||
if isinstance(target, Command):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,6 +14,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
The implementation and auxilary systems which implement the standard Gajim
|
||||
commands and also provide an infrastructure for adding custom commands.
|
||||
The implementation and auxilary systems which implement the standard
|
||||
Gajim commands and also provide an infrastructure for adding custom
|
||||
commands.
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,21 +14,22 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
The module contains examples of how to create your own commands, by creating a
|
||||
new command container and definding a set of commands.
|
||||
The module contains examples of how to create your own commands, by
|
||||
creating a new command container and definding a set of commands.
|
||||
|
||||
Keep in mind that this module is not being loaded, so the code will not be
|
||||
executed and commands defined here will not be detected.
|
||||
Keep in mind that this module is not being loaded, so the code will not
|
||||
be executed and commands defined here will not be detected.
|
||||
"""
|
||||
|
||||
from ..framework import CommandContainer, command, documentation
|
||||
from ..framework import CommandContainer, command, doc
|
||||
from hosts import ChatCommands, PrivateChatCommands, GroupChatCommands
|
||||
|
||||
class CustomCommonCommands(CommandContainer):
|
||||
"""
|
||||
This command container bounds to all three available in the default
|
||||
implementation command hosts. This means that commands defined in this
|
||||
container will be available to all - chat, private chat and a group chat.
|
||||
implementation command hosts. This means that commands defined in
|
||||
this container will be available to all - chat, private chat and a
|
||||
group chat.
|
||||
"""
|
||||
|
||||
HOSTS = (ChatCommands, PrivateChatCommands, GroupChatCommands)
|
||||
|
@ -39,12 +40,13 @@ class CustomCommonCommands(CommandContainer):
|
|||
First line of the doc string is called a description and will be
|
||||
programmatically extracted and formatted.
|
||||
|
||||
After that you can give more help, like explanation of the options. This
|
||||
one will be programatically extracted and formatted too.
|
||||
After that you can give more help, like explanation of the
|
||||
options. This one will be programatically extracted and
|
||||
formatted too.
|
||||
|
||||
After all the documentation - there will be autogenerated (based on the
|
||||
method signature) usage information appended. You can turn it off
|
||||
though, if you want.
|
||||
After all the documentation - there will be autogenerated (based
|
||||
on the method signature) usage information appended. You can
|
||||
turn it off though, if you want.
|
||||
"""
|
||||
return "I can't dance, you stupid fuck, I'm just a command system! A cool one, though..."
|
||||
|
||||
|
@ -56,15 +58,16 @@ class CustomChatCommands(CommandContainer):
|
|||
|
||||
HOSTS = (ChatCommands,)
|
||||
|
||||
@documentation(_("The same as using a doc-string, except it supports translation"))
|
||||
@doc(_("The same as using a doc-string, except it supports translation"))
|
||||
@command
|
||||
def sing(self):
|
||||
return "Are you phreaking kidding me? Buy yourself a damn stereo..."
|
||||
|
||||
class CustomPrivateChatCommands(CommandContainer):
|
||||
"""
|
||||
This command container bounds only to the PrivateChatCommands command host.
|
||||
Therefore command defined here will be available only to a private chat.
|
||||
This command container bounds only to the PrivateChatCommands
|
||||
command host. Therefore command defined here will be available only
|
||||
to a private chat.
|
||||
"""
|
||||
|
||||
HOSTS = (PrivateChatCommands,)
|
||||
|
@ -75,8 +78,9 @@ class CustomPrivateChatCommands(CommandContainer):
|
|||
|
||||
class CustomGroupChatCommands(CommandContainer):
|
||||
"""
|
||||
This command container bounds only to the GroupChatCommands command host.
|
||||
Therefore command defined here will be available only to a group chat.
|
||||
This command container bounds only to the GroupChatCommands command
|
||||
host. Therefore command defined here will be available only to a
|
||||
group chat.
|
||||
"""
|
||||
|
||||
HOSTS = (GroupChatCommands,)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,29 +14,29 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
The module defines a set of command hosts, which are bound to a different
|
||||
command processors, which are the source of commands.
|
||||
The module defines a set of command hosts, which are bound to a
|
||||
different command processors, which are the source of commands.
|
||||
"""
|
||||
|
||||
from ..framework import CommandHost
|
||||
|
||||
class ChatCommands(CommandHost):
|
||||
"""
|
||||
This command host is bound to the command processor which processes commands
|
||||
from a chat.
|
||||
This command host is bound to the command processor which processes
|
||||
commands from a chat.
|
||||
"""
|
||||
pass
|
||||
|
||||
class PrivateChatCommands(CommandHost):
|
||||
"""
|
||||
This command host is bound to the command processor which processes commands
|
||||
from a private chat.
|
||||
This command host is bound to the command processor which processes
|
||||
commands from a private chat.
|
||||
"""
|
||||
pass
|
||||
|
||||
class GroupChatCommands(CommandHost):
|
||||
"""
|
||||
This command host is bound to the command processor which processes commands
|
||||
from a group chat.
|
||||
This command host is bound to the command processor which processes
|
||||
commands from a group chat.
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,10 +14,10 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Provides a glue to tie command system framework and the actual code where it
|
||||
would be dropped in. Defines a little bit of scaffolding to support interaction
|
||||
between the two and a few utility methods so you don't need to dig up the code
|
||||
itself code to write basic commands.
|
||||
Provides a glue to tie command system framework and the actual code
|
||||
where it would be dropped in. Defines a little bit of scaffolding to
|
||||
support interaction between the two and a few utility methods so you
|
||||
don't need to dig up the code itself code to write basic commands.
|
||||
"""
|
||||
|
||||
from types import StringTypes
|
||||
|
@ -26,17 +26,18 @@ from traceback import print_exc
|
|||
from common import gajim
|
||||
|
||||
from ..framework import CommandProcessor
|
||||
from ..errors import CommandError
|
||||
from ..errors import CommandError, NoCommandError
|
||||
|
||||
class ChatCommandProcessor(CommandProcessor):
|
||||
"""
|
||||
A basic scaffolding to provide convenient interaction between the command
|
||||
system and chat controls.
|
||||
A basic scaffolding to provide convenient interaction between the
|
||||
command system and chat controls.
|
||||
"""
|
||||
|
||||
def process_as_command(self, text):
|
||||
self.command_succeeded = False
|
||||
flag = super(ChatCommandProcessor, self).process_as_command(text)
|
||||
if flag:
|
||||
if flag and self.command_succeeded:
|
||||
self.add_history(text)
|
||||
self.clear_input()
|
||||
return flag
|
||||
|
@ -44,40 +45,49 @@ class ChatCommandProcessor(CommandProcessor):
|
|||
def execute_command(self, name, arguments):
|
||||
try:
|
||||
super(ChatCommandProcessor, self).execute_command(name, arguments)
|
||||
except NoCommandError, error:
|
||||
details = dict(name=error.name, message=error.message)
|
||||
message = "%(name)s: %(message)s\n" % details
|
||||
message += "Try using the //%(name)s or /say /%(name)s " % details
|
||||
message += "construct if you intended to send it as a text."
|
||||
self.echo(message, 'error')
|
||||
except CommandError, error:
|
||||
self.echo("%s: %s" %(error.name, error.message), 'error')
|
||||
self.echo("%s: %s" % (error.name, error.message), 'error')
|
||||
except Exception:
|
||||
self.echo("An error occured while trying to execute the command", 'error')
|
||||
print_exc()
|
||||
else:
|
||||
self.command_succeeded = True
|
||||
|
||||
def looks_like_command(self, text, body, name, arguments):
|
||||
# Command escape stuff ggoes here. If text was prepended by the command
|
||||
# prefix twice, like //not_a_command (if prefix is set to /) then it
|
||||
# will be escaped, that is sent just as a regular message with one (only
|
||||
# one) prefix removed, so message will be /not_a_command.
|
||||
# Command escape stuff ggoes here. If text was prepended by the
|
||||
# command prefix twice, like //not_a_command (if prefix is set
|
||||
# to /) then it will be escaped, that is sent just as a regular
|
||||
# message with one (only one) prefix removed, so message will be
|
||||
# /not_a_command.
|
||||
if body.startswith(self.COMMAND_PREFIX):
|
||||
self.send(body)
|
||||
return True
|
||||
|
||||
def command_preprocessor(self, command, name, arguments, args, kwargs):
|
||||
# If command argument contain h or help option - forward it to the /help
|
||||
# command. Dont forget to pass self, as all commands are unbound. And
|
||||
# also don't forget to print output.
|
||||
# If command argument contain h or help option - forward it to
|
||||
# the /help command. Dont forget to pass self, as all commands
|
||||
# are unbound. And also don't forget to print output.
|
||||
if 'h' in kwargs or 'help' in kwargs:
|
||||
help = self.get_command('help')
|
||||
self.echo(help(self, name))
|
||||
return True
|
||||
|
||||
def command_postprocessor(self, command, name, arguments, args, kwargs, value):
|
||||
# If command returns a string - print it to a user. A convenient and
|
||||
# sufficient in most simple cases shortcut to a using echo.
|
||||
# If command returns a string - print it to a user. A convenient
|
||||
# and sufficient in most simple cases shortcut to a using echo.
|
||||
if value and isinstance(value, StringTypes):
|
||||
self.echo(value)
|
||||
|
||||
class CommandTools:
|
||||
"""
|
||||
Contains a set of basic tools and shortcuts you can use in your commands to
|
||||
performe some simple operations.
|
||||
Contains a set of basic tools and shortcuts you can use in your
|
||||
commands to performe some simple operations.
|
||||
"""
|
||||
|
||||
def echo(self, text, kind='info'):
|
||||
|
@ -107,8 +117,8 @@ class CommandTools:
|
|||
|
||||
def add_history(self, text):
|
||||
"""
|
||||
Add given text to the input history, so user can scroll through it using
|
||||
ctrl + up/down arrow keys.
|
||||
Add given text to the input history, so user can scroll through
|
||||
it using ctrl + up/down arrow keys.
|
||||
"""
|
||||
self.save_sent_message(text)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -27,7 +27,7 @@ from common.exceptions import GajimGeneralException
|
|||
from common.logger import Constants
|
||||
|
||||
from ..errors import CommandError
|
||||
from ..framework import CommandContainer, command, documentation
|
||||
from ..framework import CommandContainer, command, doc
|
||||
from ..mapping import generate_usage
|
||||
|
||||
from hosts import ChatCommands, PrivateChatCommands, GroupChatCommands
|
||||
|
@ -38,25 +38,25 @@ lc = Constants()
|
|||
|
||||
class StandardCommonCommands(CommandContainer):
|
||||
"""
|
||||
This command container contains standard commands which are common to all -
|
||||
chat, private chat, group chat.
|
||||
This command container contains standard commands which are common
|
||||
to all - chat, private chat, group chat.
|
||||
"""
|
||||
|
||||
HOSTS = (ChatCommands, PrivateChatCommands, GroupChatCommands)
|
||||
|
||||
@command
|
||||
@documentation(_("Clear the text window"))
|
||||
@doc(_("Clear the text window"))
|
||||
def clear(self):
|
||||
self.conv_textview.clear()
|
||||
|
||||
@command
|
||||
@documentation(_("Hide the chat buttons"))
|
||||
@doc(_("Hide the chat buttons"))
|
||||
def compact(self):
|
||||
new_status = not self.hide_chat_buttons
|
||||
self.chat_buttons_set_visible(new_status)
|
||||
|
||||
@command(overlap=True)
|
||||
@documentation(_("Show help on a given command or a list of available commands if -(-a)ll is given"))
|
||||
@doc(_("Show help on a given command or a list of available commands if -(-a)ll is given"))
|
||||
def help(self, command=None, all=False):
|
||||
if command:
|
||||
command = self.get_command(command)
|
||||
|
@ -83,17 +83,17 @@ class StandardCommonCommands(CommandContainer):
|
|||
self.echo(help(self, 'help'))
|
||||
|
||||
@command(raw=True)
|
||||
@documentation(_("Send a message to the contact"))
|
||||
@doc(_("Send a message to the contact"))
|
||||
def say(self, message):
|
||||
self.send(message)
|
||||
|
||||
@command(raw=True)
|
||||
@documentation(_("Send action (in the third person) to the current chat"))
|
||||
@doc(_("Send action (in the third person) to the current chat"))
|
||||
def me(self, action):
|
||||
self.send("/me %s" % action)
|
||||
|
||||
@command('lastlog', overlap=True)
|
||||
@documentation(_("Show logged messages which mention given text"))
|
||||
@doc(_("Show logged messages which mention given text"))
|
||||
def grep(self, text, limit=None):
|
||||
results = gajim.logger.get_search_results_for_query(self.contact.jid,
|
||||
text, self.account)
|
||||
|
@ -129,7 +129,7 @@ class StandardCommonCommands(CommandContainer):
|
|||
self.echo(formatted)
|
||||
|
||||
@command(raw=True, empty=True)
|
||||
@documentation(_("""
|
||||
@doc(_("""
|
||||
Set current the status
|
||||
|
||||
Status can be given as one of the following values: online, away,
|
||||
|
@ -142,7 +142,7 @@ class StandardCommonCommands(CommandContainer):
|
|||
connection.change_status(status, message)
|
||||
|
||||
@command(raw=True, empty=True)
|
||||
@documentation(_("Set the current status to away"))
|
||||
@doc(_("Set the current status to away"))
|
||||
def away(self, message):
|
||||
if not message:
|
||||
message = _("Away")
|
||||
|
@ -150,35 +150,40 @@ class StandardCommonCommands(CommandContainer):
|
|||
connection.change_status('away', message)
|
||||
|
||||
@command('back', raw=True, empty=True)
|
||||
@documentation(_("Set the current status to online"))
|
||||
@doc(_("Set the current status to online"))
|
||||
def online(self, message):
|
||||
if not message:
|
||||
message = _("Available")
|
||||
for connection in gajim.connections.itervalues():
|
||||
connection.change_status('online', message)
|
||||
|
||||
class StandardChatCommands(CommandContainer):
|
||||
class StandardCommonChatCommands(CommandContainer):
|
||||
"""
|
||||
This command container contains standard command which are unique to a chat.
|
||||
This command container contans standard commands, which are common
|
||||
to a chat and a private chat only.
|
||||
"""
|
||||
|
||||
HOSTS = (ChatCommands,)
|
||||
HOSTS = (ChatCommands, PrivateChatCommands)
|
||||
|
||||
@command
|
||||
@documentation(_("Send a ping to the contact"))
|
||||
@doc(_("Toggle the GPG encryption"))
|
||||
def gpg(self):
|
||||
self._toggle_gpg()
|
||||
|
||||
@command
|
||||
@doc(_("Send a ping to the contact"))
|
||||
def ping(self):
|
||||
if self.account == gajim.ZEROCONF_ACC_NAME:
|
||||
raise CommandError(_('Command is not supported for zeroconf accounts'))
|
||||
gajim.connections[self.account].sendPing(self.contact)
|
||||
|
||||
@command
|
||||
@documentation(_("Sends DTMF events through an open audio session"))
|
||||
@doc(_("Send DTMF events through an open audio session"))
|
||||
def dtmf(self, events):
|
||||
if not self.audio_sid:
|
||||
raise CommandError(_("There is no open audio session with this contact"))
|
||||
# Valid values for DTMF tones are *, # or a number
|
||||
events = [event for event in events
|
||||
if event in ('*', '#') or event.isdigit()]
|
||||
# Valid values for DTMF tones are *, # or a number.
|
||||
events = [e for e in events if e in ('*', '#') or e.isdigit()]
|
||||
if events:
|
||||
session = gajim.connections[self.account].get_jingle_session(
|
||||
self.contact.get_full_jid(), self.audio_sid)
|
||||
|
@ -188,10 +193,10 @@ class StandardChatCommands(CommandContainer):
|
|||
raise CommandError(_("No valid DTMF event specified"))
|
||||
|
||||
@command
|
||||
@documentation(_("Toggle audio session"))
|
||||
@doc(_("Toggle audio session"))
|
||||
def audio(self):
|
||||
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
raise CommandError(_("Video sessions are not available"))
|
||||
if not self.audio_available:
|
||||
raise CommandError(_("Audio sessions are not available"))
|
||||
else:
|
||||
# A state of an audio session is toggled by inverting a state of the
|
||||
# appropriate button.
|
||||
|
@ -199,9 +204,9 @@ class StandardChatCommands(CommandContainer):
|
|||
self._audio_button.set_active(not state)
|
||||
|
||||
@command
|
||||
@documentation(_("Toggle video session"))
|
||||
@doc(_("Toggle video session"))
|
||||
def video(self):
|
||||
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
|
||||
if not self.video_available:
|
||||
raise CommandError(_("Video sessions are not available"))
|
||||
else:
|
||||
# A state of a video session is toggled by inverting a state of the
|
||||
|
@ -209,24 +214,32 @@ class StandardChatCommands(CommandContainer):
|
|||
state = self._video_button.get_active()
|
||||
self._video_button.set_active(not state)
|
||||
|
||||
class StandardChatCommands(CommandContainer):
|
||||
"""
|
||||
This command container contains standard commands which are unique
|
||||
to a chat.
|
||||
"""
|
||||
|
||||
HOSTS = (ChatCommands,)
|
||||
|
||||
class StandardPrivateChatCommands(CommandContainer):
|
||||
"""
|
||||
This command container contains standard command which are unique to a
|
||||
private chat.
|
||||
This command container contains standard commands which are unique
|
||||
to a private chat.
|
||||
"""
|
||||
|
||||
HOSTS = (PrivateChatCommands,)
|
||||
|
||||
class StandardGroupchatCommands(CommandContainer):
|
||||
class StandardGroupChatCommands(CommandContainer):
|
||||
"""
|
||||
This command container contains standard command which are unique to a group
|
||||
chat.
|
||||
This command container contains standard commands which are unique
|
||||
to a group chat.
|
||||
"""
|
||||
|
||||
HOSTS = (GroupChatCommands,)
|
||||
|
||||
@command(raw=True)
|
||||
@documentation(_("Change your nickname in a group chat"))
|
||||
@doc(_("Change your nickname in a group chat"))
|
||||
def nick(self, new_nick):
|
||||
try:
|
||||
new_nick = helpers.parse_resource(new_nick)
|
||||
|
@ -236,7 +249,7 @@ class StandardGroupchatCommands(CommandContainer):
|
|||
self.new_nick = new_nick
|
||||
|
||||
@command('query', raw=True)
|
||||
@documentation(_("Open a private chat window with a specified occupant"))
|
||||
@doc(_("Open a private chat window with a specified occupant"))
|
||||
def chat(self, nick):
|
||||
nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
|
||||
if nick in nicks:
|
||||
|
@ -245,7 +258,7 @@ class StandardGroupchatCommands(CommandContainer):
|
|||
raise CommandError(_("Nickname not found"))
|
||||
|
||||
@command('msg', raw=True)
|
||||
@documentation(_("Open a private chat window with a specified occupant and send him a message"))
|
||||
@doc(_("Open a private chat window with a specified occupant and send him a message"))
|
||||
def message(self, nick, a_message):
|
||||
nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
|
||||
if nick in nicks:
|
||||
|
@ -254,7 +267,7 @@ class StandardGroupchatCommands(CommandContainer):
|
|||
raise CommandError(_("Nickname not found"))
|
||||
|
||||
@command(raw=True, empty=True)
|
||||
@documentation(_("Display or change a group chat topic"))
|
||||
@doc(_("Display or change a group chat topic"))
|
||||
def topic(self, new_topic):
|
||||
if new_topic:
|
||||
self.connection.send_gc_subject(self.room_jid, new_topic)
|
||||
|
@ -262,13 +275,13 @@ class StandardGroupchatCommands(CommandContainer):
|
|||
return self.subject
|
||||
|
||||
@command(raw=True, empty=True)
|
||||
@documentation(_("Invite a user to a room for a reason"))
|
||||
@doc(_("Invite a user to a room for a reason"))
|
||||
def invite(self, jid, reason):
|
||||
self.connection.send_invite(self.room_jid, jid, reason)
|
||||
return _("Invited %s to %s") % (jid, self.room_jid)
|
||||
|
||||
@command(raw=True, empty=True)
|
||||
@documentation(_("Join a group chat given by a jid, optionally using given nickname"))
|
||||
@doc(_("Join a group chat given by a jid, optionally using given nickname"))
|
||||
def join(self, jid, nick):
|
||||
if not nick:
|
||||
nick = self.nick
|
||||
|
@ -285,12 +298,12 @@ class StandardGroupchatCommands(CommandContainer):
|
|||
pass
|
||||
|
||||
@command('part', 'close', raw=True, empty=True)
|
||||
@documentation(_("Leave the groupchat, optionally giving a reason, and close tab or window"))
|
||||
@doc(_("Leave the groupchat, optionally giving a reason, and close tab or window"))
|
||||
def leave(self, reason):
|
||||
self.parent_win.remove_tab(self, self.parent_win.CLOSE_COMMAND, reason)
|
||||
|
||||
@command(raw=True, empty=True)
|
||||
@documentation(_("""
|
||||
@doc(_("""
|
||||
Ban user by a nick or a jid from a groupchat
|
||||
|
||||
If given nickname is not found it will be treated as a jid.
|
||||
|
@ -302,14 +315,14 @@ class StandardGroupchatCommands(CommandContainer):
|
|||
self.connection.gc_set_affiliation(self.room_jid, who, 'outcast', reason or str())
|
||||
|
||||
@command(raw=True, empty=True)
|
||||
@documentation(_("Kick user by a nick from a groupchat"))
|
||||
@doc(_("Kick user by a nick from a groupchat"))
|
||||
def kick(self, who, reason):
|
||||
if not who in gajim.contacts.get_nick_list(self.account, self.room_jid):
|
||||
raise CommandError(_("Nickname not found"))
|
||||
self.connection.gc_set_role(self.room_jid, who, 'none', reason or str())
|
||||
|
||||
@command
|
||||
@documentation(_("Display names of all group chat occupants"))
|
||||
@doc(_("Display names of all group chat occupants"))
|
||||
def names(self, verbose=False):
|
||||
get_contact = lambda nick: gajim.contacts.get_gc_contact(self.account, self.room_jid, nick)
|
||||
nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
|
||||
|
@ -330,11 +343,11 @@ class StandardGroupchatCommands(CommandContainer):
|
|||
return ', '.join(nicks)
|
||||
|
||||
@command('ignore', raw=True)
|
||||
@documentation(_("Forbid an occupant to send you public or private messages"))
|
||||
@doc(_("Forbid an occupant to send you public or private messages"))
|
||||
def block(self, who):
|
||||
self.on_block(None, who)
|
||||
|
||||
@command('unignore', raw=True)
|
||||
@documentation(_("Allow an occupant to send you public or private messages"))
|
||||
@doc(_("Allow an occupant to send you public or private messages"))
|
||||
def unblock(self, who):
|
||||
self.on_unblock(None, who)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
# Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,17 +14,16 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
The module contains routines to parse command arguments and map them to the
|
||||
command handler's positonal and keyword arguments.
|
||||
The module contains routines to parse command arguments and map them to
|
||||
the command handler's positonal and keyword arguments.
|
||||
|
||||
Mapping is done in two stages: 1) parse arguments into positional arguments and
|
||||
options; 2) adapt them to the specific command handler according to the command
|
||||
properties.
|
||||
Mapping is done in two stages: 1) parse arguments into positional
|
||||
arguments and options; 2) adapt them to the specific command handler
|
||||
according to the command properties.
|
||||
"""
|
||||
|
||||
import re
|
||||
from types import BooleanType, UnicodeType
|
||||
from types import TupleType, ListType
|
||||
from operator import itemgetter
|
||||
|
||||
from errors import DefinitionError, CommandError
|
||||
|
@ -34,28 +33,32 @@ from errors import DefinitionError, CommandError
|
|||
ARG_PATTERN = re.compile(r'(\'|")?(?P<body>(?(1).+?|\S+))(?(1)\1)')
|
||||
OPT_PATTERN = re.compile(r'(?<!\w)--?(?P<key>[\w-]+)(?:(?:=|\s)(\'|")?(?P<value>(?(2)[^-]+?|[^-\s]+))(?(2)\2))?')
|
||||
|
||||
# Option keys needs to be encoded to a specific encoding as Python does not
|
||||
# allow to expand dictionary with raw unicode strings as keys from a **kwargs.
|
||||
# Option keys needs to be encoded to a specific encoding as Python does
|
||||
# not allow to expand dictionary with raw unicode strings as keys from a
|
||||
# **kwargs.
|
||||
KEY_ENCODING = 'UTF-8'
|
||||
|
||||
# Defines how complete representation of command usage (generated based on
|
||||
# command handler argument specification) will be rendered.
|
||||
# Defines how complete representation of command usage (generated based
|
||||
# on command handler argument specification) will be rendered.
|
||||
USAGE_PATTERN = 'Usage: %s %s'
|
||||
|
||||
def parse_arguments(arguments):
|
||||
"""
|
||||
Simple yet effective and sufficient in most cases parser which parses
|
||||
command arguments and returns them as two lists.
|
||||
Simple yet effective and sufficient in most cases parser which
|
||||
parses command arguments and returns them as two lists.
|
||||
|
||||
First list represents positional arguments as (argument, position), and
|
||||
second representing options as (key, value, position) tuples, where position
|
||||
is a (start, end) span tuple of where it was found in the string.
|
||||
First list represents positional arguments as (argument, position),
|
||||
and second representing options as (key, value, position) tuples,
|
||||
where position is a (start, end) span tuple of where it was found in
|
||||
the string.
|
||||
|
||||
Options may be given in --long or -short format. As --option=value or
|
||||
--option value or -option value. Keys without values will get None as value.
|
||||
Options may be given in --long or -short format. As --option=value
|
||||
or --option value or -option value. Keys without values will get
|
||||
None as value.
|
||||
|
||||
Arguments and option values that contain spaces may be given as 'one two
|
||||
three' or "one two three"; that is between single or double quotes.
|
||||
Arguments and option values that contain spaces may be given as 'one
|
||||
two three' or "one two three"; that is between single or double
|
||||
quotes.
|
||||
"""
|
||||
args, opts = [], []
|
||||
|
||||
|
@ -90,14 +93,16 @@ def parse_arguments(arguments):
|
|||
position = match.span()
|
||||
args.append((body, position))
|
||||
|
||||
# Primitive but sufficiently effective way of disposing of conflicted
|
||||
# sectors. Remove any arguments that intersect with options.
|
||||
# Primitive but sufficiently effective way of disposing of
|
||||
# conflicted sectors. Remove any arguments that intersect with
|
||||
# options.
|
||||
for arg, position in args[:]:
|
||||
if intersects_opts(position):
|
||||
args.remove((arg, position))
|
||||
|
||||
# Primitive but sufficiently effective way of disposing of conflicted
|
||||
# sectors. Remove any options that intersect with arguments.
|
||||
# Primitive but sufficiently effective way of disposing of
|
||||
# conflicted sectors. Remove any options that intersect with
|
||||
# arguments.
|
||||
for key, value, position in opts[:]:
|
||||
if intersects_args(position):
|
||||
opts.remove((key, value, position))
|
||||
|
@ -106,41 +111,40 @@ def parse_arguments(arguments):
|
|||
|
||||
def adapt_arguments(command, arguments, args, opts):
|
||||
"""
|
||||
Adapt args and opts got from the parser to a specific handler by means of
|
||||
arguments specified on command definition. That is transform them to *args
|
||||
and **kwargs suitable for passing to a command handler.
|
||||
Adapt args and opts got from the parser to a specific handler by
|
||||
means of arguments specified on command definition. That is
|
||||
transform them to *args and **kwargs suitable for passing to a
|
||||
command handler.
|
||||
|
||||
Dashes (-) in the option names will be converted to underscores. So you can
|
||||
map --one-more-option to a one_more_option=None.
|
||||
Dashes (-) in the option names will be converted to underscores. So
|
||||
you can map --one-more-option to a one_more_option=None.
|
||||
|
||||
If the initial value of a keyword argument is a boolean (False in most
|
||||
cases) - then this option will be treated as a switch, that is an option
|
||||
which does not take an argument. If a switch is followed by an argument -
|
||||
then this argument will be treated just like a normal positional argument.
|
||||
|
||||
If the initial value of a keyword argument is a sequence, that is a tuple or
|
||||
list - then a value of this option will be considered correct only if it is
|
||||
present in the sequence.
|
||||
If the initial value of a keyword argument is a boolean (False in
|
||||
most cases) - then this option will be treated as a switch, that is
|
||||
an option which does not take an argument. If a switch is followed
|
||||
by an argument - then this argument will be treated just like a
|
||||
normal positional argument.
|
||||
"""
|
||||
spec_args, spec_kwargs, var_args, var_kwargs = command.extract_specification()
|
||||
norm_kwargs = dict(spec_kwargs)
|
||||
|
||||
# Quite complex piece of neck-breaking logic to extract raw arguments if
|
||||
# there is more, then one positional argument specified by the command. In
|
||||
# case if it's just one argument which is the collector - this is fairly
|
||||
# easy. But when it's more then one argument - the neck-breaking logic of
|
||||
# how to retrieve residual arguments as a raw, all in one piece string,
|
||||
# kicks in.
|
||||
# Quite complex piece of neck-breaking logic to extract raw
|
||||
# arguments if there is more, then one positional argument specified
|
||||
# by the command. In case if it's just one argument which is the
|
||||
# collector - this is fairly easy. But when it's more then one
|
||||
# argument - the neck-breaking logic of how to retrieve residual
|
||||
# arguments as a raw, all in one piece string, kicks in.
|
||||
if command.raw:
|
||||
if arguments:
|
||||
spec_fix = 1 if command.source else 0
|
||||
spec_len = len(spec_args) - spec_fix
|
||||
arguments_end = len(arguments) - 1
|
||||
|
||||
# If there are any optional arguments given they should be either an
|
||||
# unquoted postional argument or part of the raw argument. So we
|
||||
# find all optional arguments that can possibly be unquoted argument
|
||||
# and append them as is to the args.
|
||||
# If there are any optional arguments given they should be
|
||||
# either an unquoted postional argument or part of the raw
|
||||
# argument. So we find all optional arguments that can
|
||||
# possibly be unquoted argument and append them as is to the
|
||||
# args.
|
||||
for key, value, (start, end) in opts[:spec_len]:
|
||||
if value:
|
||||
end -= len(value) + 1
|
||||
|
@ -149,9 +153,9 @@ def adapt_arguments(command, arguments, args, opts):
|
|||
else:
|
||||
args.append((arguments[start:end], (start, end)))
|
||||
|
||||
# We need in-place sort here because after manipulations with
|
||||
# options order of arguments might be wrong and we just can't have
|
||||
# more complex logic to not let that happen.
|
||||
# We need in-place sort here because after manipulations
|
||||
# with options order of arguments might be wrong and we just
|
||||
# can't have more complex logic to not let that happen.
|
||||
args.sort(key=itemgetter(1))
|
||||
|
||||
if spec_len > 1:
|
||||
|
@ -160,27 +164,28 @@ def adapt_arguments(command, arguments, args, opts):
|
|||
except IndexError:
|
||||
raise CommandError("Missing arguments", command)
|
||||
|
||||
# The essential point of the whole play. After boundaries are
|
||||
# being determined (supposingly correct) we separate raw part
|
||||
# from the rest of arguments, which should be normally
|
||||
# processed.
|
||||
# The essential point of the whole play. After
|
||||
# boundaries are being determined (supposingly correct)
|
||||
# we separate raw part from the rest of arguments, which
|
||||
# should be normally processed.
|
||||
raw = arguments[end:]
|
||||
raw = raw.strip() or None
|
||||
|
||||
if not raw and not command.empty:
|
||||
raise CommandError("Missing arguments", command)
|
||||
|
||||
# Discard residual arguments and all of the options as raw
|
||||
# command does not support options and if an option is given it
|
||||
# is rather a part of a raw argument.
|
||||
# Discard residual arguments and all of the options as
|
||||
# raw command does not support options and if an option
|
||||
# is given it is rather a part of a raw argument.
|
||||
args = args[:spec_len - 1]
|
||||
opts = []
|
||||
|
||||
args.append((raw, (end, arguments_end)))
|
||||
else:
|
||||
# Substitue all of the arguments with only one, which contain
|
||||
# raw and unprocessed arguments as a string. And discard all the
|
||||
# options, as raw command does not support them.
|
||||
# Substitue all of the arguments with only one, which
|
||||
# contain raw and unprocessed arguments as a string. And
|
||||
# discard all the options, as raw command does not
|
||||
# support them.
|
||||
args = [(arguments, (0, arguments_end))]
|
||||
opts = []
|
||||
else:
|
||||
|
@ -189,16 +194,17 @@ def adapt_arguments(command, arguments, args, opts):
|
|||
else:
|
||||
raise CommandError("Missing arguments", command)
|
||||
|
||||
# The first stage of transforming options we have got to a format that can
|
||||
# be used to associate them with declared keyword arguments. Substituting
|
||||
# dashes (-) in their names with underscores (_).
|
||||
# The first stage of transforming options we have got to a format
|
||||
# that can be used to associate them with declared keyword
|
||||
# arguments. Substituting dashes (-) in their names with
|
||||
# underscores (_).
|
||||
for index, (key, value, position) in enumerate(opts):
|
||||
if '-' in key:
|
||||
opts[index] = (key.replace('-', '_'), value, position)
|
||||
|
||||
# The second stage of transforming options to an associatable state.
|
||||
# Expanding short, one-letter options to a verbose ones, if corresponding
|
||||
# optin has been given.
|
||||
# Expanding short, one-letter options to a verbose ones, if
|
||||
# corresponding optin has been given.
|
||||
if command.expand_short:
|
||||
expanded = []
|
||||
for spec_key, spec_value in norm_kwargs.iteritems():
|
||||
|
@ -210,26 +216,27 @@ def adapt_arguments(command, arguments, args, opts):
|
|||
opts[index] = (spec_key, value, position)
|
||||
break
|
||||
|
||||
# Detect switches and set their values accordingly. If any of them carries a
|
||||
# value - append it to args.
|
||||
# Detect switches and set their values accordingly. If any of them
|
||||
# carries a value - append it to args.
|
||||
for index, (key, value, position) in enumerate(opts):
|
||||
if isinstance(norm_kwargs.get(key), BooleanType):
|
||||
opts[index] = (key, True, position)
|
||||
if value:
|
||||
args.append((value, position))
|
||||
|
||||
# Sorting arguments and options (just to be sure) in regarding to their
|
||||
# positions in the string.
|
||||
# Sorting arguments and options (just to be sure) in regarding to
|
||||
# their positions in the string.
|
||||
args.sort(key=itemgetter(1))
|
||||
opts.sort(key=itemgetter(2))
|
||||
|
||||
# Stripping down position information supplied with arguments and options as
|
||||
# it won't be needed again.
|
||||
# Stripping down position information supplied with arguments and
|
||||
# options as it won't be needed again.
|
||||
args = map(lambda (arg, position): arg, args)
|
||||
opts = map(lambda (key, value, position): (key, value), opts)
|
||||
|
||||
# If command has extra option enabled - collect all extra arguments and pass
|
||||
# them to a last positional argument command defines as a list.
|
||||
# If command has extra option enabled - collect all extra arguments
|
||||
# and pass them to a last positional argument command defines as a
|
||||
# list.
|
||||
if command.extra:
|
||||
if not var_args:
|
||||
spec_fix = 1 if not command.source else 2
|
||||
|
@ -240,9 +247,9 @@ def adapt_arguments(command, arguments, args, opts):
|
|||
else:
|
||||
raise DefinitionError("Can not have both, extra and *args")
|
||||
|
||||
# Detect if positional arguments overlap keyword arguments. If so and this
|
||||
# is allowed by command options - then map them directly to their options,
|
||||
# so they can get propert further processings.
|
||||
# Detect if positional arguments overlap keyword arguments. If so
|
||||
# and this is allowed by command options - then map them directly to
|
||||
# their options, so they can get propert further processings.
|
||||
spec_fix = 1 if command.source else 0
|
||||
spec_len = len(spec_args) - spec_fix
|
||||
if len(args) > spec_len:
|
||||
|
@ -262,49 +269,32 @@ def adapt_arguments(command, arguments, args, opts):
|
|||
if not isinstance(value, BooleanType):
|
||||
raise CommandError("%s: Switch can not take an argument" % key, command)
|
||||
|
||||
# Detect every sequence constraint and ensure that if corresponding options
|
||||
# are given - they contain proper values, within the constraint range.
|
||||
for key, value in opts:
|
||||
initial = norm_kwargs.get(key)
|
||||
if isinstance(initial, (TupleType, ListType)):
|
||||
if value not in initial:
|
||||
raise CommandError("%s: Invalid argument" % key, command)
|
||||
|
||||
# If argument to an option constrained by a sequence was not given - then
|
||||
# it's value should be set to None.
|
||||
for spec_key, spec_value in spec_kwargs:
|
||||
if isinstance(spec_value, (TupleType, ListType)):
|
||||
for key, value in opts:
|
||||
if spec_key == key:
|
||||
break
|
||||
else:
|
||||
opts.append((spec_key, None))
|
||||
|
||||
# We need to encode every keyword argument to a simple string, not the
|
||||
# unicode one, because ** expansion does not support it.
|
||||
# We need to encode every keyword argument to a simple string, not
|
||||
# the unicode one, because ** expansion does not support it.
|
||||
for index, (key, value) in enumerate(opts):
|
||||
if isinstance(key, UnicodeType):
|
||||
opts[index] = (key.encode(KEY_ENCODING), value)
|
||||
|
||||
# Inject the source arguments as a string as a first argument, if command
|
||||
# has enabled the corresponding option.
|
||||
# Inject the source arguments as a string as a first argument, if
|
||||
# command has enabled the corresponding option.
|
||||
if command.source:
|
||||
args.insert(0, arguments)
|
||||
|
||||
# Return *args and **kwargs in the form suitable for passing to a command
|
||||
# handler and being expanded.
|
||||
# Return *args and **kwargs in the form suitable for passing to a
|
||||
# command handler and being expanded.
|
||||
return tuple(args), dict(opts)
|
||||
|
||||
def generate_usage(command, complete=True):
|
||||
"""
|
||||
Extract handler's arguments specification and wrap them in a human-readable
|
||||
format usage information. If complete is given - then USAGE_PATTERN will be
|
||||
used to render the specification completly.
|
||||
Extract handler's arguments specification and wrap them in a
|
||||
human-readable format usage information. If complete is given - then
|
||||
USAGE_PATTERN will be used to render the specification completly.
|
||||
"""
|
||||
spec_args, spec_kwargs, var_args, var_kwargs = command.extract_specification()
|
||||
|
||||
# Remove some special positional arguments from the specifiaction, but store
|
||||
# their names so they can be used for usage info generation.
|
||||
# Remove some special positional arguments from the specifiaction,
|
||||
# but store their names so they can be used for usage info
|
||||
# generation.
|
||||
sp_source = spec_args.pop(0) if command.source else None
|
||||
sp_extra = spec_args.pop() if command.extra else None
|
||||
|
||||
|
@ -317,8 +307,6 @@ def generate_usage(command, complete=True):
|
|||
|
||||
if isinstance(value, BooleanType):
|
||||
value = str()
|
||||
elif isinstance(value, (TupleType, ListType)):
|
||||
value = '={%s}' % ', '.join(value)
|
||||
else:
|
||||
value = '=%s' % value
|
||||
|
||||
|
@ -350,8 +338,8 @@ def generate_usage(command, complete=True):
|
|||
if var_kwargs:
|
||||
usage += (' ' if args else str()) + '[[%s]]' % var_kwargs
|
||||
|
||||
# Native name will be the first one if it is included. Otherwise, names will
|
||||
# be in the order they were specified.
|
||||
# Native name will be the first one if it is included. Otherwise,
|
||||
# names will be in the order they were specified.
|
||||
if len(command.names) > 1:
|
||||
names = '%s (%s)' % (command.first_name, ', '.join(command.names[1:]))
|
||||
else:
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
## src/common/GnuPG.py
|
||||
##
|
||||
## Copyright (C) 2003-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2003-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2005 Alex Mauer <hawke AT hawkesnest.net>
|
||||
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2005-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2007 Stephan Erb <steve-e AT h3c.de>
|
||||
## Copyright (C) 2008 Jean-Marie Traissard <jim AT lapin.org>
|
||||
## Jonathan Schleifer <js-gajim AT webkeks.org>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
##
|
||||
## Copyright (C) 2001 Frank J. Tobin <ftobin AT neverending.org>
|
||||
## Copyright (C) 2005 Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2006-2007 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2006-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2008 Jean-Marie Traissard <jim AT lapin.org>
|
||||
##
|
||||
## This file is part of Gajim.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
##
|
||||
## Copyright (C) 2006 Jean-Marie Traissard <jim AT lapin.org>
|
||||
## Tomasz Melcer <liori AT exroot.org>
|
||||
## Copyright (C) 2006-2007 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2006-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
##
|
||||
## This file is part of Gajim.
|
||||
##
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
##
|
||||
## Copyright (C) 2007 Tomasz Melcer <liori AT exroot.org>
|
||||
## Travis Shirk <travis AT pobox.com>
|
||||
## Copyright (C) 2007-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2007-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2008 Brendan Taylor <whateley AT gmail.com>
|
||||
## Jonathan Schleifer <js-gajim AT webkeks.org>
|
||||
## Copyright (C) 2008-2009 Stephan Erb <steve-e AT h3c.de>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
##
|
||||
## Copyright (C) 2005-2006 Travis Shirk <travis AT pobox.com>
|
||||
## Nikos Kouremenos <kourem AT gmail.com>
|
||||
## Copyright (C) 2005-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2005-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com>
|
||||
## Copyright (C) 2007 Tomasz Melcer <liori AT exroot.org>
|
||||
## Copyright (C) 2008 Jean-Marie Traissard <jim AT lapin.org>
|
||||
|
@ -129,7 +129,9 @@ def split_db():
|
|||
print 'spliting database'
|
||||
if os.name == 'nt':
|
||||
try:
|
||||
OLD_LOG_DB_FOLDER = os.path.join(fse(os.environ[u'appdata']), u'Gajim')
|
||||
import configpaths
|
||||
OLD_LOG_DB_FOLDER = os.path.join(configpaths.fse(
|
||||
os.environ[u'appdata']), u'Gajim')
|
||||
except KeyError:
|
||||
OLD_LOG_DB_FOLDER = u'.'
|
||||
else:
|
||||
|
@ -184,7 +186,8 @@ def check_and_possibly_move_config():
|
|||
|
||||
if os.name == 'nt':
|
||||
try:
|
||||
OLD_LOG_DB_FOLDER = os.path.join(fse(os.environ[u'appdata']), u'Gajim')
|
||||
OLD_LOG_DB_FOLDER = os.path.join(configpaths.fse(
|
||||
os.environ[u'appdata']), u'Gajim')
|
||||
except KeyError:
|
||||
OLD_LOG_DB_FOLDER = u'.'
|
||||
else:
|
||||
|
@ -340,5 +343,10 @@ def check_and_possibly_create_paths():
|
|||
sys.exit()
|
||||
|
||||
def create_path(directory):
|
||||
head, tail = os.path.split(directory)
|
||||
if not os.path.exists(head):
|
||||
create_path(head)
|
||||
if os.path.exists(directory):
|
||||
return
|
||||
print _('creating %s directory') % directory
|
||||
os.mkdir(directory, 0700)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# -*- coding:utf-8 -*-
|
||||
## src/common/commands.py
|
||||
##
|
||||
## Copyright (C) 2006-2007 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Tomasz Melcer <liori AT exroot.org>
|
||||
## Copyright (C) 2006-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2006-2007 Tomasz Melcer <liori AT exroot.org>
|
||||
## Copyright (C) 2007 Jean-Marie Traissard <jim AT lapin.org>
|
||||
## Copyright (C) 2008 Brendan Taylor <whateley AT gmail.com>
|
||||
## Stephan Erb <steve-e AT h3c.de>
|
||||
|
@ -290,6 +290,41 @@ class ForwardMessagesCommand(AdHocCommand):
|
|||
|
||||
return False # finish the session
|
||||
|
||||
class FwdMsgThenDisconnectCommand(AdHocCommand):
|
||||
commandnode = 'fwd-msd-disconnect'
|
||||
commandname = _('Forward unread message then disconnect')
|
||||
|
||||
@staticmethod
|
||||
def isVisibleFor(samejid):
|
||||
"""
|
||||
Change status is visible only if the entity has the same bare jid
|
||||
"""
|
||||
return samejid
|
||||
|
||||
def execute(self, request):
|
||||
account = self.connection.name
|
||||
# Forward messages
|
||||
events = gajim.events.get_events(account, types=['chat', 'normal'])
|
||||
j, resource = gajim.get_room_and_nick_from_fjid(self.jid)
|
||||
for jid in events:
|
||||
for event in events[jid]:
|
||||
self.connection.send_message(j, event.parameters[0], '',
|
||||
type_=event.type_, subject=event.parameters[1],
|
||||
resource=resource, forward_from=jid, delayed=event.time_,
|
||||
now=True)
|
||||
|
||||
response, cmd = self.buildResponse(request, status = 'completed')
|
||||
cmd.addChild('note', {}, _('The status has been changed.'))
|
||||
|
||||
# if going offline, we need to push response so it won't go into
|
||||
# queue and disappear
|
||||
self.connection.connection.send(response, now = True)
|
||||
|
||||
# send new status
|
||||
gajim.interface.roster.send_status(self.connection.name, 'offline', '')
|
||||
# finish the session
|
||||
return False
|
||||
|
||||
class ConnectionCommands:
|
||||
"""
|
||||
This class depends on that it is a part of Connection() class
|
||||
|
@ -299,7 +334,7 @@ class ConnectionCommands:
|
|||
# a list of all commands exposed: node -> command class
|
||||
self.__commands = {}
|
||||
for cmdobj in (ChangeStatusCommand, ForwardMessagesCommand,
|
||||
LeaveGroupchatsCommand):
|
||||
LeaveGroupchatsCommand, FwdMsgThenDisconnectCommand):
|
||||
self.__commands[cmdobj.commandnode] = cmdobj
|
||||
|
||||
# a list of sessions; keys are tuples (jid, sessionid, node)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding:utf-8 -*-
|
||||
## src/common/config.py
|
||||
##
|
||||
## Copyright (C) 2003-2008 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2003-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2004-2005 Vincent Hanquez <tab AT snarc.org>
|
||||
## Copyright (C) 2005 Stéphan Kochen <stephan AT kochen.nl>
|
||||
## Copyright (C) 2005-2006 Dimitur Kirov <dkirov AT gmail.com>
|
||||
|
@ -277,6 +277,8 @@ class Config:
|
|||
'audio_output_device': [opt_str, 'autoaudiosink'],
|
||||
'video_input_device': [opt_str, 'autovideosrc ! videoscale ! ffmpegcolorspace'],
|
||||
'video_output_device': [opt_str, 'autovideosink'],
|
||||
'video_framerate': [opt_str, '', _('Optionally fix jingle output video framerate. Example: 10/1 or 25/2')],
|
||||
'video_size': [opt_str, '', _('Optionally resize jingle output video. Example: 320x240')],
|
||||
'audio_input_volume': [opt_int, 50],
|
||||
'audio_output_volume': [opt_int, 50],
|
||||
'use_stun_server': [opt_bool, True, _('If True, Gajim will try to use a STUN server when using jingle. The one in "stun_server" option, or the one given by the jabber server.')],
|
||||
|
@ -289,6 +291,7 @@ class Config:
|
|||
'name': [ opt_str, '', '', True ],
|
||||
'hostname': [ opt_str, '', '', True ],
|
||||
'anonymous_auth': [ opt_bool, False ],
|
||||
'client_cert': [ opt_str, '', '', True ],
|
||||
'savepass': [ opt_bool, False ],
|
||||
'password': [ opt_str, '' ],
|
||||
'resource': [ opt_str, 'gajim', '', True ],
|
||||
|
@ -315,6 +318,7 @@ class Config:
|
|||
'connection_types': [ opt_str, 'tls ssl plain', _('Ordered list (space separated) of connection type to try. Can contain tls, ssl or plain')],
|
||||
'warn_when_plaintext_connection': [ opt_bool, True, _('Show a warning dialog before sending password on an plaintext connection.') ],
|
||||
'warn_when_insecure_ssl_connection': [ opt_bool, True, _('Show a warning dialog before using standard SSL library.') ],
|
||||
'warn_when_insecure_password': [ opt_bool, True, _('Show a warning dialog before sending PLAIN password over a plain conenction.') ],
|
||||
'ssl_fingerprint_sha1': [ opt_str, '', '', True ],
|
||||
'ignore_ssl_errors': [ opt_str, '', _('Space separated list of ssl errors to ignore.') ],
|
||||
'use_srv': [ opt_bool, True, '', True ],
|
||||
|
@ -451,8 +455,8 @@ class Config:
|
|||
'urgency_hint': [opt_bool, False],
|
||||
}, {}),
|
||||
'plugins': ({
|
||||
'active': [opt_bool, False, _('State whether plugins should be activated on exit (this is saved on Gajim exit). This option SHOULD NOT be used to (de)activate plug-ins. Use GUI instead.')],
|
||||
}, {}),
|
||||
'active': [opt_bool, False, _('State whether plugins should be activated on exit (this is saved on Gajim exit). This option SHOULD NOT be used to (de)activate plug-ins. Use GUI instead.')],
|
||||
},{}),
|
||||
}
|
||||
|
||||
statusmsg_default = {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
##
|
||||
## Copyright (C) 2006 Jean-Marie Traissard <jim AT lapin.org>
|
||||
## Junglecow J <junglecow AT gmail.com>
|
||||
## Copyright (C) 2006-2007 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2006-2010 Yann Leboulanger <asterix AT lagaule.org>
|
||||
## Copyright (C) 2007 Brendan Taylor <whateley AT gmail.com>
|
||||
## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
||||
##
|
||||
|
@ -157,7 +157,7 @@ class ConfigPaths:
|
|||
self.add('ICONS', None, os.path.join(basedir, windowsify(u'icons')))
|
||||
self.add('HOME', None, fse(os.path.expanduser('~')))
|
||||
self.add('PLUGINS_BASE', None, os.path.join(basedir,
|
||||
windowsify(u'plugins')))
|
||||
windowsify(u'plugins')))
|
||||
try:
|
||||
self.add('TMP', None, fse(tempfile.gettempdir()))
|
||||
except IOError, e:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue