mirror of
https://github.com/ModOrganizer2/pystubs-generation.git
synced 2026-07-27 14:07:13 -07:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a5c16af21 | ||
|
|
3eb1daa053 | ||
|
|
0eca0f7644 |
@@ -94,6 +94,22 @@ It is possible to start a (i)python interpreter with `mobase` imported by runnin
|
||||
python -i -m mo2.stubs.generator.loader ${MO2_INSTALL_PATH}
|
||||
```
|
||||
|
||||
You can also import `mobase` in your code using the following (after installing
|
||||
this package):
|
||||
|
||||
```python
|
||||
from mo2.stubs.generator import load_mobase
|
||||
|
||||
mobase = load_mobase(MO2_INSTALL_PATH)
|
||||
|
||||
# the above will probably not give you type-completion in your IDE or typing, so
|
||||
# you can use the following (if the stubs are installed)
|
||||
load_mobase(MO2_INSTALL_PATH)
|
||||
import mobase
|
||||
import mobase.widgets
|
||||
```
|
||||
|
||||
|
||||
**Note:** Most classes in `mobase` cannot be instantiated, so this is mostly intended
|
||||
for MO2 developers.
|
||||
|
||||
|
||||
+118
-4
@@ -3004,11 +3004,11 @@ mobase:
|
||||
__doc__:
|
||||
__abstract__: true
|
||||
|
||||
BinaryName:
|
||||
binaryName:
|
||||
__doc__:
|
||||
returns: The name of the script extender binary.
|
||||
|
||||
PluginPath:
|
||||
pluginPath:
|
||||
__doc__:
|
||||
returns: The script extender plugin path, relative to the data folder.
|
||||
|
||||
@@ -3140,6 +3140,120 @@ mobase:
|
||||
|
||||
mobase.widgets:
|
||||
|
||||
TaskDialog: {}
|
||||
TaskDialog:
|
||||
__doc__: Customizable choice dialog.
|
||||
|
||||
TaskDialogButton: {}
|
||||
__init__:
|
||||
__doc__: Construct a new TaskDialog.
|
||||
|
||||
args:
|
||||
parent: Parent widget of the dialog.
|
||||
title: Title of the dialog.
|
||||
main: Header of the dialog (big text at the top).
|
||||
content: Main message of the dialog (text below main).
|
||||
details: Details for the dialog, initially collapsed (bottom of the dialog).
|
||||
icon: Icon for the dialog.
|
||||
buttons: List of buttons for the dialog.
|
||||
remember: Remember the choice for this dialog.
|
||||
|
||||
addButton:
|
||||
__doc__: Add a custom button to this TaskDialog.
|
||||
|
||||
args:
|
||||
button: Button to add to the dialog.
|
||||
|
||||
addContent:
|
||||
__doc__: |
|
||||
Add a custom widget content to this TaskDialog. Widget content are put between
|
||||
content and buttons (above buttons).
|
||||
|
||||
args:
|
||||
widget: Widget to add.
|
||||
|
||||
exec:
|
||||
__doc__: |
|
||||
Display this dialog and wait for user-interaction to return. This is a blocking
|
||||
function.
|
||||
|
||||
returns:
|
||||
The button clicked by the user. Without custom buttons, this return Ok,
|
||||
otherwise it returns the button set in the TaskDialogButton.
|
||||
|
||||
setContent:
|
||||
__doc__: Set the top-level message of this dialog.
|
||||
|
||||
args:
|
||||
content: Top-level message to set.
|
||||
|
||||
setDetails:
|
||||
__doc__: |
|
||||
Set the details for this TaskDialog.
|
||||
|
||||
The details are hidden by default and the user can display them by clicking
|
||||
the "Details" button at the bottom of the TaskDialog.
|
||||
|
||||
args:
|
||||
details: Details content to display. Can be a multi-line string.
|
||||
|
||||
setIcon:
|
||||
__doc__: Set the icon of the dialog.
|
||||
|
||||
args:
|
||||
icon: Icon of the dialog.
|
||||
|
||||
setMain:
|
||||
__doc__: |
|
||||
Set the main message of the dialog. The main message is displayed at the top of
|
||||
the dialog in large font.
|
||||
|
||||
args:
|
||||
main: Main message of the dialog.
|
||||
|
||||
setRemember:
|
||||
__doc__: Configure the dialog to remember user-choice.
|
||||
|
||||
args:
|
||||
action:
|
||||
file:
|
||||
|
||||
setTitle:
|
||||
__doc__: Set the title of the dialog.
|
||||
|
||||
args:
|
||||
title: Title of the dialog.
|
||||
|
||||
setWidth:
|
||||
__doc__: Set the width of the dialog.
|
||||
|
||||
args:
|
||||
width: Width of the dialog.
|
||||
|
||||
|
||||
TaskDialogButton:
|
||||
__doc__: Special button to be used inside TaskDialog widgets.
|
||||
|
||||
__init__.1:
|
||||
__doc__: Create a TaskDialogButton.
|
||||
|
||||
args:
|
||||
text: Label of the button.
|
||||
description: Description of the button.
|
||||
button: Value returned by TaskDialog.exec() if this button is clicked.
|
||||
|
||||
__init__.2:
|
||||
__doc__: Create a TaskDialogButton without description.
|
||||
|
||||
args:
|
||||
text: Label of the button.
|
||||
button: Value returned by TaskDialog.exec() if this button is clicked.
|
||||
|
||||
properties[]:
|
||||
text:
|
||||
type: str
|
||||
desc: Label of the button.
|
||||
description:
|
||||
type: str
|
||||
desc: Description of the button.
|
||||
button:
|
||||
type: PyQt6.QtWidgets.QMessageBox.StandardButton
|
||||
desc: Value returned by TaskDialog.exec() if this button is clicked.
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
import logging
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
from .loader import load_mobase # noqa: F401
|
||||
|
||||
@@ -3,25 +3,29 @@
|
||||
import argparse
|
||||
import inspect
|
||||
import logging
|
||||
import types
|
||||
from pathlib import Path
|
||||
from typing import Callable, TextIO, cast
|
||||
from typing import Callable
|
||||
|
||||
import black
|
||||
import isort
|
||||
|
||||
from . import LOGGER
|
||||
from .loader import load_mobase
|
||||
from .mtypes import Class, Function, PyType
|
||||
from .mtypes import Class, PyTyping
|
||||
from .parser import is_enum
|
||||
from .register import MobaseRegister
|
||||
from .utils import Settings, clean_class
|
||||
from .writer import Writer
|
||||
from .writer import Writer, is_list_of_functions
|
||||
|
||||
|
||||
def extract_objects(module: object, skips: list[str] = []) -> list[tuple[str, object]]:
|
||||
|
||||
objects: list[tuple[str, object]] = []
|
||||
|
||||
assert hasattr(module, "__name__")
|
||||
module_name: str = module.__name__ # type: ignore
|
||||
|
||||
for name in dir(module):
|
||||
if name.startswith("__") or name in skips:
|
||||
continue
|
||||
@@ -32,6 +36,11 @@ def extract_objects(module: object, skips: list[str] = []) -> list[tuple[str, ob
|
||||
if inspect.ismodule(obj):
|
||||
continue
|
||||
|
||||
# skip imports - type object have wrong __module__?
|
||||
if hasattr(obj, "__module__") and obj.__module__ != module_name:
|
||||
if obj.__module__ != types.__name__ or hasattr(types, name):
|
||||
continue
|
||||
|
||||
objects.append((name, obj))
|
||||
|
||||
return objects
|
||||
@@ -42,23 +51,23 @@ def add_mobase_header(writer: Writer):
|
||||
[
|
||||
"abc",
|
||||
("enum", ["Enum"]),
|
||||
("pathlib", ["Path"]),
|
||||
"os",
|
||||
(
|
||||
"typing",
|
||||
[
|
||||
"Any",
|
||||
"Callable",
|
||||
"Dict",
|
||||
"Iterator",
|
||||
"List",
|
||||
"Tuple",
|
||||
"Union",
|
||||
"Any",
|
||||
"Optional",
|
||||
"Callable",
|
||||
"overload",
|
||||
"Sequence",
|
||||
"Set",
|
||||
"TypeVar",
|
||||
"Tuple",
|
||||
"Type",
|
||||
"TypeVar",
|
||||
"Union",
|
||||
],
|
||||
),
|
||||
"PyQt6.QtCore",
|
||||
@@ -67,13 +76,6 @@ def add_mobase_header(writer: Writer):
|
||||
]
|
||||
)
|
||||
|
||||
# Needs to define the MVariant and GameFeatureType type:
|
||||
writer._print(f"MoVariant = {PyType.MO_VARIANT}")
|
||||
writer._print(f"FileWrapper = {PyType.FILE_WRAPPER}")
|
||||
writer._print(f"DirectoryWrapper = {PyType.DIRECTORY_WRAPPER}")
|
||||
writer._print('GameFeatureType = TypeVar("GameFeatureType")')
|
||||
writer._print()
|
||||
|
||||
|
||||
def add_mobase_widgets_header(writer: Writer):
|
||||
writer.print_imports(
|
||||
@@ -148,8 +150,6 @@ def main():
|
||||
"mobase": extract_objects(
|
||||
mobase,
|
||||
[
|
||||
# we do not want the real MoVariant
|
||||
"MoVariant",
|
||||
# the "real" IPlugin is IPluginBase
|
||||
"IPlugin",
|
||||
],
|
||||
@@ -187,7 +187,10 @@ def main():
|
||||
# Path the class using the configuration:
|
||||
settings.patch_class(c)
|
||||
|
||||
elif isinstance(c, list) and isinstance(c[0], Function):
|
||||
elif isinstance(c, PyTyping):
|
||||
...
|
||||
|
||||
elif is_list_of_functions(c):
|
||||
settings.patch_functions(c)
|
||||
|
||||
else:
|
||||
@@ -220,12 +223,7 @@ def main():
|
||||
# Get the corresponding object:
|
||||
c = register.get_object(n)
|
||||
|
||||
if isinstance(c, Class):
|
||||
writer.print_class(c)
|
||||
|
||||
elif isinstance(c, list) and isinstance(c[0], Function):
|
||||
for fn in c:
|
||||
writer.print_function(fn)
|
||||
writer.print_object(c)
|
||||
|
||||
black.format_file_in_place(
|
||||
output_folder.joinpath("__init__.pyi"),
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
from modulefinder import Module
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def load_mobase(path: Path):
|
||||
def load_mobase(path: os.PathLike) -> Module:
|
||||
"""
|
||||
Load the mobase from the given MO2 installation path and
|
||||
returns it.
|
||||
@@ -16,6 +17,8 @@ def load_mobase(path: Path):
|
||||
Returns: The mobase module.
|
||||
"""
|
||||
|
||||
path = Path(path)
|
||||
|
||||
# We need absolute path for loading DLL and modules:
|
||||
path = path.resolve()
|
||||
|
||||
@@ -35,7 +38,7 @@ def load_mobase(path: Path):
|
||||
|
||||
import mobase # type: ignore
|
||||
|
||||
return mobase
|
||||
return mobase # type: ignore
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import Final, TypeVar
|
||||
|
||||
|
||||
class PyType:
|
||||
@@ -430,3 +431,26 @@ class Enum(Class):
|
||||
|
||||
def is_abstract(self):
|
||||
return False
|
||||
|
||||
|
||||
class PyTyping:
|
||||
"""
|
||||
Class representing a typing object, e.g., MoVariant.
|
||||
"""
|
||||
|
||||
name: Final[str]
|
||||
typing: Final[str]
|
||||
|
||||
def __init__(self, name: str, obj: object):
|
||||
self.name = name
|
||||
|
||||
_typing: str
|
||||
if obj.__module__ == "types":
|
||||
_typing = str(obj)
|
||||
# type-var have a weird name, e.g., ~Name
|
||||
elif type(obj) is TypeVar:
|
||||
_typing = f'TypeVar("{name}")'
|
||||
else:
|
||||
_typing = str(obj)
|
||||
|
||||
self.typing = _typing
|
||||
|
||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from .mtypes import Class, Function
|
||||
from .mtypes import Class, Function, PyTyping
|
||||
|
||||
|
||||
class MobaseRegister:
|
||||
@@ -46,6 +46,10 @@ class MobaseRegister:
|
||||
elif callable(e):
|
||||
self.objects[name] = make_functions(e)
|
||||
|
||||
# typing stuff
|
||||
elif type(e).__module__ == "types" or type(e).__module__ == "typing":
|
||||
self.objects[name] = PyTyping(name, e)
|
||||
|
||||
return self.objects[name]
|
||||
|
||||
def get_object(self, name: str):
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from typing import TextIO
|
||||
from typing import TextIO, TypeGuard
|
||||
|
||||
from . import LOGGER
|
||||
from .mtypes import Class, Enum, Function, Method, Property
|
||||
from .mtypes import Class, Enum, Function, Method, Property, PyTyping
|
||||
from .utils import Settings
|
||||
|
||||
|
||||
def is_list_of_functions(e: object) -> TypeGuard[list[Function]]:
|
||||
return isinstance(e, list) and all(isinstance(x, Function) for x in e)
|
||||
|
||||
|
||||
class Writer:
|
||||
|
||||
_output: TextIO
|
||||
@@ -240,3 +244,18 @@ class Writer:
|
||||
if isinstance(cls, Enum):
|
||||
self._print()
|
||||
self._print()
|
||||
|
||||
def print_typing(self, typ: PyTyping):
|
||||
self._print(f"{typ.name} = {typ.typing}")
|
||||
|
||||
def print_object(self, e: object):
|
||||
|
||||
if isinstance(e, Class):
|
||||
self.print_class(e)
|
||||
|
||||
elif is_list_of_functions(e):
|
||||
for fn in e:
|
||||
self.print_function(fn)
|
||||
|
||||
elif isinstance(e, PyTyping):
|
||||
self.print_typing(e)
|
||||
|
||||
@@ -3,8 +3,8 @@ from __future__ import annotations
|
||||
__version__ = "2.5.0"
|
||||
|
||||
import abc
|
||||
import os
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
@@ -25,12 +25,10 @@ import PyQt6.QtCore
|
||||
import PyQt6.QtGui
|
||||
import PyQt6.QtWidgets
|
||||
|
||||
MoVariant = Union[None, bool, int, str, list[Any], dict[str, Any]]
|
||||
FileWrapper = Union[str, PyQt6.QtCore.QFileInfo, Path]
|
||||
DirectoryWrapper = Union[str, PyQt6.QtCore.QDir, Path]
|
||||
GameFeatureType = TypeVar("GameFeatureType")
|
||||
MoVariant = None | bool | int | str | list[object] | dict[str, object]
|
||||
|
||||
def getFileVersion(filepath: FileWrapper) -> str:
|
||||
def getFileVersion(filepath: Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]) -> str:
|
||||
"""
|
||||
Retrieve the file version of the given executable.
|
||||
|
||||
@@ -42,7 +40,9 @@ def getFileVersion(filepath: FileWrapper) -> str:
|
||||
"""
|
||||
...
|
||||
|
||||
def getIconForExecutable(executable: FileWrapper) -> PyQt6.QtGui.QIcon:
|
||||
def getIconForExecutable(
|
||||
executable: Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]
|
||||
) -> PyQt6.QtGui.QIcon:
|
||||
"""
|
||||
Retrieve the icon of an executable. Currently this always extracts the biggest icon.
|
||||
|
||||
@@ -54,7 +54,9 @@ def getIconForExecutable(executable: FileWrapper) -> PyQt6.QtGui.QIcon:
|
||||
"""
|
||||
...
|
||||
|
||||
def getProductVersion(executable: FileWrapper) -> str:
|
||||
def getProductVersion(
|
||||
executable: Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]
|
||||
) -> str:
|
||||
"""
|
||||
Retrieve the product version of the given executable.
|
||||
|
||||
@@ -343,7 +345,11 @@ class ExecutableForcedLoadSetting:
|
||||
) -> ExecutableForcedLoadSetting: ...
|
||||
|
||||
class ExecutableInfo:
|
||||
def __init__(self: ExecutableInfo, title: str, binary: FileWrapper): ...
|
||||
def __init__(
|
||||
self: ExecutableInfo,
|
||||
title: str,
|
||||
binary: Union[str, os.PathLike, PyQt6.QtCore.QFileInfo],
|
||||
): ...
|
||||
def arguments(self: ExecutableInfo) -> Sequence[str]: ...
|
||||
def asCustom(self: ExecutableInfo) -> ExecutableInfo: ...
|
||||
def binary(self: ExecutableInfo) -> PyQt6.QtCore.QFileInfo: ...
|
||||
@@ -354,7 +360,7 @@ class ExecutableInfo:
|
||||
def withArgument(self: ExecutableInfo, argument: str) -> ExecutableInfo: ...
|
||||
def withSteamAppId(self: ExecutableInfo, app_id: str) -> ExecutableInfo: ...
|
||||
def withWorkingDirectory(
|
||||
self: ExecutableInfo, directory: DirectoryWrapper
|
||||
self: ExecutableInfo, directory: Union[str, os.PathLike, PyQt6.QtCore.QDir]
|
||||
) -> ExecutableInfo: ...
|
||||
def workingDirectory(self: ExecutableInfo) -> PyQt6.QtCore.QDir: ...
|
||||
|
||||
@@ -1280,7 +1286,7 @@ class IInstallationManager:
|
||||
def installArchive(
|
||||
self: IInstallationManager,
|
||||
mod_name: GuessedString,
|
||||
archive: FileWrapper,
|
||||
archive: Union[str, os.PathLike, PyQt6.QtCore.QFileInfo],
|
||||
mod_id: int = 0,
|
||||
) -> Tuple[InstallResult, str, int]:
|
||||
"""
|
||||
@@ -1945,7 +1951,9 @@ class IOrganizer:
|
||||
"""
|
||||
...
|
||||
def findFileInfos(
|
||||
self: IOrganizer, path: DirectoryWrapper, filter: Callable[[FileInfo], bool]
|
||||
self: IOrganizer,
|
||||
path: Union[str, os.PathLike, PyQt6.QtCore.QDir],
|
||||
filter: Callable[[FileInfo], bool],
|
||||
) -> Sequence[FileInfo]:
|
||||
"""
|
||||
Find files in the virtual directory matching the specified filter.
|
||||
@@ -1960,7 +1968,9 @@ class IOrganizer:
|
||||
...
|
||||
@overload
|
||||
def findFiles(
|
||||
self: IOrganizer, path: DirectoryWrapper, filter: Callable[[str], bool]
|
||||
self: IOrganizer,
|
||||
path: Union[str, os.PathLike, PyQt6.QtCore.QDir],
|
||||
filter: Callable[[str], bool],
|
||||
) -> Sequence[str]:
|
||||
"""
|
||||
Find files in the given folder that matches the given filter.
|
||||
@@ -1975,7 +1985,9 @@ class IOrganizer:
|
||||
...
|
||||
@overload
|
||||
def findFiles(
|
||||
self: IOrganizer, path: DirectoryWrapper, patterns: Sequence[str]
|
||||
self: IOrganizer,
|
||||
path: Union[str, os.PathLike, PyQt6.QtCore.QDir],
|
||||
patterns: Sequence[str],
|
||||
) -> Sequence[str]:
|
||||
"""
|
||||
Find files in the given folder that matches one of the given glob patterns.
|
||||
@@ -1990,7 +2002,7 @@ class IOrganizer:
|
||||
...
|
||||
@overload
|
||||
def findFiles(
|
||||
self: IOrganizer, path: DirectoryWrapper, pattern: str
|
||||
self: IOrganizer, path: Union[str, os.PathLike, PyQt6.QtCore.QDir], pattern: str
|
||||
) -> Sequence[str]:
|
||||
"""
|
||||
Find files in the given folder that matches the given glob pattern.
|
||||
@@ -2036,7 +2048,9 @@ class IOrganizer:
|
||||
"""
|
||||
...
|
||||
def installMod(
|
||||
self: IOrganizer, filename: FileWrapper, name_suggestion: str = ""
|
||||
self: IOrganizer,
|
||||
filename: Union[str, os.PathLike, PyQt6.QtCore.QFileInfo],
|
||||
name_suggestion: str = "",
|
||||
) -> IModInterface:
|
||||
"""
|
||||
Install a mod archive at the specified location.
|
||||
@@ -2350,7 +2364,9 @@ class IOrganizer:
|
||||
save_changes: If True, the relevant profile information is saved first (enabled mods and order of mods).
|
||||
"""
|
||||
...
|
||||
def resolvePath(self: IOrganizer, filename: FileWrapper) -> str:
|
||||
def resolvePath(
|
||||
self: IOrganizer, filename: Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]
|
||||
) -> str:
|
||||
"""
|
||||
Resolves a path relative to the virtual data directory to its absolute real path.
|
||||
|
||||
@@ -2398,9 +2414,9 @@ class IOrganizer:
|
||||
...
|
||||
def startApplication(
|
||||
self: IOrganizer,
|
||||
executable: FileWrapper,
|
||||
executable: Union[str, os.PathLike, PyQt6.QtCore.QFileInfo],
|
||||
args: Sequence[str] = [],
|
||||
cwd: DirectoryWrapper = "",
|
||||
cwd: Union[str, os.PathLike, PyQt6.QtCore.QDir] = "",
|
||||
profile: str = "",
|
||||
forcedCustomOverwrite: str = "",
|
||||
ignoreCustomOverwrite: bool = False,
|
||||
@@ -3710,7 +3726,9 @@ class ISaveGame:
|
||||
"""
|
||||
|
||||
def __init__(self: ISaveGame): ...
|
||||
def allFiles(self: ISaveGame) -> Sequence[str]:
|
||||
def allFiles(
|
||||
self: ISaveGame,
|
||||
) -> Sequence[Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]]:
|
||||
"""
|
||||
Returns:
|
||||
The list of all files related to this save.
|
||||
@@ -3727,7 +3745,7 @@ class ISaveGame:
|
||||
The creation time of the save.
|
||||
"""
|
||||
...
|
||||
def getFilepath(self: ISaveGame) -> str:
|
||||
def getFilepath(self: ISaveGame) -> Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]:
|
||||
"""
|
||||
Returns:
|
||||
The path name to the (main) file or folder for the save.
|
||||
@@ -4235,20 +4253,13 @@ class SaveGameInfo(abc.ABC):
|
||||
class ScriptExtender(abc.ABC):
|
||||
def __init__(self: ScriptExtender): ...
|
||||
@abc.abstractmethod
|
||||
def BinaryName(self: ScriptExtender) -> str:
|
||||
def binaryName(self: ScriptExtender) -> str:
|
||||
"""
|
||||
Returns:
|
||||
The name of the script extender binary.
|
||||
"""
|
||||
...
|
||||
@abc.abstractmethod
|
||||
def PluginPath(self: ScriptExtender) -> str:
|
||||
"""
|
||||
Returns:
|
||||
The script extender plugin path, relative to the data folder.
|
||||
"""
|
||||
...
|
||||
@abc.abstractmethod
|
||||
def getArch(self: ScriptExtender) -> int:
|
||||
"""
|
||||
Returns:
|
||||
@@ -4277,13 +4288,22 @@ class ScriptExtender(abc.ABC):
|
||||
"""
|
||||
...
|
||||
@abc.abstractmethod
|
||||
def loaderPath(self: ScriptExtender) -> str:
|
||||
def loaderPath(
|
||||
self: ScriptExtender,
|
||||
) -> Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]:
|
||||
"""
|
||||
Returns:
|
||||
The full path to the script extender loader.
|
||||
"""
|
||||
...
|
||||
@abc.abstractmethod
|
||||
def pluginPath(self: ScriptExtender) -> Union[str, os.PathLike, PyQt6.QtCore.QDir]:
|
||||
"""
|
||||
Returns:
|
||||
The script extender plugin path, relative to the data folder.
|
||||
"""
|
||||
...
|
||||
@abc.abstractmethod
|
||||
def savegameExtension(self: ScriptExtender) -> str:
|
||||
"""
|
||||
Retrieve the extension of script extender save files.
|
||||
@@ -4320,7 +4340,9 @@ class UnmanagedMods(abc.ABC):
|
||||
"""
|
||||
...
|
||||
@abc.abstractmethod
|
||||
def referenceFile(self: UnmanagedMods, mod_name: str) -> PyQt6.QtCore.QFileInfo:
|
||||
def referenceFile(
|
||||
self: UnmanagedMods, mod_name: str
|
||||
) -> Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]:
|
||||
"""
|
||||
Retrieve the reference file for the requested mod.
|
||||
|
||||
@@ -4335,7 +4357,9 @@ class UnmanagedMods(abc.ABC):
|
||||
"""
|
||||
...
|
||||
@abc.abstractmethod
|
||||
def secondaryFiles(self: UnmanagedMods, mod_name: str) -> Sequence[str]:
|
||||
def secondaryFiles(
|
||||
self: UnmanagedMods, mod_name: str
|
||||
) -> Sequence[Union[str, os.PathLike, PyQt6.QtCore.QFileInfo]]:
|
||||
"""
|
||||
Retrieve the secondary files for the requested mod.
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ import PyQt6.QtGui
|
||||
import PyQt6.QtWidgets
|
||||
|
||||
class TaskDialog:
|
||||
"""
|
||||
Customizable choice dialog.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self: TaskDialog,
|
||||
parent: PyQt6.QtWidgets.QWidget = None,
|
||||
@@ -19,31 +23,149 @@ class TaskDialog:
|
||||
icon: PyQt6.QtWidgets.QMessageBox.Icon = PyQt6.QtWidgets.QMessageBox.Icon.NoIcon,
|
||||
buttons: List[TaskDialogButton] = [],
|
||||
remember: Union[str, Tuple[str, str]] = "",
|
||||
): ...
|
||||
def addButton(self: TaskDialog, button: TaskDialogButton) -> TaskDialog: ...
|
||||
def addContent(self: TaskDialog, widget: PyQt6.QtWidgets.QWidget): ...
|
||||
def exec(self: TaskDialog) -> PyQt6.QtWidgets.QMessageBox.StandardButton: ...
|
||||
def setContent(self: TaskDialog, content: str) -> TaskDialog: ...
|
||||
def setDetails(self: TaskDialog, details: str) -> TaskDialog: ...
|
||||
def setIcon(
|
||||
self: TaskDialog, icon: PyQt6.QtWidgets.QMessageBox.Icon
|
||||
) -> TaskDialog: ...
|
||||
def setMain(self: TaskDialog, main: str) -> TaskDialog: ...
|
||||
def setRemember(self: TaskDialog, action: str, file: str = "") -> TaskDialog: ...
|
||||
def setTitle(self: TaskDialog, title: str) -> TaskDialog: ...
|
||||
def setWidth(self: TaskDialog, widget: int): ...
|
||||
):
|
||||
"""
|
||||
Construct a new TaskDialog.
|
||||
|
||||
Args:
|
||||
parent: Parent widget of the dialog.
|
||||
title: Title of the dialog.
|
||||
main: Header of the dialog (big text at the top).
|
||||
content: Main message of the dialog (text below main).
|
||||
details: Details for the dialog, initially collapsed (bottom of the dialog).
|
||||
icon: Icon for the dialog.
|
||||
buttons: List of buttons for the dialog.
|
||||
remember: Remember the choice for this dialog.
|
||||
"""
|
||||
...
|
||||
def addButton(self: TaskDialog, button: TaskDialogButton) -> TaskDialog:
|
||||
"""
|
||||
Add a custom button to this TaskDialog.
|
||||
|
||||
Args:
|
||||
button: Button to add to the dialog.
|
||||
"""
|
||||
...
|
||||
def addContent(self: TaskDialog, widget: PyQt6.QtWidgets.QWidget):
|
||||
"""
|
||||
Add a custom widget content to this TaskDialog. Widget content are put between
|
||||
content and buttons (above buttons).
|
||||
|
||||
Args:
|
||||
widget: Widget to add.
|
||||
"""
|
||||
...
|
||||
def exec(self: TaskDialog) -> PyQt6.QtWidgets.QMessageBox.StandardButton:
|
||||
"""
|
||||
Display this dialog and wait for user-interaction to return. This is a blocking
|
||||
function.
|
||||
|
||||
Returns:
|
||||
The button clicked by the user. Without custom buttons, this return Ok, otherwise it returns the button set in the TaskDialogButton.
|
||||
"""
|
||||
...
|
||||
def setContent(self: TaskDialog, content: str) -> TaskDialog:
|
||||
"""
|
||||
Set the top-level message of this dialog.
|
||||
|
||||
Args:
|
||||
content: Top-level message to set.
|
||||
"""
|
||||
...
|
||||
def setDetails(self: TaskDialog, details: str) -> TaskDialog:
|
||||
"""
|
||||
Set the details for this TaskDialog.
|
||||
|
||||
The details are hidden by default and the user can display them by clicking
|
||||
the "Details" button at the bottom of the TaskDialog.
|
||||
|
||||
Args:
|
||||
details: Details content to display. Can be a multi-line string.
|
||||
"""
|
||||
...
|
||||
def setIcon(self: TaskDialog, icon: PyQt6.QtWidgets.QMessageBox.Icon) -> TaskDialog:
|
||||
"""
|
||||
Set the icon of the dialog.
|
||||
|
||||
Args:
|
||||
icon: Icon of the dialog.
|
||||
"""
|
||||
...
|
||||
def setMain(self: TaskDialog, main: str) -> TaskDialog:
|
||||
"""
|
||||
Set the main message of the dialog. The main message is displayed at the top of
|
||||
the dialog in large font.
|
||||
|
||||
Args:
|
||||
main: Main message of the dialog.
|
||||
"""
|
||||
...
|
||||
def setRemember(self: TaskDialog, action: str, file: str = "") -> TaskDialog:
|
||||
"""
|
||||
Configure the dialog to remember user-choice.
|
||||
"""
|
||||
...
|
||||
def setTitle(self: TaskDialog, title: str) -> TaskDialog:
|
||||
"""
|
||||
Set the title of the dialog.
|
||||
|
||||
Args:
|
||||
title: Title of the dialog.
|
||||
"""
|
||||
...
|
||||
def setWidth(self: TaskDialog, width: int):
|
||||
"""
|
||||
Set the width of the dialog.
|
||||
|
||||
Args:
|
||||
width: Width of the dialog.
|
||||
"""
|
||||
...
|
||||
|
||||
class TaskDialogButton:
|
||||
"""
|
||||
Special button to be used inside TaskDialog widgets.
|
||||
"""
|
||||
|
||||
@property
|
||||
def button(self) -> PyQt6.QtWidgets.QMessageBox.StandardButton: ...
|
||||
@button.setter
|
||||
def button(self, arg0: PyQt6.QtWidgets.QMessageBox.StandardButton): ...
|
||||
@property
|
||||
def description(self) -> str: ...
|
||||
@description.setter
|
||||
def description(self, arg0: str): ...
|
||||
@property
|
||||
def text(self) -> str: ...
|
||||
@text.setter
|
||||
def text(self, arg0: str): ...
|
||||
@overload
|
||||
def __init__(
|
||||
self: TaskDialogButton,
|
||||
text: str,
|
||||
description: str,
|
||||
button: PyQt6.QtWidgets.QMessageBox.StandardButton,
|
||||
): ...
|
||||
):
|
||||
"""
|
||||
Create a TaskDialogButton.
|
||||
|
||||
Args:
|
||||
text: Label of the button.
|
||||
description: Description of the button.
|
||||
button: Value returned by TaskDialog.exec() if this button is clicked.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def __init__(
|
||||
self: TaskDialogButton,
|
||||
text: str,
|
||||
button: PyQt6.QtWidgets.QMessageBox.StandardButton,
|
||||
): ...
|
||||
):
|
||||
"""
|
||||
Create a TaskDialogButton without description.
|
||||
|
||||
Args:
|
||||
text: Label of the button.
|
||||
button: Value returned by TaskDialog.exec() if this button is clicked.
|
||||
"""
|
||||
...
|
||||
|
||||
Reference in New Issue
Block a user