Added auto(dis)connect params + misc
- parameters,xmlui: "bool" type is now managed - parameters,xmlui: categories now use label in addition of name - QuickFrontend: auto(dis)connection management - plugin XEP-0045: an error dialog is now show in frontend if room cannot be joined - Wix: fixed unproper close event management
This commit is contained in:
parent
b3bff009e8
commit
007f12d2ae
11 changed files with 125 additions and 59 deletions
|
|
@ -436,6 +436,7 @@ class PrimitivusApp(QuickApp):
|
|||
self.addWindow(params)
|
||||
|
||||
def onExitRequest(self, menu):
|
||||
QuickApp.onExit(self)
|
||||
raise urwid.ExitMainLoop()
|
||||
|
||||
def onJoinRoomRequest(self, menu):
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ class XMLUI(urwid.WidgetWrap):
|
|||
elif type=="textbox":
|
||||
ctrl = custom_widgets.AdvancedEdit(edit_text = value, multiline=True)
|
||||
self.ctrl_list[name] = ({'type':type, 'control':ctrl})
|
||||
elif type=="bool":
|
||||
ctrl = urwid.CheckBox('', state = value=="true")
|
||||
self.ctrl_list[name] = ({'type':type, 'control':ctrl})
|
||||
elif type=="list":
|
||||
style=[] if elem.getAttribute("multi")=='yes' else ['single']
|
||||
ctrl = custom_widgets.List(options=[option.getAttribute("value") for option in elem.getElementsByTagName("option")], style=style)
|
||||
|
|
@ -102,7 +105,7 @@ class XMLUI(urwid.WidgetWrap):
|
|||
error(_("FIXME FIXME FIXME: type [%s] is not implemented") % type) #FIXME !
|
||||
raise NotImplementedError
|
||||
if self.type == 'param':
|
||||
if isinstance(ctrl,urwid.Edit):
|
||||
if isinstance(ctrl,urwid.Edit) or isinstance(ctrl,urwid.CheckBox):
|
||||
urwid.connect_signal(ctrl,'change',self.onParamChange)
|
||||
ctrl._param_category = self._current_category
|
||||
ctrl._param_name = name
|
||||
|
|
@ -133,12 +136,13 @@ class XMLUI(urwid.WidgetWrap):
|
|||
self.__parseElems(node, current)
|
||||
elif node.nodeName == "category":
|
||||
name = node.getAttribute('name')
|
||||
label = node.getAttribute('label')
|
||||
if not name or not isinstance(data,custom_widgets.TabsContainer):
|
||||
raise InvalidXMLUI
|
||||
if self.type == 'param':
|
||||
self._current_category = name #XXX: awful hack because params need category and we don't keep parent
|
||||
tab_cont = data
|
||||
listbox = tab_cont.addTab(name)
|
||||
listbox = tab_cont.addTab(label or name)
|
||||
self.__parseChilds(listbox.body, node, ['layout'])
|
||||
else:
|
||||
message=_("Unknown tag")
|
||||
|
|
@ -217,7 +221,7 @@ class XMLUI(urwid.WidgetWrap):
|
|||
id = self.host.bridge.launchAction("button", data, profile_key = self.host.profile)
|
||||
self.host.current_action_ids.add(id)
|
||||
|
||||
def onParamChange(self, widget, text):
|
||||
def onParamChange(self, widget, extra=None):
|
||||
"""Called when type is param and a widget to save is modified"""
|
||||
assert(self.type == "param")
|
||||
self.param_changed.add(widget)
|
||||
|
|
@ -228,6 +232,8 @@ class XMLUI(urwid.WidgetWrap):
|
|||
ctrl = self.ctrl_list[ctrl_name]
|
||||
if isinstance(ctrl['control'], custom_widgets.List):
|
||||
data.append((ctrl_name, ctrl['control'].getSelectedValue()))
|
||||
if isinstance(ctrl['control'], urwid.CheckBox):
|
||||
data.append((ctrl_name, "true" if ctrl['control'].get_state() else "false"))
|
||||
else:
|
||||
data.append((ctrl_name, ctrl['control'].get_edit_text()))
|
||||
if self.misc.has_key('action_back'): #FIXME FIXME FIXME: WTF ! Must be cleaned
|
||||
|
|
@ -247,5 +253,9 @@ class XMLUI(urwid.WidgetWrap):
|
|||
|
||||
def onSaveParams(self, button):
|
||||
for ctrl in self.param_changed:
|
||||
self.host.bridge.setParam(ctrl._param_name, ctrl.get_edit_text(), ctrl._param_category, profile_key = self.host.profile)
|
||||
if isinstance(ctrl, urwid.CheckBox):
|
||||
value = "true" if ctrl.get_state() else "false"
|
||||
else:
|
||||
value = ctrl.get_edit_text()
|
||||
self.host.bridge.setParam(ctrl._param_name, value, ctrl._param_category, profile_key = self.host.profile)
|
||||
self.host.removeWindow()
|
||||
|
|
|
|||
|
|
@ -119,42 +119,47 @@ class QuickApp():
|
|||
|
||||
###now we get the essential params###
|
||||
self.profiles[profile]['whoami']=JID(self.bridge.getParamA("JabberID","Connection", profile))
|
||||
autoconnect = self.bridge.getParamA("autoconnect","Connection", profile) == "true"
|
||||
self.profiles[profile]['watched']=self.bridge.getParamA("Watched", "Misc", profile).split() #TODO: put this in a plugin
|
||||
|
||||
## misc ##
|
||||
self.profiles[profile]['onlineContact'] = set() #FIXME: temporary
|
||||
|
||||
#TODO: gof: managed multi-profiles here
|
||||
if self.bridge.isConnected(profile):
|
||||
self.setStatusOnline(True)
|
||||
else:
|
||||
#TODO: gof: manage multi-profiles here
|
||||
if not self.bridge.isConnected(profile):
|
||||
self.setStatusOnline(False)
|
||||
return
|
||||
else:
|
||||
self.setStatusOnline(True)
|
||||
|
||||
### now we fill the contact list ###
|
||||
for contact in self.bridge.getContacts(profile):
|
||||
self.newContact(contact[0], contact[1], contact[2], profile)
|
||||
### now we fill the contact list ###
|
||||
for contact in self.bridge.getContacts(profile):
|
||||
self.newContact(contact[0], contact[1], contact[2], profile)
|
||||
|
||||
presences = self.bridge.getPresenceStatus(profile)
|
||||
for contact in presences:
|
||||
for res in presences[contact]:
|
||||
jabber_id = contact+('/'+res if res else '')
|
||||
show = presences[contact][res][0]
|
||||
priority = presences[contact][res][1]
|
||||
statuses = presences[contact][res][2]
|
||||
self.presenceUpdate(jabber_id, show, priority, statuses, profile)
|
||||
presences = self.bridge.getPresenceStatus(profile)
|
||||
for contact in presences:
|
||||
for res in presences[contact]:
|
||||
jabber_id = contact+('/'+res if res else '')
|
||||
show = presences[contact][res][0]
|
||||
priority = presences[contact][res][1]
|
||||
statuses = presences[contact][res][2]
|
||||
self.presenceUpdate(jabber_id, show, priority, statuses, profile)
|
||||
|
||||
#The waiting subscription requests
|
||||
waitingSub = self.bridge.getWaitingSub(profile)
|
||||
for sub in waitingSub:
|
||||
self.subscribe(waitingSub[sub], sub, profile)
|
||||
#The waiting subscription requests
|
||||
waitingSub = self.bridge.getWaitingSub(profile)
|
||||
for sub in waitingSub:
|
||||
self.subscribe(waitingSub[sub], sub, profile)
|
||||
|
||||
#Now we open the MUC window where we already are:
|
||||
for room_args in self.bridge.getRoomJoined(profile):
|
||||
self.roomJoined(*room_args, profile=profile)
|
||||
#Now we open the MUC window where we already are:
|
||||
for room_args in self.bridge.getRoomJoined(profile):
|
||||
self.roomJoined(*room_args, profile=profile)
|
||||
|
||||
for subject_args in self.bridge.getRoomSubjects(profile):
|
||||
self.roomNewSubject(*subject_args, profile=profile)
|
||||
for subject_args in self.bridge.getRoomSubjects(profile):
|
||||
self.roomNewSubject(*subject_args, profile=profile)
|
||||
|
||||
if autoconnect and not self.bridge.isConnected(profile_key):
|
||||
#Does the user want autoconnection ?
|
||||
self.bridge.connect(profile_key)
|
||||
|
||||
|
||||
def unplug_profile(self, profile):
|
||||
"""Tell the application to not follow anymore the profile"""
|
||||
|
|
@ -420,3 +425,11 @@ class QuickApp():
|
|||
|
||||
def actionResult(self, type, id, data):
|
||||
raise NotImplementedError
|
||||
|
||||
def onExit(self):
|
||||
"""Must be called when the frontend is terminating"""
|
||||
#TODO: mange multi-profile here
|
||||
autodisconnect = self.bridge.getParamA("autodisconnect","Connection", self.profile) == "true"
|
||||
if autodisconnect and self.bridge.isConnected(self.profile):
|
||||
#Does the user want autodisconnection ?
|
||||
self.bridge.disconnect(self.profile)
|
||||
|
|
|
|||
|
|
@ -188,9 +188,6 @@ class Chat(wx.Frame, QuickChat):
|
|||
def onClose(self, event):
|
||||
"""Close event: we only hide the frame."""
|
||||
event.Veto()
|
||||
self.Show() ## this is a workaround to a wxpython bug:
|
||||
## with Raise on hidden frame, Hide doesn't work anymore
|
||||
## TODO: check this and repport bug to wxpython devs
|
||||
self.Hide()
|
||||
|
||||
def onEnterPressed(self, event):
|
||||
|
|
@ -222,9 +219,10 @@ class Chat(wx.Frame, QuickChat):
|
|||
self.chatWindow.AppendText("%s\n" % msg)
|
||||
if not mymess:
|
||||
#TODO: use notification system
|
||||
self.RequestUserAttention() #FIXME: do this only if in background.
|
||||
self.Show() #gof: FIXME: to check
|
||||
#self.Raise() #FIXME: too intrusive
|
||||
if not self.IsActive():
|
||||
self.RequestUserAttention()
|
||||
if not self.IsShown():
|
||||
self.Show()
|
||||
|
||||
### events ###
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ class ContactList(wx.SimpleHtmlListBox, QuickContactList):
|
|||
def add(self, contact, groups = None):
|
||||
"""add a contact to the list"""
|
||||
debug (_("adding %s"),contact)
|
||||
#gof: groups = param_groups or self.CM.getAttr(jid, 'groups')
|
||||
if not groups:
|
||||
idx = self.Insert(self.__presentItem(contact), 0, contact)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -125,8 +125,6 @@ class MainWindow(wx.Frame, QuickApp):
|
|||
for i in range(self.menuBar.GetMenuCount()):
|
||||
self.menuBar.EnableTop(i, True)
|
||||
super(MainWindow, self).plug_profile(profile_key)
|
||||
if not self.bridge.isConnected(profile_key):
|
||||
self.bridge.connect(profile_key)
|
||||
|
||||
def createMenus(self):
|
||||
info(_("Creating menus"))
|
||||
|
|
@ -464,7 +462,10 @@ class MainWindow(wx.Frame, QuickApp):
|
|||
gatewayManager = GatewaysManager(self, data, server=target)
|
||||
|
||||
def onClose(self, e):
|
||||
QuickApp.onExit(self)
|
||||
info(_("Exiting..."))
|
||||
for win in self.chat_wins:
|
||||
self.chat_wins[win].Destroy()
|
||||
e.Skip()
|
||||
|
||||
def onTrayClick(self, e):
|
||||
|
|
|
|||
|
|
@ -61,30 +61,37 @@ class Param(wx.Frame):
|
|||
|
||||
for param in cat_dom.documentElement.getElementsByTagName("param"):
|
||||
name = param.getAttribute("name")
|
||||
label = param.getAttribute("label")
|
||||
type = param.getAttribute("type")
|
||||
value = param.getAttribute("value")
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
if type=="string":
|
||||
label=wx.StaticText(panel, -1, name+" ")
|
||||
label=wx.StaticText(panel, -1, (label or name)+" ")
|
||||
ctrl = wx.TextCtrl(panel, -1, value)
|
||||
sizer.Add(label)
|
||||
elif type=="password":
|
||||
label=wx.StaticText(panel, -1, name+" ")
|
||||
label=wx.StaticText(panel, -1, (label or name)+" ")
|
||||
ctrl = wx.TextCtrl(panel, -1, value, style=wx.TE_PASSWORD)
|
||||
sizer.Add(label)
|
||||
elif type=="bool":
|
||||
ctrl = wx.CheckBox(panel, -1, label or name, style = wx.CHK_2STATE)
|
||||
ctrl.SetValue(value=="true")
|
||||
elif type=="button":
|
||||
ctrl = wx.Button(panel, -1, value)
|
||||
ctrl.callback_id = param.getAttribute("callback_id")
|
||||
else:
|
||||
error(_("FIXME FIXME FIXME")) #FIXME !
|
||||
raise NotImplementedError
|
||||
ctrl.param_id=(name, category)
|
||||
if name:
|
||||
ctrl.param_id=(name, category)
|
||||
self.ctl_list[(name, category)] = ctrl
|
||||
sizer.Add(ctrl, 1, flag=wx.EXPAND)
|
||||
self.ctl_list[(name, category)] = ctrl
|
||||
panel.sizer.Add(sizer, flag=wx.EXPAND)
|
||||
|
||||
if type=="string" or type=="password":
|
||||
panel.Bind(wx.EVT_TEXT, self.onTextChanged, ctrl)
|
||||
elif type=="bool":
|
||||
panel.Bind(wx.EVT_CHECKBOX, self.onCheckBoxClicked, ctrl)
|
||||
elif type=="button":
|
||||
panel.Bind(wx.EVT_BUTTON, self.onButtonClicked, ctrl)
|
||||
|
||||
|
|
@ -94,7 +101,7 @@ class Param(wx.Frame):
|
|||
cat_dom.unlink()
|
||||
|
||||
def onTextChanged(self, event):
|
||||
"""Called when a paramated is modified"""
|
||||
"""Called when a string paramater is modified"""
|
||||
self.modified[event.GetEventObject().param_id]=event.GetString()
|
||||
|
||||
### FIXME # Some hacks for better presentation, should be generic # FIXME ###
|
||||
|
|
@ -105,8 +112,13 @@ class Param(wx.Frame):
|
|||
|
||||
event.Skip()
|
||||
|
||||
def onCheckBoxClicked(self, event):
|
||||
"""Called when a bool paramater is modified"""
|
||||
self.modified[event.GetEventObject().param_id]="true" if event.GetEventObject().GetValue() else "false"
|
||||
event.Skip()
|
||||
|
||||
def onButtonClicked(self, event):
|
||||
"""Called when a paramated is modified"""
|
||||
"""Called when a button paramater is modified"""
|
||||
self.__save_parameters()
|
||||
name, category = event.GetEventObject().param_id
|
||||
callback_id = event.GetEventObject().callback_id
|
||||
|
|
|
|||
|
|
@ -88,6 +88,11 @@ class XMLUI(wx.Frame):
|
|||
ctrl = wx.TextCtrl(parent, -1, value, style=wx.TE_MULTILINE)
|
||||
self.ctrl_list[name] = ({'type':type, 'control':ctrl})
|
||||
_proportion = 1
|
||||
elif type=="bool":
|
||||
ctrl = wx.CheckBox(panel, -1, "", style = wx.CHK_2STATE)
|
||||
ctrl.SetValue(value=="true")
|
||||
self.ctrl_list[name] = ({'type':type, 'control':ctrl})
|
||||
_proportion = 1
|
||||
elif type=="list":
|
||||
style=wx.LB_MULTIPLE if elem.getAttribute("multi")=='yes' else wx.LB_SINGLE
|
||||
ctrl = wx.ListBox(parent, -1, choices=[option.getAttribute("value") for option in elem.getElementsByTagName("option")], style=style)
|
||||
|
|
@ -138,13 +143,14 @@ class XMLUI(wx.Frame):
|
|||
parent.sizer.Add(current, _proportion, flag=wx.EXPAND)
|
||||
elif node.nodeName == "category":
|
||||
name = node.getAttribute('name')
|
||||
label = node.getAttribute('label')
|
||||
if not node.nodeName in wanted or not name or not isinstance(parent,wx.Notebook):
|
||||
raise Exception("Invalid XMLUI") #TODO: make a custom exception
|
||||
notebook = parent
|
||||
tab_panel = wx.Panel(notebook, -1)
|
||||
tab_panel.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
tab_panel.SetSizer(tab_panel.sizer)
|
||||
notebook.AddPage(tab_panel, name)
|
||||
notebook.AddPage(tab_panel, label or name)
|
||||
self.__parseChilds(tab_panel, None, node, ['layout'])
|
||||
|
||||
else:
|
||||
|
|
@ -211,6 +217,8 @@ class XMLUI(wx.Frame):
|
|||
ctrl = self.ctrl_list[ctrl_name]
|
||||
if isinstance(ctrl['control'], wx.ListBox):
|
||||
data.append((ctrl_name, ctrl['control'].GetStringSelection()))
|
||||
elif isinstance(ctrl['control'], wx.CheckBox):
|
||||
data.append((ctrl_name, "true" if ctrl['control'].GetValue() else "false"))
|
||||
else:
|
||||
data.append((ctrl_name, ctrl['control'].GetValue()))
|
||||
if self.misc.has_key('action_back'): #FIXME FIXME FIXME: WTF ! Must be cleaned
|
||||
|
|
|
|||
|
|
@ -96,8 +96,9 @@ class XEP_0045():
|
|||
|
||||
def __err_joining_room(self, failure, profile):
|
||||
"""Called when something is going wrong when joining the room"""
|
||||
error ("Error when joining the room")
|
||||
#TODO: gof: send an error message throught the bridge
|
||||
mess = _("Error when joining the room")
|
||||
error (mess)
|
||||
self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile)
|
||||
|
||||
def getRoomJoined(self, profile_key='@DEFAULT@'):
|
||||
"""Return room where user is"""
|
||||
|
|
|
|||
|
|
@ -40,24 +40,31 @@ class Param():
|
|||
"""This class manage parameters with xml"""
|
||||
### TODO: add desciption in params
|
||||
|
||||
#TODO: mettre Watched dans un plugin
|
||||
#TODO: move Watched in a plugin
|
||||
default_xml = u"""
|
||||
<params>
|
||||
<general>
|
||||
</general>
|
||||
<individual>
|
||||
<category name='"""+_("Connection")+"""'>
|
||||
<category name="Connection" label="%(category_connection)s">
|
||||
<param name="JabberID" value="goffi@necton2.int/TestScript" type="string" />
|
||||
<param name="Password" value="toto" type="password" />
|
||||
<param name="Server" value="necton2.int" type="string" />
|
||||
<param name="NewAccount" value='"""+_("Register new account")+"""' type="button" callback_id="registerNewAccount"/>
|
||||
<param name="NewAccount" value="%(label_NewAccount)s" type="button" callback_id="registerNewAccount"/>
|
||||
<param name="autoconnect" label="%(label_autoconnect)s" value="true" type="bool" />
|
||||
<param name="autodisconnect" label="%(label_autodisconnect)s" value="false" type="bool" />
|
||||
</category>
|
||||
<category name='"""+_("Misc")+"""'>
|
||||
<category name="Misc" label="%(category_misc)s">
|
||||
<param name="Watched" value="test@Jabber.goffi.int" type="string" />
|
||||
</category>
|
||||
</individual>
|
||||
</params>
|
||||
"""
|
||||
""" % {'category_connection': _("Connection"),
|
||||
'label_NewAccount': _("Register new account"),
|
||||
'label_autoconnect': _('Connect on frontend startup'),
|
||||
'label_autodisconnect': _('Disconnect on frontend closure'),
|
||||
'category_misc': _("Misc")
|
||||
}
|
||||
|
||||
def load_default_params(self):
|
||||
self.dom = minidom.parseString(Param.default_xml.encode('utf-8'))
|
||||
|
|
|
|||
|
|
@ -81,12 +81,14 @@ def paramsXml2xmlUI(xml):
|
|||
param_ui = XMLUI("param", "tabs")
|
||||
for category in top.getElementsByTagName("category"):
|
||||
name = category.getAttribute('name')
|
||||
label = category.getAttribute('label')
|
||||
if not name:
|
||||
error(_('INTERNAL ERROR: params categories must have a name'))
|
||||
assert(False)
|
||||
param_ui.addCategory(name, 'pairs')
|
||||
param_ui.addCategory(name, 'pairs', label=label)
|
||||
for param in category.getElementsByTagName("param"):
|
||||
name = param.getAttribute('name')
|
||||
label = param.getAttribute('label')
|
||||
if not name:
|
||||
error(_('INTERNAL ERROR: params must have a name'))
|
||||
assert(False)
|
||||
|
|
@ -96,7 +98,7 @@ def paramsXml2xmlUI(xml):
|
|||
if type == "button":
|
||||
param_ui.addEmpty()
|
||||
else:
|
||||
param_ui.addLabel(name)
|
||||
param_ui.addLabel(label or name)
|
||||
param_ui.addElement(name=name, type=type, value=value, callback_id=callback_id)
|
||||
|
||||
return param_ui.toXml()
|
||||
|
|
@ -209,6 +211,12 @@ class XMLUI:
|
|||
if value:
|
||||
elem.setAttribute('value', value)
|
||||
|
||||
def addBool(self, name=None, value="true"):
|
||||
"""Add a string box"""
|
||||
assert value in ["true","false"]
|
||||
elem = self.__createElem('bool', name, self.currentLayout)
|
||||
elem.setAttribute('value', value)
|
||||
|
||||
def addList(self, options, name=None, value=None, style=set()):
|
||||
"""Add a list of choices"""
|
||||
styles = set(style)
|
||||
|
|
@ -253,6 +261,10 @@ class XMLUI:
|
|||
self.addPassword(name, value)
|
||||
elif type == 'textbox':
|
||||
self.addTextBox(name, value)
|
||||
elif type == 'bool':
|
||||
if not value:
|
||||
value = "true"
|
||||
self.addBool(name, value)
|
||||
elif type == 'list':
|
||||
self.addList(options, name, value)
|
||||
elif type == 'button':
|
||||
|
|
@ -267,7 +279,7 @@ class XMLUI:
|
|||
opt.setAttribute('value', option)
|
||||
parent.appendChild(opt)
|
||||
|
||||
def addCategory(self, name, layout):
|
||||
def addCategory(self, name, layout, label=None):
|
||||
"""Add a category to current layout (must be a tabs layout)"""
|
||||
assert(layout != 'tabs')
|
||||
if not self.parentTabsLayout:
|
||||
|
|
@ -276,8 +288,12 @@ class XMLUI:
|
|||
if self.parentTabsLayout.getAttribute('type') != 'tabs':
|
||||
error(_("parent layout of a category is not tabs"))
|
||||
assert(False)
|
||||
|
||||
if not label:
|
||||
label = name
|
||||
self.currentCategory = cat = self.doc.createElement('category')
|
||||
cat.setAttribute('name', name)
|
||||
cat.setAttribute('label', label)
|
||||
self.changeLayout(layout)
|
||||
self.parentTabsLayout.appendChild(cat)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue