core (XMLUI): Dialogs are now managemed in XMLUI:
- currents dialogs are available:
- Message: a classical informational/error message, usually a popup that user has to close after reading
- Note: more discreet message, usually a notification with a timeout (user don't need to close manually)
- Confirm: a Ok/Cancel or Yes/No dialog
- File: a dialog to get a file or dir path
- dialog_opt parameter is used to customise dialogs
- submit_id is used in a similar way as for forms
This commit is contained in:
parent
8e66a4b736
commit
38efb8b0bd
1 changed files with 114 additions and 10 deletions
|
|
@ -18,6 +18,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sat.core.i18n import _
|
||||
from sat.core.constants import Const as C
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from xml.dom import minidom, NotFoundErr
|
||||
|
|
@ -740,8 +741,8 @@ class ListWidget(InputWidget):
|
|||
|
||||
@param xmlui
|
||||
@param options (list[string, tuple]): each option can be given as:
|
||||
- a string if the label and the value are the same
|
||||
- a couple if the label and the value differ
|
||||
- a string if the label and the value are the same
|
||||
- a couple if the label and the value differ
|
||||
@param selected (list[string]): list of the selected values
|
||||
@param style (string)
|
||||
@param name (string)
|
||||
|
|
@ -772,35 +773,108 @@ class ListWidget(InputWidget):
|
|||
OptionElement(self, option, value in selected)
|
||||
|
||||
|
||||
## Dialog Elements ##
|
||||
|
||||
|
||||
class DialogElement(Element):
|
||||
"""Main dialog element """
|
||||
type = 'dialog'
|
||||
|
||||
def __init__(self, parent, type_, level=None):
|
||||
if not isinstance(parent, TopElement):
|
||||
raise exceptions.DataError(_("DialogElement must be a direct child of TopElement"))
|
||||
super(DialogElement, self).__init__(parent.xmlui, parent)
|
||||
self.elem.setAttribute(C.XMLUI_DATA_TYPE, type_)
|
||||
self.elem.setAttribute(C.XMLUI_DATA_LVL, level or C.XMLUI_DATA_LVL_DEFAULT)
|
||||
|
||||
|
||||
class MessageElement(Element):
|
||||
"""Element with the instruction message"""
|
||||
type = C.XMLUI_DATA_MESS
|
||||
|
||||
def __init__(self, parent, message):
|
||||
if not isinstance(parent, DialogElement):
|
||||
raise exceptions.DataError(_("MessageElement must be a direct child of DialogElement"))
|
||||
super(MessageElement, self).__init__(parent.xmlui, parent)
|
||||
message_txt = self.xmlui.doc.createTextNode(message)
|
||||
self.elem.appendChild(message_txt)
|
||||
|
||||
|
||||
class ButtonsElement(Element):
|
||||
"""Buttons element which indicate which set to use"""
|
||||
type = 'buttons'
|
||||
|
||||
def __init__(self, parent, set_):
|
||||
if not isinstance(parent, DialogElement):
|
||||
raise exceptions.DataError(_("ButtonsElement must be a direct child of DialogElement"))
|
||||
super(ButtonsElement, self).__init__(parent.xmlui, parent)
|
||||
self.elem.setAttribute('set', set_)
|
||||
|
||||
|
||||
class FileElement(Element):
|
||||
"""File element used for FileDialog"""
|
||||
type = 'file'
|
||||
|
||||
def __init__(self, parent, type_):
|
||||
if not isinstance(parent, DialogElement):
|
||||
raise exceptions.DataError(_("FileElement must be a direct child of DialogElement"))
|
||||
super(FileElement, self).__init__(parent.xmlui, parent)
|
||||
self.elem.setAttribute('type', type_)
|
||||
|
||||
|
||||
## XMLUI main class
|
||||
|
||||
|
||||
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="window", container="vertical", title=None, submit_id=None, session_id=None):
|
||||
def __init__(self, panel_type="window", container="vertical", dialog_opt=None, title=None, submit_id=None, session_id=None):
|
||||
"""Init SàT XML Panel
|
||||
|
||||
@param panel_type: one of
|
||||
- window (new window)
|
||||
- popup
|
||||
- form (formulaire, depend of the frontend, usually a panel with cancel/submit buttons)
|
||||
- param (parameters, presentation depend of the frontend)
|
||||
- C.XMLUI_WINDOW (new window)
|
||||
- C.XMLUI_POPUP
|
||||
- C.XMLUI_FORM (formulaire, depend of the frontend, usually a panel with cancel/submit buttons)
|
||||
- C.XMLUI_PARAM (parameters, presentation depend of the frontend)
|
||||
- C.XMLUI_DIALOG (one common dialog, presentation depend of frontend)
|
||||
@param container: disposition of elements, one of:
|
||||
- vertical: elements are disposed up to bottom
|
||||
- horizontal: elements are disposed left to right
|
||||
- pairs: elements come on two aligned columns
|
||||
(usually one for a label, the next for the element)
|
||||
- tabs: elemens are in categories with tabs (notebook)
|
||||
@param dialog_opt: only used if panel_type == C.XMLUI_DIALOG. Dictionnary (string/string) where key can be:
|
||||
- C.XMLUI_DATA_TYPE: type of dialog, value can be:
|
||||
- C.XMLUI_DIALOG_MESSAGE (default): an information/error message. Action of user is necessary to close the dialog. Usually the frontend display a classic popup
|
||||
- C.XMLUI_DIALOG_NOTE: like a C.XMLUI_DIALOG_MESSAGE, but action of user is not necessary to close, at frontend choice (it can be closed after a timeout). Usually the frontend display as a timed out notification
|
||||
- C.XMLUI_DIALOG_CONFIRM: dialog with 2 choices (usualy "Ok"/"Cancel").
|
||||
returned data can contain:
|
||||
- "answer": "true" if answer is "ok", "yes" or equivalent, "false" else
|
||||
- C.XLMUI_DIALOG_FILE: a file selection dialog
|
||||
returned data can contain:
|
||||
- "cancelled": "true" if dialog has been cancelled, not present or "false" else
|
||||
- "path": path of the choosed file/dir
|
||||
- C.XMLUI_DATA_MESS: message shown in dialog
|
||||
- C.XMLUI_DATA_LVL: one of:
|
||||
- C.XMLUI_DATA_LVL_INFO (default): normal message
|
||||
- C.XMLUI_DATA_LVL_WARNING: attention of user is important
|
||||
- C.XMLUI_DATA_LVL_ERROR: something went wrong
|
||||
- C.XMLUI_DATA_BTNS_SET: one of:
|
||||
- C.XMLUI_DATA_BTNS_SET_OKCANCEL (default): classical "OK" and "Cancel" set
|
||||
- C.XMLUI_DATA_BTNS_SET_YESNO: a translated "yes" for OK, and "no" for Cancel
|
||||
@param title: title or default if None
|
||||
@param submit_id: callback id to call for panel_type we can submit (form, param)
|
||||
@param submit_id: callback id to call for panel_type we can submit (form, param, dialog)
|
||||
@param session_id: use to keep a session attached to the dialog, must be returned by frontends
|
||||
"""
|
||||
self._introspect()
|
||||
if panel_type not in ['window', 'form', 'param', 'popup']:
|
||||
if panel_type not in [C.XMLUI_WINDOW, C.XMLUI_FORM, C.XMLUI_PARAM, C.XMLUI_POPUP, C.XMLUI_DIALOG]:
|
||||
raise exceptions.DataError(_("Unknown panel type [%s]") % panel_type)
|
||||
if panel_type == 'form' and submit_id is None:
|
||||
if panel_type == C.XMLUI_FORM and submit_id is None:
|
||||
raise exceptions.DataError(_("form XMLUI need a submit_id"))
|
||||
if not isinstance(container, basestring):
|
||||
raise exceptions.DataError(_("container argument must be a string"))
|
||||
if dialog_opt is not None and panel_type != C.XMLUI_DIALOG:
|
||||
raise exceptions.DataError(_("dialog_opt can only be used with dialog panels"))
|
||||
self.type = panel_type
|
||||
impl = minidom.getDOMImplementation()
|
||||
|
||||
|
|
@ -811,6 +885,11 @@ class XMLUI(object):
|
|||
top_element.setAttribute("title", title)
|
||||
self.submit_id = submit_id
|
||||
self.session_id = session_id
|
||||
if panel_type == C.XMLUI_DIALOG:
|
||||
if dialog_opt is None:
|
||||
dialog_opt = {}
|
||||
self._createDialog(dialog_opt)
|
||||
return
|
||||
self.main_container = self._createContainer(container, TopElement(self))
|
||||
self.current_container = self.main_container
|
||||
|
||||
|
|
@ -836,6 +915,8 @@ class XMLUI(object):
|
|||
|
||||
def __getattr__(self, name):
|
||||
if name.startswith("add") and name not in ('addWidget',): # addWidgetName(...) create an instance of WidgetName
|
||||
if self.type == C.XMLUI_DIALOG:
|
||||
raise exceptions.InternalError(_("addXXX can't be used with dialogs"))
|
||||
class_name = name[3:]+"Widget"
|
||||
if class_name in globals():
|
||||
cls = globals()[class_name]
|
||||
|
|
@ -886,6 +967,29 @@ class XMLUI(object):
|
|||
else:
|
||||
raise exceptions.DataError("session_id can't be empty")
|
||||
|
||||
def _createDialog(self, dialog_opt):
|
||||
dialog_type = dialog_opt.setdefault(C.XMLUI_DATA_TYPE, C.XMLUI_DIALOG_MESSAGE)
|
||||
if dialog_type in [C.XMLUI_DIALOG_CONFIRM, C.XMLUI_DIALOG_FILE] and self.submit_id is None:
|
||||
raise exceptions.InternalError(_("Submit ID must be filled for this kind of dialog"))
|
||||
top_element = TopElement(self)
|
||||
level = dialog_opt.get(C.XMLUI_DATA_LVL)
|
||||
dialog_elt = DialogElement(top_element, dialog_type, level)
|
||||
|
||||
try:
|
||||
MessageElement(dialog_elt, dialog_opt[C.XMLUI_DATA_MESS])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
ButtonsElement(dialog_elt, dialog_opt[C.XMLUI_DATA_BTNS_SET])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
FileElement(dialog_elt, dialog_opt[C.XMLUI_DATA_FILETYPE])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def _createContainer(self, container, parent=None, **kwargs):
|
||||
"""Create a container element
|
||||
@param type: container type (cf init doc)
|
||||
|
|
|
|||
Loading…
Reference in a new issue