コード例 #1
0
    def on_file_opened(self):
        """Update the UI after a ROM file has been opened."""
        assert current_thread() == main_thread
        logger.debug('File opened.')
        # Init the sprite provider
        RomProject.get_current().get_sprite_provider().init_loader(
            self.window.get_screen())

        self._init_window_after_rom_load(
            os.path.basename(RomProject.get_current().filename))
        try:
            # Load root node, ROM
            project = RomProject.get_current()
            rom_module = project.get_rom_module()
            rom_module.load_rom_data()

            # Initialize patch-specific properties for this rom project
            project.init_patch_properties()

            logger.info(
                f'Loaded ROM {project.filename} ({rom_module.get_static_data().game_edition})'
            )
            logger.debug(f"Loading ROM module tree items...")
            rom_module.load_tree_items(self._item_store, None)
            root_node = rom_module.get_root_node()

            # Tell the debugger
            self._debugger_manager.handle_project_change()

            # Load item tree items
            for module in sorted(project.get_modules(False),
                                 key=lambda m: m.sort_order()):
                logger.debug(
                    f"Loading {module.__class__.__name__} module tree items..."
                )
                module.load_tree_items(self._item_store, root_node)
                if module.__class__.__name__ == 'MapBgModule':
                    self._loaded_map_bg_module = module
            # TODO: Load settings from ROM for history, bookmarks, etc? - separate module?
            logger.debug(f"Loaded all modules.")

            # Trigger event
            EventManager.instance().trigger(EVT_PROJECT_OPEN, project=project)

            # Select & load main ROM item by default
            selection: TreeSelection = self._main_item_list.get_selection()
            selection.select_path(self._item_store.get_path(root_node))
            self.load_view(self._item_store, root_node, self._main_item_list)
        except BaseException as ex:
            self.on_file_opened_error(sys.exc_info(), ex)
            return

        if self._loading_dialog is not None:
            self._loading_dialog.hide()
            self._loading_dialog = None

        # Show the initial assistant window
        if not self.settings.get_assistant_shown():
            self.on_settings_show_assistant_clicked()
コード例 #2
0
 def _open_file(self, filename: str):
     """Open a file"""
     if self._check_open_file():
         self._loading_dialog = self.builder.get_object('file_opening_dialog')
         self.builder.get_object('file_opening_dialog_label').set_label(
             f'Loading ROM "{os.path.basename(filename)}"...'
         )
         logger.debug(f'Opening {filename}.')
         RomProject.open(filename, self)
         # Add to the list of recent files and save
         self._update_recent_files(filename)
         # Show loading spinner
         self._loading_dialog.run()
コード例 #3
0
 def open_scene_editor_for_map(self, map_name):
     try:
         RomProject.get_current().request_open(OpenRequest(
             REQUEST_TYPE_SCENE, map_name
         ), True)
         self._manager.main_window.present()
     except ValueError:
         md = Gtk.MessageDialog(self._manager.get_window(),
                                Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
                                Gtk.ButtonsType.OK, f"A scene for this script was not found.",
                                title="No Scenes Found")
         md.run()
         md.destroy()
コード例 #4
0
 def _open_file(self, filename: str):
     """Open a file"""
     if self._check_open_file(filename):
         self._loading_dialog = self.builder.get_object(
             'file_opening_dialog')
         # noinspection PyUnusedLocal
         rom_name = os.path.basename(filename)
         self.builder.get_object('file_opening_dialog_label').set_label(
             f(_('Loading ROM "{rom_name}"...')))
         logger.debug(f(_('Opening {filename}.')))
         RomProject.open(filename, self)  # type: ignore
         # Add to the list of recent files and save
         self._update_recent_files(filename)
         # Show loading spinner
         self._loading_dialog.run()
コード例 #5
0
ファイル: context.py プロジェクト: marius851000/skytemple
 def _get_special_words_uncached(self):
     pro = RomProject.get_current()
     yield from self.get_static_data().script_data.op_codes__by_name.keys()
     yield from (x.name.replace('$', '') for x in SsbConstant.collect_all(
         self.get_static_data().script_data))
     yield from EXPS_KEYWORDS
     yield from pro.get_string_provider().get_all(StringType.POKEMON_NAMES)
コード例 #6
0
 def on_main_item_list_button_press_event(self, tree: TreeView, event: Gdk.Event):
     """Handle click on item: Switch view"""
     assert current_thread() == main_thread
     if event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS:
         model, treeiter = tree.get_selection().get_selected()
         if model is not None and treeiter is not None and RomProject.get_current() is not None:
             self.load_view(model, treeiter, tree, False)
コード例 #7
0
 def get_ssb(self, filename, ssb_file_manager: 'SsbFileManager') -> 'SsbLoadedFile':
     f: 'SsbLoadedFile' = RomProject.get_current().open_file_in_rom(filename, SsbLoadedFileHandler,
                                                                    filename=filename,
                                                                    static_data=self.get_static_data(),
                                                                    project_fm=self._project_fm)
     f.file_manager = ssb_file_manager
     return f
コード例 #8
0
ファイル: context.py プロジェクト: SkyTemple/skytemple
 def edit_position_mark(self, mapname: str, scene_name: str,
                        scene_type: str,
                        pos_marks: List[SourceMapPositionMark],
                        pos_mark_to_edit: int) -> bool:
     try:
         cntrl: PosMarkEditorController = RomProject.get_current(
         ).get_module(
             'script').get_pos_mark_editor_controller(  # type: ignore
                 self._manager.get_window(), mapname,
                 scene_name.split('/')[-1], scene_type, pos_marks,
                 pos_mark_to_edit)
         return cntrl.run() == Gtk.ResponseType.OK
     except IndexError:
         md = SkyTempleMessageDialog(
             self._manager.get_window(),
             Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
             Gtk.ButtonsType.OK, f"SkyTemple is missing the 'script' "
             f"module to handle this request.")
         md.run()
         md.destroy()
     except ValueError as err:
         md = SkyTempleMessageDialog(self._manager.get_window(),
                                     Gtk.DialogFlags.DESTROY_WITH_PARENT,
                                     Gtk.MessageType.INFO,
                                     Gtk.ButtonsType.OK, str(err))
         md.run()
         md.destroy()
     return False
コード例 #9
0
    def on_save_as_button_clicked(self, wdg):
        project = RomProject.get_current()

        dialog = Gtk.FileChooserNative.new(
            "Save As...",
            self.window,
            Gtk.FileChooserAction.SAVE,
            None, None
        )
        dialog.set_filename(project.filename)

        add_dialog_file_filters(dialog)

        response = dialog.run()
        fn = dialog.get_filename()
        if '.' not in fn:
            fn += '.nds'
        dialog.destroy()

        if response == Gtk.ResponseType.ACCEPT:
            project.filename = fn
            self._save(True)
            project.get_rom_module().update_filename()

            self._update_recent_files(fn)

            self.reload_view()
コード例 #10
0
ファイル: context.py プロジェクト: marius851000/skytemple
 def save_ssb(self, filename, ssb_model,
              ssb_file_manager: 'SsbFileManager'):
     project = RomProject.get_current()
     ssb_loaded_file = self.get_ssb(filename, ssb_file_manager)
     ssb_loaded_file.ssb_model = ssb_model
     project.prepare_save_model(filename, assert_that=ssb_loaded_file)
     project.save_as_is()
コード例 #11
0
 def handle_project_change(self):
     """
     If the debugger is currently open, handles changing the project for it.
     The global singleton instance of RomProject is used.
     """
     project = RomProject.get_current()
     if project is not None and self.is_opened():
         self._opened_main_controller.load_rom()
コード例 #12
0
    def on_file_saved(self):
        if self._loading_dialog is not None:
            self._loading_dialog.hide()
            self._loading_dialog = None

        rom = RomProject.get_current()
        self._set_title(os.path.basename(rom.filename), False)
        recursive_down_item_store_mark_as_modified(self._item_store[self._item_store.get_iter_first()], False)
コード例 #13
0
ファイル: module.py プロジェクト: retke/skytemple
    def __init__(self, rom_project: RomProject):
        """Loads the list of backgrounds for the ROM."""
        self.project = rom_project
        self.bgs: BgList = rom_project.open_file_in_rom(
            MAP_BG_LIST, FileType.BG_LIST_DAT)

        self._tree_model = None
        self._tree_level_iter = []
コード例 #14
0
    def _init_window_before_view_load(self, node: TreeModelRow):
        """Update the subtitle / breadcrumb before switching views"""
        bc = ""
        parent = node
        bc_array = []
        while parent:
            bc = f" > {parent[6]}" + bc
            bc_array.append(parent[6])
            parent = parent.parent
        bc = bc[3:]
        self._current_breadcrumbs = bc_array
        self.window.get_titlebar().set_subtitle(bc)

        # Check if files are modified
        if RomProject.get_current().has_modifications():
            self._set_title(
                os.path.basename(RomProject.get_current().filename), True)
コード例 #15
0
ファイル: module.py プロジェクト: SkyTemple/skytemple
    def __init__(self, rom_project: RomProject):
        """Loads the list of backgrounds for the ROM."""
        self.project = rom_project
        self.bgs: BgListProtocol = rom_project.open_file_in_rom(MAP_BG_LIST, FileType.BG_LIST_DAT)

        self._tree_model: Gtk.TreeModel
        self._tree_level_iter: List[Gtk.TreeIter] = []
        self._sub_nodes: Gtk.TreeIter
        self._other_node: Gtk.TreeIter
コード例 #16
0
 def on_intro_dialog_created_with_clicked(self, *args):
     if RomProject.get_current() is None or self._loaded_map_bg_module is None:
         md = SkyTempleMessageDialog(MainController.window(),
                                     Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR,
                                     Gtk.ButtonsType.OK, _("A project must be opened to use this."))
         md.set_position(Gtk.WindowPosition.CENTER)
         md.run()
         md.destroy()
         return
     self._loaded_map_bg_module.add_created_with_logo()
コード例 #17
0
 def _open_file(self, filename: str):
     """Open a file"""
     if self._check_open_file():
         self._loading_dialog = self.builder.get_object(
             'file_opening_dialog')
         self.builder.get_object('file_opening_dialog_label').set_label(
             f'Loading ROM "{os.path.basename(filename)}"...')
         logger.debug(f'Opening {filename}.')
         RomProject.open(filename, self)
         # Add to the list of recent files and save
         new_recent_files = []
         for rf in self.recent_files:
             if rf != filename and rf not in new_recent_files:
                 new_recent_files.append(rf)
         new_recent_files.insert(0, filename)
         self.recent_files = new_recent_files
         self.settings.set_recent_files(self.recent_files)
         # TODO: Update recent files store too!
         # Show loading spinner
         self._loading_dialog.run()
コード例 #18
0
    def _init_window_before_view_load(self, node: Gtk.TreeModelRow):
        """Update the subtitle / breadcrumb before switching views"""
        try:
            bc = ""
            parent = node
            bc_array = []
            while parent:
                bc = f" > {parent[6]}" + bc
                bc_array.append(parent[6])
                parent = parent.parent
            bc = bc[3:]
            self._current_breadcrumbs = bc_array
            self._window.get_titlebar().set_subtitle(bc)

            # Check if files are modified
            if RomProject.get_current().has_modifications():  # type: ignore
                self._set_title(
                    os.path.basename(RomProject.get_current().filename),
                    True)  # type: ignore
        except BaseException as ex:
            logger.warning("Failed updating window titles.", exc_info=ex)
コード例 #19
0
 def open_scene_editor(self, type_of_scene, path):
     try:
         map_name, filename = path.split('/')[-2:]
         if type_of_scene == 'ssa':
             RomProject.get_current().request_open(OpenRequest(
                 REQUEST_TYPE_SCENE_SSA, (map_name, filename.replace(SSB_EXT, SSA_EXT))
             ), True)
         elif type_of_scene == 'sss':
             RomProject.get_current().request_open(OpenRequest(
                 REQUEST_TYPE_SCENE_SSS, (map_name, filename.replace(SSB_EXT, SSS_EXT))
             ), True)
         elif type_of_scene == 'sse':
             RomProject.get_current().request_open(OpenRequest(
                 REQUEST_TYPE_SCENE_SSE, map_name
             ), True)
         else:
             raise ValueError()
         self._manager.main_window.present()
     except ValueError:
         md = Gtk.MessageDialog(self._manager.get_window(),
                                Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
                                Gtk.ButtonsType.OK, f"A scene for this script was not found.",
                                title="No Scenes Found")
         md.run()
         md.destroy()
コード例 #20
0
def collect_state_context() -> Dict[str, 'Captured']:
    from skytemple.controller.main import MainController
    from skytemple.core.rom_project import RomProject
    from skytemple_files.common.util import capture_any
    rom_project = RomProject.get_current()
    try:
        view_state = MainController._instance._current_view_module.collect_debugging_info(  # type: ignore
            MainController._instance._current_view_controller  # type: ignore
        )
        if "models" in view_state:  # type: ignore
            view_state["models"] = {
                k: capture_any(v)
                for k, v in view_state["models"].items()
            }  # type: ignore
    except Exception as ex:
        view_state = {"error_collecting": str(ex)}
    w, h = MainController.window().get_size()
    dw = if_not_none(MainController.debugger_manager()._opened_main_window,
                     lambda w: w.get_size()[0])
    dh = if_not_none(MainController.debugger_manager()._opened_main_window,
                     lambda w: w.get_size()[1])
    return {
        "skytemple": {
            "window": {
                "width": w,
                "height": h,
            },
            "rom": {
                "filename":
                if_not_none(rom_project, lambda p: p.get_rom_name()),
                "edition":
                if_not_none(rom_project,
                            lambda p: p.get_rom_module().get_static_data()),
            },
            "module":
            type(MainController._instance._current_view_module).__qualname__,
            "view": MainController._instance._current_view_controller_class.
            __qualname__,  # type: ignore
            "view_state": view_state
        },
        "ssb_debugger": {
            "window": {
                "width": dw,
                "height": dh,
            },
            "open_scripts":
            debugger_open_scripts(MainController.debugger_manager()),
            "focused_script":
            debugger_focused_script(MainController.debugger_manager()),
            #"emulator_state": debugger_emulator_state(MainController.debugger_manager())
        }
    }
コード例 #21
0
    def _save(self, force=False):
        rom = RomProject.get_current()

        if rom.has_modifications() or force:
            self._loading_dialog = self.builder.get_object(
                'file_opening_dialog')
            self.builder.get_object('file_opening_dialog_label').set_label(
                f'Saving ROM "{os.path.basename(rom.filename)}"...')
            logger.debug(f'Saving {rom.filename}.')

            # This will trigger a signal.
            rom.save(self)
            self._loading_dialog.run()
コード例 #22
0
    def _save(self, force=False, after_save_action=None):
        rom = RomProject.get_current()

        if rom is not None and (rom.has_modifications() or force):
            self._after_save_action = after_save_action
            self._loading_dialog = self.builder.get_object(
                'file_opening_dialog')
            # noinspection PyUnusedLocal
            rom_name = os.path.basename(rom.filename)
            self.builder.get_object('file_opening_dialog_label').set_label(
                f(_('Saving ROM "{rom_name}"...')))
            logger.debug(f(_('Saving {rom.filename}.')))

            # This will trigger a signal.
            rom.save(self)  # type: ignore
            self._loading_dialog.run()
コード例 #23
0
 def on_main_window_delete_event(self, *args):
     if not self._debugger_manager.close():
         # Cancel
         return True
     rom = RomProject.get_current()
     if rom is not None and rom.has_modifications():
         response = self._show_are_you_sure(rom)
         if response == 0:
             return False
         elif response == 1:
             # Save (True on success, False on failure. Don't close the file if we can't save it...)
             self._save(after_save_action=lambda: self._window.destroy())
             return True
         else:
             # Cancel
             return True
     return False
コード例 #24
0
ファイル: context.py プロジェクト: SkyTemple/skytemple
 def open_scene_editor_for_map(self, map_name):
     try:
         current = RomProject.get_current()
         assert current is not None
         current.request_open(OpenRequest(REQUEST_TYPE_SCENE, map_name),
                              True)
         if self._manager.main_window is not None:
             self._manager.main_window.present()
     except ValueError:
         md = SkyTempleMessageDialog(
             self._manager.get_window(),
             Gtk.DialogFlags.DESTROY_WITH_PARENT,
             Gtk.MessageType.INFO,
             Gtk.ButtonsType.OK,
             _("A scene for this script was not found."),
             title=_("No Scenes Found"))
         md.run()
         md.destroy()
コード例 #25
0
    def _check_open_file(self, filename):
        """Check for open files, and ask the user what to do. Returns false if they cancel."""
        rom = RomProject.get_current()
        if not self._debugger_manager.check_save():
            # Cancel
            return False
        if rom is not None and rom.has_modifications():
            response = self._show_are_you_sure(rom)

            if response == 0:
                # Don't save
                return True
            elif response == 1:
                # Save (True on success, False on failure. Don't close the file if we can't save it...)
                return self._save(after_save_action=lambda: self._open_file(filename))
            else:
                # Cancel
                return False
        return True
コード例 #26
0
 def on_main_window_delete_event(self, *args):
     if not self._debugger_manager.close():
         # Cancel
         return True
     rom = RomProject.get_current()
     if rom is not None and rom.has_modifications():
         response = self._show_are_you_sure(rom)
         if response == 0:
             return False
         elif response == 1:
             # Save (True on success, False on failure. Don't close the file if we can't save it...)
             self._save()
             # TODO: we just cancel atm, because the saving is done async. It would probably be nice to also
             #       exit, when it's done without error
             return True
         else:
             # Cancel
             return True
     return False
コード例 #27
0
    def _check_open_file(self):
        """Check for open files, and ask the user what to do. Returns false if they cancel."""
        rom = RomProject.get_current()
        if not self._debugger_manager.check_save():
            # Cancel
            return False
        if rom is not None and rom.has_modifications():
            response = self._show_are_you_sure(rom)

            if response == 0:
                # Don't save
                return True
            elif response == 1:
                # Save (True on success, False on failure. Don't close the file if we can't save it...)
                # TODO: NOT TRUE. We are using signals. This is broken right now!
                return self._save()
            else:
                # Cancel
                return False
        return True
コード例 #28
0
    def on_save_as_button_clicked(self, wdg):
        project = RomProject.get_current()
        if project is None:
            return

        dialog = Gtk.FileChooserNative.new(_("Save As..."), self._window,
                                           Gtk.FileChooserAction.SAVE, None,
                                           None)
        dialog.set_filename(project.filename)

        add_dialog_file_filters(dialog)

        response = dialog.run()
        fn = dialog.get_filename()
        dialog.destroy()

        if response == Gtk.ResponseType.ACCEPT:
            fn = add_extension_if_missing(fn, 'nds')
            project.filename = fn
            self._save(True)
            project.get_rom_module().update_filename()
            self._update_recent_files(fn)
コード例 #29
0
ファイル: context.py プロジェクト: SkyTemple/skytemple
 def save_rom(self):
     # We only save the current ROM contents!
     current = RomProject.get_current()
     if current:
         current.save_as_is()
コード例 #30
0
ファイル: context.py プロジェクト: SkyTemple/skytemple
 def get_rom_filename(self) -> str:
     return RomProject.get_current().filename  # type: ignore