Mercurial > libervia-backend
view frontends/src/wix/xmlui.py @ 1198:16ce9a6580a3
misc (install): Lower default setuptools version
From 0d607b6ed49eab758fd9b272e148f032e65fb2e2 Mon Sep 17 00:00:00 2001
python-setuptools 5.7 is not yet in Debian, so we need to set the
default version to 5.5 (the current version in sid) to avoid the newer
version to be downloaded from pypi.
author | Matteo Cypriani <mcy@lm7.fr> |
---|---|
date | Tue, 09 Sep 2014 22:09:51 -0400 |
parents | e2e1e27a3680 |
children | f91e7028e2c3 |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- # wix: a SAT frontend # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from sat.core.i18n import _ import wx from sat.core.log import getLogger log = getLogger(__name__) from sat_frontends.tools import xmlui from sat_frontends.constants import Const as C class EventWidget(object): """ Used to manage change event of widgets """ def _xmluiOnChange(self, callback): """ Call callback with widget as only argument """ def change_cb(event): callback(self) self.Bind(self._xmlui_change_event, change_cb) class WixWidget(object): _xmlui_proportion = 0 class ValueWidget(WixWidget): def _xmluiSetValue(self, value): self.SetValue(value) def _xmluiGetValue(self): return self.GetValue() class EmptyWidget(WixWidget, xmlui.EmptyWidget, wx.Window): def __init__(self, _xmlui_parent): wx.Window.__init__(self, _xmlui_parent, -1) class TextWidget(WixWidget, xmlui.TextWidget, wx.StaticText): def __init__(self, _xmlui_parent, value): wx.StaticText.__init__(self, _xmlui_parent, -1, value) class LabelWidget(xmlui.LabelWidget, TextWidget): def __init__(self, _xmlui_parent, value): super(LabelWidget, self).__init__(_xmlui_parent, value+": ") class JidWidget(xmlui.JidWidget, TextWidget): pass class DividerWidget(WixWidget, xmlui.DividerWidget, wx.StaticLine): def __init__(self, _xmlui_parent, style='line'): wx.StaticLine.__init__(self, _xmlui_parent, -1) class StringWidget(EventWidget, ValueWidget, xmlui.StringWidget, wx.TextCtrl): _xmlui_change_event = wx.EVT_TEXT def __init__(self, _xmlui_parent, value, read_only=False): style = wx.TE_READONLY if read_only else 0 wx.TextCtrl.__init__(self, _xmlui_parent, -1, value, style=style) self._xmlui_proportion = 1 class PasswordWidget(EventWidget, ValueWidget, xmlui.PasswordWidget, wx.TextCtrl): _xmlui_change_event = wx.EVT_TEXT def __init__(self, _xmlui_parent, value, read_only=False): style = wx.TE_PASSWORD if read_only: style |= wx.TE_READONLY wx.TextCtrl.__init__(self, _xmlui_parent, -1, value, style=style) self._xmlui_proportion = 1 class TextBoxWidget(EventWidget, ValueWidget, xmlui.TextBoxWidget, wx.TextCtrl): _xmlui_change_event = wx.EVT_TEXT def __init__(self, _xmlui_parent, value, read_only=False): style = wx.TE_MULTILINE if read_only: style |= wx.TE_READONLY wx.TextCtrl.__init__(self, _xmlui_parent, -1, value, style=style) self._xmlui_proportion = 1 class BoolWidget(EventWidget, ValueWidget, xmlui.BoolWidget, wx.CheckBox): _xmlui_change_event = wx.EVT_CHECKBOX def __init__(self, _xmlui_parent, state, read_only=False): style = wx.CHK_2STATE if read_only: style |= wx.TE_READONLY wx.CheckBox.__init__(self, _xmlui_parent, -1, "", style=wx.CHK_2STATE) self.SetValue(state) self._xmlui_proportion = 1 def _xmluiSetValue(self, value): self.SetValue(value == 'true') def _xmluiGetValue(self): return "true" if self.GetValue() else "false" class ButtonWidget(EventWidget, WixWidget, xmlui.ButtonWidget, wx.Button): _xmlui_change_event = wx.EVT_BUTTON def __init__(self, _xmlui_parent, value, click_callback): wx.Button.__init__(self, _xmlui_parent, -1, value) self._xmlui_click_callback = click_callback _xmlui_parent.Bind(wx.EVT_BUTTON, lambda evt: click_callback(evt.GetEventObject()), self) self._xmlui_parent = _xmlui_parent def _xmluiOnClick(self, callback): self._xmlui_parent.Bind(wx.EVT_BUTTON, lambda evt: callback(evt.GetEventObject()), self) class ListWidget(EventWidget, WixWidget, xmlui.ListWidget, wx.ListBox): _xmlui_change_event = wx.EVT_LISTBOX def __init__(self, _xmlui_parent, options, selected, flags): styles = wx.LB_MULTIPLE if not 'single' in flags else wx.LB_SINGLE wx.ListBox.__init__(self, _xmlui_parent, -1, choices=[option[1] for option in options], style=styles) self._xmlui_attr_map = {label: value for value, label in options} self._xmlui_proportion = 1 self._xmluiSelectValues(selected) def _xmluiSelectValue(self, value): try: label = [label for label, _value in self._xmlui_attr_map.items() if _value == value][0] except IndexError: log.warning(_("Can't find value [%s] to select" % value)) return for idx in xrange(self.GetCount()): self.SetSelection(idx, self.GetString(idx) == label) def _xmluiSelectValues(self, values): labels = [label for label, _value in self._xmlui_attr_map.items() if _value in values] for idx in xrange(self.GetCount()): self.SetSelection(idx, self.GetString(idx) in labels) def _xmluiGetSelectedValues(self): ret = [] labels = [self.GetString(idx) for idx in self.GetSelections()] for label in labels: ret.append(self._xmlui_attr_map[label]) return ret def _xmluiAddValues(self, values, select=True): selected = self._xmluiGetSelectedValues() for value in values: if value not in self._xmlui_attr_map.values(): wx.ListBox.Append(self, value) self._xmlui_attr_map[value] = value if value not in selected: selected.append(value) self._xmluiSelectValues(selected) class WixContainer(object): _xmlui_proportion = 1 def _xmluiAppend(self, widget): self.sizer.Add(widget, self._xmlui_proportion, flag=wx.EXPAND) class AdvancedListContainer(WixContainer, xmlui.AdvancedListContainer, wx.ScrolledWindow): def __init__(self, _xmlui_parent, columns, selectable='no'): wx.ScrolledWindow.__init__(self, _xmlui_parent) self._xmlui_selectable = selectable != 'no' if selectable: columns += 1 self.sizer = wx.FlexGridSizer(cols=columns) self.SetSizer(self.sizer) self._xmlui_select_cb = None self._xmlui_select_idx = None self._xmlui_select_widgets = [] def _xmluiAddRow(self, idx): # XXX: select_button is a Q&D way to implement row selection # FIXME: must be done properly if not self._xmlui_selectable: return select_button = wx.Button(self, wx.ID_OK, label=_("select")) self.sizer.Add(select_button) def click_cb(event, idx=idx): cb = self._xmlui_select_cb self._xmlui_select_idx = idx # TODO: fill self._xmlui_select_widgets if cb is not None: cb(self) event.Skip() self.Bind(wx.EVT_BUTTON, click_cb) def _xmluiGetSelectedWidgets(self): return self._xmlui_select_widgets def _xmluiGetSelectedIndex(self): return self._xmlui_select_idx def _xmluiOnSelect(self, callback): self._xmlui_select_cb = callback class PairsContainer(WixContainer, xmlui.PairsContainer, wx.Panel): def __init__(self, _xmlui_parent): wx.Panel.__init__(self, _xmlui_parent) self.sizer = wx.FlexGridSizer(cols=2) self.sizer.AddGrowableCol(1) #The growable column need most of time to be the right one in pairs self.SetSizer(self.sizer) class TabsContainer(WixContainer, xmlui.TabsContainer, wx.Notebook): def __init__(self, _xmlui_parent): wx.Notebook.__init__(self, _xmlui_parent, -1, style=wx.NB_LEFT if self._xmlui_main.type=='param' else 0) def _xmluiAddTab(self, label): tab_panel = wx.Panel(self, -1) tab_panel.sizer = wx.BoxSizer(wx.VERTICAL) tab_panel.SetSizer(tab_panel.sizer) self.AddPage(tab_panel, label) VerticalContainer._xmluiAdapt(tab_panel) return tab_panel class VerticalContainer(WixContainer, xmlui.VerticalContainer, wx.Panel): def __init__(self, _xmlui_parent): wx.Panel.__init__(self, _xmlui_parent) self.sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.sizer) ## Dialogs ## class WixDialog(object): def __init__(self, _xmlui_parent, level): self.host = _xmlui_parent.host self.ok_cb = None self.cancel_cb = None if level == C.XMLUI_DATA_LVL_INFO: self.flags = wx.ICON_INFORMATION elif level == C.XMLUI_DATA_LVL_ERROR: self.flags = wx.ICON_ERROR else: self.flags = wx.ICON_INFORMATION log.warning(_("Unmanaged dialog level: %s") % level) def _xmluiShow(self): answer = self.ShowModal() if answer == wx.ID_YES or answer == wx.ID_OK: self._xmluiValidated() else: self._xmluiCancelled() def _xmluiClose(self): self.Destroy() class MessageDialog(WixDialog, xmlui.MessageDialog, wx.MessageDialog): def __init__(self, _xmlui_parent, title, message, level): WixDialog.__init__(self, _xmlui_parent, level) xmlui.MessageDialog.__init__(self, _xmlui_parent) self.flags |= wx.OK wx.MessageDialog.__init__(self, _xmlui_parent.host, message, title, style = self.flags) class NoteDialog(xmlui.NoteDialog, MessageDialog): # TODO: separate NoteDialog pass class ConfirmDialog(WixDialog, xmlui.ConfirmDialog, wx.MessageDialog): def __init__(self, _xmlui_parent, title, message, level, buttons_set): WixDialog.__init__(self, _xmlui_parent, level) xmlui.ConfirmDialog.__init__(self, _xmlui_parent) if buttons_set == C.XMLUI_DATA_BTNS_SET_YESNO: self.flags |= wx.YES_NO else: self.flags |= wx.OK | wx.CANCEL wx.MessageDialog.__init__(self, _xmlui_parent.host, message, title, style = self.flags) class FileDialog(WixDialog, xmlui.FileDialog, wx.FileDialog): def __init__(self, _xmlui_parent, title, message, level, filetype): # TODO: message and filetype are not managed yet WixDialog.__init__(self, _xmlui_parent, level) self.flags = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT # FIXME: use the legacy flags, but must manage cases like dir or open xmlui.FileDialog.__init__(self, _xmlui_parent) wx.FileDialog.__init__(self, _xmlui_parent.host, title, style = self.flags) def _xmluiShow(self): answer = self.ShowModal() if answer == wx.ID_OK: self._xmluiValidated({'path': self.GetPath()}) else: self._xmluiCancelled() class GenericFactory(object): def __getattr__(self, attr): if attr.startswith("create"): cls = globals()[attr[6:]] return cls class WidgetFactory(GenericFactory): def __getattr__(self, attr): if attr.startswith("create"): cls = GenericFactory.__getattr__(self, attr) cls._xmlui_main = self._xmlui_main return cls class XMLUIPanel(xmlui.XMLUIPanel, wx.Frame): """Create an user interface from a SàT XML""" widget_factory = WidgetFactory() def __init__(self, host, parsed_xml, title=None, flags = None,): self.widget_factory._xmlui_main = self xmlui.XMLUIPanel.__init__(self, host, parsed_xml, title, flags) def constructUI(self, parsed_dom): style = wx.DEFAULT_FRAME_STYLE & ~wx.CLOSE_BOX if 'NO_CANCEL' in self.flags else wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, None, style=style) self.sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.sizer) def postTreat(): if self.title: self.SetTitle(self.title) if self.type == 'form': dialogButtons = wx.StdDialogButtonSizer() submitButton = wx.Button(self.main_cont,wx.ID_OK, label=_("Submit")) dialogButtons.AddButton(submitButton) self.main_cont.Bind(wx.EVT_BUTTON, self.onFormSubmitted, submitButton) if not 'NO_CANCEL' in self.flags: cancelButton = wx.Button(self.main_cont,wx.ID_CANCEL) dialogButtons.AddButton(cancelButton) self.main_cont.Bind(wx.EVT_BUTTON, self.onFormCancelled, cancelButton) dialogButtons.Realize() self.main_cont.sizer.Add(dialogButtons, flag=wx.ALIGN_CENTER_HORIZONTAL) self.sizer.Add(self.main_cont, 1, flag=wx.EXPAND) self.sizer.Fit(self) self.Show() super(XMLUIPanel, self).constructUI(parsed_dom, postTreat) if not 'NO_CANCEL' in self.flags: self.Bind(wx.EVT_CLOSE, self.onClose, self) self.MakeModal() def _xmluiClose(self): self.MakeModal(False) self.Destroy() ###events def onParamChange(self, ctrl): super(XMLUIPanel, self).onParamChange(ctrl) def onFormSubmitted(self, event): """Called when submit button is clicked""" button = event.GetEventObject() super(XMLUIPanel, self).onFormSubmitted(button) def onClose(self, event): """Close event: we have to send the form.""" log.debug(_("close")) if self.type == 'param': self.onSaveParams() else: self._xmluiClose() event.Skip() class XMLUIDialog(xmlui.XMLUIDialog): dialog_factory = WidgetFactory() xmlui.registerClass(xmlui.CLASS_PANEL, XMLUIPanel) xmlui.registerClass(xmlui.CLASS_DIALOG, XMLUIDialog) create = xmlui.create