Skip to content
Snippets Groups Projects
Commit 145cdbbf authored by Liorithiel's avatar Liorithiel
Browse files

Fetching command list from entity now works.

If the entity has at least one command exposed, it will be displayed as
a radio button. Other changes: run python interpreter without optimalizations,
otherwise asserts doesn't work. Names of widgets in the glade file were
changed a bit.
parent 23fa0bf8
No related branches found
No related tags found
No related merge requests found
......@@ -17,6 +17,7 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<signal name="destroy" handler="on_adhoc_commands_window_destroy" last_modification_time="Thu, 22 Jun 2006 22:50:45 GMT"/>
<child>
<widget class="GtkVBox" id="vbox1">
......@@ -26,7 +27,7 @@
<property name="spacing">0</property>
<child>
<widget class="GtkNotebook" id="mode_notebook">
<widget class="GtkNotebook" id="stages_notebook">
<property name="visible">True</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
......@@ -35,7 +36,7 @@
<property name="enable_popup">False</property>
<child>
<widget class="GtkVBox" id="vbox2">
<widget class="GtkVBox" id="retrieving_commands_stage_vbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
......@@ -114,7 +115,7 @@
</child>
<child>
<widget class="GtkVBox" id="vbox5">
<widget class="GtkVBox" id="command_list_stage_vbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
......@@ -187,7 +188,7 @@
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<widget class="GtkVBox" id="sending_form_stage_vbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
......@@ -314,7 +315,27 @@
</child>
<child>
<placeholder/>
<widget class="GtkLabel" id="label257">
<property name="visible">True</property>
<property name="label" translatable="yes">An error has occured.</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="tab_expand">False</property>
<property name="tab_fill">True</property>
</packing>
</child>
<child>
......
#!/bin/sh
cd `dirname $0`/src
exec python -OOt gajim.py $@
exec python -t gajim.py $@
......@@ -19,9 +19,16 @@
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
# TODO: think if we need caching command list. it may be wrong if there will
# TODO: be entities that often change the list, it may be slow to fetch it
# TODO: every time
import gobject
import gtk
import common.xmpp as xmpp
import common.gajim as gajim
import gtkgui_helpers
class CommandWindow:
......@@ -35,45 +42,158 @@ class CommandWindow:
def __init__(self, account, jid):
'''Create new window.'''
self.pulse_id=None # to satisfy self..setup_pulsing()
# an account object
self.account = gajim.connections[account]
self.jid = jid
# connecting to handlers
self.pulse_id=None # to satisfy self.setup_pulsing()
self.commandlist=None # a list of (commandname, commanddescription)
# retrieving widgets from xml
self.xml = gtkgui_helpers.get_glade('adhoc_commands_window.glade')
self.window = self.xml.get_widget('adhoc_commands_window')
for name in ('cancel_button', 'back_button', 'forward_button',
'execute_button','stages_notebook',
'retrieving_commands_stage_vbox',
'command_list_stage_vbox','command_list_vbox',
'sending_form_stage_vbox'):
self.__dict__[name] = self.xml.get_widget(name)
# setting initial state of widgets
self.setup_pulsing(self.xml.get_widget('retrieving_commands_progressbar'))
# invoking disco to find commands
# setting initial stage
self.stage1()
# displaying the window
self.xml.signal_autoconnect(self)
self.window.show_all()
def on_adhoc_commands_window_destroy(self, window):
''' The window dissappeared somehow... clean the environment,
Stop pulsing.'''
self.remove_pulsing()
# these functions are set up by appropriate stageX methods
def stage_finish(self, *anything): pass
def on_cancel_button_clicked(self, *anything): pass
def on_back_button_clicked(self, *anything): pass
def on_forward_button_clicked(self, *anything): pass
def on_execute_button_clicked(self, *anything): pass
def on_adhoc_commands_window_destroy(self, *anything): pass
# stage 1: waiting for command list
def stage1(self):
'''Prepare the first stage. Request command list,
set appropriate state of widgets.'''
# close old stage...
self.stage_finish()
# show the stage
self.stages_notebook.set_current_page(
self.stages_notebook.page_num(
self.retrieving_commands_stage_vbox))
# set widgets' state
self.cancel_button.set_sensitive(True)
self.back_button.set_sensitive(False)
self.forward_button.set_sensitive(False)
self.execute_button.set_sensitive(False)
# request command list
self.request_command_list()
self.setup_pulsing(
self.xml.get_widget('retrieving_commands_progressbar'))
# setup the callbacks
self.stage_finish = self.stage1_finish
self.on_cancel_button_clicked = self.stage1_on_cancel_button_clicked
def stage1_finish(self):
self.remove_pulsing()
def stage1_on_cancel_button_clicked(self, widget):
# cancelling in this stage is not critical, so we don't
# show any popups to user
self.stage1_finish()
self.window.destroy()
# stage 2: choosing the command to execute
def stage2(self):
'''Populate the command list vbox with radiobuttons
(TODO: if there is more commands, maybe some kind of list?),
set widgets' state.'''
# close old stage
self.stage_finish()
assert len(self.commandlist)>0
self.stages_notebook.set_current_page(
self.stages_notebook.page_num(
self.command_list_stage_vbox))
self.cancel_button.set_sensitive(True)
self.back_button.set_sensitive(False)
self.forward_button.set_sensitive(True)
self.execute_button.set_sensitive(False)
# build the commands list radiobuttons
first_radio = None
for (commandnode, commandname) in self.commandlist:
radio = gtk.RadioButton(first_radio, label=commandname)
if first_radio is None: first_radio = radio
self.command_list_vbox.pack_end(radio, expand=False)
self.command_list_vbox.show_all()
self.stage_finish = self.stage_finish
self.on_cancel_button_clicked = self.stage2_on_cancel_button_clicked
self.on_forward_button_clicked = self.stage2_on_forward_button_clicked
def stage2_on_cancel_button_clicked(self):
self.stage_finish()
self.window.destroy()
def stage2_on_forward_button_clicked(self):
pass
# helpers to handle pulsing in progressbar
def setup_pulsing(self, progressbar):
'''Useful to set the progressbar to pulse. Makes a custom
'''Set the progressbar to pulse. Makes a custom
function to repeatedly call progressbar.pulse() method.'''
assert self.pulse_id is None
assert isinstance(progressbar, Gtk.ProgressBar)
assert False
assert isinstance(progressbar, gtk.ProgressBar)
def callback():
progressbar.pulse()
return True # important to keep callback be called back!
# 12 times per second (40 miliseconds)
# 12 times per second (80 miliseconds)
self.pulse_id = gobject.timeout_add(80, callback)
progressbar.pulse() # start from now!
def remove_pulsing(self):
'''Useful to stop pulsing, especially when removing widget.'''
'''Stop pulsing, useful when especially when removing widget.'''
if self.pulse_id is not None:
gobject.source_remove(self.pulse_id)
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), xmlns=xmpp.NS_DISCO_ITEMS)
query.setQuerynode(xmpp.NS_COMMANDS)
def callback(response):
'''Called on response to query.'''
# is error => error stage
error = response.getError()
if error is not None:
pass
# no commands => no commands stage
# commands => command selection stage
items = response.getTag('query').getTags('item')
if len(items)==0:
self.commandlist = []
self.stage2() # stageX, where X is the number for error page
else:
self.commandlist = [(t.getAttr('node'), t.getAttr('name')) for t in items]
self.stage2()
self.account.connection.SendAndCallForResponse(query, callback)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment