def __init__(self, filename: str, cb_open_view: Callable[[Gtk.TreeIter], None]): self.filename = filename self._rom: NintendoDSRom = None # type: ignore self._rom_module: Optional['RomModule'] = None self._loaded_modules: Dict[str, AbstractModule] = {} self._sprite_renderer: Optional[SpriteProvider] = None self._string_provider: Optional[StringProvider] = None # Dict of filenames -> models self._opened_files: Dict[str, Any] = {} self._opened_files_contexts: Dict[str, ModelContext] = {} # List of filenames that were requested to be opened threadsafe. self._files_threadsafe: List[str] = [] self._files_unsafe: List[str] = [] # Dict of filenames -> file handler object self._file_handlers: Dict[str, Type[DataHandler]] = {} self._file_handler_kwargs: Dict[str, Dict[str, Any]] = {} # List of modified filenames self._modified_files: List[str] = [] self._forced_modified = False # Callback for opening views using iterators from the main view list. self._cb_open_view: Callable[[Gtk.TreeIter], None] = cb_open_view self._project_fm = ProjectFileManager(filename) self._icon_banner: Optional[IconBanner] = None # Lazy self._patcher: Optional[Patcher] = None
def __init__(self): self.config_dir = os.path.join(ProjectFileManager.shared_config_dir()) os.makedirs(self.config_dir, exist_ok=True) self.config_file = os.path.join(self.config_dir, CONFIG_FILE_NAME) self.loaded_config = configparser.ConfigParser() if os.path.exists(self.config_file): with open_utf8(self.config_file, 'r') as f: self.loaded_config.read_file(f)
def __init__(self): self.config_dir = os.path.join(ProjectFileManager.shared_config_dir()) os.makedirs(self.config_dir, exist_ok=True) self.config_file = os.path.join(self.config_dir, CONFIG_FILE_NAME) self.loaded_config = configparser.ConfigParser() if os.path.exists(self.config_file): try: with open_utf8(self.config_file, 'r') as f: self.loaded_config.read_file(f) except BaseException as err: logger.error("Error reading config, falling back to default.", exc_info=err)
def setup_logging(): """ Creates a rotating log """ sys.excepthook = handle_exception dirn = ProjectFileManager.shared_config_dir() os.makedirs(dirn, exist_ok=True) handler = RotatingFileHandler(os.path.join(dirn, 'skytemple.log'), maxBytes=100000, backupCount=5) logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler(), handler])
def open_rom(self, filename: str): self._rom = NintendoDSRom.fromFile(filename) self._rom_filename = filename self._project_fm = ProjectFileManager(filename) self._static_data = get_ppmdu_config_for_rom(self._rom) self._open_files = {}
class StandaloneDebuggerControlContext(AbstractDebuggerControlContext): """Context for running the debugger as a standalone application.""" def __init__(self, main_window: Gtk.Window): self._rom: Optional[NintendoDSRom] = None self._rom_filename: Optional[str] = None self._project_fm: Optional[ProjectFileManager] = None self._static_data: Optional[Pmd2Data] = None self._open_files: Dict[str, SsbLoadedFile] = {} self._main_window = main_window def allows_interactive_file_management(self) -> bool: return True def before_quit(self) -> bool: return True def on_quit(self): Gtk.main_quit() emu_instance = EmulatorThread.instance() if emu_instance is not None: emu_instance.end() EmulatorThread.destroy_lib() def on_focus(self): pass def on_blur(self): pass def on_selected_string_changed(self, string: str): pass def show_ssb_script_editor(self) -> bool: return True def open_rom(self, filename: str): self._rom = NintendoDSRom.fromFile(filename) self._rom_filename = filename self._project_fm = ProjectFileManager(filename) self._static_data = get_ppmdu_config_for_rom(self._rom) self._open_files = {} def get_project_dir(self) -> str: return self._project_fm.dir() # type: ignore def load_script_files(self) -> ScriptFiles: return load_script_files(get_rom_folder(self._rom, SCRIPT_DIR)) # type: ignore def is_project_loaded(self) -> bool: return self._rom is not None def get_rom_filename(self) -> str: self._check_loaded() return self._rom_filename # type: ignore def save_rom(self): self._check_loaded() self._rom.saveToFile(self._rom_filename) def get_static_data(self) -> Pmd2Data: self._check_loaded() return self._static_data # type: ignore def get_project_filemanager(self) -> ProjectFileManager: self._check_loaded() return self._project_fm # type: ignore @synchronized_now(file_load_lock) def get_ssb(self, filename, ssb_file_manager: 'SsbFileManager') -> 'SsbLoadedFile': self._check_loaded() if filename not in self._open_files: try: ssb_bin = self._rom.getFileByName(filename) # type: ignore except ValueError as err: raise FileNotFoundError(str(err)) from err self._open_files[filename] = SsbLoadedFile( filename, FileType.SSB.deserialize(ssb_bin, self._static_data), ssb_file_manager, self._project_fm # type: ignore ) self._open_files[filename].exps.ssb_hash = ssb_file_manager.hash( ssb_bin) return self._open_files[filename] def on_script_edit(self, filename): pass @synchronized_now(file_load_lock) def save_ssb(self, filename, ssb_model, ssb_file_manager: 'SsbFileManager'): self._check_loaded() self._rom.setFileByName( # type: ignore filename, FileType.SSB.serialize(ssb_model, self._static_data)) self.save_rom() def _check_loaded(self): if self._rom is None: raise RuntimeError("No ROM is currently loaded.") def open_scene_editor(self, type_of_scene, filename): self._scene_editing_not_supported() def open_scene_editor_for_map(self, map_name): self._scene_editing_not_supported() def edit_position_mark(self, mapname: str, scene_name: str, scene_type: str, pos_marks: List[SourceMapPositionMark], pos_mark_to_edit: int) -> bool: self.display_error( None, f"Visual Position Mark editing is not supported in the standalone version of " f"SkyTemple Script Engine Debugger.\n" f"Please open the debugger through the SkyTemple main application " f"instead.") return False def _scene_editing_not_supported(self): self.display_error( None, f"Scene editing is not supported in the standalone version of " f"SkyTemple Script Engine Debugger.\n" f"Please open the debugger through the SkyTemple main application " f"instead.", "Action not supported") def display_error(self, exc_info, error_message, error_title='SkyTemple Script Engine Debugger - Error', *, context: Optional[Dict[str, Capturable]] = None): logger.error(error_message, exc_info=exc_info) md = self.message_dialog_cls()(self._main_window, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, error_message, title=error_title) md.set_position(Gtk.WindowPosition.CENTER) md.run() md.destroy() def capture_error(self, exc_info, *, context: Optional[Dict[str, Capturable]] = None): pass def get_special_words(self) -> Iterable[str]: """ Just returns the script operations and constants, more data is only supported by the main SkyTemple application """ yield from self._static_data.script_data.op_codes__by_name.keys( ) # type: ignore yield from ( x.name.replace('$', '') for x in SsbConstant.collect_all(self._static_data.script_data) ) # type: ignore yield from EXPS_KEYWORDS @staticmethod def message_dialog_cls(): return Gtk.MessageDialog
def on_settings_dir_clicked(self, *args): open_dir(ProjectFileManager.shared_config_dir())