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.
This commit is contained in:
parent
23fa0bf8e6
commit
145cdbbf40
|
@ -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>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/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)
|
||||
|
|
Loading…
Reference in New Issue