#------------------------------------------------------------------------------
# Copyright (c) 2013, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
#------------------------------------------------------------------------------
from atom.api import (
Bool, Int, Str, Enum, List, Typed, ForwardTyped, set_default
)
from enaml.core.declarative import d_, observe
from enaml.validator import Validator
from .control import Control, ProxyControl
class ProxyField(ProxyControl):
""" The abstract definition of a proxy Field object.
"""
#: A reference to the Field declaration.
declaration = ForwardTyped(lambda: Field)
def set_text(self, text):
raise NotImplementedError
def set_mask(self, mask):
raise NotImplementedError
def set_submit_triggers(self, triggers):
raise NotImplementedError
def set_sync_time(self, time):
raise NotImplementedError
def set_placeholder(self, placeholder):
raise NotImplementedError
def set_echo_mode(self, mode):
raise NotImplementedError
def set_max_length(self, length):
raise NotImplementedError
def set_read_only(self, read_only):
raise NotImplementedError
def set_text_align(self, text_align):
raise NotImplementedError
def field_text(self):
raise NotImplementedError
[docs]
class Field(Control):
""" A single line editable text widget.
"""
#: The unicode text to display in the field.
text = d_(Str())
#: The mask to use for text input
#: http://qt-project.org/doc/qt-4.8/qlineedit.html#inputMask-prop
#:
#: The summary of the mask grammar is as follows:
#: A ASCII alphabetic character required. A-Z, a-z.
#: a ASCII alphabetic character permitted but not required.
#: N ASCII alphanumeric character required. A-Z, a-z, 0-9.
#: n ASCII alphanumeric character permitted but not required.
#: X Any character required.
#: x Any character permitted but not required.
#: 9 ASCII digit required. 0-9.
#: 0 ASCII digit permitted but not required.
#: D ASCII digit required. 1-9.
#: d ASCII digit permitted but not required (1-9).
#: # ASCII digit or plus/minus sign permitted but not required.
#: H Hexadecimal character required. A-F, a-f, 0-9.
#: h Hexadecimal character permitted but not required.
#: B Binary character required. 0-1.
#: b Binary character permitted but not required.
#: > All following alphabetic characters are uppercased.
#: < All following alphabetic characters are lowercased.
#: ! Switch off case conversion.
#: \ Use \ to escape the special characters listed above to use them as separators.
#:
#: The mask consists of a string of mask characters and separators, optionally
#: followed by a semicolon and the character used for blanks
#: Eg: 9 digit phone number: (999) 999-9999;_
mask = d_(Str())
#: The validator to use for this field. If the validator provides
#: a client side validator, then text will only be submitted if it
#: passes that validator.
validator = d_(Typed(Validator))
#: The list of actions which should cause the client to submit its
#: text to the server for validation and update. The currently
#: supported values are 'lost_focus', 'return_pressed', and 'auto_sync'.
#: The 'auto_sync' mode will attempt to validate and synchronize the
#: text when the user stops typing.
submit_triggers = d_(List(
Enum('lost_focus', 'return_pressed', 'auto_sync'),
['lost_focus', 'return_pressed']
))
#: Time in ms after which the client submit its text to the server for
#: validation and update when the user stop typing. This is used only when
#: the 'auto_sync' mode is part of the submit_triggers.
sync_time = d_(Int(300))
#: The grayed-out text to display if the field is empty and the
#: widget doesn't have focus. Defaults to the empty string.
placeholder = d_(Str())
#: How to display the text in the field. Valid values are 'normal'
#: which displays the text as normal, 'password' which displays the
#: text with an obscured character, and 'silent' which displays no
#: text at all but still allows input.
echo_mode = d_(Enum('normal', 'password', 'silent'))
#: The maximum length of the field in characters. The default value
#: is Zero and indicates there is no maximum length.
max_length = d_(Int(0))
#: Whether or not the field is read only. Defaults to False.
read_only = d_(Bool(False))
#: Alignment for the text inside the field. Defaults to 'left'.
text_align = d_(Enum('left', 'right', 'center'))
#: How strongly a component hugs it's contents' width. Fields ignore
#: the width hug by default, so they expand freely in width.
hug_width = set_default('ignore')
#: A reference to the ProxyField object.
proxy = Typed(ProxyField)
#--------------------------------------------------------------------------
# Observers
#--------------------------------------------------------------------------
@observe('text', 'mask', 'submit_triggers', 'placeholder', 'echo_mode',
'max_length', 'read_only', 'text_align', 'sync_time')
def _update_proxy(self, change):
""" An observer which sends state change to the proxy.
"""
# The superclass implementation is sufficient.
super(Field, self)._update_proxy(change)
#--------------------------------------------------------------------------
# Public API
#--------------------------------------------------------------------------
[docs]
def field_text(self):
""" Get the text stored in the field control.
Depending on the state of the field, this text may be different
than that stored in the 'text' attribute.
Returns
-------
result : unicode
The unicode text stored in the field.
"""
if self.proxy_is_active:
return self.proxy.field_text()
return ''