<commit_before>#!/usr/bin/env python
#coding=utf8

from collections import OrderedDict
from whacked4 import config, utils
from whacked4.dehacked import engine, patch
from whacked4.doom import wadlist, wad
from whacked4.ui import windows, workspace
from whacked4.ui.dialogs import startdialog, aboutdialog, patchinfodialog
from whacked4.ui.editors import thingsframe, statesframe, soundsframe, stringsframe, weaponsframe, ammoframe, \
    cheatsframe, miscframe, parframe
import glob
import os.path
import shutil
import sys
import wx


class MainWindow(windows.MainFrameBase):
    """
    The main MDI parent window.
    """

    def __init__(self, parent, arguments):
        windows.MainFrameBase.__init__(self, parent)
        
        wx.BeginBusyCursor()
        
        self.SetIcon(wx.Icon(u'res/icon-hatchet.ico'))
        
        # Patch-related data.
        self.patch = None
        self.patch_info = None
        self.patch_modified = False
        
        # Workspace info.
        self.workspace = None
        self.workspace_modified = False
        
        # WAD\lump management.
        self.iwad = None
        self.pwads = wadlist.WADList()
        
        # Engine configuration related data.
        self.engines = OrderedDict()
        self.load_engines()
        
        # Window\ID relationships.
        self.editor_windows = {
            windows.MAIN_TOOL_THINGS: thingsframe.ThingsFrame(self),
            windows.MAIN_TOOL_STATES: statesframe.StatesFrame(self),
            windows.MAIN_TOOL_SOUNDS: soundsframe.SoundsFrame(self),
            windows.MAIN_TOOL_STRINGS: stringsframe.StringsFrame(self),
            windows.MAIN_TOOL_WEAPONS: weaponsframe.WeaponsFrame(self),
            windows.MAIN_TOOL_AMMO: ammoframe.AmmoFrame(self),
            windows.MAIN_TOOL_CHEATS: cheatsframe.CheatsFrame(self),
            windows.MAIN_TOOL_MISC: miscframe.MiscFrame(self),
            windows.MAIN_TOOL_PAR: parframe.ParFrame(self)
        }
        self.menu_windows = {
            windows.MAIN_MENU_THINGS: windows.MAIN_TOOL_THINGS,
            windows.MAIN_MENU_STATES: windows.MAIN_TOOL_STATES,
            windows.MAIN_MENU_SOUNDS: windows.MAIN_TOOL_SOUNDS,
            windows.MAIN_MENU_STRINGS: windows.MAIN_TOOL_STRINGS,
            windows.MAIN_MENU_WEAPONS: windows.MAIN_TOOL_WEAPONS,
            windows.MAIN_MENU_AMMO: windows.MAIN_TOOL_AMMO,
            windows.MAIN_MENU_CHEATS: windows.MAIN_TOOL_CHEATS,
            windows.MAIN_MENU_MISC: windows.MAIN_TOOL_MISC,
            windows.MAIN_MENU_PAR: windows.MAIN_TOOL_PAR
        }
        self.workspace_windows = {
            'things': self.editor_windows[windows.MAIN_TOOL_THINGS],
            'states': self.editor_windows[windows.MAIN_TOOL_STATES],
            'sounds': self.editor_windows[windows.MAIN_TOOL_SOUNDS],
            'strings': self.editor_windows[windows.MAIN_TOOL_STRINGS],
            'weapons': self.editor_windows[windows.MAIN_TOOL_WEAPONS],
            'ammo': self.editor_windows[windows.MAIN_TOOL_AMMO],
            'cheats': self.editor_windows[windows.MAIN_TOOL_CHEATS],
            'misc': self.editor_windows[windows.MAIN_TOOL_MISC],
            'par': self.editor_windows[windows.MAIN_TOOL_PAR]
        }
        
        # Reset editor window states.
        self.editor_windows_show(False)
        self.toolbar_set_enabled(False)
        
        self.Show()
        
        # Dialogs.
        self.start_dialog = startdialog.StartDialog(self)
        self.about_dialog = aboutdialog.AboutDialog(self)

        self.update_recent_files_menu()        
        config.settings.main_window_state_restore(self)
        
        wx.EndBusyCursor()
        
        self.parse_options(arguments)
        
        # Late bind these to prevent bad workspace data from being saved.
        self.Bind(wx.EVT_MOVE, self.workspace_update_data)
        self.Bind(wx.EVT_SIZE, self.workspace_update_data)
        
        self.editor_window_set_edit()
        self.file_set_state()
    
    
    def parse_options(self, args):
        """
        Parses commandline options and acts on them.
        """
        
        for arg in sys.argv[1:]:
            if os.path.exists(arg):
                self.open_file(arg)
                return
                
        self.start_dialog.ShowModal()
    
        
    def load_engines(self):
        """
        Loads all engine configuration files. These are kept in memory for patch compatibility auto-detection.
        """
        
        for file_name in glob.glob('cfg/tables_*.json'):
            new_engine = engine.Engine()
            try:
                new_engine.read_table(file_name)
            except engine.DehackedEngineError:
                wx.MessageBox(message='Invalid engine configuration file {}'.format(file_name),
                    caption='Engine configuration error',
                    style=wx.OK | wx.ICON_EXCLAMATION,
                    parent=self)
            else:
                name = os.path.basename(file_name)
                name = os.path.splitext(name)[0]
                self.engines[name] = new_engine
                    
        
    def view_patch_settings(self, event):
        """
        Displays the patch settings dialog.
        """
        
        self.patch_info.set_state(self.patch, self.engines, self.workspace, modify_engine=False)
        self.patch_info.ShowModal()
        
        # Alter workspace settings if the user clicked Ok.
        if self.patch_info.selected_engine is not None:
            self.workspace.iwad = self.patch_info.selected_iwad
            self.workspace.pwads = self.patch_info.selected_pwads
            self.load_wads()
            
            self.set_modified(True)
            self.workspace_modified = True
            
            self.editor_windows[windows.MAIN_TOOL_STATES].tools_update()
    
    
    def open_file_dialog(self, force_show_settings=False):
        """
        Displays an open file dialog to open a patch file.
        """
        
        if self.save_if_needed() == False:
            return
        
        filename = utils.file_dialog(self, message='Choose a Dehacked file to open.',
                                     wildcard='All supported files|*.deh;*.bex|Dehacked files (*.deh)|*.deh|Extended Dehacked files (*.bex)|*.bex|All files|*.*',
                                     style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        
        if filename is not None:
            self.open_file(filename, force_show_settings)
            
    
    def open_file(self, filename, force_show_settings=False):
        """
        Opens and reads a new Dehacked patch.
        
        @param filename: the filename of the file to open.
        @param force_show_settings: if True, will always display the patch settings dialog.  
        """
        
        # Load the accompanying workspace file if it exists.
        new_workspace = workspace.Workspace()<commit_msg>Fix missed function rename from a previous commit.<commit_after>#!/usr/bin/env python
#coding=utf8

from collections import OrderedDict
from whacked4 import config, utils
from whacked4.dehacked import engine, patch
from whacked4.doom import wadlist, wad
from whacked4.ui import windows, workspace
from whacked4.ui.dialogs import startdialog, aboutdialog, patchinfodialog
from whacked4.ui.editors import thingsframe, statesframe, soundsframe, stringsframe, weaponsframe, ammoframe, \
    cheatsframe, miscframe, parframe
import glob
import os.path
import shutil
import sys
import wx


class MainWindow(windows.MainFrameBase):
    """
    The main MDI parent window.
    """

    def __init__(self, parent, arguments):
        windows.MainFrameBase.__init__(self, parent)
        
        wx.BeginBusyCursor()
        
        self.SetIcon(wx.Icon(u'res/icon-hatchet.ico'))
        
        # Patch-related data.
        self.patch = None
        self.patch_info = None
        self.patch_modified = False
        
        # Workspace info.
        self.workspace = None
        self.workspace_modified = False
        
        # WAD\lump management.
        self.iwad = None
        self.pwads = wadlist.WADList()
        
        # Engine configuration related data.
        self.engines = OrderedDict()
        self.load_engines()
        
        # Window\ID relationships.
        self.editor_windows = {
            windows.MAIN_TOOL_THINGS: thingsframe.ThingsFrame(self),
            windows.MAIN_TOOL_STATES: statesframe.StatesFrame(self),
            windows.MAIN_TOOL_SOUNDS: soundsframe.SoundsFrame(self),
            windows.MAIN_TOOL_STRINGS: stringsframe.StringsFrame(self),
            windows.MAIN_TOOL_WEAPONS: weaponsframe.WeaponsFrame(self),
            windows.MAIN_TOOL_AMMO: ammoframe.AmmoFrame(self),
            windows.MAIN_TOOL_CHEATS: cheatsframe.CheatsFrame(self),
            windows.MAIN_TOOL_MISC: miscframe.MiscFrame(self),
            windows.MAIN_TOOL_PAR: parframe.ParFrame(self)
        }
        self.menu_windows = {
            windows.MAIN_MENU_THINGS: windows.MAIN_TOOL_THINGS,
            windows.MAIN_MENU_STATES: windows.MAIN_TOOL_STATES,
            windows.MAIN_MENU_SOUNDS: windows.MAIN_TOOL_SOUNDS,
            windows.MAIN_MENU_STRINGS: windows.MAIN_TOOL_STRINGS,
            windows.MAIN_MENU_WEAPONS: windows.MAIN_TOOL_WEAPONS,
            windows.MAIN_MENU_AMMO: windows.MAIN_TOOL_AMMO,
            windows.MAIN_MENU_CHEATS: windows.MAIN_TOOL_CHEATS,
            windows.MAIN_MENU_MISC: windows.MAIN_TOOL_MISC,
            windows.MAIN_MENU_PAR: windows.MAIN_TOOL_PAR
        }
        self.workspace_windows = {
            'things': self.editor_windows[windows.MAIN_TOOL_THINGS],
            'states': self.editor_windows[windows.MAIN_TOOL_STATES],
            'sounds': self.editor_windows[windows.MAIN_TOOL_SOUNDS],
            'strings': self.editor_windows[windows.MAIN_TOOL_STRINGS],
            'weapons': self.editor_windows[windows.MAIN_TOOL_WEAPONS],
            'ammo': self.editor_windows[windows.MAIN_TOOL_AMMO],
            'cheats': self.editor_windows[windows.MAIN_TOOL_CHEATS],
            'misc': self.editor_windows[windows.MAIN_TOOL_MISC],
            'par': self.editor_windows[windows.MAIN_TOOL_PAR]
        }
        
        # Reset editor window states.
        self.editor_windows_show(False)
        self.toolbar_set_enabled(False)
        
        self.Show()
        
        # Dialogs.
        self.start_dialog = startdialog.StartDialog(self)
        self.about_dialog = aboutdialog.AboutDialog(self)

        self.update_recent_files_menu()        
        config.settings.main_window_state_restore(self)
        
        wx.EndBusyCursor()
        
        self.parse_options(arguments)
        
        # Late bind these to prevent bad workspace data from being saved.
        self.Bind(wx.EVT_MOVE, self.workspace_update_data)
        self.Bind(wx.EVT_SIZE, self.workspace_update_data)
        
        self.editor_window_set_edit()
        self.file_set_state()
    
    
    def parse_options(self, args):
        """
        Parses commandline options and acts on them.
        """
        
        for arg in sys.argv[1:]:
            if os.path.exists(arg):
                self.open_file(arg)
                return
                
        self.start_dialog.ShowModal()
    
        
    def load_engines(self):
        """
        Loads all engine configuration files. These are kept in memory for patch compatibility auto-detection.
        """
        
        for file_name in glob.glob('cfg/tables_*.json'):
            new_engine = engine.Engine()
            try:
                new_engine.read_table(file_name)
            except engine.DehackedEngineError:
                wx.MessageBox(message='Invalid engine configuration file {}'.format(file_name),
                    caption='Engine configuration error',
                    style=wx.OK | wx.ICON_EXCLAMATION,
                    parent=self)
            else:
                name = os.path.basename(file_name)
                name = os.path.splitext(name)[0]
                self.engines[name] = new_engine
                    
        
    def view_patch_settings(self, event):
        """
        Displays the patch settings dialog.
        """
        
        self.patch_info.set_state(self.patch, self.engines, self.workspace, modify_engine=False)
        self.patch_info.ShowModal()
        
        # Alter workspace settings if the user clicked Ok.
        if self.patch_info.selected_engine is not None:
            self.workspace.iwad = self.patch_info.selected_iwad
            self.workspace.pwads = self.patch_info.selected_pwads
            self.load_wads()
            
            self.set_modified(True)
            self.workspace_modified = True
            
            self.editor_windows[windows.MAIN_TOOL_STATES].update_properties()
    
    
    def open_file_dialog(self, force_show_settings=False):
        """
        Displays an open file dialog to open a patch file.
        """
        
        if self.save_if_needed() == False:
            return
        
        filename = utils.file_dialog(self, message='Choose a Dehacked file to open.',
                                     wildcard='All supported files|*.deh;*.bex|Dehacked files (*.deh)|*.deh|Extended Dehacked files (*.bex)|*.bex|All files|*.*',
                                     style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        
        if filename is not None:
            self.open_file(filename, force_show_settings)
            
    
    def open_file(self, filename, force_show_settings=False):
        """
        Opens and reads a new Dehacked patch.
        
        @param filename: the filename of the file to open.
        @param force_show_settings: if True, will always display the patch settings dialog.  
        """
        
        # Load the accompanying workspace file if it exists.
        new_workspace = workspace.Workspace()
{'fraction_non_alphanumeric': 0.08315427589170606, 'fraction_numerical': 0.001289213579716373, 'mean_word_length': 2.0694658166630027, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3812288', 'n_tokens_mistral': 4131, 'n_tokens_neox': 3963, 'n_words': 748}