- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
676 lines
25 KiB
Python
676 lines
25 KiB
Python
"""
|
|
Android text.method 包 — KeyListener, MovementMethod, TransformationMethod 等
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import time
|
|
from typing import Any, Dict, List, Optional, Set, Tuple
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
from ..java.lang import RuntimeException
|
|
|
|
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
|
|
|
|
__all__ = [
|
|
"KeyListener",
|
|
"MetaKeyKeyListener",
|
|
"NumberKeyListener",
|
|
"DigitsKeyListener",
|
|
"TextKeyListener",
|
|
"MovementMethod",
|
|
"ArrowKeyMovementMethod",
|
|
"LinkMovementMethod",
|
|
"Touch",
|
|
"BaseMovementMethod",
|
|
"ScrollingMovementMethod",
|
|
"WordIterator",
|
|
"PasswordTransformationMethod",
|
|
"TransformationMethod",
|
|
"TransformationMethod2",
|
|
"SingleLineTransformationMethod",
|
|
"HideReturnsTransformationMethod",
|
|
"TimeDisplayTruncationMethod",
|
|
"DateTimeKeyListener",
|
|
"DateKeyListener",
|
|
"TimeKeyListener",
|
|
]
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# KeyListener
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class KeyListener(Stub):
|
|
"""KeyListener — 按键监听器接口 (桌面存根)"""
|
|
|
|
META_SHIFT_MASK = 0x1
|
|
META_ALT_MASK = 0x2
|
|
META_SYM_MASK = 0x4
|
|
META_CTRL_MASK = 0x1000
|
|
META_META_MASK = 0x10000
|
|
META_CAPS_LOCK = 0x100000
|
|
META_ALT_LOCK = 0x200000
|
|
META_SYM_LOCK = 0x400000
|
|
META_SELECTING = 0x800000
|
|
META_SHIFTING = 0x1000000
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._input_type = 0
|
|
self._meta_state = 0
|
|
|
|
def clearMetaKeyState(self, view: Any, content: Any, states: int) -> None:
|
|
"""清除元键状态"""
|
|
self._meta_state = self._meta_state & ~states
|
|
|
|
def getInputType(self) -> int:
|
|
"""获取输入类型"""
|
|
return self._input_type
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""按键按下事件"""
|
|
return False
|
|
|
|
def onKeyUp(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""按键释放事件"""
|
|
return False
|
|
|
|
def onKeyOther(self, view: Any, content: Any, event: Any) -> bool:
|
|
"""其他按键事件"""
|
|
return False
|
|
|
|
@staticmethod
|
|
def metaStateHasNoModifiers(metaState: int) -> bool:
|
|
"""检查元状态是否没有修饰键"""
|
|
return (metaState & 0x0000FFFF) == 0
|
|
|
|
@staticmethod
|
|
def metaStateHasModifiers(metaState: int, modifiers: int) -> bool:
|
|
"""检查元状态是否有指定修饰键"""
|
|
return (metaState & modifiers) != 0
|
|
|
|
@staticmethod
|
|
def metaStateFilterDirectionLocked(metaState: int) -> int:
|
|
"""过滤方向锁定"""
|
|
return metaState & ~(KeyListener.META_CAPS_LOCK | KeyListener.META_ALT_LOCK | KeyListener.META_SYM_LOCK)
|
|
|
|
def __repr__(self) -> str:
|
|
return f"KeyListener(inputType={self._input_type})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# MetaKeyKeyListener
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class MetaKeyKeyListener(KeyListener):
|
|
"""MetaKeyKeyListener — 元键按键监听器 (桌面存根)"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._locked_meta: Dict[int, int] = {}
|
|
|
|
def clearMetaKeyState(self, view: Any, content: Any, states: int) -> None:
|
|
"""清除元键状态"""
|
|
self._meta_state = self._meta_state & ~states
|
|
for state_bit in [KeyListener.META_CAPS_LOCK, KeyListener.META_ALT_LOCK, KeyListener.META_SYM_LOCK]:
|
|
if states & state_bit:
|
|
self._locked_meta.pop(state_bit, None)
|
|
|
|
@staticmethod
|
|
def resetMetaState(content: Any) -> None:
|
|
"""重置元状态"""
|
|
if hasattr(content, '_meta_state'):
|
|
content._meta_state = 0
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""按键按下事件处理"""
|
|
return super().onKeyDown(view, content, keyCode, event)
|
|
|
|
def onKeyUp(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""按键释放事件处理"""
|
|
return super().onKeyUp(view, content, keyCode, event)
|
|
|
|
@staticmethod
|
|
def adjustMetaAfterKeypress(content: Any) -> None:
|
|
"""按键后调整元状态"""
|
|
pass
|
|
|
|
def handleKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""处理按键按下 (内部)"""
|
|
return self.onKeyDown(view, content, keyCode, event)
|
|
|
|
def handleKeyUp(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""处理按键释放 (内部)"""
|
|
return self.onKeyUp(view, content, keyCode, event)
|
|
|
|
@staticmethod
|
|
def getMetaState(content: Any) -> int:
|
|
"""获取元状态"""
|
|
return getattr(content, '_meta_state', 0)
|
|
|
|
@staticmethod
|
|
def getMetaState_ex(content: Any, meta: int) -> bool:
|
|
"""检查特定元状态"""
|
|
state = getattr(content, '_meta_state', 0)
|
|
return (state & meta) != 0
|
|
|
|
@staticmethod
|
|
def isMetaTracker(content: Any) -> bool:
|
|
"""检查是否是元追踪器"""
|
|
return hasattr(content, '_meta_state')
|
|
|
|
@staticmethod
|
|
def isSelectingMetaTracker(content: Any) -> bool:
|
|
"""检查是否是选择元追踪器"""
|
|
return hasattr(content, '_meta_state') and (getattr(content, '_meta_state', 0) & KeyListener.META_SELECTING) != 0
|
|
|
|
@staticmethod
|
|
def peekMetaState(content: Any) -> int:
|
|
"""窥视元状态"""
|
|
return getattr(content, '_meta_state', 0)
|
|
|
|
def resetLockedMeta(self, content: Any) -> None:
|
|
"""重置锁定元键"""
|
|
self._locked_meta.clear()
|
|
|
|
def clearLockedMeta(self, content: Any) -> None:
|
|
"""清除锁定元键"""
|
|
self._locked_meta.clear()
|
|
|
|
@staticmethod
|
|
def releaseAllMetaKeys(content: Any) -> None:
|
|
"""释放所有元键"""
|
|
if hasattr(content, '_meta_state'):
|
|
content._meta_state = 0
|
|
|
|
def toString(self) -> str:
|
|
return f"MetaKeyKeyListener(metaState={self._meta_state}, locked={self._locked_meta})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# NumberKeyListener
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class NumberKeyListener(MetaKeyKeyListener):
|
|
"""NumberKeyListener — 数字按键监听器 (桌面存根)"""
|
|
|
|
_ACCEPTED_CHARS: str = ""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._input_type = 0x0002 # TYPE_CLASS_NUMBER
|
|
|
|
def getAcceptedChars(self) -> List[str]:
|
|
"""获取接受的字符列表"""
|
|
return list(self._ACCEPTED_CHARS)
|
|
|
|
def filter(self, source: str, start: int, end: int, dest: str, dstart: int, dend: int) -> str:
|
|
"""过滤输入,只保留接受的字符"""
|
|
result = ""
|
|
for i in range(start, end):
|
|
ch = source[i] if i < len(source) else ''
|
|
if ch in self._ACCEPTED_CHARS:
|
|
result += ch
|
|
return result if result != source[start:end] else ""
|
|
|
|
def lookup(self, key: int, event: Any) -> Optional[str]:
|
|
"""查找按键映射的字符"""
|
|
key_map = {
|
|
7: '0', 8: '1', 9: '2', 10: '3', 11: '4',
|
|
12: '5', 13: '6', 14: '7', 15: '8', 16: '9',
|
|
}
|
|
return key_map.get(key)
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""按键按下事件"""
|
|
char = self.lookup(keyCode, event)
|
|
if char and char in self._ACCEPTED_CHARS:
|
|
return True
|
|
return False
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# DigitsKeyListener
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class DigitsKeyListener(NumberKeyListener):
|
|
"""DigitsKeyListener — 数字按键监听器 (桌面存根)"""
|
|
|
|
_instances: Dict[str, "DigitsKeyListener"] = {}
|
|
|
|
def __init__(self, accepted: str = "0123456789"):
|
|
super().__init__()
|
|
self._ACCEPTED_CHARS = accepted
|
|
self._input_type = 0x0002
|
|
|
|
@staticmethod
|
|
def getInstance(locale: Any = None, sign: bool = False, decimal: bool = False) -> "DigitsKeyListener":
|
|
"""获取实例"""
|
|
key = f"{locale}_{sign}_{decimal}"
|
|
if key not in DigitsKeyListener._instances:
|
|
accepted = "0123456789"
|
|
if sign:
|
|
accepted += "-"
|
|
if decimal:
|
|
accepted += "."
|
|
DigitsKeyListener._instances[key] = DigitsKeyListener(accepted)
|
|
return DigitsKeyListener._instances[key]
|
|
|
|
def getAcceptedChars(self) -> List[str]:
|
|
return list(self._ACCEPTED_CHARS)
|
|
|
|
def filter(self, source: str, start: int, end: int, dest: str, dstart: int, dend: int) -> str:
|
|
return super().filter(source, start, end, dest, dstart, dend)
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# TextKeyListener
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class TextKeyListener(MetaKeyKeyListener):
|
|
"""TextKeyListener — 文本按键监听器 (桌面存根)"""
|
|
|
|
CAP_MODE_CHARACTERS = 0x1
|
|
CAP_MODE_WORDS = 0x2
|
|
CAP_MODE_SENTENCES = 0x4
|
|
|
|
_instance: Optional["TextKeyListener"] = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._input_type = 0x0001 # TYPE_CLASS_TEXT
|
|
self._auto_cap_mode = 0
|
|
|
|
@staticmethod
|
|
def getInstance() -> "TextKeyListener":
|
|
"""获取单例实例"""
|
|
if TextKeyListener._instance is None:
|
|
TextKeyListener._instance = TextKeyListener()
|
|
return TextKeyListener._instance
|
|
|
|
def clear(self, view: Any, content: Any) -> None:
|
|
"""清除内容"""
|
|
if hasattr(content, 'clear'):
|
|
content.clear()
|
|
|
|
def release(self, view: Any) -> None:
|
|
"""释放资源"""
|
|
pass
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
return True
|
|
|
|
def onKeyUp(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
return True
|
|
|
|
def toString(self) -> str:
|
|
return f"TextKeyListener(capMode={self._auto_cap_mode})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# MovementMethod
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class MovementMethod(Stub):
|
|
"""MovementMethod — 移动方法接口 (桌面存根)"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._movement_meta_state = 0
|
|
|
|
def initialize(self, view: Any, content: Any) -> None:
|
|
"""初始化"""
|
|
pass
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""按键按下"""
|
|
return False
|
|
|
|
def onKeyUp(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
"""按键释放"""
|
|
return False
|
|
|
|
def onTakeFocus(self, view: Any, content: Any, direction: int) -> bool:
|
|
"""获取焦点"""
|
|
return False
|
|
|
|
def canSelectArbitrarily(self) -> bool:
|
|
"""能否任意选择"""
|
|
return False
|
|
|
|
def dispatchTouchEvent(self, view: Any, content: Any, event: Any) -> bool:
|
|
"""分发触摸事件"""
|
|
return False
|
|
|
|
def onGenericMotionEvent(self, view: Any, content: Any, event: Any) -> bool:
|
|
"""通用运动事件"""
|
|
return False
|
|
|
|
def getMovementMetaState(self) -> int:
|
|
"""获取移动元状态"""
|
|
return self._movement_meta_state
|
|
|
|
def setMovementMetaState(self, state: int) -> None:
|
|
"""设置移动元状态"""
|
|
self._movement_meta_state = state
|
|
|
|
def toString(self) -> str:
|
|
return f"{self.__class__.__name__}@MovementMethod"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ArrowKeyMovementMethod
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ArrowKeyMovementMethod(MovementMethod):
|
|
"""ArrowKeyMovementMethod — 箭头键移动方法 (桌面存根)"""
|
|
|
|
_instance: Optional["ArrowKeyMovementMethod"] = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
@staticmethod
|
|
def getInstance() -> "ArrowKeyMovementMethod":
|
|
if ArrowKeyMovementMethod._instance is None:
|
|
ArrowKeyMovementMethod._instance = ArrowKeyMovementMethod()
|
|
return ArrowKeyMovementMethod._instance
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
return True
|
|
|
|
def canSelectArbitrarily(self) -> bool:
|
|
return True
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# LinkMovementMethod
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class LinkMovementMethod(MovementMethod):
|
|
"""LinkMovementMethod — 链接移动方法 (桌面存根)"""
|
|
|
|
_instance: Optional["LinkMovementMethod"] = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
@staticmethod
|
|
def getInstance() -> "LinkMovementMethod":
|
|
if LinkMovementMethod._instance is None:
|
|
LinkMovementMethod._instance = LinkMovementMethod()
|
|
return LinkMovementMethod._instance
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
return True
|
|
|
|
def canSelectArbitrarily(self) -> bool:
|
|
return False
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# Touch
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class Touch(Stub):
|
|
"""Touch — 触摸工具类 (桌面存根)"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._initial_scroll_x = 0
|
|
self._initial_scroll_y = 0
|
|
|
|
@staticmethod
|
|
def getInitialScrollX(widget: Any, content: Any) -> int:
|
|
"""获取初始滚动 X"""
|
|
return getattr(widget, '_initial_scroll_x', 0)
|
|
|
|
@staticmethod
|
|
def getInitialScrollY(widget: Any, content: Any) -> int:
|
|
"""获取初始滚动 Y"""
|
|
return getattr(widget, '_initial_scroll_y', 0)
|
|
|
|
@staticmethod
|
|
def scrollTo(widget: Any, content: Any, x: int, y: int) -> None:
|
|
"""滚动到指定位置"""
|
|
if hasattr(widget, '_scroll_x'):
|
|
widget._scroll_x = x
|
|
if hasattr(widget, '_scroll_y'):
|
|
widget._scroll_y = y
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# BaseMovementMethod
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class BaseMovementMethod(MovementMethod):
|
|
"""BaseMovementMethod — 基本移动方法 (桌面存根)"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
return False
|
|
|
|
def canSelectArbitrarily(self) -> bool:
|
|
return False
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ScrollingMovementMethod
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ScrollingMovementMethod(BaseMovementMethod):
|
|
"""ScrollingMovementMethod — 滚动移动方法 (桌面存根)"""
|
|
|
|
_instance: Optional["ScrollingMovementMethod"] = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
@staticmethod
|
|
def getInstance() -> "ScrollingMovementMethod":
|
|
if ScrollingMovementMethod._instance is None:
|
|
ScrollingMovementMethod._instance = ScrollingMovementMethod()
|
|
return ScrollingMovementMethod._instance
|
|
|
|
def onKeyDown(self, view: Any, content: Any, keyCode: int, event: Any) -> bool:
|
|
return True
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# WordIterator
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class WordIterator(Stub):
|
|
"""WordIterator — 单词迭代器 (桌面存根)"""
|
|
|
|
def __init__(self, locale: Optional[Any] = None):
|
|
super().__init__()
|
|
self._locale = locale
|
|
self._text = ""
|
|
self._cursor = 0
|
|
|
|
def setText(self, text: str, start: int, end: int) -> None:
|
|
"""设置文本"""
|
|
self._text = text[start:end] if end <= len(text) else text[start:]
|
|
self._cursor = 0
|
|
|
|
def next(self) -> int:
|
|
"""下一个单词边界"""
|
|
self._cursor += 1
|
|
return self._cursor
|
|
|
|
def prev(self) -> int:
|
|
"""上一个单词边界"""
|
|
self._cursor -= 1
|
|
return max(self._cursor, 0)
|
|
|
|
def getEnd(self) -> int:
|
|
"""获取结束位置"""
|
|
return len(self._text)
|
|
|
|
def getBegin(self) -> int:
|
|
"""获取开始位置"""
|
|
return 0
|
|
|
|
def isBoundary(self, offset: int) -> bool:
|
|
"""检查是否是单词边界"""
|
|
return True
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# TransformationMethod / PasswordTransformationMethod
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class TransformationMethod(Stub):
|
|
"""TransformationMethod — 变换方法接口 (桌面存根)"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def getTransformation(self, source: Any, view: Any) -> Any:
|
|
"""获取变换后的文本"""
|
|
return source
|
|
|
|
def onFocusChanged(self, view: Any, source: Any, focused: bool, direction: int, previouslyFocused: Any) -> None:
|
|
"""焦点变化事件"""
|
|
pass
|
|
|
|
|
|
class TransformationMethod2(TransformationMethod):
|
|
"""TransformationMethod2 — 带长度变化通知的变换方法"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._length_changes_allowed = True
|
|
|
|
def setLengthChangesAllowed(self, allowLengthChanges: bool) -> None:
|
|
"""设置是否允许长度变化"""
|
|
self._length_changes_allowed = allowLengthChanges
|
|
|
|
|
|
class PasswordTransformationMethod(TransformationMethod):
|
|
"""PasswordTransformationMethod — 密码变换方法 (桌面存根)"""
|
|
|
|
_instance: Optional["PasswordTransformationMethod"] = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
@staticmethod
|
|
def getInstance() -> "PasswordTransformationMethod":
|
|
if PasswordTransformationMethod._instance is None:
|
|
PasswordTransformationMethod._instance = PasswordTransformationMethod()
|
|
return PasswordTransformationMethod._instance
|
|
|
|
def getTransformation(self, source: Any, view: Any) -> Any:
|
|
"""将文本转换为掩码字符"""
|
|
text = str(source) if source else ""
|
|
return "\u2022" * len(text) # bullet character
|
|
|
|
def onFocusChanged(self, view: Any, source: Any, focused: bool, direction: int, previouslyFocused: Any) -> None:
|
|
pass
|
|
|
|
|
|
class SingleLineTransformationMethod(TransformationMethod):
|
|
"""SingleLineTransformationMethod — 单行变换方法 (桌面存根)"""
|
|
|
|
_instance: Optional["SingleLineTransformationMethod"] = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
@staticmethod
|
|
def getInstance() -> "SingleLineTransformationMethod":
|
|
if SingleLineTransformationMethod._instance is None:
|
|
SingleLineTransformationMethod._instance = SingleLineTransformationMethod()
|
|
return SingleLineTransformationMethod._instance
|
|
|
|
def getTransformation(self, source: Any, view: Any) -> Any:
|
|
"""移除换行符"""
|
|
text = str(source) if source else ""
|
|
return text.replace("\n", " ").replace("\r", "")
|
|
|
|
|
|
class HideReturnsTransformationMethod(SingleLineTransformationMethod):
|
|
"""HideReturnsTransformationMethod — 隐藏回车变换方法 (桌面存根)"""
|
|
|
|
_instance: Optional["HideReturnsTransformationMethod"] = None
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
@staticmethod
|
|
def getInstance() -> "HideReturnsTransformationMethod":
|
|
if HideReturnsTransformationMethod._instance is None:
|
|
HideReturnsTransformationMethod._instance = HideReturnsTransformationMethod()
|
|
return HideReturnsTransformationMethod._instance
|
|
|
|
def getTransformation(self, source: Any, view: Any) -> Any:
|
|
text = str(source) if source else ""
|
|
return text.replace("\r", "")
|
|
|
|
|
|
class TimeDisplayTruncationMethod(TransformationMethod):
|
|
"""TimeDisplayTruncationMethod — 时间显示截断方法 (桌面存根)"""
|
|
|
|
def __init__(self, max_digits: int = 4):
|
|
super().__init__()
|
|
self._max_digits = max_digits
|
|
|
|
def getTransformation(self, source: Any, view: Any) -> Any:
|
|
text = str(source) if source else ""
|
|
if len(text) > self._max_digits:
|
|
return text[:self._max_digits]
|
|
return text
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# DateTimeKeyListener / DateKeyListener / TimeKeyListener
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class DateTimeKeyListener(NumberKeyListener):
|
|
"""DateTimeKeyListener — 日期时间按键监听器 (桌面存根)"""
|
|
|
|
def __init__(self, locale: Optional[Any] = None):
|
|
super().__init__()
|
|
self._locale = locale
|
|
self._ACCEPTED_CHARS = "0123456789/: "
|
|
|
|
|
|
class DateKeyListener(NumberKeyListener):
|
|
"""DateKeyListener — 日期按键监听器 (桌面存根)"""
|
|
|
|
_instance: Optional["DateKeyListener"] = None
|
|
|
|
def __init__(self, locale: Optional[Any] = None):
|
|
super().__init__()
|
|
self._locale = locale
|
|
self._ACCEPTED_CHARS = "0123456789/"
|
|
|
|
@staticmethod
|
|
def getInstance(locale: Any = None) -> "DateKeyListener":
|
|
if DateKeyListener._instance is None:
|
|
DateKeyListener._instance = DateKeyListener(locale)
|
|
return DateKeyListener._instance
|
|
|
|
|
|
class TimeKeyListener(NumberKeyListener):
|
|
"""TimeKeyListener — 时间按键监听器 (桌面存根)"""
|
|
|
|
_instance: Optional["TimeKeyListener"] = None
|
|
|
|
def __init__(self, locale: Optional[Any] = None):
|
|
super().__init__()
|
|
self._locale = locale
|
|
self._ACCEPTED_CHARS = "0123456789:"
|
|
|
|
@staticmethod
|
|
def getInstance(locale: Any = None) -> "TimeKeyListener":
|
|
if TimeKeyListener._instance is None:
|
|
TimeKeyListener._instance = TimeKeyListener(locale)
|
|
return TimeKeyListener._instance |