diff options
Diffstat (limited to 'Tools')
-rw-r--r-- | Tools/Python/ContextTool.py | 590 | ||||
-rw-r--r-- | Tools/Python/EdkIIWorkspace.py | 148 | ||||
-rw-r--r-- | Tools/Python/Fd.py | 573 | ||||
-rwxr-xr-x | Tools/Python/XmlRoutines.py | 83 |
4 files changed, 1391 insertions, 3 deletions
diff --git a/Tools/Python/ContextTool.py b/Tools/Python/ContextTool.py new file mode 100644 index 0000000..3c95adb --- /dev/null +++ b/Tools/Python/ContextTool.py @@ -0,0 +1,590 @@ +#!/usr/bin/env python + +# The EDK II Build System Context Tool Utility maintains Target.txt settings in an EDK II Workspace. + +import wx, os, sys, copy +from EdkIIWorkspace import * + +class ContextToolModel(EdkIIWorkspace): + def __init__(self): + self.WorkspaceStatus = EdkIIWorkspace.__init__(self) + self.Database = {} + self.OriginalDatabase = {} + + def LoadTargetTxtFile(self): + self.ConvertTextFileToDictionary('Tools/Conf/Target.txt', self.TargetTxtDictionary, '#', '=', True, None) + if self.TargetTxtDictionary['ACTIVE_PLATFORM'] == []: + self.TargetTxtDictionary['ACTIVE_PLATFORM'] = [''] + else: + self.TargetTxtDictionary['ACTIVE_PLATFORM'] = [self.TargetTxtDictionary['ACTIVE_PLATFORM'][0]] + self.TargetTxtDictionary['TOOL_CHAIN_CONF'] = [self.TargetTxtDictionary['TOOL_CHAIN_CONF'][0]] + self.TargetTxtDictionary['MULTIPLE_THREAD'] = [self.TargetTxtDictionary['MULTIPLE_THREAD'][0]] + self.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'] = [self.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'][0]] + self.TargetTxtDictionary['TARGET'] = list(set(self.TargetTxtDictionary['TARGET'])) + self.TargetTxtDictionary['TOOL_CHAIN_TAG'] = list(set(self.TargetTxtDictionary['TOOL_CHAIN_TAG'])) + self.TargetTxtDictionary['TARGET_ARCH'] = list(set(self.TargetTxtDictionary['TARGET_ARCH'])) + if self.TargetTxtDictionary['TARGET'] == []: + self.TargetTxtDictionary['TARGET'] = [''] + if self.TargetTxtDictionary['TOOL_CHAIN_TAG'] == []: + self.TargetTxtDictionary['TOOL_CHAIN_TAG'] = [''] + if self.TargetTxtDictionary['TARGET_ARCH'] == []: + self.TargetTxtDictionary['TARGET_ARCH'] = [''] + self.TargetTxtDictionary['TARGET'].sort() + self.TargetTxtDictionary['TOOL_CHAIN_TAG'].sort() + self.TargetTxtDictionary['TARGET_ARCH'].sort() + self.OriginalTargetTxtDictionary = copy.deepcopy(self.TargetTxtDictionary) + + def LoadToolsDefTxtFile(self): + self.ToolsDefTxtDictionary = {} + if self.TargetTxtDictionary['TOOL_CHAIN_CONF'] != ['']: + self.ConvertTextFileToDictionary(self.TargetTxtDictionary['TOOL_CHAIN_CONF'][0], self.ToolsDefTxtDictionary, '#', '=', False, None) + + def LoadFrameworkDatabase(self): + self.PlatformDatabase = {} + Fd = self.XmlParseFile ('Tools/Conf/FrameworkDatabase.db') + PlatformList = XmlList (Fd, '/FrameworkDatabase/PlatformList/Filename') + for File in PlatformList: + FpdFileName = XmlElementData(File) + FpdPlatformHeader = self.XmlParseFileSection (FpdFileName, 'PlatformHeader') + FpdPlatformDefinitions = self.XmlParseFileSection (FpdFileName,'PlatformDefinitions') + PlatformName = XmlElement (FpdPlatformHeader, '/PlatformHeader/PlatformName') + PlatformVersion = XmlElement (FpdPlatformHeader, '/PlatformHeader/Version') + PlatformUiName = PlatformName + '[' + PlatformVersion + ']' + if PlatformUiName not in self.PlatformDatabase: + self.PlatformDatabase[PlatformUiName] = {} + self.PlatformDatabase[PlatformUiName]['XmlFileName'] = FpdFileName + self.PlatformDatabase[PlatformUiName]['SupportedArchitectures'] = set(XmlElement (FpdPlatformDefinitions, '/PlatformSurfaceArea/PlatformDefinitions/SupportedArchitectures').split(' ')) + self.PlatformDatabase[PlatformUiName]['BuildTargets'] = set(XmlElement (FpdPlatformDefinitions, '/PlatformSurfaceArea/PlatformDefinitions/BuildTargets').split(' ')) + + def ComputeToolsDefTxtDatabase(self): + self.ToolsDefTxtDatabase = { + 'TARGET' : [], + 'TOOL_CHAIN_TAG' : [], + 'TARGET_ARCH' : [] + } + for Key in dict(self.ToolsDefTxtDictionary): + List = Key.split('_') + if len(List) != 5: + del self.ToolsDefTxtDictionary[Key] + elif List[4] == '*': + del self.ToolsDefTxtDictionary[Key] + else: + if List[0] != '*': + self.ToolsDefTxtDatabase['TARGET'] += [List[0]] + if List[1] != '*': + self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'] += [List[1]] + if List[2] != '*': + self.ToolsDefTxtDatabase['TARGET_ARCH'] += [List[2]] + self.ToolsDefTxtDatabase['TARGET'] = list(set(self.ToolsDefTxtDatabase['TARGET'])) + self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'] = list(set(self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'])) + self.ToolsDefTxtDatabase['TARGET_ARCH'] = list(set(self.ToolsDefTxtDatabase['TARGET_ARCH'])) + self.ToolsDefTxtDatabase['TARGET'].sort() + self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'].sort() + self.ToolsDefTxtDatabase['TARGET_ARCH'].sort() + + def NewModel(self): + self.TargetTxtDictionary = { + 'ACTIVE_PLATFORM' : [''], + 'TOOL_CHAIN_CONF' : [''], + 'MULTIPLE_THREAD' : ['Disable'], + 'MAX_CONCURRENT_THREAD_NUMBER' : ['2'], + 'TARGET' : [''], + 'TOOL_CHAIN_TAG' : [''], + 'TARGET_ARCH' : [''] + } + + def RevertModel(self): + self.TargetTxtDictionary = copy.deepcopy(self.OriginalTargetTxtDictionary) + + def RescanModel(self): + self.NewModel() + self.LoadTargetTxtFile() + + def RefreshModel(self): + self.LoadFrameworkDatabase() + self.LoadToolsDefTxtFile() + self.ComputeToolsDefTxtDatabase() + + if self.Verbose: + print self.TargetTxtDictionary + print 'ActivePlatform = ', self.TargetTxtDictionary['ACTIVE_PLATFORM'][0] + print 'ToolChainConf = ', self.TargetTxtDictionary['TOOL_CHAIN_CONF'][0] + print 'MultipleThread = ', self.TargetTxtDictionary['MULTIPLE_THREAD'][0] + print 'MaxThreads = ', self.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'][0] + print 'TargetSet = ', self.TargetTxtDictionary['TARGET'] + print 'ToolChainSet = ', self.TargetTxtDictionary['TOOL_CHAIN_TAG'] + print 'TargetArchSet = ', self.TargetTxtDictionary['TARGET_ARCH'] + Platforms = self.PlatformDatabase.keys() + print 'Possible Settings:' + print ' Platforms = ', Platforms + print ' TargetSet = ', self.ToolsDefTxtDatabase['TARGET'] + print ' ToolChainSet = ', self.ToolsDefTxtDatabase['TOOL_CHAIN_TAG'] + print ' TargetArchSet = ', self.ToolsDefTxtDatabase['TARGET_ARCH'] + return True + + def ModelModified(self): + if self.TargetTxtDictionary != self.OriginalTargetTxtDictionary: + return True + return False + + def SaveModel(self, Filename='Tools/Conf/Target.txt'): + if self.Verbose: + for Item in self.TargetTxtDictionary: + print Item,'=',self.TargetTxtDictionary[Item] + self.ConvertDictionaryToTextFile(Filename, self.TargetTxtDictionary, '#', '=', True, None) + self.OriginalTargetTxtDictionary = copy.deepcopy(self.TargetTxtDictionary) + + def CloseModel(self): + pass + +class Frame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self,None,-1,'EDK II Build System Context Tool') + panel = wx.Panel(self, style=wx.SUNKEN_BORDER | wx.TAB_TRAVERSAL) + wx.HelpProvider_Set(wx.SimpleHelpProvider()) + self.Model = ContextToolModel() + if not self.Model.WorkspaceStatus: + self.Close() + return + + # + # Help text + # + ActivePlatformHelpText = ( + "Specifies the Platform Name and Platform Version of the platform that will be " + "used for build. If set to [Build Directory] and the current directory contains " + "an FPD file, then a plaform build on that FPD file will be performed. If set " + "to [Build Directory] and there is no FPD file in the current directory, then no " + "build will be performed." + ) + + ToolChainConfHelpText = ( + "Specifies the name of the file that declares all the tools and flag settings " + "required to complete a build. This is typically set to Tools/Conf/tools_def.txt." + ) + + MultipleThreadHelpText = ( + "Flag to enable or disable multi-thread builds. If your computer is multi-core " + "or contans multiple CPUs, enabling this feature will improve build performance. " + "For multi-thread builds, a log will be written to ${BUILD_DIR}/build.log. This " + "feature is only for platform builds. Clean, cleanall, and stand-alone module " + "builds only use one thread." + ) + + ThreadsHelpText = ( + "The number of concurrent threads. The best performance is achieved if this " + "value is set to one greater than the number or cores or CPUs in the build system." + ) + + TargetHelpText = ( + "Specifies the set of targets to build. If set to All, then all build targets " + "are built. Otherwise, the subset of enabled build targets are built. The " + "standard build targets are RELEASE and DEBUG, but additional user-defined build " + "targets may be declared in the TOOL_CHAIN_CONF file. The DEBUG builds with " + "source level debugging enabled. RELEASE builds with source level debugging " + "disabled and results in smaller firmware images." + ) + + ToolChainTagHelpText = ( + "Specifies the set of tool chains to use during a build. If set to All, then " + "all of the supported tools chains are used. Otherwise, only the subset of " + "enabled tool chains are used. The TOOL_CHAIN_CONF file declares one or more " + "tool chains that may be used." + ) + + TargetArchHelpText = ( + "Specifies the set of CPU architectures to build. If set to All, then all the " + "CPU architectures supported by the platform FPD file are built. Otherwise, " + "only the subset of enabled CPU architectures are built. The standard CPU " + "architectures are IA32, X64, IPF, and EBC, but additional CPU architectures " + "may be declared in the TOOL_CHAIN_CONF file." + ) + + # + # Status Bar + # + self.CreateStatusBar() + + # + # Build Menus + # + MenuBar = wx.MenuBar() + + FileMenu = wx.Menu() + NewMenuItem = FileMenu.Append(-1, "&New\tCtrl+N", "New target.txt") + SaveMenuItem = FileMenu.Append(-1, "&Save\tCtrl+S", "Save target.txt") + SaveAsMenuItem = FileMenu.Append(-1, "Save &As...", "Save target.txt as...") + RevertMenuItem = FileMenu.Append(-1, "&Revert", "Revert to the original target.txt") + ExitMenuItem = FileMenu.Append(-1, "E&xit\tAlt+F4", "Exit ContextTool") + MenuBar.Append(FileMenu, "&File") + self.Bind(wx.EVT_MENU, self.OnSaveClick, SaveMenuItem) + self.Bind(wx.EVT_MENU, self.OnSaveAsClick, SaveAsMenuItem) + self.Bind(wx.EVT_MENU, self.OnRevertClick, RevertMenuItem) + self.Bind(wx.EVT_MENU, self.OnExitClick, ExitMenuItem) + + ViewMenu = wx.Menu() + RefreshMenuItem = ViewMenu.Append (-1, "&Refresh\tF5", "Rescan target.txt") + ShowToolBarMenuItem = ViewMenu.AppendCheckItem (-1, "Show &Toolbar", "Shows or hides the toolbar") + ShowToolBarMenuItem.Check(True) + MenuBar.Append(ViewMenu, "&View") + self.Bind(wx.EVT_MENU, self.OnViewRefreshClick, RefreshMenuItem) + self.Bind(wx.EVT_MENU, self.OnShowToolBarClick, ShowToolBarMenuItem) + + HelpMenu = wx.Menu() + AboutMenuItem = HelpMenu.Append (-1, "&About...", "About") + MenuBar.Append(HelpMenu, "&Help") + self.Bind(wx.EVT_MENU, self.OnAboutClick, AboutMenuItem) + + self.SetMenuBar (MenuBar) + + # + # Build Toolbar + # + self.ShowToolBar = False + self.OnShowToolBarClick(self) + + # + # Active Platform Combo Box + # + ActivePlatformLabel = wx.StaticText(panel, -1, 'ACTIVE_PLATFORM') + ActivePlatformLabel.SetHelpText(ActivePlatformHelpText) + self.ActivePlatformText = wx.ComboBox(panel,-1, style=wx.CB_DROPDOWN | wx.CB_SORT | wx.CB_READONLY) + self.ActivePlatformText.SetHelpText(ActivePlatformHelpText) + self.ActivePlatformText.Bind(wx.EVT_TEXT, self.OnActivePlatformClick) + + # + # Tool Chain Configuration Text Control and Browse Button for a File Dialog Box + # + ToolChainConfFileLabel = wx.StaticText(panel, -1, 'TOOL_CHAIN_CONF') + ToolChainConfFileLabel.SetHelpText(ToolChainConfHelpText) + self.ToolChainConfFileText = wx.TextCtrl(panel, -1, style=wx.TE_PROCESS_ENTER) + self.ToolChainConfFileText.Bind(wx.EVT_TEXT_ENTER, self.OnToolChainConfClick) + self.ToolChainConfFileText.Bind(wx.EVT_KILL_FOCUS, self.OnToolChainConfClick) + self.ToolChainConfFileText.SetHelpText(ToolChainConfHelpText) + self.BrowseButton = wx.Button(panel, -1, 'Browse...') + self.BrowseButton.Bind(wx.EVT_BUTTON, self.OnBrowseButtonClick) + + # + # Multiple Thread enable/disable radio button + # + MultipleThreadLabel = wx.StaticText(panel, -1, 'MULTIPLE_THREAD') + MultipleThreadLabel.SetHelpText(MultipleThreadHelpText) + self.MultipleThreadRadioBox = wx.RadioBox(panel, -1, choices=['Enable','Disable'], style=wx.RA_SPECIFY_COLS) + self.MultipleThreadRadioBox.Bind(wx.EVT_RADIOBOX, self.OnMultipleThreadRadioBox) + self.MultipleThreadRadioBox.SetHelpText(MultipleThreadHelpText) + + # + # Thread count spin control + # + ThreadsLabel = wx.StaticText(panel, -1, 'THREADS') + ThreadsLabel.SetHelpText(ThreadsHelpText) + self.ThreadsSpinCtrl = wx.SpinCtrl(panel, -1, size=(50, -1), min=2) + self.ThreadsSpinCtrl.Bind(wx.EVT_TEXT, self.OnThreadsSpinCtrl) + self.ThreadsSpinCtrl.SetHelpText(ThreadsHelpText) + + # + # Target, ToolChain, and Arch Check List Boxes + # + TargetLabel = wx.StaticText(panel, -1, 'TARGET') + TargetLabel.SetHelpText(TargetHelpText) + + ToolChainTagLabel = wx.StaticText(panel, -1, 'TOOL_CHAIN_TAG') + ToolChainTagLabel.SetHelpText(ToolChainTagHelpText) + + TargetArchLabel = wx.StaticText(panel, -1, 'TARGET_ARCH') + TargetArchLabel.SetHelpText(TargetArchHelpText) + + self.TargetCheckListBox = wx.CheckListBox(panel, -1) + self.TargetCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnTargetCheckListClick) + self.TargetCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnTargetSetFocus) + self.TargetCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnTargetKillFocus) + self.TargetCheckListBox.SetHelpText(TargetHelpText) + + self.ToolChainTagCheckListBox = wx.CheckListBox(panel, -1) + self.ToolChainTagCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnToolChainTagCheckListClick) + self.ToolChainTagCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnToolChainTagSetFocus) + self.ToolChainTagCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnToolChainTagKillFocus) + self.ToolChainTagCheckListBox.SetHelpText(ToolChainTagHelpText) + + self.TargetArchCheckListBox = wx.CheckListBox(panel, -1) + self.TargetArchCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnTargetArchCheckListClick) + self.TargetArchCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnTargetArchSetFocus) + self.TargetArchCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnTargetArchKillFocus) + self.TargetArchCheckListBox.SetHelpText(TargetArchHelpText) + + # + # Define layout using sizers + # + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + + flexSizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5) + flexSizer.AddGrowableCol(1) + flexSizer.Add(ActivePlatformLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(self.ActivePlatformText, 0, wx.EXPAND) + flexSizer.Add((0,0), wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) + + flexSizer.Add(ToolChainConfFileLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(self.ToolChainConfFileText, 0, wx.EXPAND) + flexSizer.Add(self.BrowseButton, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) + + self.mainSizer.Add (flexSizer, 0, wx.EXPAND | wx.ALL, 10) + + threadsSizer = wx.FlexGridSizer(cols = 5, hgap=5, vgap=5) + threadsSizer.Add(MultipleThreadLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) + threadsSizer.Add(self.MultipleThreadRadioBox, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) + threadsSizer.Add(ThreadsLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) + threadsSizer.Add(self.ThreadsSpinCtrl, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) + + self.mainSizer.Add (threadsSizer, 0, wx.ALL, 10) + + listSizer = wx.FlexGridSizer(rows = 2, cols = 3, hgap=5, vgap=5) + listSizer.AddGrowableRow(1) + listSizer.AddGrowableCol(0) + listSizer.AddGrowableCol(1) + listSizer.AddGrowableCol(2) + listSizer.Add(TargetLabel, 0, wx.ALIGN_CENTER) + listSizer.Add(ToolChainTagLabel, 0, wx.ALIGN_CENTER) + listSizer.Add(TargetArchLabel, 0, wx.ALIGN_CENTER) + listSizer.Add(self.TargetCheckListBox, 0, wx.ALL | wx.EXPAND) + listSizer.Add(self.ToolChainTagCheckListBox, 0, wx.ALL | wx.EXPAND) + listSizer.Add(self.TargetArchCheckListBox, 0, wx.ALL | wx.EXPAND) + + self.mainSizer.Add (listSizer, wx.EXPAND | wx.ALL, wx.EXPAND | wx.ALL, 10) + + panel.SetSizer (self.mainSizer) + + self.Model.RescanModel() + self.OnRefreshClick(self) + + def OnActivePlatformClick(self, event): + Platform = self.ActivePlatformText.GetValue() + if Platform == ' [Build Directory]': + self.Model.TargetTxtDictionary['ACTIVE_PLATFORM'][0] = '' + else: + self.Model.TargetTxtDictionary['ACTIVE_PLATFORM'][0] = self.Model.PlatformDatabase[Platform]['XmlFileName'] + + def OnToolChainConfClick(self, event): + if self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0] != self.ToolChainConfFileText.GetValue(): + self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0] = self.ToolChainConfFileText.GetValue() + self.OnRefreshClick(self) + + def OnBrowseButtonClick(self, event): + wildcard = "Text Documents (*.txt)|*.txt|" \ + "All files (*.*)|*.*" + dialog = wx.FileDialog (None, 'Choose a Tool Chain Configuration File', self.Model.WorkspaceFile('Tools/Conf'), '', wildcard, wx.OPEN) + if dialog.ShowModal() == wx.ID_OK: + print dialog.GetPath() + ToolChainConfFile = self.Model.WorkspaceRelativePath(dialog.GetPath()) + self.ToolChainConfFileText.SetValue(ToolChainConfFile) + self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0] = self.ToolChainConfFileText.GetValue() + self.OnRefreshClick(self) + dialog.Destroy() + + def OnMultipleThreadRadioBox (self, event): + self.Model.TargetTxtDictionary['MULTIPLE_THREAD'] = [self.MultipleThreadRadioBox.GetStringSelection()] + if self.MultipleThreadRadioBox.GetStringSelection() == 'Disable': + self.ThreadsSpinCtrl.Disable() + else: + self.ThreadsSpinCtrl.Enable() + + def OnThreadsSpinCtrl(self, event): + self.Model.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'] = [str(self.ThreadsSpinCtrl.GetValue())] + + def CheckListFocus(self, CheckListBox, Set): + Index = 0 + while Index < CheckListBox.GetCount(): + CheckListBox.SetSelection(Index, False) + Index += 1 + if Set: + CheckListBox.SetSelection(0, True) + + def CheckListClick(self, CheckListBox, Name): + if CheckListBox.IsChecked(0): + Index = 1 + while Index < CheckListBox.GetCount(): + CheckListBox.Check(Index, False) + Index += 1 + if CheckListBox.IsChecked(0): + self.Model.TargetTxtDictionary[Name] = [''] + else: + self.Model.TargetTxtDictionary[Name] = [] + Index = 1 + while Index < CheckListBox.GetCount(): + if CheckListBox.IsChecked(Index): + self.Model.TargetTxtDictionary[Name] += [CheckListBox.GetString(Index)] + Index += 1 + if self.Model.TargetTxtDictionary[Name] == []: + self.Model.TargetTxtDictionary[Name] = [''] + + def OnTargetCheckListClick(self, event): + self.CheckListClick(self.TargetCheckListBox, 'TARGET') + + def OnTargetSetFocus(self, event): + self.CheckListFocus(self.TargetCheckListBox, True) + + def OnTargetKillFocus(self, event): + self.CheckListFocus(self.TargetCheckListBox, False) + + def OnToolChainTagCheckListClick(self, event): + self.CheckListClick(self.ToolChainTagCheckListBox, 'TOOL_CHAIN_TAG') + + def OnToolChainTagSetFocus(self, event): + self.CheckListFocus(self.ToolChainTagCheckListBox, True) + + def OnToolChainTagKillFocus(self, event): + self.CheckListFocus(self.ToolChainTagCheckListBox, False) + + def OnTargetArchCheckListClick(self, event): + self.CheckListClick(self.TargetArchCheckListBox, 'TARGET_ARCH') + + def OnTargetArchSetFocus(self, event): + self.CheckListFocus(self.TargetArchCheckListBox, True) + + def OnTargetArchKillFocus(self, event): + self.CheckListFocus(self.TargetArchCheckListBox, False) + + def OnRevertClick(self, event): + self.Model.RevertModel() + self.OnRefreshClick(self) + + def RefreshCheckListBox(self, CheckListBox, Name): + CheckListBox.Set(['All'] + self.Model.ToolsDefTxtDatabase[Name]) + Index = 0 + MaximumString = '' + while Index < CheckListBox.GetCount(): + String = CheckListBox.GetString(Index) + if len(String) > len(MaximumString): + MaximumString = String + if String in self.Model.TargetTxtDictionary[Name]: + CheckListBox.Check(Index, True) + else: + CheckListBox.Check(Index, False) + Index += 1 + if self.Model.TargetTxtDictionary[Name] == ['']: + CheckListBox.Check(0, True) + Extents = CheckListBox.GetFullTextExtent (MaximumString) + CheckListBox.SetMinSize((Extents[0],(CheckListBox.GetCount()+1) * (Extents[1]+Extents[2]))) + + def OnRefreshClick(self, event): + self.Model.RefreshModel() + Platforms = self.Model.PlatformDatabase.keys() + Platforms.sort() + self.ActivePlatformText.SetItems([' [Build Directory]'] + Platforms) + self.ActivePlatformText.SetValue(' [Build Directory]') + for Platform in self.Model.PlatformDatabase: + if self.Model.PlatformDatabase[Platform]['XmlFileName'] == self.Model.TargetTxtDictionary['ACTIVE_PLATFORM'][0]: + self.ActivePlatformText.SetValue(Platform) + if self.ActivePlatformText.GetValue() == ' [Build Directory]': + self.Model.TargetTxtDictionary['ACTIVE_PLATFORM'][0] = '' + MaximumString = ' [Build Directory]' + for String in Platforms: + if len(String) > len(MaximumString): + MaximumString = String + Extents = self.ActivePlatformText.GetFullTextExtent (MaximumString) + self.ActivePlatformText.SetMinSize((Extents[0] + 24,-1)) + + self.ToolChainConfFileText.SetValue(self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0]) + Extents = self.ToolChainConfFileText.GetFullTextExtent (self.Model.TargetTxtDictionary['TOOL_CHAIN_CONF'][0]) + self.ToolChainConfFileText.SetMinSize((Extents[0] + 24,-1)) + + self.MultipleThreadRadioBox.SetStringSelection(self.Model.TargetTxtDictionary['MULTIPLE_THREAD'][0]) + if self.MultipleThreadRadioBox.GetStringSelection() == 'Disable': + self.ThreadsSpinCtrl.Disable() + self.ThreadsSpinCtrl.SetValue(int(self.Model.TargetTxtDictionary['MAX_CONCURRENT_THREAD_NUMBER'][0])) + + self.RefreshCheckListBox (self.TargetCheckListBox, 'TARGET') + self.RefreshCheckListBox (self.ToolChainTagCheckListBox, 'TOOL_CHAIN_TAG') + self.RefreshCheckListBox (self.TargetArchCheckListBox, 'TARGET_ARCH') + + self.mainSizer.SetSizeHints(self) + self.mainSizer.Fit(self) + + def OnViewRefreshClick(self, event): + self.Model.RescanModel() + self.OnRefreshClick(self) + + def AddTool (self, Handler, ArtId, Label, HelpText): + Tool = self.ToolBar.AddSimpleTool( + -1, + wx.ArtProvider.GetBitmap(ArtId, wx.ART_TOOLBAR, self.ToolSize), + Label, + HelpText + ) + self.Bind(wx.EVT_MENU, Handler, Tool) + + def OnShowToolBarClick(self, event): + if self.ShowToolBar: + self.ShowToolBar = False + self.ToolBar.Destroy() + else: + self.ShowToolBar = True + self.ToolBar = self.CreateToolBar() + self.ToolSize = (24,24) + self.ToolBar.SetToolBitmapSize(self.ToolSize) + self.AddTool (self.OnNewClick, wx.ART_NEW, "New", "New target.txt") + self.AddTool (self.OnSaveClick, wx.ART_FILE_SAVE, "Save", "Save target.txt") + self.AddTool (self.OnSaveAsClick, wx.ART_FILE_SAVE_AS, "Save As...", "Save target.txt as...") + self.AddTool (self.OnRevertClick, wx.ART_UNDO, "Revert", "Revert to original target.txt") + self.AddTool (self.OnHelpClick, wx.ART_HELP, "Help", "Context Sensitive Help") + self.AddTool (self.OnExitClick, wx.ART_QUIT, "Exit", "Exit Context Tool application") + self.ToolBar.Realize() + + def OnNewClick(self, event): + self.Model.NewModel() + self.OnRefreshClick(self) + + def OnSaveClick(self, event): + self.Model.SaveModel() + + def OnSaveAsClick(self, event): + wildcard = "Text Documents (*.txt)|*.txt|" \ + "All files (*.*)|*.*" + dialog = wx.FileDialog (None, 'Save As', self.Model.WorkspaceFile('Tools/Conf'), '', wildcard, wx.SAVE | wx.OVERWRITE_PROMPT) + if dialog.ShowModal() == wx.ID_OK: + TargetTxtFile = self.Model.WorkspaceRelativePath(dialog.GetPath()) + if TargetTxtFile != '': + self.Model.SaveModel(TargetTxtFile) + dialog.Destroy() + + def OnExitClick(self, event): + if self.Model.ModelModified(): + dialog = wx.MessageDialog(None, 'The contents have changed.\nDo you want to save changes?', 'EDK II Build System Context Tool', style = wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_EXCLAMATION) + Status = dialog.ShowModal() + dialog.Destroy() + if Status == wx.ID_YES: + self.OnSaveClick (self) + elif Status == wx.ID_CANCEL: + return + self.Model.CloseModel() + self.Close() + + def OnHelpClick(self, event): + wx.ContextHelp().BeginContextHelp() + + def OnAboutClick(self, event): + AboutInfo = wx.AboutDialogInfo() + AboutInfo.Name = 'EDK II Build System Context Tool' + AboutInfo.Version = '0.3' + AboutInfo.Copyright = 'Copyright (c) 2006, Intel Corporation' + AboutInfo.Description = """ + The EDK II Build System Context Tool maintains the target.txt + settings in an EDK II Workspace.""" + AboutInfo.WebSite = ("http://tianocore.org", "Tiano Core home page") + AboutInfo.License = """ + All rights reserved. This program and the accompanying materials are + licensed and made available under the terms and conditions of the BSD + License which accompanies this distribution. The full text of the + license may be found at http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" + BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, + EITHER EXPRESS OR IMPLIED.""" + if self.Model.Icon != None: + AboutInfo.Icon = self.Model.Icon + wx.AboutBox(AboutInfo) + +if __name__ == '__main__': + app = wx.PySimpleApp() + frame = Frame() + frame.Show() + app.MainLoop() diff --git a/Tools/Python/EdkIIWorkspace.py b/Tools/Python/EdkIIWorkspace.py new file mode 100644 index 0000000..935ffad --- /dev/null +++ b/Tools/Python/EdkIIWorkspace.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +# This is the base class for applications that operate on an EDK II Workspace + +import os, sys +from XmlRoutines import * + +class EdkIIWorkspace: + def __init__(self): + """Collect WorkspaceDir from the environment, the Verbose command line flag, and detect an icon bitmap file.""" + if os.environ.get('WORKSPACE') == None: + print 'ERROR: WORKSPACE not defined. Please run EdkSetup from the EDK II install directory.' + return False + + self.WorkspaceDir = os.path.realpath(os.environ.get('WORKSPACE')) + (Drive, Path) = os.path.splitdrive(self.WorkspaceDir) + if Drive == '': + (Drive, CwdPath) = os.path.splitdrive(os.getcwd()) + if Drive != '': + self.WorkspaceDir = Drive + Path + else: + self.WorkspaceDir = Drive.upper() + Path + + try: + self.Icon = wx.Icon(self.WorkspaceFile('tools/Python/TianoCoreOrgLogo.gif'),wx.BITMAP_TYPE_GIF) + except: + self.Icon = None + + self.Verbose = False + for arg in sys.argv: + if arg.lower() == '-v': + self.Verbose = True + + return True + + def WorkspaceRelativePath(self, FileName): + """Convert a full path filename to a workspace relative filename.""" + FileName = os.path.realpath(FileName) + if FileName.find(self.WorkspaceDir) != 0: + return '' + return FileName.replace (self.WorkspaceDir, '').strip('\\').strip('/') + + def WorkspaceFile(self, FileName): + """Convert a workspace relative filename to a full path filename.""" + return os.path.realpath(os.path.join(self.WorkspaceDir,FileName)) + + def XmlParseFile (self, FileName): + """Parse an XML file into a DOM and return the DOM.""" + if self.Verbose: + print FileName + return XmlParseFile (self.WorkspaceFile(FileName)) + + def XmlParseFileSection (self, FileName, SectionTag): + """Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.""" + if self.Verbose: + print FileName + return XmlParseFileSection (self.WorkspaceFile(FileName), SectionTag) + + def XmlSaveFile (self, Dom, FileName): + """Save a DOM(Document Object Model) into an XML file.""" + if self.Verbose: + print FileName + return XmlSaveFile (Dom, self.WorkspaceFile(FileName)) + + def ConvertTextFileToDictionary(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + """Convert a workspace relative text file to a dictionary of (name:value) pairs.""" + if self.Verbose: + print FileName + return ConvertTextFileToDictionary(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) + + def ConvertDictionaryToTextFile(self, FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + """Convert a dictionary of (name:value) pairs to a workspace relative text file.""" + if self.Verbose: + print FileName + return ConvertDictionaryToTextFile(self.WorkspaceFile(FileName), Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter) + +# +# Convert a text file to a dictionary +# +def ConvertTextFileToDictionary(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + """Convert a text file to a dictionary of (name:value) pairs.""" + try: + f = open(FileName,'r') + except: + return False + Keys = [] + for Line in f: + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].split() + if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] not in Keys: + if ValueSplitFlag: + Dictionary[Key[0]] = LineList[1].replace('\\','/').split(ValueSplitCharacter) + else: + Dictionary[Key[0]] = LineList[1].strip().replace('\\','/') + Keys += [Key[0]] + f.close() + return True + +def ConvertDictionaryToTextFile(FileName, Dictionary, CommentCharacter, KeySplitCharacter, ValueSplitFlag, ValueSplitCharacter): + """Convert a dictionary of (name:value) pairs to a text file.""" + try: + f = open(FileName,'r') + Lines = [] + Lines = f.readlines() + f.close() + except: + Lines = [] + Keys = Dictionary.keys() + MaxLength = 0 + for Key in Keys: + if len(Key) > MaxLength: + MaxLength = len(Key) + Index = 0 + for Line in Lines: + LineList = Line.split(KeySplitCharacter,1) + if len(LineList) >= 2: + Key = LineList[0].split() + if len(Key) == 1 and Key[0][0] != CommentCharacter and Key[0] in Dictionary: + if ValueSplitFlag: + Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, ' '.join(Dictionary[Key[0]])) + else: + Line = '%-*s %c %s\n' % (MaxLength, Key[0], KeySplitCharacter, Dictionary[Key[0]]) + Lines.pop(Index) + if Key[0] in Keys: + Lines.insert(Index,Line) + Keys.remove(Key[0]) + Index += 1 + for RemainingKey in Keys: + if ValueSplitFlag: + Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter,' '.join(Dictionary[RemainingKey])) + else: + Line = '%-*s %c %s\n' % (MaxLength, RemainingKey, KeySplitCharacter, Dictionary[RemainingKey]) + Lines.append(Line) + try: + f = open(FileName,'w') + except: + return False + f.writelines(Lines) + f.close() + return True + +# This acts like the main() function for the script, unless it is 'import'ed into another +# script. +if __name__ == '__main__': + + # Nothing to do here. Could do some unit tests. + pass diff --git a/Tools/Python/Fd.py b/Tools/Python/Fd.py new file mode 100644 index 0000000..f71cc07 --- /dev/null +++ b/Tools/Python/Fd.py @@ -0,0 +1,573 @@ +#!/usr/bin/env python + +# An EDK II Build System Framework Database Utility maintains FrameworkDatabase.db +# settings in an EDK II Workspace. + +import wx, os, sys, copy +from EdkIIWorkspace import * + +class FrameworkDatabaseModel(EdkIIWorkspace): + def __init__(self): + self.WorkspaceStatus = EdkIIWorkspace.__init__(self) + self.Database = {} + self.OriginalDatabase = {} + + def AddFile (self, DirName, FileName, FileType, Enabled): + if DirName != '': + FileName = os.path.join(DirName,FileName) + if FileType == 'Package': + Header = self.XmlParseFileSection (FileName, 'SpdHeader') + Name = XmlElement (Header, '/SpdHeader/PackageName') + Version = XmlElement (Header, '/SpdHeader/Version') + elif FileType == 'Platform': + Header = self.XmlParseFileSection (FileName, 'PlatformHeader') + Name = XmlElement (Header, '/PlatformHeader/PlatformName') + Version = XmlElement (Header, '/PlatformHeader/Version') + else: + return + FileName = FileName.replace('\\','/') + if Name == '' and Version == '': + ValidType = 'Invalid' + OtherType = 'Valid' + UiName = FileName + else: + ValidType = 'Valid' + OtherType = 'Invalid' + UiName = Name + ' [' + Version + ']' + self.Database[FileType][OtherType]['PossibleSettings'].pop(FileName, None) + self.Database[FileType][OtherType]['EnabledSettings'].pop(FileName, None) + self.Database[FileType][ValidType]['PossibleSettings'][FileName] = UiName + if Enabled: + self.Database[FileType][ValidType]['EnabledSettings'][FileName] = UiName + return + + def NewModel(self): + self.Database['Platform'] = {'Valid': {'PossibleSettings':{}, 'EnabledSettings':{}},'Invalid': {'PossibleSettings':{}, 'EnabledSettings':{}}} + self.Database['Package'] = {'Valid': {'PossibleSettings':{}, 'EnabledSettings':{}},'Invalid': {'PossibleSettings':{}, 'EnabledSettings':{}}} + + def RevertModel(self): + self.Database = copy.deepcopy(self.OriginalDatabase) + + def RescanModel(self): + self.NewModel() + self.Fd = self.XmlParseFile ('Tools/Conf/FrameworkDatabase.db') + PackageList = XmlList (self.Fd, '/FrameworkDatabase/PackageList/Filename') + for File in PackageList: + SpdFileName = XmlElementData(File) + self.AddFile ('', SpdFileName, 'Package', True) + PlatformList = XmlList (self.Fd, '/FrameworkDatabase/PlatformList/Filename') + for File in PlatformList: + FpdFileName = XmlElementData(File) + self.AddFile ('', FpdFileName, 'Platform', True) + self.OriginalDatabase = copy.deepcopy(self.Database) + + def RefreshModel(self): + Temp = copy.deepcopy(self.Database) + for FileType in ['Package','Platform']: + for Valid in ['Valid','Invalid']: + for Item in Temp[FileType][Valid]['PossibleSettings']: + self.AddFile('',Item, FileType, Item in Temp[FileType][Valid]['EnabledSettings']) + return True + + def ModelModified(self): + if self.Database['Package']['Valid']['EnabledSettings'] != self.OriginalDatabase['Package']['Valid']['EnabledSettings']: + return True + if self.Database['Package']['Invalid']['EnabledSettings'] != self.OriginalDatabase['Package']['Invalid']['EnabledSettings']: + return True + if self.Database['Platform']['Valid']['EnabledSettings'] != self.OriginalDatabase['Platform']['Valid']['EnabledSettings']: + return True + if self.Database['Platform']['Invalid']['EnabledSettings'] != self.OriginalDatabase['Platform']['Invalid']['EnabledSettings']: + return True + return False + + def SaveModel(self, Filename='Tools/Conf/FrameworkDatabase.db'): + EnabledList = self.Database['Package']['Valid']['EnabledSettings'].keys() + EnabledList += self.Database['Package']['Invalid']['EnabledSettings'].keys() + PackageList = XmlList (self.Fd, '/FrameworkDatabase/PackageList/Filename') + for File in PackageList: + SpdFileName = XmlElementData(File) + if SpdFileName in EnabledList: + EnabledList.remove(SpdFileName) + continue + XmlRemoveElement(File) + + ParentNode = XmlList (self.Fd, '/FrameworkDatabase/PackageList')[0] + for SpdFileName in EnabledList: + XmlAppendChildElement(ParentNode, u'Filename', SpdFileName) + + EnabledList = self.Database['Platform']['Valid']['EnabledSettings'].keys() + EnabledList += self.Database['Platform']['Invalid']['EnabledSettings'].keys() + PlatformList = XmlList (self.Fd, '/FrameworkDatabase/PlatformList/Filename') + for File in PlatformList: + FpdFileName = XmlElementData(File) + if FpdFileName in EnabledList: + EnabledList.remove(FpdFileName) + continue + XmlRemoveElement(File) + + ParentNode = XmlList (self.Fd, '/FrameworkDatabase/PlatformList')[0] + for FpdFileName in EnabledList: + XmlAppendChildElement(ParentNode, u'Filename', FpdFileName) + + self.XmlSaveFile (self.Fd, Filename) + self.OriginalDatabase = copy.deepcopy(self.Database) + + def CloseModel(self): + pass + +class Frame(wx.Frame): + def __init__(self): + wx.Frame.__init__(self,None,-1,'EDK II Build System Framework Database Utility') + panel = wx.Panel(self, style=wx.SUNKEN_BORDER | wx.TAB_TRAVERSAL) + wx.HelpProvider_Set(wx.SimpleHelpProvider()) + + self.Model = FrameworkDatabaseModel() + + # + # Help text + # + PackagesHelpText = ( + "The set of packages that are active in the current WORKSPACE." + ) + + PlatformsHelpText = ( + "The set of platforms that are active in the current WORKSPACE." + ) + + InvalidPackagesHelpText = ( + "The set of packages that are in Framework Database, but not in the current WORKSPACE." + ) + + InvalidPlatformsHelpText = ( + "The set of platforms that are in Framework Database, but not in the current WORKSPACE." + ) + + # + # Status Bar + # + self.StatusBar = self.CreateStatusBar() + + # + # Build Menus + # + MenuBar = wx.MenuBar() + + FileMenu = wx.Menu() + NewMenuItem = FileMenu.Append(-1, "&New\tCtrl+N", "New FrameworkDatabase.db") + SaveMenuItem = FileMenu.Append(-1, "&Save\tCtrl+S", "Save FramdworkDatabase.db") + SaveAsMenuItem = FileMenu.Append(-1, "Save &As...", "Save FrameworkDatabase.db as...") + RevertMenuItem = FileMenu.Append(-1, "&Revert", "Revert to the original FrameworkDatabase.db") + ScanMenuItem = FileMenu.Append(-1, "Scan &WORKSPACE\tCtrl+W", "Scan WORKSPACE for additional packages and platforms") + ScanAndSyncMenuItem = FileMenu.Append(-1, "Scan &WORKSPACE and Sync\tCtrl+W", "Scan WORKSPACE for additional packages and platforms and sync FramdworkDatabase.db") + ExitMenuItem = FileMenu.Append(-1, "E&xit\tAlt+F4", "Exit Framework Database Tool") + MenuBar.Append(FileMenu, "&File") + self.Bind(wx.EVT_MENU, self.OnSaveClick, SaveMenuItem) + self.Bind(wx.EVT_MENU, self.OnSaveAsClick, SaveAsMenuItem) + self.Bind(wx.EVT_MENU, self.OnRevertClick, RevertMenuItem) + self.Bind(wx.EVT_MENU, self.OnScanClick, ScanMenuItem) + self.Bind(wx.EVT_MENU, self.OnScanAndSyncClick, ScanAndSyncMenuItem) + self.Bind(wx.EVT_MENU, self.OnExitClick, ExitMenuItem) + + EditMenu = wx.Menu() + SelectAllPlatformsMenuItem = EditMenu.Append (-1, "Select All Platforms", "Select all platforms") + ClearAllPlatformsMenuItem = EditMenu.Append (-1, "Clear All Platforms", "Clear all platforms") + SelectAllPackagesMenuItem = EditMenu.Append (-1, "Select All Packages", "Select all packages") + ClearAllPackagesMenuItem = EditMenu.Append (-1, "Clear All Packages", "Clear all packages") + SelectAllInvalidPlatformsMenuItem = EditMenu.Append (-1, "Select All Invalid Platforms", "Select all invalid platforms") + ClearAllInvalidPlatformsMenuItem = EditMenu.Append (-1, "Clear All Invalid Platforms", "Clear all invalid platforms") + SelectAllInvalidPackagesMenuItem = EditMenu.Append (-1, "Select All Invalid Packages", "Select all invalid packages") + ClearAllInvalidPackagesMenuItem = EditMenu.Append (-1, "Clear All Invalid Packages", "Clear all invalid packages") + MenuBar.Append(EditMenu, "&Edit") + self.Bind(wx.EVT_MENU, self.OnSelectAllPlatformsClick, SelectAllPlatformsMenuItem) + self.Bind(wx.EVT_MENU, self.OnClearAllPlatformsClick, ClearAllPlatformsMenuItem) + self.Bind(wx.EVT_MENU, self.OnSelectAllPackagesClick, SelectAllPackagesMenuItem) + self.Bind(wx.EVT_MENU, self.OnClearAllPackagesClick, ClearAllPackagesMenuItem) + self.Bind(wx.EVT_MENU, self.OnSelectAllInvalidPlatformsClick, SelectAllInvalidPlatformsMenuItem) + self.Bind(wx.EVT_MENU, self.OnClearAllInvalidPlatformsClick, ClearAllInvalidPlatformsMenuItem) + self.Bind(wx.EVT_MENU, self.OnSelectAllInvalidPackagesClick, SelectAllInvalidPackagesMenuItem) + self.Bind(wx.EVT_MENU, self.OnClearAllInvalidPackagesClick, ClearAllInvalidPackagesMenuItem) + + ViewMenu = wx.Menu() + RefreshMenuItem = ViewMenu.Append (-1, "&Refresh\tF5", "Rescan FrameworkDatabase.db") + ShowToolBarMenuItem = ViewMenu.AppendCheckItem (-1, "Show &Toolbar", "Shows or hides the toolbar") + ShowToolBarMenuItem.Check(True) + MenuBar.Append(ViewMenu, "&View") + self.Bind(wx.EVT_MENU, self.OnViewRefreshClick, RefreshMenuItem) + self.Bind(wx.EVT_MENU, self.OnShowToolBarClick, ShowToolBarMenuItem) + + HelpMenu = wx.Menu() + AboutMenuItem = HelpMenu.Append (-1, "&About...", "About") + MenuBar.Append(HelpMenu, "&Help") + self.Bind(wx.EVT_MENU, self.OnAboutClick, AboutMenuItem) + + self.SetMenuBar (MenuBar) + + # + # Build Toolbar + # + self.ShowToolBar = False + self.OnShowToolBarClick(self) + + # + # Target, ToolChain, and Arch Check List Boxes + # + PackagesLabel = wx.StaticText(panel, -1, 'Packages') + PackagesLabel.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) + PackagesLabel.SetHelpText(PackagesHelpText) + + PlatformsLabel = wx.StaticText(panel, -1, 'Platforms') + PlatformsLabel.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) + PlatformsLabel.SetHelpText(PlatformsHelpText) + + # + # Buttons + # + self.SelectAllPackagesButton = wx.Button(panel, -1, 'Select All') + self.ClearAllPackagesButton = wx.Button(panel, -1, 'Clear All') + self.SelectAllPackagesButton.Bind (wx.EVT_BUTTON, self.OnSelectAllPackagesClick) + self.ClearAllPackagesButton.Bind (wx.EVT_BUTTON, self.OnClearAllPackagesClick) + + self.PackagesCheckListBox = wx.CheckListBox(panel, -1) + self.PackagesCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnPackagesCheckListClick) + self.PackagesCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnPackagesSetFocus) + self.PackagesCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnPackagesKillFocus) + self.PackagesCheckListBox.SetHelpText(PackagesHelpText) + + + self.SelectAllPlatformsButton = wx.Button(panel, -1, 'Select All') + self.ClearAllPlatformsButton = wx.Button(panel, -1, 'Clear All') + self.SelectAllPlatformsButton.Bind(wx.EVT_BUTTON, self.OnSelectAllPlatformsClick) + self.ClearAllPlatformsButton.Bind (wx.EVT_BUTTON, self.OnClearAllPlatformsClick) + + self.PlatformsCheckListBox = wx.CheckListBox(panel, -1) + self.PlatformsCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnPlatformsCheckListClick) + self.PlatformsCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnPlatformsSetFocus) + self.PlatformsCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnPlatformsKillFocus) + self.PlatformsCheckListBox.SetHelpText(PlatformsHelpText) + + InvalidPackagesLabel = wx.StaticText(panel, -1, 'Invalid Packages') + InvalidPackagesLabel.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) + InvalidPackagesLabel.SetHelpText(InvalidPackagesHelpText) + + InvalidPlatformsLabel = wx.StaticText(panel, -1, 'Invalid Platforms') + InvalidPlatformsLabel.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) + InvalidPlatformsLabel.SetHelpText(InvalidPlatformsHelpText) + + self.SelectAllInvalidPackagesButton = wx.Button(panel, -1, 'Select All') + self.ClearAllInvalidPackagesButton = wx.Button(panel, -1, 'Clear All') + self.SelectAllInvalidPackagesButton.Bind (wx.EVT_BUTTON, self.OnSelectAllInvalidPackagesClick) + self.ClearAllInvalidPackagesButton.Bind (wx.EVT_BUTTON, self.OnClearAllInvalidPackagesClick) + + self.InvalidPackagesCheckListBox = wx.CheckListBox(panel, -1) + self.InvalidPackagesCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnInvalidPackagesCheckListClick) + self.InvalidPackagesCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnInvalidPackagesSetFocus) + self.InvalidPackagesCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnInvalidPackagesKillFocus) + self.InvalidPackagesCheckListBox.SetHelpText(PackagesHelpText) + + self.SelectAllInvalidPlatformsButton = wx.Button(panel, -1, 'Select All') + self.ClearAllInvalidPlatformsButton = wx.Button(panel, -1, 'Clear All') + self.SelectAllInvalidPlatformsButton.Bind(wx.EVT_BUTTON, self.OnSelectAllInvalidPlatformsClick) + self.ClearAllInvalidPlatformsButton.Bind (wx.EVT_BUTTON, self.OnClearAllInvalidPlatformsClick) + + self.InvalidPlatformsCheckListBox = wx.CheckListBox(panel, -1) + self.InvalidPlatformsCheckListBox.Bind(wx.EVT_CHECKLISTBOX, self.OnInvalidPlatformsCheckListClick) + self.InvalidPlatformsCheckListBox.Bind(wx.EVT_SET_FOCUS, self.OnInvalidPlatformsSetFocus) + self.InvalidPlatformsCheckListBox.Bind(wx.EVT_KILL_FOCUS, self.OnInvalidPlatformsKillFocus) + self.InvalidPlatformsCheckListBox.SetHelpText(PlatformsHelpText) + + # + # Define layout using sizers + # + self.mainSizer = wx.BoxSizer(wx.VERTICAL) + + listSizer = wx.GridBagSizer(hgap=5, vgap=5) + listSizer.Add(PackagesLabel, pos=(0,0), span=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(PlatformsLabel, pos=(0,2), span=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(self.SelectAllPackagesButton, pos=(1,0), flag=wx.ALIGN_CENTER) + listSizer.Add(self.ClearAllPackagesButton, pos=(1,1), flag=wx.ALIGN_CENTER) + listSizer.Add(self.SelectAllPlatformsButton, pos=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(self.ClearAllPlatformsButton, pos=(1,3), flag=wx.ALIGN_CENTER) + listSizer.Add(self.PackagesCheckListBox, pos=(2,0), span=(1,2), flag=wx.ALL | wx.EXPAND) + listSizer.Add(self.PlatformsCheckListBox, pos=(2,2), span=(1,2), flag=wx.ALL | wx.EXPAND) + + listSizer.Add(InvalidPackagesLabel, pos=(3,0), span=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(InvalidPlatformsLabel, pos=(3,2), span=(1,2), flag=wx.ALIGN_CENTER) + listSizer.Add(self.SelectAllInvalidPackagesButton, pos=(4,0), flag=wx.ALIGN_CENTER) + listSizer.Add(self.ClearAllInvalidPackagesButton, pos=(4,1), flag=wx.ALIGN_CENTER) + listSizer.Add(self.SelectAllInvalidPlatformsButton, pos=(4,2), flag=wx.ALIGN_CENTER) + listSizer.Add(self.ClearAllInvalidPlatformsButton, pos=(4,3), flag=wx.ALIGN_CENTER) + listSizer.Add(self.InvalidPackagesCheckListBox, pos=(5,0), span=(1,2), flag=wx.ALL | wx.EXPAND) + listSizer.Add(self.InvalidPlatformsCheckListBox, pos=(5,2), span=(1,2), flag=wx.ALL | wx.EXPAND) + + listSizer.AddGrowableRow(2) + listSizer.AddGrowableRow(5) + listSizer.AddGrowableCol(0) + listSizer.AddGrowableCol(1) + listSizer.AddGrowableCol(2) + listSizer.AddGrowableCol(3) + + self.mainSizer.Add (listSizer, wx.EXPAND | wx.ALL, wx.EXPAND | wx.ALL, 10) + + panel.SetSizer (self.mainSizer) + + self.OnViewRefreshClick(self) + + def CheckListFocus(self, CheckListBox, Set): + Index = 0 + while Index < CheckListBox.GetCount(): + CheckListBox.SetSelection(Index, False) + Index += 1 + if Set and CheckListBox.GetCount() > 0: + CheckListBox.SetSelection(0, True) + + def CheckListClick(self, CheckListBox, Database): + Index = 0 + Database['EnabledSettings'] = {} + while Index < CheckListBox.GetCount(): + if CheckListBox.IsChecked(Index): + for Item in Database['PossibleSettings']: + if Database['PossibleSettings'][Item] == CheckListBox.GetString(Index): + Database['EnabledSettings'][Item] = Database['PossibleSettings'][Item] + Index += 1 + + def OnPackagesCheckListClick(self, event): + self.CheckListClick(self.PackagesCheckListBox, self.Model.Database['Package']['Valid']) + + def OnPackagesSetFocus(self, event): + self.CheckListFocus(self.PackagesCheckListBox, True) + + def OnPackagesKillFocus(self, event): + self.CheckListFocus(self.PackagesCheckListBox, False) + + def OnPlatformsCheckListClick(self, event): + self.CheckListClick(self.PlatformsCheckListBox, self.Model.Database['Platform']['Valid']) + + def OnPlatformsSetFocus(self, event): + self.CheckListFocus(self.PlatformsCheckListBox, True) + + def OnPlatformsKillFocus(self, event): + self.CheckListFocus(self.PlatformsCheckListBox, False) + + def OnInvalidPackagesCheckListClick(self, event): + self.CheckListClick(self.InvalidPackagesCheckListBox, self.Model.Database['Package']['Invalid']) + + def OnInvalidPackagesSetFocus(self, event): + self.CheckListFocus(self.InvalidPackagesCheckListBox, True) + + def OnInvalidPackagesKillFocus(self, event): + self.CheckListFocus(self.InvalidPackagesCheckListBox, False) + + def OnInvalidPlatformsCheckListClick(self, event): + self.CheckListClick(self.InvalidPlatformsCheckListBox, self.Model.Database['Platform']['Invalid']) + + def OnInvalidPlatformsSetFocus(self, event): + self.CheckListFocus(self.InvalidPlatformsCheckListBox, True) + + def OnInvalidPlatformsKillFocus(self, event): + self.CheckListFocus(self.InvalidPlatformsCheckListBox, False) + + def OnRevertClick(self, event): + self.Model.RevertModel() + self.StatusBar.SetFocus() + self.OnRefreshClick(self) + + def RefreshCheckListBox(self, CheckListBox, SelectAllButton, ClearAllButton, Database): + NameList = [] + for Item in Database['PossibleSettings']: + NameList.append(Database['PossibleSettings'][Item]) + NameList.sort() + CheckListBox.Set(NameList) + Index = 0 + MaximumString = '.' + while Index < CheckListBox.GetCount(): + String = CheckListBox.GetString(Index) + if len(String) > len(MaximumString): + MaximumString = String + Enabled = False + for Item in Database['EnabledSettings']: + if String == Database['EnabledSettings'][Item]: + Enabled = True + if Enabled: + CheckListBox.Check(Index, True) + else: + CheckListBox.Check(Index, False) + Index += 1 + Extents = CheckListBox.GetFullTextExtent (MaximumString) + CheckListBox.SetMinSize((Extents[0] + 30,(CheckListBox.GetCount()+2) * (Extents[1]+Extents[2]))) + if NameList == []: + CheckListBox.Disable() + SelectAllButton.Disable() + ClearAllButton.Disable() + else: + CheckListBox.Enable() + SelectAllButton.Enable() + ClearAllButton.Enable() + + def OnRefreshClick(self, event): + self.Model.RefreshModel() + self.RefreshCheckListBox (self.PackagesCheckListBox, self.SelectAllPackagesButton, self.ClearAllPackagesButton, self.Model.Database['Package']['Valid']) + self.RefreshCheckListBox (self.PlatformsCheckListBox, self.SelectAllPlatformsButton, self.ClearAllPlatformsButton, self.Model.Database['Platform']['Valid']) + self.RefreshCheckListBox (self.InvalidPackagesCheckListBox, self.SelectAllInvalidPackagesButton, self.ClearAllInvalidPackagesButton, self.Model.Database['Package']['Invalid']) + self.RefreshCheckListBox (self.InvalidPlatformsCheckListBox, self.SelectAllInvalidPlatformsButton, self.ClearAllInvalidPlatformsButton, self.Model.Database['Platform']['Invalid']) + self.mainSizer.SetSizeHints(self) + self.mainSizer.Fit(self) + self.Update() + + def OnViewRefreshClick(self, event): + self.Model.RescanModel() + self.StatusBar.SetFocus() + self.OnRefreshClick(self) + + def AddTool (self, Handler, ArtId, Label, HelpText): + Tool = self.ToolBar.AddSimpleTool( + -1, + wx.ArtProvider.GetBitmap(ArtId, wx.ART_TOOLBAR, self.ToolSize), + Label, + HelpText + ) + self.Bind(wx.EVT_MENU, Handler, Tool) + + def OnShowToolBarClick(self, event): + if self.ShowToolBar: + self.ShowToolBar = False + self.ToolBar.Destroy() + else: + self.ShowToolBar = True + self.ToolBar = self.CreateToolBar() + self.ToolSize = (24,24) + self.ToolBar.SetToolBitmapSize(self.ToolSize) + self.AddTool (self.OnNewClick, wx.ART_NEW, "New", "New FrameworkDatabase.db") + self.AddTool (self.OnScanAndSyncClick, wx.ART_HARDDISK, "Scan WORKSPACE and Sync", "Scan WORKSPACE for new Packages and Platforms and sync FrameworkDatabase.db") + self.AddTool (self.OnSaveClick, wx.ART_FILE_SAVE, "Save", "Save FrameworkDatabase.db") + self.AddTool (self.OnSaveAsClick, wx.ART_FILE_SAVE_AS, "Save As...", "Save FrameworkDatabase.db as...") + self.AddTool (self.OnRevertClick, wx.ART_UNDO, "Revert", "Revert to original FrameworkDatabase.db") + self.AddTool (self.OnHelpClick, wx.ART_HELP, "Help", "Context Sensitive Help") + self.AddTool (self.OnExitClick, wx.ART_QUIT, "Exit", "Exit EDK II Build System Framework Database Utility") + self.ToolBar.Realize() + + def OnNewClick(self, event): + self.Model.NewModel() + self.OnRefreshClick(self) + + def ScanDirectory(self, Data, DirName, FilesInDir): + WorkspaceDirName = self.Model.WorkspaceRelativePath(DirName) + self.StatusBar.SetStatusText('Scanning: ' + WorkspaceDirName) + RemoveList = [] + for File in FilesInDir: + if File[0] == '.': + RemoveList.insert(0, File) + for File in RemoveList: + FilesInDir.remove(File) + for File in FilesInDir: + if os.path.splitext(File)[1].lower() == '.spd': + self.Model.AddFile (WorkspaceDirName, File, 'Package', False) + self.OnRefreshClick(self) + if os.path.splitext(File)[1].lower() == '.fpd': + self.Model.AddFile (WorkspaceDirName, File, 'Platform', False) + self.OnRefreshClick(self) + + def OnScanClick(self, event): + os.path.walk(self.Model.WorkspaceFile(''), self.ScanDirectory, None) + self.StatusBar.SetStatusText('Scanning: Complete') + self.StatusBar.SetFocus() + self.OnRefreshClick(self) + + def OnScanAndSyncClick(self, event): + self.OnSelectAllPackagesClick(self) + self.OnSelectAllPlatformsClick(self) + self.OnClearAllInvalidPackagesClick(self) + self.OnClearAllInvalidPlatformsClick(self) + self.OnScanClick(self) + self.OnSelectAllPackagesClick(self) + self.OnSelectAllPlatformsClick(self) + self.OnClearAllInvalidPackagesClick(self) + self.OnClearAllInvalidPlatformsClick(self) + + def OnSelectAllPackagesClick(self, event): + self.Model.Database['Package']['Valid']['EnabledSettings'] = self.Model.Database['Package']['Valid']['PossibleSettings'] + self.OnRefreshClick(self) + + def OnClearAllPackagesClick(self, event): + self.Model.Database['Package']['Valid']['EnabledSettings'] = {} + self.OnRefreshClick(self) + + def OnSelectAllPlatformsClick(self, event): + self.Model.Database['Platform']['Valid']['EnabledSettings'] = self.Model.Database['Platform']['Valid']['PossibleSettings'] + self.OnRefreshClick(self) + + def OnClearAllPlatformsClick(self, event): + self.Model.Database['Platform']['Valid']['EnabledSettings'] = {} + self.OnRefreshClick(self) + + def OnSelectAllInvalidPackagesClick(self, event): + self.Model.Database['Package']['Invalid']['EnabledSettings'] = self.Model.Database['Package']['Invalid']['PossibleSettings'] + self.OnRefreshClick(self) + + def OnClearAllInvalidPackagesClick(self, event): + self.Model.Database['Package']['Invalid']['EnabledSettings'] = {} + self.OnRefreshClick(self) + + def OnSelectAllInvalidPlatformsClick(self, event): + self.Model.Database['Platform']['Invalid']['EnabledSettings'] = self.Model.Database['Platform']['Invalid']['PossibleSettings'] + self.OnRefreshClick(self) + + def OnClearAllInvalidPlatformsClick(self, event): + self.Model.Database['Platform']['Invalid']['EnabledSettings'] = {} + self.OnRefreshClick(self) + + def OnSaveClick(self, event): + self.Model.SaveModel() + + def OnSaveAsClick(self, event): + wildcard = "Text Documents (*.db)|*.db|" \ + "All files (*.*)|*.*" + dialog = wx.FileDialog (None, 'Save As', self.Model.WorkspaceFile('Tools/Conf'), '', wildcard, wx.SAVE | wx.OVERWRITE_PROMPT) + if dialog.ShowModal() == wx.ID_OK: + FrameworkDatabaseDbFile = self.Model.WorkspaceRelativePath(dialog.GetPath()) + if FrameworkDatabaseDbFile != '': + self.Model.SaveModel(FrameworkDatabaseDbFile) + dialog.Destroy() + + def OnExitClick(self, event): + if self.Model.ModelModified(): + dialog = wx.MessageDialog(None, 'The contents have changed.\nDo you want to save changes?', 'EDK II Build System Framework Databsase Utility', style = wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_EXCLAMATION) + Status = dialog.ShowModal() + dialog.Destroy() + if Status == wx.ID_YES: + self.OnSaveClick (self) + elif Status == wx.ID_CANCEL: + return + self.Model.CloseModel() + self.Close() + + def OnHelpClick(self, event): + wx.ContextHelp().BeginContextHelp() + + def OnAboutClick(self, event): + AboutInfo = wx.AboutDialogInfo() + AboutInfo.Name = 'EDK II Build System Framework Database Utility' + AboutInfo.Version = '0.3' + AboutInfo.Copyright = 'Copyright (c) 2006, Intel Corporation' + AboutInfo.Description = """ + The EDK II Build System Framework Database Utility maintains FrameworkDatabase.db + settings in an EDK II Workspace.""" + AboutInfo.WebSite = ("http://tianocore.org", "Tiano Core home page") + AboutInfo.License = """ + All rights reserved. This program and the accompanying materials are + licensed and made available under the terms and conditions of the BSD + License which accompanies this distribution. The full text of the + license may be found at http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" + BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, + EITHER EXPRESS OR IMPLIED.""" + if self.Model.Icon != None: + AboutInfo.Icon = self.Model.Icon + wx.AboutBox(AboutInfo) + +if __name__ == '__main__': + app = wx.PySimpleApp() + frame = Frame() + frame.Show() + app.MainLoop() +
\ No newline at end of file diff --git a/Tools/Python/XmlRoutines.py b/Tools/Python/XmlRoutines.py index 9d1ff4a..2707bcb 100755 --- a/Tools/Python/XmlRoutines.py +++ b/Tools/Python/XmlRoutines.py @@ -27,13 +27,13 @@ def XmlList(Dom, String): def XmlElement (Dom, String): """Return a single element that matches the String which is XPath style syntax.""" try: - return XmlList (Dom, String)[0].firstChild.data.strip(' ') + return XmlList (Dom, String)[0].firstChild.data.strip() except: return '' def XmlElementData (Dom): """Get the text for this element.""" - return Dom.firstChild.data.strip(' ') + return Dom.firstChild.data.strip() def XmlAttribute (Dom, String): """Return a single attribute that named by String.""" @@ -44,7 +44,84 @@ def XmlAttribute (Dom, String): def XmlTopTag(Dom): """Return the name of the Root or top tag in the XML tree.""" - return Dom.documentElement.nodeName + return Dom.firstChild.nodeName + +def XmlParseFile (FileName): + """Parse an XML file into a DOM and return the DOM.""" + try: + f = open(FileName, 'r') + Dom = xml.dom.minidom.parse(f) + f.close() + return Dom + except: + return xml.dom.minidom.parseString('<empty/>') + +def XmlParseFileSection (FileName, Tag): + """Parse a section of an XML file into a DOM(Document Object Model) and return the DOM.""" + try: + f = open(FileName, 'r') + except: + return xml.dom.minidom.parseString('<empty/>') + Start = '<' + Tag + End = '</' + Tag + '>' + File = '' + while File.find(Start) < 0 or File.find(End) < 0: + Section = f.read(0x1000) + if Section == '': + break + File += Section + f.close() + if File.find(Start) < 0 or File.find(End) < 0: + return xml.dom.minidom.parseString('<empty/>') + File = File[File.find(Start):File.find(End)+len(End)] + try: + return xml.dom.minidom.parseString(File) + except: + return xml.dom.minidom.parseString('<empty/>') + +def XmlSaveFile (Dom, FileName, Encoding='UTF-8'): + """Save a DOM(Document Object Model) into an XML file.""" + try: + f = open(FileName, 'w') + f.write(Dom.toxml(Encoding).replace('"','"').replace('>','>')) + f.close() + return True + except: + return False + +def XmlRemoveElement(Node): + """Remove an element node from DOM(Document Object Model) tree.""" + ParentNode = Node.parentNode + if ParentNode == None: + return False + PreviousSibling = Node.previousSibling + while PreviousSibling != None and PreviousSibling.nodeType == PreviousSibling.TEXT_NODE and PreviousSibling.data.strip() == '': + Temp = PreviousSibling + PreviousSibling = PreviousSibling.previousSibling + ParentNode.removeChild(Temp) + ParentNode.removeChild(Node) + return True + +def XmlAppendChildElement(ParentNode, TagName, ElementText='', AttributeDictionary = {}): + """Add a child element to a DOM(Document Object Model) tree with optional Attributes.""" + TagName = TagName.strip() + if TagName == '': + return False + Depth = 0 + Dom = ParentNode + while Dom != None and Dom.nodeType != Dom.DOCUMENT_NODE: + Dom = Dom.parentNode + Depth += 1 + if Dom == None: + return False + ParentNode.appendChild(Dom.createTextNode('\n%*s' % (Depth * 2, ''))) + ElementNode = Dom.createElement(TagName) + if ElementText != '': + ElementNode.appendChild(Dom.createTextNode(ElementText)) + for Item in AttributeDictionary: + ElementNode.setAttribute(Item, AttributeDictionary[Item]) + ParentNode.appendChild(ElementNode) + return True # This acts like the main() function for the script, unless it is 'import'ed into another |