backend, frontends: callbacks refactoring:
- launchAction is now async, and return a dictionary for its result
- no more action_id, actionResult* are deprecated
- callback system is about to be unified
This commit is contained in:
parent
aa8ca0772c
commit
069a250b04
12 changed files with 151 additions and 78 deletions
|
|
@ -190,8 +190,8 @@ class DBusBridgeFrontend(BridgeFrontend):
|
|||
def isConnected(self, profile_key="@DEFAULT@"):
|
||||
return self.db_core_iface.isConnected(profile_key)
|
||||
|
||||
def launchAction(self, action_type, data, profile_key="@DEFAULT@"):
|
||||
return unicode(self.db_core_iface.launchAction(action_type, data, profile_key))
|
||||
def launchAction(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None):
|
||||
return self.db_core_iface.launchAction(callback_id, data, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:]))
|
||||
|
||||
def registerNewAccount(self, login, password, email, host, port=5222):
|
||||
return unicode(self.db_core_iface.registerNewAccount(login, password, email, host, port))
|
||||
|
|
|
|||
|
|
@ -282,7 +282,6 @@ class PrimitivusApp(QuickApp, InputHistory):
|
|||
return input
|
||||
|
||||
def _dynamicMenuCb(self, xmlui):
|
||||
misc = {}
|
||||
ui = XMLUI(self, xml_data = xmlui)
|
||||
ui.show('popup')
|
||||
|
||||
|
|
@ -448,6 +447,29 @@ class PrimitivusApp(QuickApp, InputHistory):
|
|||
#No notification left, we can hide the bar
|
||||
self.main_widget.footer = self.editBar
|
||||
|
||||
def launchAction(self, callback_id, data=None, profile_key="@NONE@"):
|
||||
""" Launch a dynamic action
|
||||
@param callback_id: id of the action to launch
|
||||
@param data: data needed only for certain actions
|
||||
@param profile_key: %(doc_profile_key)s
|
||||
|
||||
"""
|
||||
if data is None:
|
||||
data = dict()
|
||||
def action_cb(data):
|
||||
if not data:
|
||||
# action was a one shot, nothing to do
|
||||
pass
|
||||
elif "xmlui" in data:
|
||||
ui = XMLUI(self, xml_data = data['xmlui'])
|
||||
ui.show('popup')
|
||||
else:
|
||||
self.showPopUp(sat_widgets.Alert(_("Error"), _(u"Unmanaged action result"), ok_cb=self.removePopUp))
|
||||
def action_eb(failure):
|
||||
self.showPopUp(sat_widgets.Alert(_("Error"), unicode(failure), ok_cb=self.removePopUp))
|
||||
|
||||
self.bridge.launchAction(callback_id, data, profile_key, callback=action_cb, errback=action_eb)
|
||||
|
||||
def askConfirmation(self, confirmation_id, confirmation_type, data, profile):
|
||||
if not self.check_profile(profile):
|
||||
return
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ class XMLUI(urwid.WidgetWrap):
|
|||
ctrl.selectValue(elem.getAttribute("value"))
|
||||
self.ctrl_list[name] = ({'type':type_, 'control':ctrl})
|
||||
elif type_=="button":
|
||||
callback_id = elem.getAttribute("callback_id")
|
||||
callback_id = elem.getAttribute("callback")
|
||||
ctrl = sat_widgets.CustomButton(value, on_press=self.onButtonPress)
|
||||
ctrl.param_id = (callback_id,[field.getAttribute('name') for field in elem.getElementsByTagName("field_back")])
|
||||
elif type_=="advanced_list":
|
||||
|
|
@ -178,6 +178,7 @@ class XMLUI(urwid.WidgetWrap):
|
|||
top=cat_dom.documentElement
|
||||
self.type = top.getAttribute("type")
|
||||
self.title = top.getAttribute("title") or self.title
|
||||
self.submit_id = top.getAttribute("submit") or None
|
||||
if top.nodeName != "sat_xmlui" or not self.type in ['form', 'param', 'window']:
|
||||
raise InvalidXMLUI
|
||||
|
||||
|
|
@ -234,7 +235,7 @@ class XMLUI(urwid.WidgetWrap):
|
|||
|
||||
def onButtonPress(self, button):
|
||||
callback_id, fields = button.param_id
|
||||
data = {"callback_id":callback_id}
|
||||
data = {}
|
||||
for field in fields:
|
||||
ctrl = self.ctrl_list[field]
|
||||
if isinstance(ctrl['control'],sat_widgets.List):
|
||||
|
|
@ -242,8 +243,7 @@ class XMLUI(urwid.WidgetWrap):
|
|||
else:
|
||||
data[field] = ctrl['control'].getValue()
|
||||
|
||||
id = self.host.bridge.launchAction("button", data, profile_key = self.host.profile)
|
||||
self.host.current_action_ids.add(id)
|
||||
self.host.launchAction(callback_id, data, profile_key = self.host.profile)
|
||||
|
||||
def onParamChange(self, widget, extra=None):
|
||||
"""Called when type is param and a widget to save is modified"""
|
||||
|
|
@ -262,12 +262,13 @@ class XMLUI(urwid.WidgetWrap):
|
|||
data.append((ctrl_name, ctrl['control'].get_edit_text()))
|
||||
if self.misc.has_key('action_back'): #FIXME FIXME FIXME: WTF ! Must be cleaned
|
||||
raise NotImplementedError
|
||||
self.host.debug()
|
||||
elif 'callback' in self.misc:
|
||||
elif 'callback' in self.misc: # FIXME: this part is not needed anymore
|
||||
try:
|
||||
self.misc['callback'](data, *self.misc['callback_args'])
|
||||
self.misc['callback'](data, submit_id=self.submit_id, *self.misc['callback_args'])
|
||||
except KeyError:
|
||||
self.misc['callback'](data)
|
||||
self.misc['callback'](data, submit_id=self.submit_id)
|
||||
elif self.submit_id is not None:
|
||||
self.host.launchAction(self.submit_id, dict(data), profile_key=self.host.profile)
|
||||
|
||||
else:
|
||||
warning (_("The form data is not sent back, the type is not managed properly"))
|
||||
|
|
|
|||
|
|
@ -238,6 +238,39 @@ class MainWindow(wx.Frame, QuickApp):
|
|||
self.tools.Disable()
|
||||
return
|
||||
|
||||
def launchAction(self, callback_id, data=None, profile_key="@NONE@"):
|
||||
""" Launch a dynamic action
|
||||
@param callback_id: id of the action to launch
|
||||
@param data: data needed only for certain actions
|
||||
@param profile_key: %(doc_profile_key)s
|
||||
|
||||
"""
|
||||
if data is None:
|
||||
data = dict()
|
||||
def action_cb(data):
|
||||
if not data:
|
||||
# action was a one shot, nothing to do
|
||||
pass
|
||||
elif "xmlui" in data:
|
||||
debug (_("XML user interface received"))
|
||||
XMLUI(self, xml_data = data['xmlui'])
|
||||
else:
|
||||
dlg = wx.MessageDialog(self, _(u"Unmanaged action result"),
|
||||
_('Error'),
|
||||
wx.OK | wx.ICON_ERROR
|
||||
)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
def action_eb(failure):
|
||||
dlg = wx.MessageDialog(self, unicode(failure),
|
||||
_('Error'),
|
||||
wx.OK | wx.ICON_ERROR
|
||||
)
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
self.bridge.launchAction(callback_id, data, profile_key, callback=action_cb, errback=action_eb)
|
||||
|
||||
def askConfirmation(self, confirmation_id, confirmation_type, data, profile):
|
||||
#TODO: refactor this in QuickApp
|
||||
if not self.check_profile(profile):
|
||||
|
|
|
|||
|
|
@ -129,9 +129,7 @@ class Param(wx.Frame):
|
|||
self.__save_parameters()
|
||||
name, category = event.GetEventObject().param_id
|
||||
callback_id = event.GetEventObject().callback_id
|
||||
data = {"name":name, "category":category, "callback_id":callback_id}
|
||||
id = self.host.bridge.launchAction("button", data, profile_key = self.host.profile)
|
||||
self.host.current_action_ids.add(id)
|
||||
self.host.launchAction(callback_id, None, profile_key = self.host.profile)
|
||||
event.Skip()
|
||||
|
||||
def __save_parameters(self):
|
||||
|
|
|
|||
|
|
@ -30,11 +30,13 @@ class XMLUI(wx.Frame):
|
|||
"""Create an user interface from a SàT xml"""
|
||||
|
||||
def __init__(self, host, xml_data='', title="Form", options = None, misc = None):
|
||||
style = wx.DEFAULT_FRAME_STYLE & ~wx.CLOSE_BOX if 'NO_CANCEL' in options else wx.DEFAULT_FRAME_STYLE #FIXME: gof: Q&D tmp hack
|
||||
if options is None:
|
||||
options = []
|
||||
style = wx.DEFAULT_FRAME_STYLE & ~wx.CLOSE_BOX if 'NO_CANCEL' in options else wx.DEFAULT_FRAME_STYLE #FIXME: Q&D tmp hack
|
||||
super(XMLUI, self).__init__(None, title=title, style=style)
|
||||
|
||||
self.host = host
|
||||
self.options = options or []
|
||||
self.options = options
|
||||
self.misc = misc or {}
|
||||
self.ctrl_list = {} # usefull to access ctrl
|
||||
|
||||
|
|
@ -165,6 +167,7 @@ class XMLUI(wx.Frame):
|
|||
top= cat_dom.documentElement
|
||||
self.type = top.getAttribute("type")
|
||||
self.title = top .getAttribute("title")
|
||||
self.submit_id = top.getAttribute("submit") or None
|
||||
if self.title:
|
||||
self.SetTitle(self.title)
|
||||
if top.nodeName != "sat_xmlui" or not self.type in ['form', 'param', 'window']:
|
||||
|
|
@ -195,7 +198,6 @@ class XMLUI(wx.Frame):
|
|||
def onButtonClicked(self, event):
|
||||
"""Called when a button is pushed"""
|
||||
callback_id, fields = event.GetEventObject().param_id
|
||||
data = {"callback_id":callback_id}
|
||||
for field in fields:
|
||||
ctrl = self.ctrl_list[field]
|
||||
if isinstance(ctrl['control'], wx.ListBox):
|
||||
|
|
@ -203,8 +205,7 @@ class XMLUI(wx.Frame):
|
|||
else:
|
||||
data[field] = ctrl['control'].GetValue()
|
||||
|
||||
id = self.host.bridge.launchAction("button", data, profile_key = self.host.profile)
|
||||
self.host.current_action_ids.add(id)
|
||||
self.host.launchAction(callback_id, None, profile_key = self.host.profile)
|
||||
event.Skip()
|
||||
|
||||
def onFormSubmitted(self, event):
|
||||
|
|
@ -224,6 +225,10 @@ class XMLUI(wx.Frame):
|
|||
self.host.current_action_ids.add(id)
|
||||
elif self.misc.has_key('callback'):
|
||||
self.misc['callback'](data)
|
||||
|
||||
elif self.submit_id is not None:
|
||||
data = dict(selected_values)
|
||||
self.host.launchAction(self.submit_id, data, profile_key=self.host.profile)
|
||||
else:
|
||||
warning (_("The form data is not sent back, the type is not managed properly"))
|
||||
self.MakeModal(False)
|
||||
|
|
|
|||
|
|
@ -378,10 +378,10 @@ class DbusObject(dbus.service.Object):
|
|||
return self._callback("isConnected", unicode(profile_key))
|
||||
|
||||
@dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
|
||||
in_signature='sa{ss}s', out_signature='s',
|
||||
async_callbacks=None)
|
||||
def launchAction(self, action_type, data, profile_key="@DEFAULT@"):
|
||||
return self._callback("launchAction", unicode(action_type), data, unicode(profile_key))
|
||||
in_signature='sa{ss}s', out_signature='a{ss}',
|
||||
async_callbacks=('callback', 'errback'))
|
||||
def launchAction(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None):
|
||||
return self._callback("launchAction", unicode(callback_id), data, unicode(profile_key), callback=callback, errback=errback)
|
||||
|
||||
@dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
|
||||
in_signature='ssssi', out_signature='s',
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ doc_param_0=entity_jid: JID of the contact removed from roster
|
|||
doc_param_1=%(doc_profile)s
|
||||
|
||||
[askConfirmation]
|
||||
deprecated=
|
||||
type=signal
|
||||
category=core
|
||||
sig_in=ssa{ss}s
|
||||
|
|
@ -116,6 +117,7 @@ doc_param_2=data: conf_type dependent data
|
|||
doc_param_3=%(doc_profile)s
|
||||
|
||||
[actionResult]
|
||||
deprecated=
|
||||
type=signal
|
||||
category=core
|
||||
sig_in=ssa{ss}s
|
||||
|
|
@ -130,6 +132,7 @@ doc_param_2=data: answer_type specific data
|
|||
doc_param_3=%(doc_profile)s
|
||||
|
||||
[actionResultExt]
|
||||
deprecated=
|
||||
type=signal
|
||||
category=core
|
||||
sig_in=ssa{sa{ss}}s
|
||||
|
|
@ -533,18 +536,21 @@ doc_param_0=entity_jid: JID to remove from roster
|
|||
doc_param_1=%(doc_profile_key)s
|
||||
|
||||
[launchAction]
|
||||
async=
|
||||
type=method
|
||||
category=core
|
||||
sig_in=sa{ss}s
|
||||
sig_out=s
|
||||
sig_out=a{ss}
|
||||
param_2_default="@DEFAULT@"
|
||||
doc=Launch a specific action
|
||||
doc_param_0=action_type: type of the action which can be:
|
||||
- button: A button is pushed
|
||||
doc_param_1=data: action_type dependant data
|
||||
doc=Launch a registred action
|
||||
doc_param_0=callback_id: id of the registred callback
|
||||
doc_param_1=data: optional data
|
||||
doc_param_2=%(doc_profile_key)s
|
||||
doc_return=dict where key can be:
|
||||
- xmlui: a XMLUI need to be displayed
|
||||
|
||||
[confirmationAnswer]
|
||||
deprecated=
|
||||
type=method
|
||||
category=core
|
||||
sig_in=sba{ss}s
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ from sat.memory.memory import Memory
|
|||
from sat.tools.xml_tools import tupleList2dataForm
|
||||
from sat.tools.misc import TriggerManager
|
||||
from glob import glob
|
||||
from uuid import uuid4
|
||||
|
||||
try:
|
||||
from twisted.words.protocols.xmlstream import XMPPHandler
|
||||
|
|
@ -103,10 +104,8 @@ class SAT(service.Service):
|
|||
CONST[name] = value
|
||||
|
||||
def __init__(self):
|
||||
#TODO: standardize callback system
|
||||
|
||||
self.__general_cb_map = {} # callback called for general reasons (key = name)
|
||||
self.__private_data = {} # used for internal callbacks (key = id)
|
||||
self._cb_map = {} # map from callback_id to callbacks
|
||||
self.__private_data = {} # used for internal callbacks (key = id) FIXME: to be removed
|
||||
self.profiles = {}
|
||||
self.plugins = {}
|
||||
self.menus = {} # dynamic menus. key: (type, category, name), value: menu data (dictionnary)
|
||||
|
|
@ -157,7 +156,7 @@ class SAT(service.Service):
|
|||
self.bridge.register("updateContact", self.updateContact)
|
||||
self.bridge.register("delContact", self.delContact)
|
||||
self.bridge.register("isConnected", self.isConnected)
|
||||
self.bridge.register("launchAction", self.launchAction)
|
||||
self.bridge.register("launchAction", self.launchCallback)
|
||||
self.bridge.register("confirmationAnswer", self.confirmationAnswer)
|
||||
self.bridge.register("getProgress", self.getProgress)
|
||||
self.bridge.register("getMenus", self.getMenus)
|
||||
|
|
@ -388,7 +387,8 @@ class SAT(service.Service):
|
|||
|
||||
return next_id
|
||||
|
||||
def registerNewAccountCB(self, id, data, profile):
|
||||
def registerNewAccountCB(self, data, profile):
|
||||
# FIXME: to be removed/redone elsewhere
|
||||
user = jid.parse(self.memory.getParamA("JabberID", "Connection", profile_key=profile))[0]
|
||||
password = self.memory.getParamA("Password", "Connection", profile_key=profile)
|
||||
server = self.memory.getParamA("Server", "Connection", profile_key=profile)
|
||||
|
|
@ -407,8 +407,6 @@ class SAT(service.Service):
|
|||
{"message": _("Are you sure to register new account [%(user)s] to server %(server)s ?") % {'user': user, 'server': server, 'profile': profile}},
|
||||
self.regisConfirmCB, profile)
|
||||
print "===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============"
|
||||
print "id=", id
|
||||
print "data=", data
|
||||
|
||||
def regisConfirmCB(self, id, accepted, data, profile):
|
||||
print _("register Confirmation CB ! (%s)") % str(accepted)
|
||||
|
|
@ -428,6 +426,7 @@ class SAT(service.Service):
|
|||
@param fields: list of tuples (name, value)
|
||||
@return: tuple: (id, deferred)
|
||||
"""
|
||||
# FIXME: to be removed
|
||||
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
assert(profile)
|
||||
|
|
@ -469,29 +468,6 @@ class SAT(service.Service):
|
|||
return False
|
||||
return self.profiles[profile].isConnected()
|
||||
|
||||
def launchAction(self, type, data, profile_key):
|
||||
"""Launch a specific action asked by client
|
||||
@param type: action type (button)
|
||||
@param data: needed data to launch the action
|
||||
|
||||
@return: action id for result, or empty string in case or error
|
||||
"""
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_('trying to launch action with a non-existant profile'))
|
||||
raise Exception # TODO: raise a proper exception
|
||||
if type == "button":
|
||||
try:
|
||||
cb_name = data['callback_id']
|
||||
except KeyError:
|
||||
error(_("Incomplete data"))
|
||||
return ""
|
||||
id = sat_next_id()
|
||||
self.callGeneralCB(cb_name, id, data, profile=profile)
|
||||
return id
|
||||
else:
|
||||
error(_("Unknown action type"))
|
||||
return ""
|
||||
|
||||
## jabber methods ##
|
||||
|
||||
|
|
@ -808,6 +784,7 @@ class SAT(service.Service):
|
|||
@param data: data (depend of confirmation conf_type)
|
||||
@param cb: callback called with the answer
|
||||
"""
|
||||
# FIXME: use XMLUI and *callback methods for dialog
|
||||
client = self.getClient(profile)
|
||||
if not client:
|
||||
raise exceptions.ProfileUnknownError(_("Asking confirmation a non-existant profile"))
|
||||
|
|
@ -863,24 +840,53 @@ class SAT(service.Service):
|
|||
#debug("Requested progress for unknown progress_id")
|
||||
return data
|
||||
|
||||
def registerGeneralCB(self, name, CB):
|
||||
"""Register a callback called for general reason"""
|
||||
self.__general_cb_map[name] = CB
|
||||
|
||||
def removeGeneralCB(self, name):
|
||||
"""Remove a general callback"""
|
||||
if name not in self.__general_cb_map:
|
||||
error(_("Trying to remove an unknow general callback"))
|
||||
def registerCallback(self, callback, *args, **kwargs):
|
||||
""" Register a callback.
|
||||
Use with_data=True in kwargs if the callback use the optional data dict
|
||||
use force_id=id to avoid generated id. Can lead to name conflict, avoid if possible
|
||||
@param callback: any callable
|
||||
@return: id of the registered callback
|
||||
"""
|
||||
callback_id = kwargs.pop('force_id', None)
|
||||
if callback_id is None:
|
||||
callback_id = str(uuid4())
|
||||
else:
|
||||
del self.__general_cb_map[name]
|
||||
if callback_id in self._cb_map:
|
||||
raise exceptions.ConflictError(_(u"id already registered"))
|
||||
self._cb_map[callback_id] = (callback, args, kwargs)
|
||||
return callback_id
|
||||
|
||||
def removeCallback(self, callback_id):
|
||||
""" Remove a previously registered callback
|
||||
@param callback_id: id returned by [registerCallback] """
|
||||
del self._cb_map[callback_id]
|
||||
|
||||
def launchCallback(self, callback_id, data=None, profile_key="@NONE@"):
|
||||
"""Launch a specific callback
|
||||
@param callback_id: id of the action (callback) to launch
|
||||
@param data: optional data
|
||||
@profile_key: %(doc_profile_key)s
|
||||
@return: a deferred which fire a dict where key can be:
|
||||
- xmlui: a XMLUI need to be displayed
|
||||
"""
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
raise exceptions.ProfileUnknownError(_('trying to launch action with a non-existant profile'))
|
||||
|
||||
def callGeneralCB(self, name, *args, **kwargs):
|
||||
"""Call general function back"""
|
||||
try:
|
||||
return self.__general_cb_map[name](*args, **kwargs)
|
||||
callback, args, kwargs = self._cb_map[callback_id]
|
||||
except KeyError:
|
||||
error(_("Trying to call unknown function (%s)") % name)
|
||||
return None
|
||||
raise exceptions.DataError("Unknown callback id")
|
||||
|
||||
if kwargs.get("with_data", False):
|
||||
if data is None:
|
||||
raise exceptions.DataError("Required data for this callback is missing")
|
||||
args,kwargs=list(args)[:],kwargs.copy() # we don't want to modify the original (kw)args
|
||||
args.insert(0, data)
|
||||
kwargs["profile"] = profile
|
||||
del kwargs["with_data"]
|
||||
|
||||
return defer.maybeDeferred(callback, *args, **kwargs)
|
||||
|
||||
#Menus management
|
||||
|
||||
|
|
@ -925,6 +931,7 @@ class SAT(service.Service):
|
|||
@param profile_key: %(doc_profile_key)s
|
||||
@return: XMLUI or empty string if it's a one shot menu
|
||||
"""
|
||||
# TODO: menus should use launchCallback
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
raise exceptions.ProfileUnknownError
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ class Params(object):
|
|||
self.default_profile = None
|
||||
self.params = {}
|
||||
self.params_gen = {}
|
||||
host.registerGeneralCB("registerNewAccount", host.registerNewAccountCB)
|
||||
host.registerCallback(host.registerNewAccountCB, force_id="registerNewAccount")
|
||||
|
||||
def createProfile(self, profile):
|
||||
"""Create a new profile
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ from twisted.words.protocols.jabber.xmlstream import IQ
|
|||
import random
|
||||
|
||||
from wokkel import data_form
|
||||
from sat.tools.xml_tools import dataForm2XML
|
||||
from sat_frontends.tools.games import TarotCard
|
||||
from time import time
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ class Field(object):
|
|||
class XMLUI(object):
|
||||
"""This class is used to create a user interface (form/window/parameters/etc) using SàT XML"""
|
||||
|
||||
def __init__(self, panel_type, layout="vertical", title=None):
|
||||
def __init__(self, panel_type, layout="vertical", title=None, submit_id=None):
|
||||
"""Init SàT XML Panel
|
||||
@param panel_type: one of
|
||||
- window (new window)
|
||||
|
|
@ -232,6 +232,7 @@ class XMLUI(object):
|
|||
(usually one for a label, the next for the element)
|
||||
- tabs: elemens are in categories with tabs (notebook)
|
||||
@param title: title or default if None
|
||||
@param submit_id: callback id to call for panel_type we can submit (form, param)
|
||||
"""
|
||||
if not panel_type in ['window', 'form', 'param']:
|
||||
error(_("Unknown panel type [%s]") % panel_type)
|
||||
|
|
@ -244,6 +245,8 @@ class XMLUI(object):
|
|||
top_element.setAttribute("type", panel_type)
|
||||
if title:
|
||||
top_element.setAttribute("title", title)
|
||||
if submit_id:
|
||||
top_element.setAttribute("submit", submit_id)
|
||||
self.parentTabsLayout = None # used only we have 'tabs' layout
|
||||
self.currentCategory = None # used only we have 'tabs' layout
|
||||
self.currentLayout = None
|
||||
|
|
@ -369,7 +372,7 @@ class XMLUI(object):
|
|||
@fields_back: list of names of field to give back when pushing the button
|
||||
"""
|
||||
elem = self._createElem('button', name, self.currentLayout)
|
||||
elem.setAttribute('callback_id', callback_id)
|
||||
elem.setAttribute('callback', callback_id)
|
||||
elem.setAttribute('value', value)
|
||||
for field in fields_back:
|
||||
fback_el = self.doc.createElement('field_back')
|
||||
|
|
|
|||
Loading…
Reference in a new issue