""" Android Dialog API — Dialog, AlertDialog, DatePickerDialog, TimePickerDialog, ProgressDialog, etc. 方法签名完全对齐 Android SDK """ from __future__ import annotations import time from datetime import datetime from typing import Any, Dict, List, Optional, Set, Tuple, Callable from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) # ═══════════════════════════════════════════════════════════════ # 常量 # ═══════════════════════════════════════════════════════════════ # BUTTON_* 常量 BUTTON_POSITIVE = -1 BUTTON_NEGATIVE = -2 BUTTON_NEUTRAL = -3 # THEME_* 常量 THEME_TRADITIONAL = 0 THEME_DEVICE_DEFAULT_DARK = 1 THEME_DEVICE_DEFAULT_LIGHT = 2 THEME_HOLO_DARK = 3 THEME_HOLO_LIGHT = 4 THEME_MATERIAL_DARK = 5 THEME_MATERIAL_LIGHT = 6 # Dialog 常量 DISMISS_OTHER = 0 DISMISS_BUTTON_POSITIVE = 1 DISMISS_BUTTON_NEGATIVE = 2 DISMISS_BUTTON_NEUTRAL = 3 # ═══════════════════════════════════════════════════════════════ # DialogInterface # ═══════════════════════════════════════════════════════════════ class DialogInterface(Stub): """DialogInterface — 对话框接口""" BUTTON_POSITIVE = BUTTON_POSITIVE BUTTON_NEGATIVE = BUTTON_NEGATIVE BUTTON_NEUTRAL = BUTTON_NEUTRAL def __init__(self): super().__init__() def cancel(self) -> None: pass def dismiss(self) -> None: pass class OnClickListener(Stub): """DialogInterface.OnClickListener — 点击监听器""" def __init__(self): super().__init__() def onClick(self, dialog: Any, which: int) -> None: pass def toString(self) -> str: return "OnClickListener" class OnDismissListener(Stub): """DialogInterface.OnDismissListener — 消除监听器""" def __init__(self): super().__init__() def onDismiss(self, dialog: Any) -> None: pass def toString(self) -> str: return "OnDismissListener" class OnCancelListener(Stub): """DialogInterface.OnCancelListener — 取消监听器""" def __init__(self): super().__init__() def onCancel(self, dialog: Any) -> None: pass def toString(self) -> str: return "OnCancelListener" class OnMultiChoiceClickListener(Stub): """DialogInterface.OnMultiChoiceClickListener — 多选点击监听器""" def __init__(self): super().__init__() def onClick(self, dialog: Any, which: int, isChecked: bool) -> None: pass def toString(self) -> str: return "OnMultiChoiceClickListener" class OnShowListener(Stub): """DialogInterface.OnShowListener — 显示监听器""" def __init__(self): super().__init__() def onShow(self, dialog: Any) -> None: pass def toString(self) -> str: return "OnShowListener" class OnKeyListener(Stub): """DialogInterface.OnKeyListener — 按键监听器""" def __init__(self): super().__init__() def onKey(self, dialog: Any, keyCode: int, event: Any) -> bool: return False def toString(self) -> str: return "OnKeyListener" def toString(self) -> str: return "DialogInterface" # ═══════════════════════════════════════════════════════════════ # Dialog # ═══════════════════════════════════════════════════════════════ class Dialog(DialogInterface): """Dialog — 对话框基类 (桌面存根)""" def __init__(self, context: Any = None, themeResId: int = 0): super().__init__() self._context = context self._theme_res_id = themeResId self._mShowing = False self._mCancelable = True self._mCanceled = False self._mCancelMessage: Optional[Any] = None self._mDismissMessage: Optional[Any] = None self._mShowMessage: Optional[Any] = None self._mWindow: Optional[Any] = None self._mOwnerActivity: Optional[Any] = None self._mOnCancelListener: Optional[DialogInterface.OnCancelListener] = None self._mOnDismissListener: Optional[DialogInterface.OnDismissListener] = None self._mOnShowListener: Optional[DialogInterface.OnShowListener] = None self._mOnKeyListener: Optional[DialogInterface.OnKeyListener] = None self._mCancelListeners: List[DialogInterface.OnCancelListener] = [] self._mDismissListeners: List[DialogInterface.OnDismissListener] = [] self._mShowListeners: List[DialogInterface.OnShowListener] = [] self._mCreated = False self._mDecor: Optional[Any] = None self._mActionMode: Optional[Any] = None self._mActionModeType: Optional[Any] = None self._mDismissRunnable: Optional[Any] = None def show(self) -> None: self._mShowing = True if self._mOnShowListener: self._mOnShowListener.onShow(self) for listener in self._mShowListeners: listener.onShow(self) def hide(self) -> None: self._mShowing = False def dismiss(self) -> None: self._mShowing = False if self._mOnDismissListener: self._mOnDismissListener.onDismiss(self) for listener in self._mDismissListeners: listener.onDismiss(self) def cancel(self) -> None: if not self._mCancelable: return self._mCanceled = True if self._mOnCancelListener: self._mOnCancelListener.onCancel(self) for listener in self._mCancelListeners: listener.onCancel(self) self.dismiss() def isShowing(self) -> bool: return self._mShowing def setCancelable(self, flag: bool) -> None: self._mCancelable = flag def setCanceledOnTouchOutside(self, cancel: bool) -> None: pass def isCancelable(self) -> bool: return self._mCancelable def getContext(self) -> Optional[Any]: return self._context def getWindow(self) -> Optional[Any]: return self._mWindow def getOwnerActivity(self) -> Optional[Any]: return self._mOwnerActivity def setOwnerActivity(self, activity: Any) -> None: self._mOwnerActivity = activity def setOnCancelListener(self, listener: Optional[DialogInterface.OnCancelListener]) -> None: self._mOnCancelListener = listener def setOnDismissListener(self, listener: Optional[DialogInterface.OnDismissListener]) -> None: self._mOnDismissListener = listener def setOnShowListener(self, listener: Optional[DialogInterface.OnShowListener]) -> None: self._mOnShowListener = listener def setOnKeyListener(self, listener: Optional[DialogInterface.OnKeyListener]) -> None: self._mOnKeyListener = listener def setCancelMessage(self, msg: Any) -> None: self._mCancelMessage = msg def setDismissMessage(self, msg: Any) -> None: self._mDismissMessage = msg def setTitle(self, title: str) -> None: pass def setVolumeControlStream(self, streamType: int) -> None: pass def getVolumeControlStream(self) -> int: return -1 def onWindowFocusChanged(self, hasFocus: bool) -> None: pass def onBackPressed(self) -> None: self.cancel() def onAttachedToWindow(self) -> None: pass def onDetachedFromWindow(self) -> None: pass def onContentChanged(self) -> None: pass def onWindowAttributesChanged(self, attrs: Any) -> None: pass def stopManagingActionMode(self, actionMode: Any) -> None: pass def startManagingActionMode(self, actionMode: Any) -> None: pass def takeActionMode(self, actionMode: Any) -> None: pass def onActionModeStarted(self, actionMode: Any) -> None: pass def onActionModeFinished(self, actionMode: Any) -> None: pass def addContentView(self, view: Any, params: Any) -> None: pass def setContentView(self, viewOrRes: Any, params: Any = None) -> None: pass def requireViewById(self, id: int) -> Any: return None def requireViewById(self, id: int) -> Any: result = self.findViewById(id) if result is None: raise IllegalArgumentException(f"View id=0x{id:x} not found") return result def requestWindowFeature(self, featureId: int) -> bool: return True def getLayoutInflater(self) -> Any: return None def onRestoreInstanceState(self, savedInstanceState: Any) -> None: pass def onSaveInstanceState(self) -> Any: return None def toString(self) -> str: return f"Dialog(showing={self._mShowing}, cancelable={self._mCancelable})" # ═══════════════════════════════════════════════════════════════ # AlertDialog # ═══════════════════════════════════════════════════════════════ class AlertDialog(Dialog): """AlertDialog — 警示对话框""" THEME_DEVICE_DEFAULT_DARK = THEME_DEVICE_DEFAULT_DARK THEME_DEVICE_DEFAULT_LIGHT = THEME_DEVICE_DEFAULT_LIGHT THEME_HOLO_DARK = THEME_HOLO_DARK THEME_HOLO_LIGHT = THEME_HOLO_LIGHT THEME_MATERIAL_DARK = THEME_MATERIAL_DARK THEME_MATERIAL_LIGHT = THEME_MATERIAL_LIGHT THEME_TRADITIONAL = THEME_TRADITIONAL def __init__(self, context: Any, themeResId: int = 0): super().__init__(context, themeResId) self._mTitle: Optional[str] = None self._mMessage: Optional[str] = None self._mIcon: Optional[Any] = None self._mIconAttrId = 0 self._mPositiveButtonText: Optional[str] = None self._mNegativeButtonText: Optional[str] = None self._mNeutralButtonText: Optional[str] = None self._mPositiveButtonListener: Optional[DialogInterface.OnClickListener] = None self._mNegativeButtonListener: Optional[DialogInterface.OnClickListener] = None self._mNeutralButtonListener: Optional[DialogInterface.OnClickListener] = None self._mItems: Optional[List[str]] = None self._mItemClickListener: Optional[DialogInterface.OnClickListener] = None self._mAdapter: Optional[Any] = None self._mMultiChoiceItems: Optional[List[str]] = None self._mMultiChoiceListener: Optional[DialogInterface.OnMultiChoiceClickListener] = None self._mCheckedItems: Optional[List[bool]] = None self._mView: Optional[Any] = None self._mViewSpacingLeft = 0 self._mViewSpacingTop = 0 self._mViewSpacingRight = 0 self._mViewSpacingBottom = 0 self._mViewSpacingSpecified = False self._mCancelable = True self._mCancelListener: Optional[DialogInterface.OnCancelListener] = None self._mDismissListener: Optional[DialogInterface.OnDismissListener] = None self._mKeyListener: Optional[DialogInterface.OnKeyListener] = None self._mCustomTitleView: Optional[Any] = None self._mMessageView: Optional[Any] = None self._mScrollView: Optional[Any] = None self._mListView: Optional[Any] = None self._mButtonPanelLayout: Optional[Any] = None self._mAlertDialogLayout = 0 self._mButtonPanelSideLayout = 0 self._mListLayout = 0 self._mMultiChoiceLayout = 0 self._mSingleChoiceLayout = 0 self._mProgressLayout = 0 self._mProgressNumber: Optional[str] = None self._mProgressPercent: Optional[str] = None self._mProgressStyle = 0 self._mProgressValue = 0 self._mProgressValueMax = 100 self._mProgressIndeterminate = False self._mCheckedItem = -1 self._mForceInverseBackground = False self._mRecycleOnMeasure = True self._mShowTitle = True def getButton(self, whichButton: int) -> Optional[Any]: return None def setTitle(self, title: str) -> None: self._mTitle = title def setMessage(self, message: str) -> None: self._mMessage = message def setIcon(self, icon: Any) -> None: self._mIcon = icon def setIconAttribute(self, attrId: int) -> None: self._mIconAttrId = attrId def setCustomTitle(self, customTitleView: Any) -> None: self._mCustomTitleView = customTitleView def setView(self, view: Any) -> None: self._mView = view def setView(self, view: Any, viewSpacingLeft: int, viewSpacingTop: int, viewSpacingRight: int, viewSpacingBottom: int) -> None: self._mView = view self._mViewSpacingLeft = viewSpacingLeft self._mViewSpacingTop = viewSpacingTop self._mViewSpacingRight = viewSpacingRight self._mViewSpacingBottom = viewSpacingBottom self._mViewSpacingSpecified = True def setButton(self, whichButton: int, text: Any, listenerOrMsg: Any = None) -> None: text_str = str(text) if not isinstance(text, str) else text if whichButton == BUTTON_POSITIVE: self._mPositiveButtonText = text_str if isinstance(listenerOrMsg, DialogInterface.OnClickListener): self._mPositiveButtonListener = listenerOrMsg elif whichButton == BUTTON_NEGATIVE: self._mNegativeButtonText = text_str if isinstance(listenerOrMsg, DialogInterface.OnClickListener): self._mNegativeButtonListener = listenerOrMsg elif whichButton == BUTTON_NEUTRAL: self._mNeutralButtonText = text_str if isinstance(listenerOrMsg, DialogInterface.OnClickListener): self._mNeutralButtonListener = listenerOrMsg def setIconAttribute(self, attrId: int) -> None: self._mIconAttrId = attrId def getListView(self) -> Optional[Any]: return self._mListView def show(self) -> None: super().show() # 模拟按钮点击触发 if self._mPositiveButtonListener: pass if self._mNegativeButtonListener: pass if self._mNeutralButtonListener: pass def toString(self) -> str: return f"AlertDialog(title={self._mTitle}, message={self._mMessage})" # ═══════════════════════════════════════════════════════════ # AlertDialog.Builder # ═══════════════════════════════════════════════════════════ class Builder(Stub): """AlertDialog.Builder — 警示对话框构建器""" def __init__(self, context: Any): super().__init__() self._P = AlertDialog(context) self._context = context def setTitle(self, titleOrId: Any) -> "AlertDialog.Builder": if isinstance(titleOrId, int): self._P._mTitle = f"title_{titleOrId}" else: self._P._mTitle = str(titleOrId) return self def setCustomTitle(self, customTitleView: Any) -> "AlertDialog.Builder": self._P._mCustomTitleView = customTitleView return self def setMessage(self, messageOrId: Any) -> "AlertDialog.Builder": if isinstance(messageOrId, int): self._P._mMessage = f"msg_{messageOrId}" else: self._P._mMessage = str(messageOrId) return self def setIcon(self, iconOrId: Any) -> "AlertDialog.Builder": if isinstance(iconOrId, int): pass else: self._P._mIcon = iconOrId return self def setIconAttribute(self, attrId: int) -> "AlertDialog.Builder": self._P._mIconAttrId = attrId return self def setPositiveButton( self, textOrId: Any, listener: Optional[DialogInterface.OnClickListener] = None ) -> "AlertDialog.Builder": if isinstance(textOrId, int): self._P._mPositiveButtonText = f"positive_{textOrId}" else: self._P._mPositiveButtonText = str(textOrId) self._P._mPositiveButtonListener = listener return self def setNegativeButton( self, textOrId: Any, listener: Optional[DialogInterface.OnClickListener] = None ) -> "AlertDialog.Builder": if isinstance(textOrId, int): self._P._mNegativeButtonText = f"negative_{textOrId}" else: self._P._mNegativeButtonText = str(textOrId) self._P._mNegativeButtonListener = listener return self def setNeutralButton( self, textOrId: Any, listener: Optional[DialogInterface.OnClickListener] = None ) -> "AlertDialog.Builder": if isinstance(textOrId, int): self._P._mNeutralButtonText = f"neutral_{textOrId}" else: self._P._mNeutralButtonText = str(textOrId) self._P._mNeutralButtonListener = listener return self def setCancelable(self, cancelable: bool) -> "AlertDialog.Builder": self._P._mCancelable = cancelable return self def setOnCancelListener(self, listener: DialogInterface.OnCancelListener) -> "AlertDialog.Builder": self._P._mCancelListener = listener return self def setOnDismissListener(self, listener: DialogInterface.OnDismissListener) -> "AlertDialog.Builder": self._P._mDismissListener = listener return self def setOnKeyListener(self, listener: DialogInterface.OnKeyListener) -> "AlertDialog.Builder": self._P._mKeyListener = listener return self def setItems( self, itemsOrId: Any, listener: Optional[DialogInterface.OnClickListener] = None ) -> "AlertDialog.Builder": if isinstance(itemsOrId, int): self._P._mItems = [f"item_{itemsOrId}"] else: self._P._mItems = list(itemsOrId) self._P._mItemClickListener = listener return self def setAdapter( self, adapter: Any, listener: Optional[DialogInterface.OnClickListener] = None ) -> "AlertDialog.Builder": self._P._mAdapter = adapter self._P._mItemClickListener = listener return self def setSingleChoiceItems( self, itemsOrId: Any, checkedItem: int, listener: Optional[DialogInterface.OnClickListener] = None ) -> "AlertDialog.Builder": if isinstance(itemsOrId, int): self._P._mItems = [f"item_{itemsOrId}"] else: self._P._mItems = list(itemsOrId) self._P._mCheckedItem = checkedItem self._P._mItemClickListener = listener return self def setMultiChoiceItems( self, itemsOrId: Any, checkedItems: Optional[List[bool]], listener: Optional[DialogInterface.OnMultiChoiceClickListener] = None ) -> "AlertDialog.Builder": if isinstance(itemsOrId, int): self._P._mMultiChoiceItems = [f"item_{itemsOrId}"] self._P._mCheckedItems = [False] else: self._P._mMultiChoiceItems = list(itemsOrId) self._P._mCheckedItems = checkedItems or [False] * len(itemsOrId) self._P._mMultiChoiceListener = listener return self def setView(self, viewOrRes: Any) -> "AlertDialog.Builder": self._P._mView = viewOrRes return self def setInverseBackgroundForced(self, useInverse: bool) -> "AlertDialog.Builder": self._P._mForceInverseBackground = useInverse return self def setRecycleOnMeasureEnabled(self, enabled: bool) -> "AlertDialog.Builder": self._P._mRecycleOnMeasure = enabled return self def create(self) -> AlertDialog: return self._P def show(self) -> AlertDialog: dialog = self.create() dialog.show() return dialog def toString(self) -> str: return f"AlertDialog.Builder(title={self._P._mTitle})" # ═══════════════════════════════════════════════════════════════ # CharacterPickerDialog # ═══════════════════════════════════════════════════════════════ class CharacterPickerDialog(Dialog): """CharacterPickerDialog — 字符选择对话框""" def __init__(self, context: Any, view: Any, listener: Any, options: List[str], allowMultiple: bool): super().__init__(context) self._view = view self._listener = listener self._options = list(options) self._allow_multiple = allowMultiple self._selected_indices: List[int] = [] self._selected_characters: List[str] = [] def onClick(self, which: int) -> None: if 0 <= which < len(self._options): char = self._options[which] if self._allow_multiple: if which in self._selected_indices: self._selected_indices.remove(which) self._selected_characters.remove(char) else: self._selected_indices.append(which) self._selected_characters.append(char) else: self._selected_indices = [which] self._selected_characters = [char] if self._listener: self._listener(char) def getSelectedCharacters(self) -> List[str]: return list(self._selected_characters) def toString(self) -> str: return f"CharacterPickerDialog(options={len(self._options)}, multiple={self._allow_multiple})" # ═══════════════════════════════════════════════════════════════ # DatePickerDialog # ═══════════════════════════════════════════════════════════════ class DatePickerDialog(AlertDialog): """DatePickerDialog — 日期选择对话框""" class OnDateSetListener(Stub): """DatePickerDialog.OnDateSetListener — 日期设置监听器""" def __init__(self): super().__init__() def onDateSet(self, view: Any, year: int, month: int, dayOfMonth: int) -> None: pass def toString(self) -> str: return "OnDateSetListener" def __init__( self, context: Any, listener: Optional["DatePickerDialog.OnDateSetListener"] = None, year: int = 2024, month: int = 0, dayOfMonth: int = 1, ): super().__init__(context) self._mListener = listener self._mYear = year self._mMonth = month self._mDay = dayOfMonth self._mMinDate: Optional[int] = None self._mMaxDate: Optional[int] = None self._mDatePicker: Optional[Any] = None self._mTitle: Optional[str] = None self._mInitialDate = datetime(year, month + 1, dayOfMonth) def onDateChanged(self, view: Any, year: int, month: int, dayOfMonth: int) -> None: self._mYear = year self._mMonth = month self._mDay = dayOfMonth def getDatePicker(self) -> Optional[Any]: return self._mDatePicker def setOnDateSetListener(self, listener: "DatePickerDialog.OnDateSetListener") -> None: self._mListener = listener def updateDate(self, year: int, month: int, dayOfMonth: int) -> None: self._mYear = year self._mMonth = month self._mDay = dayOfMonth def getYear(self) -> int: return self._mYear def getMonth(self) -> int: return self._mMonth def getDayOfMonth(self) -> int: return self._mDay def setMinDate(self, minDate: int) -> None: self._mMinDate = minDate def setMaxDate(self, maxDate: int) -> None: self._mMaxDate = maxDate def getMinDate(self) -> Optional[int]: return self._mMinDate def getMaxDate(self) -> Optional[int]: return self._mMaxDate def show(self) -> None: super().show() if self._mListener: self._mListener.onDateSet(None, self._mYear, self._mMonth, self._mDay) def toString(self) -> str: return f"DatePickerDialog({self._mYear}-{self._mMonth + 1:02d}-{self._mDay:02d})" # ═══════════════════════════════════════════════════════════════ # TimePickerDialog # ═══════════════════════════════════════════════════════════════ class TimePickerDialog(AlertDialog): """TimePickerDialog — 时间选择对话框""" class OnTimeSetListener(Stub): """TimePickerDialog.OnTimeSetListener — 时间设置监听器""" def __init__(self): super().__init__() def onTimeSet(self, view: Any, hourOfDay: int, minute: int) -> None: pass def toString(self) -> str: return "OnTimeSetListener" def __init__( self, context: Any, listener: Optional["TimePickerDialog.OnTimeSetListener"] = None, hourOfDay: int = 0, minute: int = 0, is24HourView: bool = True, ): super().__init__(context) self._mListener = listener self._mHour = hourOfDay self._mMinute = minute self._mIs24HourView = is24HourView self._mTimePicker: Optional[Any] = None self._mTitle: Optional[str] = None def onTimeChanged(self, view: Any, hourOfDay: int, minute: int) -> None: self._mHour = hourOfDay self._mMinute = minute def getTimePicker(self) -> Optional[Any]: return self._mTimePicker def setOnTimeSetListener(self, listener: "TimePickerDialog.OnTimeSetListener") -> None: self._mListener = listener def updateTime(self, hourOfDay: int, minute: int) -> None: self._mHour = hourOfDay self._mMinute = minute def getHour(self) -> int: return self._mHour def getMinute(self) -> int: return self._mMinute def is24HourView(self) -> bool: return self._mIs24HourView def show(self) -> None: super().show() if self._mListener: self._mListener.onTimeSet(None, self._mHour, self._mMinute) def toString(self) -> str: return f"TimePickerDialog({self._mHour:02d}:{self._mMinute:02d})" # ═══════════════════════════════════════════════════════════════ # ProgressDialog # ═══════════════════════════════════════════════════════════════ class ProgressDialog(AlertDialog): """ProgressDialog — 进度对话框""" STYLE_SPINNER = 0 STYLE_HORIZONTAL = 1 def __init__(self, context: Any): super().__init__(context) self._mProgressStyle = ProgressDialog.STYLE_SPINNER self._mMax = 100 self._mProgress = 0 self._mSecondaryProgress = 0 self._mIndeterminate = False self._mHasProgress = True self._mProgressDrawable: Optional[Any] = None self._mProgressNumber: Optional[str] = None self._mProgressPercent: Optional[str] = None self._mProgressNumberFormat = "%1d/%2d" self._mProgressPercentFormat = "%.0f%%" self._mCurrentProgressText: Optional[str] = None self._mProgressTextColor = 0 self._mProgressBackgroundColor = 0 self._mMessageViewUpdate: bool = False def getMax(self) -> int: return self._mMax def setMax(self, max: int) -> None: self._mMax = max def getProgress(self) -> int: return self._mProgress def setProgress(self, value: int) -> None: self._mProgress = value def getSecondaryProgress(self) -> int: return self._mSecondaryProgress def setSecondaryProgress(self, secondaryProgress: int) -> None: self._mSecondaryProgress = secondaryProgress def getProgressStyle(self) -> int: return self._mProgressStyle def setProgressStyle(self, style: int) -> None: self._mProgressStyle = style def isIndeterminate(self) -> bool: return self._mIndeterminate def setIndeterminate(self, indeterminate: bool) -> None: self._mIndeterminate = indeterminate def incrementProgressBy(self, diff: int) -> None: self._mProgress = min(self._mProgress + diff, self._mMax) def incrementSecondaryProgressBy(self, diff: int) -> None: self._mSecondaryProgress += diff def setProgressDrawable(self, drawable: Any) -> None: self._mProgressDrawable = drawable def setProgressNumberFormat(self, format: str) -> None: self._mProgressNumberFormat = format def setProgressPercentFormat(self, format: str) -> None: self._mProgressPercentFormat = format def onStart(self) -> None: pass def setMessage(self, message: str) -> None: super().setMessage(message) def show( cls, context: Any, title: str, message: str, indeterminate: bool = True, cancelable: bool = False ) -> "ProgressDialog": dialog = ProgressDialog(context) dialog.setTitle(title) dialog.setMessage(message) dialog.setIndeterminate(indeterminate) dialog.setCancelable(cancelable) dialog.show() return dialog def toString(self) -> str: return f"ProgressDialog(style={self._mProgressStyle}, progress={self._mProgress}/{self._mMax})"