summaryrefslogtreecommitdiff
path: root/Tools
diff options
context:
space:
mode:
Diffstat (limited to 'Tools')
-rw-r--r--Tools/Python/ContextTool.py590
-rw-r--r--Tools/Python/EdkIIWorkspace.py148
-rw-r--r--Tools/Python/Fd.py573
-rwxr-xr-xTools/Python/XmlRoutines.py83
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('&quot;','"').replace('&gt;','>'))
+ 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