NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

autonaming.py (7112B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\util\autonaming.py
      2 import re
      3 import weakref
      4 import logging
      5 log = logging.getLogger(__name__)
      6 _click_registry = weakref.WeakValueDictionary()
      7 AUTO_NAMING_ENABLED = True
      8 GENERIC_NAMES = {'Container',
      9  'container',
     10  'Button',
     11  'button',
     12  'Frame',
     13  'frame',
     14  'Underlay',
     15  'underlay'}
     16 
     17 def register_clickable_element(ui_element, element_id):
     18     if not element_id or not ui_element:
     19         return
     20     try:
     21         prev = _click_registry.get(element_id)
     22         if prev is not None and prev is not ui_element:
     23             log.debug('autonaming: overwriting registry key %r: %s -> %s', element_id, prev.__class__.__name__, ui_element.__class__.__name__)
     24     except Exception:
     25         pass
     26 
     27     _click_registry[element_id] = ui_element
     28 
     29 
     30 def get_registered_element(element_id):
     31     return _click_registry.get(element_id)
     32 
     33 
     34 def _sanitize_name(name):
     35     try:
     36         name = re.sub('[^a-zA-Z0-9\\s]', '', str(name))
     37         words = name.split()
     38         if not words:
     39             return None
     40         result = words[0].lower()
     41         for word in words[1:]:
     42             result += word.capitalize()
     43 
     44         if result:
     45             return result
     46         return None
     47     except Exception:
     48         return None
     49 
     50 
     51 def _find_parent_window(element):
     52     try:
     53         current = getattr(element, 'parent', None)
     54         max_depth = 20
     55         depth = 0
     56         while current and depth < max_depth:
     57             if hasattr(current, 'windowID') and current.windowID:
     58                 return current
     59             class_name = current.__class__.__name__
     60             if 'Window' in class_name or 'Dialog' in class_name:
     61                 return current
     62             current = getattr(current, 'parent', None)
     63             depth += 1
     64 
     65         return
     66     except Exception:
     67         return
     68 
     69 
     70 def _get_semantic_role(ui_element, attributes):
     71     try:
     72         attributes = attributes or {}
     73         label = attributes.get('label') or attributes.get('text', '')
     74         if label:
     75             label_lower = str(label).lower().strip()
     76             role_map = {'submit': ['submit',
     77                         'ok',
     78                         'confirm',
     79                         'accept',
     80                         'apply'],
     81              'cancel': ['cancel',
     82                         'close',
     83                         'dismiss',
     84                         'no'],
     85              'next': ['next', 'continue', 'forward'],
     86              'back': ['back', 'previous'],
     87              'delete': ['delete', 'remove'],
     88              'save': ['save'],
     89              'edit': ['edit', 'modify']}
     90             for role, keywords in role_map.items():
     91                 if label_lower in keywords:
     92                     return role
     93 
     94             sanitized = _sanitize_name(label)
     95             if sanitized and len(sanitized) < 20 and sanitized not in GENERIC_NAMES:
     96                 return sanitized
     97         icon_path = attributes.get('iconPath') or attributes.get('texturePath', '')
     98         if icon_path:
     99             icon_lower = str(icon_path).lower()
    100             if 'close' in icon_lower:
    101                 return 'close'
    102             if 'settings' in icon_lower or 'gear' in icon_lower:
    103                 return 'settings'
    104             if 'help' in icon_lower or 'question' in icon_lower:
    105                 return 'help'
    106             if 'search' in icon_lower:
    107                 return 'search'
    108         func = attributes.get('func') or attributes.get('OnClick')
    109         if func and hasattr(func, '__name__'):
    110             func_name = func.__name__
    111             clean_name = func_name.replace('OnClick', '').replace('On', '').replace('_', '')
    112             if clean_name and len(clean_name) < 20:
    113                 if clean_name:
    114                     return clean_name[0].lower() + clean_name[1:]
    115                 return None
    116         return None
    117     except Exception:
    118         return None
    119 
    120 
    121 def _try_register_unique_ui_name(ui_element):
    122     if hasattr(ui_element, 'uniqueUiName') and ui_element.uniqueUiName:
    123         register_clickable_element(ui_element, ui_element.uniqueUiName)
    124         if hasattr(ui_element, 'elementId') and ui_element.elementId:
    125             register_clickable_element(ui_element, ui_element.elementId)
    126             return True
    127         ui_element.elementId = ui_element.uniqueUiName
    128         return True
    129     return False
    130 
    131 
    132 def _try_register_existing_element_id(ui_element):
    133     if hasattr(ui_element, 'elementId') and ui_element.elementId:
    134         register_clickable_element(ui_element, ui_element.elementId)
    135         return True
    136     return False
    137 
    138 
    139 def _try_use_btnData_id(ui_element):
    140     if hasattr(ui_element, 'btnData') and hasattr(ui_element.btnData, 'id'):
    141         btn_id = ui_element.btnData.id
    142         if btn_id:
    143             generated_name = 'neocom.%s' % btn_id
    144             ui_element.elementId = generated_name
    145             register_clickable_element(ui_element, generated_name)
    146             log.info('autonaming: generated neocom id %r (%s)', generated_name, ui_element.__class__.__name__)
    147             return True
    148     return False
    149 
    150 
    151 def _try_use_attributes_name(ui_element, attributes, window):
    152     element_name = attributes.get('name')
    153     if element_name and element_name not in GENERIC_NAMES:
    154         if window and hasattr(window, 'windowID'):
    155             generated_name = '%s.%s' % (window.windowID, element_name)
    156         else:
    157             generated_name = element_name
    158         ui_element.elementId = generated_name
    159         register_clickable_element(ui_element, generated_name)
    160         log.debug('autonaming: generated name id %r', generated_name)
    161         return True
    162     return False
    163 
    164 
    165 def _try_use_window_and_role(ui_element, attributes, window):
    166     role = _get_semantic_role(ui_element, attributes)
    167     if window and role and hasattr(window, 'windowID'):
    168         generated_name = '%s.%s' % (window.windowID, role)
    169         ui_element.elementId = generated_name
    170         register_clickable_element(ui_element, generated_name)
    171         log.debug('autonaming: generated role id %r', generated_name)
    172         return True
    173     return False
    174 
    175 
    176 def _try_use_role_only(ui_element, attributes):
    177     role = _get_semantic_role(ui_element, attributes)
    178     if role:
    179         ui_element.elementId = role
    180         register_clickable_element(ui_element, role)
    181         log.debug('autonaming: generated fallback role id %r', role)
    182         return True
    183     return False
    184 
    185 
    186 def apply_auto_naming(ui_element, attributes):
    187     try:
    188         if not AUTO_NAMING_ENABLED or not ui_element:
    189             return
    190         attributes = attributes or {}
    191         if _try_register_unique_ui_name(ui_element):
    192             return
    193         if _try_register_existing_element_id(ui_element):
    194             return
    195         if _try_use_btnData_id(ui_element):
    196             return
    197         window = _find_parent_window(ui_element)
    198         if _try_use_attributes_name(ui_element, attributes, window):
    199             return
    200         if _try_use_window_and_role(ui_element, attributes, window):
    201             return
    202         _try_use_role_only(ui_element, attributes)
    203     except Exception as exc:
    204         log.exception('Failed to apply auto naming: %s', exc)