def __init__(self, parent): """ Default class constructor. **Parameters:** * parent: the widget parent. """ wx.Panel.__init__(self, parent) self.MainFrame = wx.GetTopLevelParent(self) # Add the fancy list at the bottom self.list = BaseListCtrl(self, columnNames=[_("Time "), _("Compiler Messages")], name="messages") # Create 3 themed bitmap buttons dryBmp = self.MainFrame.CreateBitmap("dry") compileBmp = self.MainFrame.CreateBitmap("compile") killBmp = self.MainFrame.CreateBitmap("kill") # This is a bit tailored over py2exe, but it's the only one I know self.dryrun = buttons.ThemedGenBitmapTextButton(self, -1, dryBmp, _("Dry Run"), size=(-1, 25)) self.compile = buttons.ThemedGenBitmapTextButton(self, -1, compileBmp, _("Compile"), size=(-1, 25)) self.kill = buttons.ThemedGenBitmapTextButton(self, -1, killBmp, _("Kill"), size=(-1, 25)) # The animation control ani = wx.animate.Animation(os.path.normpath(self.MainFrame.installDir +"/images/throbber.gif")) self.throb = wx.animate.AnimationCtrl(self, -1, ani) self.throb.SetUseWindowBackgroundColour() # Store an id for the popup menu self.popupId = wx.NewId() # Fo the hard work on other methods self.SetProperties() self.LayoutItems() self.BindEvents()
def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="PyInstaller") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.pathSizer_staticbox = wx.StaticBox(self, -1, _("Path Extensions")) self.hookSizer_staticbox = wx.StaticBox(self, -1, _("Hooks Extensions")) self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages (PKG)")) self.dllExcludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL/Binary Excludes")) self.dllIncludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL/Binary Includes")) self.datafileSizer_staticBox = wx.StaticBox(self, -1, _("Data Files")) self.otherOptionsSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.scriptSizer_staticbox = wx.StaticBox(self, -1, _("Scripts")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText(self, -1, _("PyInstaller options for: %(projectName)s (Created: %(creationDate)s)")%transdict) # This list holds all the script files added by the user self.scriptsList = BaseListCtrl(self, columnNames=[_("Python Scripts")], name="scripts") # A list for the extension of the search path self.pathexList = BaseListCtrl(self, columnNames=[_("Paths")], name="pathex") # A list for the extension of the hooks package self.hookList = BaseListCtrl(self, columnNames=[_("Paths")], name="hookspath") # Do we want a debug build? self.debugCheck = wx.CheckBox(self, -1, _("Debug"), name="debug") # Radiobutton for the one-file build self.oneFileRadio = wx.RadioButton(self, -1, _("One File"), style=wx.RB_GROUP, name="onefile") # Name of the executable self.exeTextCtrl = wx.TextCtrl(self, -1, "", name="exename") # Whether it is a console or a windowed application self.consoleCheck = wx.CheckBox(self, -1, _("Console Application"), name="console") # Radiobutton for the one-dir build self.oneDirRadio = wx.RadioButton(self, -1, _("One Directory"), name="onedir") # A file picker for the executable icon self.iconPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="icon") # Strip or no strip? self.stripCheck = wx.CheckBox(self, -1, _("Strip Executable"), name="strip") # Do we want to include encodings or not? self.asciiCheck = wx.CheckBox(self, -1, "Ascii", name="ascii") # Name of the distribution directory self.distTextCtrl = wx.TextCtrl(self, -1, "", name="dist_dir") # Compression level self.compressCombo = MultiComboBox(self, [str(i) for i in xrange(10)], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "level") # Use UPX compression? self.upxCheck = wx.CheckBox(self, -1, _("UPX Compression"), name="upx") # Include Tk in the distribution? self.includeTkCheck = wx.CheckBox(self, -1, _("Include Tk"), name="includetk") # A file picker for the version file self.versionPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="version") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules"), _("Path")], name="includes") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages"), _("Path")], name="packages") # A couple of listctrls to hold DLL/binary includes and excludes self.dllExcludeList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="dll_excludes") self.dllIncludeList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="dll_includes") # A list control for the "data_files" option. "data_files" should contain # a sequence of (target-dir, files) tuples, where files is a sequence of # files to be copied self.datafileList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="data_files") # Less used options self.verboseCheck = wx.CheckBox(self, -1, _("Verbose Import"), name="option1") self.warningCheck = wx.CheckBox(self, -1, _("Warning Option"), name="option2") self.forceexecCheck = wx.CheckBox(self, -1, _("Force Execpv"), name="option3") self.unbufferedCheck = wx.CheckBox(self, -1, _("Unbuffered STDIO"), name="option4") self.useSiteCheck = wx.CheckBox(self, -1, _("Use Site.py"), name="option5") self.optimizeCheck = wx.CheckBox(self, -1, _("Build Optimized"), name="option6") self.addManifest = wx.CheckBox(self, -1, _("Create Manifest File (MSW)"), name="create_manifest_file") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.packagesList, self.excludeList, self.dllExcludeList, self.dllIncludeList, self.datafileList, self.scriptsList, self.pathexList, self.hookList] # Hold a reference to the most obscure PyInstaller options self.optionsCheckBoxes = [self.verboseCheck, self.warningCheck, self.forceexecCheck, self.unbufferedCheck, self.useSiteCheck, self.optimizeCheck] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents()
class PyInstallerPanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="PyInstaller") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.pathSizer_staticbox = wx.StaticBox(self, -1, _("Path Extensions")) self.hookSizer_staticbox = wx.StaticBox(self, -1, _("Hooks Extensions")) self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages (PKG)")) self.dllExcludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL/Binary Excludes")) self.dllIncludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL/Binary Includes")) self.datafileSizer_staticBox = wx.StaticBox(self, -1, _("Data Files")) self.otherOptionsSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.scriptSizer_staticbox = wx.StaticBox(self, -1, _("Scripts")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText(self, -1, _("PyInstaller options for: %(projectName)s (Created: %(creationDate)s)")%transdict) # This list holds all the script files added by the user self.scriptsList = BaseListCtrl(self, columnNames=[_("Python Scripts")], name="scripts") # A list for the extension of the search path self.pathexList = BaseListCtrl(self, columnNames=[_("Paths")], name="pathex") # A list for the extension of the hooks package self.hookList = BaseListCtrl(self, columnNames=[_("Paths")], name="hookspath") # Do we want a debug build? self.debugCheck = wx.CheckBox(self, -1, _("Debug"), name="debug") # Radiobutton for the one-file build self.oneFileRadio = wx.RadioButton(self, -1, _("One File"), style=wx.RB_GROUP, name="onefile") # Name of the executable self.exeTextCtrl = wx.TextCtrl(self, -1, "", name="exename") # Whether it is a console or a windowed application self.consoleCheck = wx.CheckBox(self, -1, _("Console Application"), name="console") # Radiobutton for the one-dir build self.oneDirRadio = wx.RadioButton(self, -1, _("One Directory"), name="onedir") # A file picker for the executable icon self.iconPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="icon") # Strip or no strip? self.stripCheck = wx.CheckBox(self, -1, _("Strip Executable"), name="strip") # Do we want to include encodings or not? self.asciiCheck = wx.CheckBox(self, -1, "Ascii", name="ascii") # Name of the distribution directory self.distTextCtrl = wx.TextCtrl(self, -1, "", name="dist_dir") # Compression level self.compressCombo = MultiComboBox(self, [str(i) for i in xrange(10)], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "level") # Use UPX compression? self.upxCheck = wx.CheckBox(self, -1, _("UPX Compression"), name="upx") # Include Tk in the distribution? self.includeTkCheck = wx.CheckBox(self, -1, _("Include Tk"), name="includetk") # A file picker for the version file self.versionPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="version") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules"), _("Path")], name="includes") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages"), _("Path")], name="packages") # A couple of listctrls to hold DLL/binary includes and excludes self.dllExcludeList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="dll_excludes") self.dllIncludeList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="dll_includes") # A list control for the "data_files" option. "data_files" should contain # a sequence of (target-dir, files) tuples, where files is a sequence of # files to be copied self.datafileList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="data_files") # Less used options self.verboseCheck = wx.CheckBox(self, -1, _("Verbose Import"), name="option1") self.warningCheck = wx.CheckBox(self, -1, _("Warning Option"), name="option2") self.forceexecCheck = wx.CheckBox(self, -1, _("Force Execpv"), name="option3") self.unbufferedCheck = wx.CheckBox(self, -1, _("Unbuffered STDIO"), name="option4") self.useSiteCheck = wx.CheckBox(self, -1, _("Use Site.py"), name="option5") self.optimizeCheck = wx.CheckBox(self, -1, _("Build Optimized"), name="option6") self.addManifest = wx.CheckBox(self, -1, _("Create Manifest File (MSW)"), name="create_manifest_file") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.packagesList, self.excludeList, self.dllExcludeList, self.dllIncludeList, self.datafileList, self.scriptsList, self.pathexList, self.hookList] # Hold a reference to the most obscure PyInstaller options self.optionsCheckBoxes = [self.verboseCheck, self.warningCheck, self.forceexecCheck, self.unbufferedCheck, self.useSiteCheck, self.optimizeCheck] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Set fonts and other default properties. """ # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance(child, wx.CheckBox) or \ isinstance(child, wx.RadioButton): child.SetFont(font) def LayoutItems(self): mainSizer = wx.BoxSizer(wx.VERTICAL) otherOptionsSizer = wx.StaticBoxSizer(self.otherOptionsSizer_staticbox, wx.HORIZONTAL) otherGridSizer = wx.FlexGridSizer(2, 4, 5, 5) dataFileSizer = wx.StaticBoxSizer(self.datafileSizer_staticBox, wx.HORIZONTAL) centerSizer2 = wx.BoxSizer(wx.HORIZONTAL) dllIncludesSizer = wx.StaticBoxSizer(self.dllIncludesSizer_staticbox, wx.HORIZONTAL) dllExcludesSizer = wx.StaticBoxSizer(self.dllExcludesSizer_staticbox, wx.HORIZONTAL) packagesSizer = wx.StaticBoxSizer(self.packagesSizer_staticbox, wx.HORIZONTAL) centerSizer1 = wx.BoxSizer(wx.HORIZONTAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.HORIZONTAL) commonGridSizer = wx.FlexGridSizer(5, 5, 0, 5) topSizer = wx.BoxSizer(wx.HORIZONTAL) hookSizer = wx.StaticBoxSizer(self.hookSizer_staticbox, wx.HORIZONTAL) pathSizer = wx.StaticBoxSizer(self.pathSizer_staticbox, wx.HORIZONTAL) scriptSizer = wx.StaticBoxSizer(self.scriptSizer_staticbox, wx.HORIZONTAL) mainSizer.Add(self.label, 0, wx.ALL, 10) flag = wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND scriptSizer.Add(self.scriptsList, 1, flag, 5) scriptSizer.Add(self.scriptsList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) topSizer.Add(scriptSizer, 2, wx.ALL|wx.EXPAND, 5) pathSizer.Add(self.pathexList, 1, flag, 5) pathSizer.Add(self.pathexList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) topSizer.Add(pathSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) hookSizer.Add(self.hookList, 1, flag, 5) hookSizer.Add(self.hookList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) topSizer.Add(hookSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) mainSizer.Add(topSizer, 0, wx.EXPAND, 0) exename = wx.StaticText(self, -1, _("Executable Name")) commonGridSizer.Add(exename, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5) compress = wx.StaticText(self, -1, _("Compression Level")) commonGridSizer.Add(compress, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 10) commonGridSizer.Add(self.debugCheck, 0, wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.oneFileRadio, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_BOTTOM, 10) icon = wx.StaticText(self, -1, _("Icon File")) commonGridSizer.Add(icon, 0, wx.ALIGN_CENTER_VERTICAL, 0) commonGridSizer.Add(self.exeTextCtrl, 0, wx.LEFT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add(self.compressCombo, 1, wx.EXPAND|wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.consoleCheck, 0, wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.oneDirRadio, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.iconPicker, 0, wx.RIGHT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add((0, 15), 0, 0, 0) commonGridSizer.Add((0, 15), 0, 0, 0) commonGridSizer.Add((0, 5), 0, 0, 0) commonGridSizer.Add((0, 15), 0, 0, 0) commonGridSizer.Add((0, 15), 0, 0, 0) distname = wx.StaticText(self, -1, _("Dist Directory Name")) commonGridSizer.Add(distname, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add((0, 5), 1, 0, 0) commonGridSizer.Add(self.stripCheck, 0, wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.asciiCheck, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_BOTTOM, 10) version = wx.StaticText(self, -1, _("Version File")) commonGridSizer.Add(version, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add(self.distTextCtrl, 0, wx.LEFT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add((0, 5), 1, 0, 0) commonGridSizer.Add(self.upxCheck, 0, wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.includeTkCheck, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.versionPicker, 0, wx.RIGHT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.AddGrowableCol(0) commonGridSizer.AddGrowableCol(4) commonSizer.Add(commonGridSizer, 1, wx.EXPAND|wx.TOP|wx.BOTTOM, 5) mainSizer.Add(commonSizer, 0, wx.ALL|wx.EXPAND, 5) # Add the list controls includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer1.Add(includesSizer, 1, wx.ALL|wx.EXPAND, 5) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer1.Add(excludesSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) mainSizer.Add(centerSizer1, 0, wx.EXPAND, 0) packagesSizer.Add(self.packagesList, 1, flag, 5) packagesSizer.Add(self.packagesList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer2.Add(packagesSizer, 1, wx.ALL|wx.EXPAND, 5) dllExcludesSizer.Add(self.dllExcludeList, 1, flag, 5) dllExcludesSizer.Add(self.dllExcludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer2.Add(dllExcludesSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) dllIncludesSizer.Add(self.dllIncludeList, 1, flag, 5) dllIncludesSizer.Add(self.dllIncludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer2.Add(dllIncludesSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) mainSizer.Add(centerSizer2, 0, wx.EXPAND, 0) dataFileSizer.Add(self.datafileList, 1, flag, 5) dataFileSizer.Add(self.datafileList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) mainSizer.Add(dataFileSizer, 0, wx.ALL|wx.EXPAND, 5) otherGridSizer.Add(self.verboseCheck, 0, wx.LEFT|wx.TOP|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.warningCheck, 0, wx.TOP|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.forceexecCheck, 0, wx.TOP|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.unbufferedCheck, 0, wx.LEFT|wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.useSiteCheck, 0, wx.LEFT|wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.optimizeCheck, 0, wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.addManifest, 0, wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.AddGrowableCol(0) otherGridSizer.AddGrowableCol(1) otherGridSizer.AddGrowableCol(2) otherGridSizer.AddGrowableCol(3) otherOptionsSizer.Add(otherGridSizer, 1, wx.EXPAND, 0) mainSizer.Add(otherOptionsSizer, 1, wx.ALL|wx.EXPAND, 5) self.SetSizer(mainSizer) mainSizer.Fit(self) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def ValidateOptions(self): """ Validates the PyInstaller input options before compiling. """ # check if the script files exist if self.scriptsList.GetItemCount() == 0: msg = _("No Python scripts have been added.") self.MainFrame.RunError(2, msg, True) return False for indx in xrange(self.scriptsList.GetItemCount()): script = self.scriptsList.GetItem(indx, 1) if not os.path.isfile(script.GetText()): transdict = dict(scriptName=script.GetText()) msg = _("Python script:\n\n%(scriptName)s\n\nIs not a valid file.")%transdict self.MainFrame.RunError(2, msg, True) return False # check if the icon/version files are not empty and if they exist iconFile = self.iconPicker.GetPath() if iconFile and not os.path.isfile(iconFile): msg = _("Icon file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False versionFile = self.versionPicker.GetPath() if versionFile and not os.path.isfile(versionFile): msg = _("Version file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Generating "%(projectName)s" setup script...')%transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, None, customCode, postCompile) def BuildTargetClass(self, configuration, project, manifestFile, customCode, postCompile): """ Builds the PyInstaller compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) pyFile = self.scriptsList.GetItem(0, 1).GetText() buildDir = os.path.split(pyFile)[0] includeTk = self.includeTkCheck.GetValue() oneDir = self.oneDirRadio.GetValue() ascii = self.asciiCheck.GetValue() normpath = os.path.normpath useRelPath = self.MainFrame.relativePaths scriptFile = pyFile # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if key.startswith("option"): continue if isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if key == "create_manifest_file": continue if type(item) == ListType and item: # Terrible hack to setup correctly the string to be included # in the setup file if key not in ["hookspath", "scripts", "excludes", "pathex"]: tmp = [] for data in item: data = data + (_pyInstallerTOC[key],) tmp.append(data) item = tmp elif key == "pathex": if buildDir not in item: item.append(buildDir) elif key == "scripts": continue item = setupString(key, item, True, useRelPath=useRelPath, mainScript=scriptFile) if key == "exename" and not item.strip() and not oneDir: item = os.path.splitext(os.path.split(pyFile)[1])[0] + ".exe" if key == "dist_dir" and not item.strip() and oneDir: item = normpath(os.path.split(pyFile)[0] + "/dist") if key in ["icon", "version"]: if not item.strip(): item = None else: if useRelPath: item = 'r"%s"'%(relpath(item, os.path.split(scriptFile)[0])) else: item = "r'%s'"%item setupDict[key] = item # Set up the obscure options otherOptions = [] for indx, checks in enumerate(self.optionsCheckBoxes): if checks.GetValue(): otherOptions.append(_pyInstallerOptions[indx]) setupDict["options"] = otherOptions # Depending on the various choices in the interface, PyInstaller # includes/excludes some Python source file located in # PyInstaller_Path/support/ pyInstallerPath = self.MainFrame.GetPyInstallerPath() if not pyInstallerPath or pyInstallerPath == "None": msg = _("PyInstaller path has not been set.\n\nPlease set the PyInstaller" \ "path using the menu Options ==> Set PyInstaller path.") self.MainFrame.RunError(2, msg) return items = configuration["scripts"][:] pyInstallerPath += "/support/" if setupDict["level"] != "0": # Include zlib as user wants compression items.append(normpath(pyInstallerPath + "_mountzlib.py").encode()) if includeTk: # That's a bit of a mess, but PyInstaller is not exactly user-friendly... if oneDir: items.append(normpath(pyInstallerPath + "useTK.py").encode()) else: items.extend([normpath(pyInstallerPath + "unpackTK.py").encode(), normpath(pyInstallerPath + "useTK.py").encode(), normpath(pyInstallerPath + "removeTK.py").encode()]) if not ascii: # Using unicode items.append(normpath(pyInstallerPath + "useUnicode.py").encode()) items.append(items[0]) items.pop(0) setupDict["scripts"] = setupString("scripts", items, True) # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Add the post-compilation code (if any) setupDict["postcompilecode"] = (postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Populate the "import" section setupScript = _pyInstaller_imports % importDict if oneDir: target = _pyInstaller_target_onedir if includeTk: setupDict["TkPKG"] = "TkTree()," else: setupDict["TkPKG"] = "" else: target = _pyInstaller_target_onefile if includeTk: setupDict["TkPKG"] = "TkPKG()," else: setupDict["TkPKG"] = "" # Populate the main section of the setup script setupScript += target % setupDict # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Setup script for "%(projectName)s" succesfully created')%transdict) return setupScript, buildDir
class MessageWindow(wx.Panel): """ A class which will show a list control at the bottom of our application. It is used to log messages coming from GUI2Exe. """ def __init__(self, parent): """ Default class constructor. **Parameters:** * parent: the widget parent. """ wx.Panel.__init__(self, parent) self.MainFrame = wx.GetTopLevelParent(self) # Add the fancy list at the bottom self.list = BaseListCtrl(self, columnNames=[_("Time "), _("Compiler Messages")], name="messages") # Create 3 themed bitmap buttons dryBmp = self.MainFrame.CreateBitmap("dry") compileBmp = self.MainFrame.CreateBitmap("compile") killBmp = self.MainFrame.CreateBitmap("kill") # This is a bit tailored over py2exe, but it's the only one I know self.dryrun = buttons.ThemedGenBitmapTextButton(self, -1, dryBmp, _("Dry Run"), size=(-1, 25)) self.compile = buttons.ThemedGenBitmapTextButton(self, -1, compileBmp, _("Compile"), size=(-1, 25)) self.kill = buttons.ThemedGenBitmapTextButton(self, -1, killBmp, _("Kill"), size=(-1, 25)) # The animation control ani = wx.animate.Animation(os.path.normpath(self.MainFrame.installDir +"/images/throbber.gif")) self.throb = wx.animate.AnimationCtrl(self, -1, ani) self.throb.SetUseWindowBackgroundColour() # Store an id for the popup menu self.popupId = wx.NewId() # Fo the hard work on other methods self.SetProperties() self.LayoutItems() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets few properties for the list control. """ font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) # Set a bigger for for the compile and kill buttons self.compile.SetFont(font) self.kill.SetFont(font) self.kill.Enable(False) def LayoutItems(self): """ Layout the widgets with sizers. """ mainSizer = wx.BoxSizer(wx.HORIZONTAL) buttonSizer = wx.BoxSizer(wx.VERTICAL) # We have the main list filling all the space with a small reserved # zone on the right for the buttons buttonSizer.Add(self.dryrun, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.LEFT|wx.RIGHT, 5) buttonSizer.Add(self.compile, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.LEFT|wx.RIGHT, 5) buttonSizer.Add((0, 0), 1, wx.EXPAND) buttonSizer.Add(self.throb, 0, wx.ALIGN_CENTER) buttonSizer.Add((0, 0), 1, wx.EXPAND) buttonSizer.Add(self.kill, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.LEFT|wx.RIGHT, 5) buttonSizer.Show(self.throb, False) buttonSizer.Layout() # Add everything to the main sizer mainSizer.Add(self.list, 1, wx.EXPAND) mainSizer.Add(buttonSizer, 0, wx.EXPAND) self.SetSizer(mainSizer) mainSizer.Layout() # Keep a reference to the buttonSizer self.buttonSizer = buttonSizer def BindEvents(self): """ Bind the events for the list control. """ self.Bind(wx.EVT_BUTTON, self.OnDryRun, self.dryrun) self.Bind(wx.EVT_BUTTON, self.OnCompile, self.compile) self.Bind(wx.EVT_BUTTON, self.OnKill, self.kill) self.Bind(wx.EVT_MENU, self.OnHistoryClear, id=self.popupId) self.list.Bind(wx.EVT_LIST_COL_RIGHT_CLICK, self.OnRightClick) self.list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnRightClick) if wx.Platform != "__WXMAC__": # Create a FlatMenu style popup and bind the events self.Bind(FM.EVT_FLAT_MENU_SELECTED, self.OnHistoryClear, id=self.popupId) # ============== # # Event handlers # # ============== # def OnDryRun(self, event): """ Handles the wx.EVT_BUTTON event for the dry run button. """ # Delegate the action to the main frame self.MainFrame.RunCompile(view=False, run=False) def OnCompile(self, event): """ Handles the wx.EVT_BUTTON event for the compile button. """ # Delegate the action to the main frame self.MainFrame.RunCompile(view=False, run=True) def OnKill(self, event): """ Handles the wx.EVT_BUTTON event for the kill button. """ # Delegate the action to the main frame self.MainFrame.KillCompile() # Hide the throb self.ShowThrobber(False) def OnRightClick(self, event): """ Handles the wx.EVT_LIST_COL_RIGHT_CLICK/wx.EVT_LIST_ITEM_RIGHT_CLICK event for the list control. """ flat, style = wx.GetApp().GetPreferences("Use_Flat_Menu", default=[0, (1, "Dark")]) menu = (flat and [FM.FlatMenu()] or [wx.Menu()])[0] MenuItem = (flat and [FM.FlatMenuItem] or [wx.MenuItem])[0] # This pops up the "clear all" message item = MenuItem(menu, self.popupId, _("Clear History")) bmp = self.MainFrame.CreateBitmap("history_clear") item.SetBitmap(bmp) menu.AppendItem(item) # Popup the menu. If an item is selected then its handler # will be called before PopupMenu returns. if flat: menu.Popup(wx.GetMousePosition(), self) else: self.list.PopupMenu(menu) menu.Destroy() def OnHistoryClear(self, event): """ Handles the wx.EVT_MENU event for the list control. """ # Freeze everything... It helps with flicker self.list.Freeze() # Delete all the items, the user cleared all self.list.DeleteAllItems() # Time to warm up self.list.Thaw() # ================= # # Auxiliary methods # # ================= # def ShowThrobber(self, show): """ Shows/hides the throbber. **Parameters:** * show: whether to show or hide the throbber. """ # Show/hide the throb self.buttonSizer.Show(self.throb, show) self.buttonSizer.Layout() # Refresh ourselves self.Refresh() if show: self.throb.Play() else: self.throb.Stop() def GetMaxWidth(self): """ Returns the maximum number of characters that can fit in the message column. """ # Use a wx.ClientDC to measure the maximum number of # characters we can fill for every list control row width = self.list.GetColumnWidth(2) font = self.list.GetFont() dc = wx.ClientDC(self.list) dc.SetFont(font) textWidth = dc.GetCharWidth() return int(width/float(textWidth)) def InsertError(self, currentTime): """ Insert some fancy line when an error happens. **Parameters:** * currentTime: the actual formatted time. """ indx = self.list.InsertImageStringItem(sys.maxint, "", 2) self.list.SetStringItem(indx, 1, currentTime) self.list.SetStringItem(indx, 2, _("Error Message")) self.list.SetItemBackgroundColour(indx, wx.NamedColour("yellow")) font = self.list.GetFont() font.SetWeight(wx.BOLD) self.list.SetItemFont(indx, font) return indx def SendMessage(self, kind, message, copy=False): """ Prints an user-friendly message on the list control. **Parameters:** * kind: the message kind (error, warning, message); * message: the actual message to display in the list control; * copy: whether to save a reference to this message or not. """ # Get the current time slightly dirrently formatted currentTime = shortNow() # Delete the "." at the end of the message (if any) message = message.strip() if message.endswith("."): message = message[:-1] # Wrap the message... error messages are often too long # to be seen in the list control width = self.GetMaxWidth() if kind == 2: # is an error # Insert the correct icon (message, error, etc...) in the first column indx = self.InsertError(currentTime) messages = message.splitlines() message = [] for msg in messages: message.extend(textwrap.wrap(msg, width)) elif kind == 1 and "\n" in message: messages = message.splitlines() message = [] for msg in messages: message.extend(textwrap.wrap(msg.strip(), width)) else: message = [message] for msg in message: try: # Insert the correct icon (message, error, etc...) in the first column indx = self.list.InsertImageStringItem(sys.maxint, "", kind) # Insert the current time and the message self.list.SetStringItem(indx, 1, currentTime) self.list.SetStringItem(indx, 2, msg.encode()) except UnicodeDecodeError: # Why does this happen here?!? continue # Ensure the last item is visible self.list.EnsureVisible(indx) if wx.Platform == "__WXGTK__": self.list.Refresh() if copy: # Save the last message self.list.lastMessage = [kind, msg] def CopyLastMessage(self): """ Re-sends the previous message to the log window (for long processes). """ if not hasattr(self.list, "lastMessage"): return # Get the current time slightly dirrently formatted currentTime = shortNow() # Insert the correct icon (message, error, etc...) in the first column kind, msg = self.list.lastMessage indx = self.list.InsertImageStringItem(sys.maxint, "", kind) # Insert the current time and the message self.list.SetStringItem(indx, 1, currentTime) self.list.SetStringItem(indx, 2, msg) # Ensure the last item is visible self.list.EnsureVisible(indx) if wx.Platform == "__WXGTK__": self.list.Refresh() def EnableButtons(self, enable): """ Enables/disables the run buttons depending on the external process status. **Parameters:** * enable: whether to enable or disable the buttons. """ # dry run and compile buttons are enabled when the kill button is # not, and vice-versa self.dryrun.Enable(enable) self.compile.Enable(enable) self.kill.Enable(not enable) def EnableDryRun(self, book): """ Enables/Disables the dry-run button depending on the selected compiler (dry-run is available only for py2exe). **Parameters:** * book: the L[LabelBook] associated to our project. """ # We enable the dry run option only if the selected compiler # is py2exe pageNum = book.GetSelection() self.dryrun.Enable(pageNum == 0) def NoPagesLeft(self, enable): """ Enables/disables all the buttons depending on the number of projects opened. **Parameters:** * enable: whether to enable or disable the buttons. """ self.dryrun.Enable(enable) self.compile.Enable(enable) self.kill.Enable(enable)
class bbFreezePanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="bbfreeze") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.otherOptionsSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.targetSizer_staticbox = wx.StaticBox(self, -1, _("Target Classes")) transdict = dict(projectName=projectName, creationDate=creationDate) # A simple label that holds information about the project self.label = wx.StaticText(self, -1, _("bbFreeze options for: %(projectName)s (Created: %(creationDate)s)")%transdict) # A list control for the target classes, scripts self.multipleExe = BaseListCtrl(self, columnNames=[_("Exe Kind"), _("Python Main Script")], name="multipleexe") # Optimization level for bbFreeze 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "optimize") # Compression level for the zipfile in bbFreeze self.compressCombo = MultiComboBox(self, ["0", "1"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "compress") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") self.includeInterpreter = wx.CheckBox(self, -1, _("Include Python Interpreter"), name="include_py") self.addManifest = wx.CheckBox(self, -1, _("Create Manifest File (MSW)"), name="create_manifest_file") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.excludeList] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets the properties fro bbFreezePanel and its children widgets. """ # I use all the bbFreeze default values (where applicable), and my standard # configuration or preferences otherwise. This can easily be changed later # with a user customizable default project options file (or wx.Config) self.distTextCtrl.Enable(False) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance(child, wx.CheckBox): child.SetFont(font) def LayoutItems(self): """ Layouts the widgets using sizers. """ # Create a whole bunch of sizers mainSizer = wx.BoxSizer(wx.VERTICAL) otherOptionsSizer = wx.StaticBoxSizer(self.otherOptionsSizer_staticbox, wx.HORIZONTAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) targetSizer = wx.StaticBoxSizer(self.targetSizer_staticbox, wx.HORIZONTAL) plusSizer = wx.BoxSizer(wx.HORIZONTAL) minusSizer = wx.BoxSizer(wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.VERTICAL) # This grid bag sizer will hold all the list controls and widgets # that display bbFreeze options commonGridSizer = wx.GridBagSizer(5, 5) commonSizer_7 = wx.BoxSizer(wx.VERTICAL) commonSizer_6 = wx.BoxSizer(wx.VERTICAL) commonSizer_5 = wx.BoxSizer(wx.VERTICAL) commonSizer_4 = wx.BoxSizer(wx.VERTICAL) commonSizer_3 = wx.BoxSizer(wx.VERTICAL) commonSizer_2 = wx.BoxSizer(wx.VERTICAL) commonSizer_1 = wx.BoxSizer(wx.VERTICAL) targetSizer = wx.StaticBoxSizer(self.targetSizer_staticbox, wx.HORIZONTAL) flag2 = wx.LEFT|wx.BOTTOM|wx.TOP|wx.EXPAND mainSizer.Add(self.label, 0, wx.ALL, 10) targetSizer.Add(self.multipleExe, 1, flag2, 5) targetSizer.Add(self.multipleExe.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) mainSizer.Add(targetSizer, 0, wx.ALL|wx.EXPAND, 5) optimize = wx.StaticText(self, -1, _("Optimize")) commonSizer_1.Add(optimize, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_1.Add(self.optimizeCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_1, (1, 0), (1, 1), wx.ALL|wx.EXPAND, 5) compress = wx.StaticText(self, -1, _("Compressed")) commonSizer_2.Add(compress, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_2.Add(self.compressCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_2, (1, 1), (1, 1), wx.ALL|wx.EXPAND, 5) commonGridSizer.Add((0, 0), (1, 3), (1, 1), wx.EXPAND) commonSizer_5.Add(self.distChoice, 0, wx.BOTTOM, 2) commonSizer_5.Add(self.distTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_5, (1, 5), (1, 1), wx.ALL|wx.EXPAND, 5) commonGridSizer.AddGrowableCol(3) commonGridSizer.AddGrowableCol(4) commonGridSizer.AddGrowableCol(5) ## commonGridSizer.AddGrowableCol(6) commonGridSizer.SetEmptyCellSize((0, 0)) commonSizer.Add(commonGridSizer, 1, wx.EXPAND, 0) mainSizer.Add(commonSizer, 0, wx.ALL|wx.EXPAND, 5) flag = wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND # Add the list controls includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) plusSizer.Add(includesSizer, 1, wx.EXPAND) plusSizer.Add(excludesSizer, 1, wx.EXPAND|wx.LEFT, 5) mainSizer.Add(plusSizer, 0, wx.ALL|wx.EXPAND, 5) otherOptionsSizer.Add(self.includeInterpreter, 0, wx.ALL|wx.EXPAND, 5) otherOptionsSizer.Add(self.addManifest, 0, wx.ALL|wx.EXPAND, 5) minusSizer.Add(otherOptionsSizer, 1, wx.EXPAND) mainSizer.Add(minusSizer, 0, wx.ALL|wx.EXPAND, 5) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def ValidateOptions(self): """ Validates the bbFreeze input options before compiling. """ # check if the script files exist if self.multipleExe.GetItemCount() == 0: msg = _("No Python scripts have been added.") self.MainFrame.RunError(2, msg, True) return False for indx in xrange(self.multipleExe.GetItemCount()): script = self.multipleExe.GetItem(indx, 2) if not os.path.isfile(script.GetText()): msg = _("Python main script is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Generating "%(projectName)s" setup script...')%transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, customCode, postCompile) def BuildTargetClass(self, configuration, project, customCode, postCompile): """ Builds the bbFreeze compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) # Delete the keys we don't need distChoice = self.distChoice.GetValue() del configuration["dist_dir_choice"] # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if key in ["create_manifest_file", "multipleexe"]: # Skip these 2 options, we'll take care of them later... continue if isinstance(item, basestring) and key != "compress": if key == "dist_dir" and (item == "" or not distChoice): item = "'dist'" if distChoice: self.MainFrame.SendMessage(1, _('Empty dist_dir option. Using default value "dist"')) else: item = "r'%s'"%item if type(item) == ListType: # Terrible hack to setup correctly the string to be included # in the setup file item = setupString(key, item) setupDict[key] = item targetclass = "" for indx in xrange(self.multipleExe.GetItemCount()): # Add the target classes gui_only = self.multipleExe.GetItem(indx, 1).GetText() scriptFile = self.multipleExe.GetItem(indx, 2).GetText() gui = (gui_only == "windows" and [True] or [False])[0] targetclass += _bbFreeze_class%{"gui_only": gui, "script": 'r"%s"'%scriptFile} buildDir, scriptFile = os.path.split(scriptFile) # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Add the post-compilation code (if any) setupDict["postcompilecode"] = (postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] setupDict["executables"] = targetclass # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Populate the "import" section setupScript = _bbFreeze_imports % importDict # Populate the main section of the setup script setupScript += _bbFreeze_target % setupDict # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Setup script for "%(projectName)s" succesfully created')%transdict) return setupScript, buildDir
def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="bbfreeze") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.otherOptionsSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.targetSizer_staticbox = wx.StaticBox(self, -1, _("Target Classes")) transdict = dict(projectName=projectName, creationDate=creationDate) # A simple label that holds information about the project self.label = wx.StaticText(self, -1, _("bbFreeze options for: %(projectName)s (Created: %(creationDate)s)")%transdict) # A list control for the target classes, scripts self.multipleExe = BaseListCtrl(self, columnNames=[_("Exe Kind"), _("Python Main Script")], name="multipleexe") # Optimization level for bbFreeze 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "optimize") # Compression level for the zipfile in bbFreeze self.compressCombo = MultiComboBox(self, ["0", "1"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "compress") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") self.includeInterpreter = wx.CheckBox(self, -1, _("Include Python Interpreter"), name="include_py") self.addManifest = wx.CheckBox(self, -1, _("Create Manifest File (MSW)"), name="create_manifest_file") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.excludeList] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents()
def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="vendorid") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.otherSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText( self, -1, _("VendorID options for: %(projectName)s (Created: %(creationDate)s)" ) % transdict) # The file picker that allows us to pick the script to be compiled by py2app self.scriptPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, wildcard=_pywild, name="script") # Name of the executable self.exeTextCtrl = wx.TextCtrl(self, -1, "", name="exename") # Optimization level for vendorid 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "optimize") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means build_dir="build_ + python main script name" self.distChoice = wx.CheckBox(self, -1, _("Build Directory"), name="build_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "", name="build_dir") # A checkbox that enables the user to choose a different name for the # installation directory. Default is unchecked, that means sys.exec_prefix self.instChoice = wx.CheckBox(self, -1, _("Installation Directory"), name="install_dir_choice") # The name of the installation directory (if enabled) self.instTextCtrl = wx.TextCtrl(self, -1, "", name="install_dir") # Prefix for compiled Python code self.prefixTextCtrl = wx.TextCtrl(self, -1, "", name="prefix") # The icon picker that allows us to pick the application icon (Windows only) self.iconPicker = wx.FilePickerCtrl( self, style=wx.FLP_USE_TEXTCTRL, wildcard="Icon files (*.ico)|*.ico", name="iconfile") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # Create a signed interpreter (default is True) self.signCheck = wx.CheckBox(self, -1, "Sign Interpreter", name="signed") # Create console application (Windows only) self.consoleCheck = wx.CheckBox(self, -1, "Console App", name="console") # Add support for Python's verbose flag (default is False) self.verboseCheck = wx.CheckBox(self, -1, "Verbose Flag", name="verbose") # Run make install after compilation self.runmakeCheck = wx.CheckBox(self, -1, "Run Make Install", name="runmake") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.packagesList] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents()
class cx_FreezePanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="cx_Freeze") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.pathSizer_staticbox = wx.StaticBox(self, -1, _("Path")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.otherOptionsSizer_staticbox = wx.StaticBox( self, -1, _("Other Options")) self.targetSizer_staticbox = wx.StaticBox(self, -1, _("Target Classes")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText( self, -1, _("cx_Freeze options for: %(projectName)s (Created: %(creationDate)s)" ) % transdict) # A list control for the target classes, scripts self.multipleExe = BaseListCtrl(self, columnNames=[ _("Exe Kind"), _("Python Main Script"), _("Executable Name"), _("Version"), _("Description"), _("Author"), _("Program Name") ], name="multipleexe") # Optimization level for cx_Freeze 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "optimize") # Compression level for the zipfile in cx_Freeze self.compressCombo = MultiComboBox(self, ["0", "1"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "compress") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "path" option, a comma separated list of # paths to search for modules self.pathList = BaseListCtrl(self, columnNames=[_("Paths")], name="path") self.copyDepFiles = wx.CheckBox(self, -1, _("Copy Dependent Files"), name="copy_dependent_files") self.appendScriptToExe = wx.CheckBox(self, -1, _("Append Script To Executable"), name="append_script_toexe") self.appendScriptToLibrary = wx.CheckBox( self, -1, _("Append Script To Library"), name="append_script_tolibrary") self.addManifest = wx.CheckBox(self, -1, _("Create Manifest File (MSW)"), name="create_manifest_file") self.icon = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="icon") self.initScriptPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="initScript") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [ self.pathList, self.includeList, self.packagesList, self.excludeList ] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets the properties fro cx_FreezePanel and its children widgets. """ # I use all the cx_Freeze default values (where applicable), and my standard # configuration or preferences otherwise. This can easily be changed later # with a user customizable default project options file (or wx.Config) # Defaults (for me), executable name = python script name self.distTextCtrl.Enable(False) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance( child, wx.CheckBox): child.SetFont(font) def LayoutItems(self): """ Layouts the widgets using sizers. """ # Create a whole bunch of sizers mainSizer = wx.BoxSizer(wx.VERTICAL) otherOptionsSizer = wx.StaticBoxSizer(self.otherOptionsSizer_staticbox, wx.VERTICAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) packagesSizer = wx.StaticBoxSizer(self.packagesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) pathSizer = wx.StaticBoxSizer(self.pathSizer_staticbox, wx.HORIZONTAL) plusSizer = wx.BoxSizer(wx.HORIZONTAL) minusSizer = wx.BoxSizer(wx.HORIZONTAL) resourceSizer = wx.BoxSizer(wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.VERTICAL) # This grid bag sizer will hold all the list controls and widgets # that display cx_Freeze options commonGridSizer = wx.GridBagSizer(5, 5) commonSizer_7 = wx.BoxSizer(wx.VERTICAL) commonSizer_6 = wx.BoxSizer(wx.VERTICAL) commonSizer_5 = wx.BoxSizer(wx.VERTICAL) commonSizer_4 = wx.BoxSizer(wx.VERTICAL) commonSizer_3 = wx.BoxSizer(wx.VERTICAL) commonSizer_2 = wx.BoxSizer(wx.VERTICAL) commonSizer_1 = wx.BoxSizer(wx.VERTICAL) targetSizer = wx.StaticBoxSizer(self.targetSizer_staticbox, wx.HORIZONTAL) topGridSizer = wx.FlexGridSizer(1, 4, 5, 5) topSizer_4 = wx.BoxSizer(wx.VERTICAL) topSizer_3 = wx.BoxSizer(wx.VERTICAL) topSizer_2 = wx.BoxSizer(wx.VERTICAL) topSizer_1 = wx.BoxSizer(wx.VERTICAL) pickerSizer_1 = wx.BoxSizer(wx.VERTICAL) pickerSizer_2 = wx.BoxSizer(wx.VERTICAL) flag = wx.LEFT | wx.RIGHT | wx.EXPAND flag2 = wx.LEFT | wx.BOTTOM | wx.TOP | wx.EXPAND # Add the VersionInfo text controls mainSizer.Add(self.label, 0, wx.ALL, 10) targetSizer.Add(self.multipleExe, 1, flag2, 5) targetSizer.Add(self.multipleExe.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) mainSizer.Add(targetSizer, 0, wx.ALL | wx.EXPAND, 5) optimize = wx.StaticText(self, -1, _("Optimize")) commonSizer_1.Add(optimize, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_1.Add(self.optimizeCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_1, (1, 0), (1, 1), wx.ALL | wx.EXPAND, 5) compress = wx.StaticText(self, -1, _("Compressed")) commonSizer_2.Add(compress, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_2.Add(self.compressCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_2, (1, 1), (1, 1), wx.ALL | wx.EXPAND, 5) commonGridSizer.Add((0, 0), (1, 3), (1, 1), wx.EXPAND) commonSizer_5.Add(self.distChoice, 0, wx.BOTTOM, 2) commonSizer_5.Add(self.distTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_5, (1, 5), (1, 1), wx.ALL | wx.EXPAND, 5) commonGridSizer.AddGrowableCol(3) commonGridSizer.AddGrowableCol(4) commonGridSizer.AddGrowableCol(5) ## commonGridSizer.AddGrowableCol(6) commonGridSizer.SetEmptyCellSize((0, 0)) commonSizer.Add(commonGridSizer, 1, wx.EXPAND, 0) mainSizer.Add(commonSizer, 0, wx.ALL | wx.EXPAND, 5) flag = wx.LEFT | wx.TOP | wx.BOTTOM | wx.EXPAND # Add the list controls pathSizer.Add(self.pathList, 1, flag, 5) pathSizer.Add(self.pathList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) packagesSizer.Add(self.packagesList, 1, flag, 5) packagesSizer.Add(self.packagesList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) plusSizer.Add(pathSizer, 1, wx.EXPAND) plusSizer.Add(includesSizer, 1, wx.EXPAND | wx.LEFT, 5) plusSizer.Add(packagesSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(plusSizer, 1, wx.ALL | wx.EXPAND, 5) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) minusSizer.Add(excludesSizer, 1, wx.EXPAND) otherOptionsSizer.Add(self.copyDepFiles, 0, wx.LEFT | wx.TOP | wx.EXPAND, 5) otherOptionsSizer.Add((0, 2)) otherOptionsSizer.Add(self.appendScriptToExe, 0, wx.LEFT | wx.EXPAND, 5) otherOptionsSizer.Add((0, 2)) otherOptionsSizer.Add(self.appendScriptToLibrary, 0, wx.LEFT | wx.EXPAND, 5) otherOptionsSizer.Add((0, 2)) otherOptionsSizer.Add(self.addManifest, 0, wx.LEFT | wx.EXPAND, 5) otherOptionsSizer.Add((0, 10)) icon = wx.StaticText(self, -1, _("Icon File")) pickerSizer_1.Add(icon, 0, wx.BOTTOM, 2) pickerSizer_1.Add(self.icon, 0, wx.EXPAND) initScript = wx.StaticText(self, -1, _("Initialization Script")) pickerSizer_2.Add(initScript, 0, wx.BOTTOM, 2) pickerSizer_2.Add(self.initScriptPicker, 0, wx.EXPAND) otherOptionsSizer.Add(pickerSizer_1, 0, wx.LEFT | wx.EXPAND, 5) otherOptionsSizer.Add((0, 4)) otherOptionsSizer.Add(pickerSizer_2, 0, wx.LEFT | wx.EXPAND, 5) minusSizer.Add(otherOptionsSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(minusSizer, 0, wx.ALL | wx.EXPAND, 5) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance( child, wx.CheckBox): child.SetFont(font) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def ValidateOptions(self): """ Validates the cx_Freeze input options before compiling. """ # check if the script files exist if self.multipleExe.GetItemCount() == 0: msg = _("No Python scripts have been added.") self.MainFrame.RunError(2, msg, True) return False for indx in xrange(self.multipleExe.GetItemCount()): script = self.multipleExe.GetItem(indx, 2) if not os.path.isfile(script.GetText()): msg = _("Python main script is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the initialization file is not empty and if it exists initScript = self.initScriptPicker.GetPath() if initScript and not os.path.isfile(initScript): msg = _("Initialization file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the icon file is not empty and if it exists icon = self.icon.GetPath() if icon and not os.path.isfile(icon): msg = _("Icon file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Generating "%(projectName)s" setup script...') % transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, customCode, postCompile) def BuildTargetClass(self, configuration, project, customCode, postCompile): """ Builds the cx_Freeze compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) # Delete the keys we don't need distChoice = self.distChoice.GetValue() del configuration["dist_dir_choice"] extension = "" if wx.Platform == "__WXMSW__": extension = ".exe" useRelPath = self.MainFrame.relativePaths scriptFile = self.multipleExe.GetItem(0, 2).GetText() # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if key == "initScript" and not item: # I don't know how often this option is used item = "" elif isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if key in ["create_manifest_file", "multipleexe"]: # Skip these 2 options, we'll take care of them later... continue if isinstance(item, basestring) and key != "compress": if key == "dist_dir": if not item.strip() or not distChoice: item = "dist" if distChoice: self.MainFrame.SendMessage( 1, _('Empty dist_dir option. Using default value "dist"' )) if not item.strip(): item = None else: if useRelPath and key in ["initScript", "icon"]: item = 'r"%s"' % (relpath( item, os.path.split(scriptFile)[0])) else: item = 'r"%s"' % item if type(item) == ListType: # Terrible hack to setup correctly the string to be included # in the setup file item = setupString(key, item, useRelPath=useRelPath, mainScript=scriptFile) setupDict[key] = item baseName = "GUI2Exe_Target_%d" targetclass = "" executables = "[" # Loop over all the Python scripts used for indx in xrange(self.multipleExe.GetItemCount()): # Add the target class tupleMultiple = (baseName % (indx + 1), ) scriptFile = self.multipleExe.GetItem(indx, 2).GetText() buildDir, scriptFile = os.path.split(scriptFile) # Add the Python script file tupleMultiple += (scriptFile, ) # Add the init script tupleMultiple += (setupDict["initScript"], ) consoleOrWindows = self.multipleExe.GetItem(indx, 1).GetText() # Check if it is a GUI app and if it runs on Windows if consoleOrWindows == "windows" and sys.platform == "win32": tupleMultiple += ("'Win32GUI'", ) else: tupleMultiple += (None, ) # Add the distribution directory tupleMultiple += (setupDict["dist_dir"], ) targetName = self.multipleExe.GetItem(indx, 3).GetText() if not targetName.strip(): # Missing executable name? Use the Python script file name targetName = os.path.splitext(scriptFile)[0] self.MainFrame.SendMessage( 1, _('Empty Executable Name option. Using Python script name') ) # Add the executable name tupleMultiple += (targetName + extension, ) # Add the remaining keys tupleMultiple += (bool(setupDict["compress"]), setupDict["copy_dependent_files"], setupDict["append_script_toexe"], setupDict["append_script_tolibrary"], setupDict["icon"]) # Build the target classes targetclass += _cx_Freeze_class % tupleMultiple # Save the executables in a list to be processed by cx_Freeze executables += tupleMultiple[0] + ", " keys = setupDict.keys() for key in keys: # Remove the keys we have already used if key not in ["includes", "excludes", "packages", "path"]: setupDict.pop(key) # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Add the post-compilation code (if any) setupDict["postcompilecode"] = ( postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] # Add the target classes and the executables list setupDict["targetclasses"] = targetclass setupDict["executables"] = executables.rstrip(", ") + "]" # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Populate the "import" section setupScript = _cx_Freeze_imports % importDict globalSetup = ["version", "description", "author", "name"] for col in xrange(4, self.multipleExe.GetColumnCount()): item = self.multipleExe.GetItem(indx, col).GetText() setupDict[globalSetup[col - 4]] = '"%s"' % item.strip() # Populate the main section of the setup script setupScript += _cx_Freeze_target % setupDict # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Setup script for "%(projectName)s" succesfully created') % transdict) return setupScript, buildDir
class VendorIDPanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="vendorid") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.otherSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText( self, -1, _("VendorID options for: %(projectName)s (Created: %(creationDate)s)" ) % transdict) # The file picker that allows us to pick the script to be compiled by py2app self.scriptPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, wildcard=_pywild, name="script") # Name of the executable self.exeTextCtrl = wx.TextCtrl(self, -1, "", name="exename") # Optimization level for vendorid 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "optimize") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means build_dir="build_ + python main script name" self.distChoice = wx.CheckBox(self, -1, _("Build Directory"), name="build_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "", name="build_dir") # A checkbox that enables the user to choose a different name for the # installation directory. Default is unchecked, that means sys.exec_prefix self.instChoice = wx.CheckBox(self, -1, _("Installation Directory"), name="install_dir_choice") # The name of the installation directory (if enabled) self.instTextCtrl = wx.TextCtrl(self, -1, "", name="install_dir") # Prefix for compiled Python code self.prefixTextCtrl = wx.TextCtrl(self, -1, "", name="prefix") # The icon picker that allows us to pick the application icon (Windows only) self.iconPicker = wx.FilePickerCtrl( self, style=wx.FLP_USE_TEXTCTRL, wildcard="Icon files (*.ico)|*.ico", name="iconfile") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # Create a signed interpreter (default is True) self.signCheck = wx.CheckBox(self, -1, "Sign Interpreter", name="signed") # Create console application (Windows only) self.consoleCheck = wx.CheckBox(self, -1, "Console App", name="console") # Add support for Python's verbose flag (default is False) self.verboseCheck = wx.CheckBox(self, -1, "Verbose Flag", name="verbose") # Run make install after compilation self.runmakeCheck = wx.CheckBox(self, -1, "Run Make Install", name="runmake") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.packagesList] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets the properties fro Py2AppPanel and its children widgets. """ # I use all the py2app default values (where applicable), and my standard # configuration or preferences otherwise. This can easily be changed later # with a user customizable default project options file (or wx.Config) self.distTextCtrl.Enable(False) self.instTextCtrl.Enable(False) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance( child, wx.CheckBox): child.SetFont(font) if wx.Platform != "__WXMSW__": # Disable non-Windows options self.iconPicker.SetPath("") self.iconPicker.Enable(False) self.consoleCheck.SetValue(0) self.consoleCheck.Enable(False) def LayoutItems(self): """ Layouts the widgets using sizers. """ # Create a whole bunch of sizers mainSizer = wx.BoxSizer(wx.VERTICAL) otherSizer = wx.StaticBoxSizer(self.otherSizer_staticbox, wx.VERTICAL) otherSizer_1 = wx.FlexGridSizer(1, 4, 5, 5) plusSizer = wx.BoxSizer(wx.HORIZONTAL) minusSizer = wx.BoxSizer(wx.HORIZONTAL) packagesSizer = wx.StaticBoxSizer(self.packagesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.VERTICAL) # This grid bag sizer will hold all the list controls and widgets # that display py2app options commonGridSizer = wx.GridBagSizer(5, 5) commonSizer_8 = wx.BoxSizer(wx.VERTICAL) commonSizer_7 = wx.BoxSizer(wx.VERTICAL) commonSizer_6 = wx.BoxSizer(wx.VERTICAL) commonSizer_5 = wx.BoxSizer(wx.VERTICAL) commonSizer_4 = wx.BoxSizer(wx.VERTICAL) commonSizer_3 = wx.BoxSizer(wx.VERTICAL) commonSizer_2 = wx.BoxSizer(wx.VERTICAL) hSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the VersionInfo text controls mainSizer.Add(self.label, 0, wx.ALL, 10) flag = wx.LEFT | wx.RIGHT | wx.EXPAND script = wx.StaticText(self, -1, _("Python Main Script")) commonSizer_2.Add(script, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_2.Add(self.scriptPicker, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_2, (1, 0), (1, 4), flag, 5) exename = wx.StaticText(self, -1, _("Executable Name")) commonSizer_3.Add(exename, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_3.Add(self.exeTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_3, (1, 4), (1, 2), flag, 5) optimize = wx.StaticText(self, -1, _("Optimize")) commonSizer_4.Add(optimize, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_4.Add(self.optimizeCombo, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_4, (3, 0), (1, 1), flag | wx.TOP, 5) commonSizer_5.Add(self.distChoice, 0, wx.BOTTOM, 2) commonSizer_5.Add(self.distTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_5, (3, 1), (1, 1), flag | wx.TOP, 5) commonSizer_6.Add(self.instChoice, 0, wx.BOTTOM, 2) commonSizer_6.Add(self.instTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_6, (3, 2), (1, 1), flag | wx.TOP, 5) prefix = wx.StaticText(self, -1, _("Prefix")) commonSizer_8.Add(prefix, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_8.Add(self.prefixTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_8, (3, 3), (1, 1), flag | wx.TOP, 5) icon = wx.StaticText(self, -1, _("Icon File")) commonSizer_7.Add(icon, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_7.Add(self.iconPicker, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_7, (3, 4), (1, 2), flag | wx.TOP, 5) commonGridSizer.AddGrowableCol(1) commonGridSizer.AddGrowableCol(2) commonGridSizer.AddGrowableCol(3) commonGridSizer.AddGrowableCol(4) commonGridSizer.SetEmptyCellSize((0, 0)) commonSizer.Add(commonGridSizer, 1, wx.EXPAND | wx.BOTTOM, 5) mainSizer.Add(commonSizer, 0, wx.ALL | wx.EXPAND, 5) flag = wx.LEFT | wx.TOP | wx.BOTTOM | wx.EXPAND # Add the list controls includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) packagesSizer.Add(self.packagesList, 1, flag, 5) packagesSizer.Add(self.packagesList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) plusSizer.Add(includesSizer, 1, wx.EXPAND) plusSizer.Add(packagesSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(plusSizer, 1, wx.ALL | wx.EXPAND, 5) # Add the other options at the bottom otherSizer_1.Add(self.signCheck, 0) otherSizer_1.Add(self.consoleCheck, 0) otherSizer_1.Add(self.verboseCheck, 0) otherSizer_1.Add(self.runmakeCheck, 0) otherSizer_1.AddGrowableCol(0) otherSizer_1.AddGrowableCol(1) otherSizer_1.AddGrowableCol(2) otherSizer_1.AddGrowableCol(3) otherSizer.Add(otherSizer_1, 1, wx.EXPAND | wx.ALL, 5) mainSizer.Add(otherSizer, 0, wx.ALL | wx.EXPAND, 5) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def ValidateOptions(self): """ Validates the VendorID input options before compiling. """ # check if the script file exists if not os.path.isfile(self.scriptPicker.GetPath()): msg = _("Python main script is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the icon file is not empty and if it exists icon = self.iconPicker.GetPath() if icon and not os.path.isfile(icon): msg = _("Icon file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Generating "%(projectName)s" setup script...') % transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, None) def BuildTargetClass(self, configuration, project, manifestFile): """ Builds the VendorID compilation options, returning it as a string. """ # A couple of dictionaries to populate the setup string configuration = dict(configuration) distChoice = self.distChoice.GetValue() instChoice = self.instChoice.GetValue() pythonName = os.path.split( os.path.splitext(self.scriptPicker.GetPath())[0])[1] optionString = "" useRelPath = self.MainFrame.relativePaths mainFile = self.scriptPicker.GetPath() # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if key in ["build_dir_choice", "install_dir_choice"]: continue if key == "script": buildDir, scriptFile = os.path.split(item) elif key == "build_dir": if not item.strip() or not distChoice: outputDir = os.path.normpath(buildDir + "/build_%s" % pythonName) if distChoice: self.MainFrame.SendMessage( 1, _('Empty build_dir option. Using default value "build_%s"' % pythonName)) else: optionString += " -d %s " % item.strip() outputDir = os.path.normpath(buildDir + "/" + item.strip()) elif key == "install": if not item.strip() or not instChoice: if instChoice: self.MainFrame.SendMessage( 1, _('Empty install_dir option. Using default value "sys.exec_prefix"' )) else: optionString += " -t %s " % item.strip() elif key == "iconfile": if item.strip(): if useRelPath: optionString += " -i %s " % relpath( item.strip(), os.path.split(mainFile)[0]) else: optionString += " -i %s " % item.strip() elif key == "exename": if item.strip(): optionString += " -n %s " % item.strip() elif key == "prefix": if item.strip(): optionString += " -p %s " % item.strip() if isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if key == "verbose" and item: optionString += " -v " elif key == "signed" and not item: optionString += " -u " elif key == "console" and item: optionString += " -c " elif key == "runmake": runMakeInstall = item if type(item) == ListType: # Loop over all the included packages and modules for pkg in item: optionString += " -m %s " % pkg # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) if wx.Platform == "__WXMSW__": separator = "&" else: separator = ";" # Get the user preference for GNU make or MS nmake vendorIDPath = self.MainFrame.GetVendorIDPath() if not vendorIDPath: makeOrNmake = "make" else: sibPath, makeOrNmake = vendorIDPath optionString = optionString + " " + self.scriptPicker.GetPath().strip() optionString += " " + separator + "cd %s " % outputDir + separator + "%s " % makeOrNmake if runMakeInstall: optionString += separator + "cd %s " % outputDir + separator + "%s install" % makeOrNmake self.MainFrame.SendMessage( 0, _('Setup script for "%(projectName)s" succesfully created') % transdict) return optionString, buildDir
def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="py2app") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.dylibExcludesSizer_staticbox = wx.StaticBox(self, -1, _("Dylib/Frameworks Excludes")) self.datamodelsSizer_staticbox = wx.StaticBox(self, -1, _("XC Data Models")) self.frameworksSizer_staticbox = wx.StaticBox(self, -1, _("Dylib/Frameworks Includes")) self.datafile_staticbox = wx.StaticBox(self, -1, _("Resources")) self.otherSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText(self, -1, _("Py2app options for: %(projectName)s (Created: %(creationDate)s)")%transdict) # A combobox to choose the application extension self.extensionCombo = MultiComboBox(self, [".app", ".plugin"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "extension") # The file picker that allows us to pick the script to be compiled by py2app self.scriptPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, wildcard=_pywild, name="script") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # Optimization level for py2app 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "optimize") # The icon picker that allows us to pick the application icon self.iconPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, wildcard=_iconwild, name="iconfile") # A picker for the PList file self.pListPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, wildcard=_plistwild, name="plist") # To add/edit PList code self.pListChoice = wx.CheckBox(self, -1, _("PList Code"), name="plistCode_choice") editBmp = self.MainFrame.CreateBitmap("edit_add") removeBmp = self.MainFrame.CreateBitmap("remove") self.pListAddButton = buttons.ThemedGenBitmapTextButton(self, -1, editBmp, _("Add/Edit"), size=(-1, 25), name="plistCode") self.pListRemoveButton = buttons.ThemedGenBitmapTextButton(self, -1, removeBmp, _("Remove"), size=(-1, 25), name="plistRemove") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # A list control for the "frameworks" option, a comma separated list of # frameworks/dylibs to include self.frameworksList = BaseListCtrl(self, columnNames=[_("Dylib/Frameworks Names")], name="frameworks") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "dylib_excludes" option, a comma separated list of # dylibs/frameworks to exclude self.dylibExcludeList = BaseListCtrl(self, columnNames=[_("Dylib/Frameworks Names")], name="dylib_excludes") # A list control for the "xcdatamodels" option, a comma separated list of # xcdatamodels to compile and include self.datamodelsList = BaseListCtrl(self, columnNames=[_("XC Data Models Names")], name="datamodels") # A list control for the "resources" option. "resources" should contain # a sequence of (target-dir, files) tuples, where files is a sequence of # files to be copied self.datafileList = BaseListCtrl(self, columnNames=[_("Files Path")], name="resources") # output module dependency graph self.graphCheck = wx.CheckBox(self, -1, "Graph", name="graph") # This command line switch instructs py2app to create a python module cross # reference and display it in the webbrowser. This allows to answer question # why a certain module has been included, or if you can exclude a certain module # and it's dependencies. Also, the html page includes links which will even # allow to view the source code of a module in the browser, for easy inspection. self.crossRefCheck = wx.CheckBox(self, -1, "Cross-Reference", name="xref") # Do not strip debug and local symbols from output self.noStripCheck = wx.CheckBox(self, -1, "No Strip", name="no_strip") # Do not change to the data directory (Contents/Resources) [forced for plugins] self.noChdirCheck = wx.CheckBox(self, -1, "No Chdir", name="no_chdir") # Depend on an existing installation of Python 2.4 self.semiStandaloneCheck = wx.CheckBox(self, -1, "Semi Standalone", name="semi_standalone") # Use argv emulation (disabled for plugins) self.argvEmulationCheck = wx.CheckBox(self, -1, "Argv Emulation", name="argv_emulation") # Allow PYTHONPATH to effect the interpreter's environment self.usePythonPathCheck = wx.CheckBox(self, -1, "Use PYTHONPATH", name="use_pythonpath") # Include the system and user site-packages into sys.path self.sitePackagesCheck= wx.CheckBox(self, -1, "Site Packages", name="site_packages") # Force application to run translated on i386 (LSPrefersPPC=True) self.preferPPCCheck= wx.CheckBox(self, -1, "Prefer PPC", name="prefer_ppc") # Drop to pdb console after the module finding phase is complete self.debugModuleGraphCheck= wx.CheckBox(self, -1, "Debug Modulegraph", name="debug_modulegraph") # Skip macholib phase (app will not be standalone!) self.skipMacholibCheck= wx.CheckBox(self, -1, "Debug Skip Macholib", name="debug_skip_macholib") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.packagesList, self.frameworksList, self.excludeList, self.dylibExcludeList, self.datamodelsList, self.datafileList] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() wx.CallAfter(self.EnableMacPList) self.Bind(wx.EVT_BUTTON, self.OnPListAdd, self.pListAddButton) self.Bind(wx.EVT_BUTTON, self.OnPListRemove, self.pListRemoveButton)
class Py2AppPanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="py2app") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.dylibExcludesSizer_staticbox = wx.StaticBox(self, -1, _("Dylib/Frameworks Excludes")) self.datamodelsSizer_staticbox = wx.StaticBox(self, -1, _("XC Data Models")) self.frameworksSizer_staticbox = wx.StaticBox(self, -1, _("Dylib/Frameworks Includes")) self.datafile_staticbox = wx.StaticBox(self, -1, _("Resources")) self.otherSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText(self, -1, _("Py2app options for: %(projectName)s (Created: %(creationDate)s)")%transdict) # A combobox to choose the application extension self.extensionCombo = MultiComboBox(self, [".app", ".plugin"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "extension") # The file picker that allows us to pick the script to be compiled by py2app self.scriptPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, wildcard=_pywild, name="script") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # Optimization level for py2app 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "optimize") # The icon picker that allows us to pick the application icon self.iconPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, wildcard=_iconwild, name="iconfile") # A picker for the PList file self.pListPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, wildcard=_plistwild, name="plist") # To add/edit PList code self.pListChoice = wx.CheckBox(self, -1, _("PList Code"), name="plistCode_choice") editBmp = self.MainFrame.CreateBitmap("edit_add") removeBmp = self.MainFrame.CreateBitmap("remove") self.pListAddButton = buttons.ThemedGenBitmapTextButton(self, -1, editBmp, _("Add/Edit"), size=(-1, 25), name="plistCode") self.pListRemoveButton = buttons.ThemedGenBitmapTextButton(self, -1, removeBmp, _("Remove"), size=(-1, 25), name="plistRemove") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # A list control for the "frameworks" option, a comma separated list of # frameworks/dylibs to include self.frameworksList = BaseListCtrl(self, columnNames=[_("Dylib/Frameworks Names")], name="frameworks") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "dylib_excludes" option, a comma separated list of # dylibs/frameworks to exclude self.dylibExcludeList = BaseListCtrl(self, columnNames=[_("Dylib/Frameworks Names")], name="dylib_excludes") # A list control for the "xcdatamodels" option, a comma separated list of # xcdatamodels to compile and include self.datamodelsList = BaseListCtrl(self, columnNames=[_("XC Data Models Names")], name="datamodels") # A list control for the "resources" option. "resources" should contain # a sequence of (target-dir, files) tuples, where files is a sequence of # files to be copied self.datafileList = BaseListCtrl(self, columnNames=[_("Files Path")], name="resources") # output module dependency graph self.graphCheck = wx.CheckBox(self, -1, "Graph", name="graph") # This command line switch instructs py2app to create a python module cross # reference and display it in the webbrowser. This allows to answer question # why a certain module has been included, or if you can exclude a certain module # and it's dependencies. Also, the html page includes links which will even # allow to view the source code of a module in the browser, for easy inspection. self.crossRefCheck = wx.CheckBox(self, -1, "Cross-Reference", name="xref") # Do not strip debug and local symbols from output self.noStripCheck = wx.CheckBox(self, -1, "No Strip", name="no_strip") # Do not change to the data directory (Contents/Resources) [forced for plugins] self.noChdirCheck = wx.CheckBox(self, -1, "No Chdir", name="no_chdir") # Depend on an existing installation of Python 2.4 self.semiStandaloneCheck = wx.CheckBox(self, -1, "Semi Standalone", name="semi_standalone") # Use argv emulation (disabled for plugins) self.argvEmulationCheck = wx.CheckBox(self, -1, "Argv Emulation", name="argv_emulation") # Allow PYTHONPATH to effect the interpreter's environment self.usePythonPathCheck = wx.CheckBox(self, -1, "Use PYTHONPATH", name="use_pythonpath") # Include the system and user site-packages into sys.path self.sitePackagesCheck= wx.CheckBox(self, -1, "Site Packages", name="site_packages") # Force application to run translated on i386 (LSPrefersPPC=True) self.preferPPCCheck= wx.CheckBox(self, -1, "Prefer PPC", name="prefer_ppc") # Drop to pdb console after the module finding phase is complete self.debugModuleGraphCheck= wx.CheckBox(self, -1, "Debug Modulegraph", name="debug_modulegraph") # Skip macholib phase (app will not be standalone!) self.skipMacholibCheck= wx.CheckBox(self, -1, "Debug Skip Macholib", name="debug_skip_macholib") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.packagesList, self.frameworksList, self.excludeList, self.dylibExcludeList, self.datamodelsList, self.datafileList] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() wx.CallAfter(self.EnableMacPList) self.Bind(wx.EVT_BUTTON, self.OnPListAdd, self.pListAddButton) self.Bind(wx.EVT_BUTTON, self.OnPListRemove, self.pListRemoveButton) # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets the properties fro Py2AppPanel and its children widgets. """ # I use all the py2app default values (where applicable), and my standard # configuration or preferences otherwise. This can easily be changed later # with a user customizable default project options file (or wx.Config) self.distTextCtrl.Enable(False) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance(child, wx.CheckBox): child.SetFont(font) def LayoutItems(self): """ Layouts the widgets using sizers. """ # Create a whole bunch of sizers mainSizer = wx.BoxSizer(wx.VERTICAL) otherSizer = wx.StaticBoxSizer(self.otherSizer_staticbox, wx.VERTICAL) otherSizer_1 = wx.FlexGridSizer(3, 4, 5, 5) plusSizer = wx.BoxSizer(wx.HORIZONTAL) minusSizer = wx.BoxSizer(wx.HORIZONTAL) dylibExcludesSizer = wx.StaticBoxSizer(self.dylibExcludesSizer_staticbox, wx.HORIZONTAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) packagesSizer = wx.StaticBoxSizer(self.packagesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) datamodelsSizer = wx.StaticBoxSizer(self.datamodelsSizer_staticbox, wx.HORIZONTAL) datafilesSizer = wx.StaticBoxSizer(self.datafile_staticbox, wx.HORIZONTAL) frameworksSizer = wx.StaticBoxSizer(self.frameworksSizer_staticbox, wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.VERTICAL) # This grid bag sizer will hold all the list controls and widgets # that display py2app options commonGridSizer = wx.GridBagSizer(5, 5) commonSizer_7 = wx.BoxSizer(wx.VERTICAL) commonSizer_6 = wx.BoxSizer(wx.VERTICAL) commonSizer_5 = wx.BoxSizer(wx.VERTICAL) commonSizer_4 = wx.BoxSizer(wx.VERTICAL) commonSizer_3 = wx.BoxSizer(wx.VERTICAL) commonSizer_2 = wx.BoxSizer(wx.VERTICAL) commonSizer_1 = wx.BoxSizer(wx.VERTICAL) hSizer = wx.BoxSizer(wx.HORIZONTAL) # Add the VersionInfo text controls mainSizer.Add(self.label, 0, wx.ALL, 10) flag = wx.LEFT|wx.RIGHT|wx.EXPAND extension = wx.StaticText(self, -1, _("Extension")) commonSizer_1.Add(extension, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_1.Add(self.extensionCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_1, (1, 0), (1, 1), flag, 5) script = wx.StaticText(self, -1, _("Python Main Script")) commonSizer_2.Add(script, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_2.Add(self.scriptPicker, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_2, (1, 1), (1, 4), flag, 5) commonSizer_3.Add(self.distChoice, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_3.Add(self.distTextCtrl, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_3, (1, 5), (1, 1), flag, 5) optimize = wx.StaticText(self, -1, _("Optimize")) commonSizer_4.Add(optimize, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_4.Add(self.optimizeCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_4, (2, 0), (1, 1), flag|wx.TOP, 5) icon = wx.StaticText(self, -1, _("Icon File")) commonSizer_5.Add(icon, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_5.Add(self.iconPicker, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_5, (2, 1), (1, 2), flag|wx.TOP, 5) plist = wx.StaticText(self, -1, _("PList File")) commonSizer_6.Add(plist, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_6.Add(self.pListPicker, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_6, (2, 3), (1, 2), flag|wx.TOP, 5) commonSizer_7.Add(self.pListChoice, 0, wx.RIGHT|wx.BOTTOM, 2) hSizer.Add(self.pListAddButton, 0, wx.RIGHT, 5) hSizer.Add(self.pListRemoveButton, 0) commonSizer_7.Add(hSizer, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_7, (2, 5), (1, 1), flag|wx.TOP, 5) commonGridSizer.AddGrowableCol(2) commonGridSizer.AddGrowableCol(3) commonGridSizer.AddGrowableCol(4) commonGridSizer.SetEmptyCellSize((0, 0)) commonSizer.Add(commonGridSizer, 1, wx.EXPAND|wx.BOTTOM, 5) mainSizer.Add(commonSizer, 0, wx.ALL|wx.EXPAND, 5) flag = wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND # Add the list controls includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) packagesSizer.Add(self.packagesList, 1, flag, 5) packagesSizer.Add(self.packagesList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) frameworksSizer.Add(self.frameworksList, 1, flag, 5) frameworksSizer.Add(self.frameworksList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) plusSizer.Add(includesSizer, 1, wx.EXPAND) plusSizer.Add(packagesSizer, 1, wx.EXPAND|wx.LEFT, 5) plusSizer.Add(frameworksSizer, 1, wx.EXPAND|wx.LEFT, 5) mainSizer.Add(plusSizer, 1, wx.ALL|wx.EXPAND, 5) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) dylibExcludesSizer.Add(self.dylibExcludeList, 1, flag, 5) dylibExcludesSizer.Add(self.dylibExcludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) datamodelsSizer.Add(self.datamodelsList, 1, flag, 5) datamodelsSizer.Add(self.datamodelsList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) minusSizer.Add(excludesSizer, 1, wx.EXPAND) minusSizer.Add(dylibExcludesSizer, 1, wx.EXPAND|wx.LEFT, 5) minusSizer.Add(datamodelsSizer, 1, wx.EXPAND|wx.LEFT, 5) mainSizer.Add(minusSizer, 1, wx.ALL|wx.EXPAND, 5) datafilesSizer.Add(self.datafileList, 1, flag, 5) datafilesSizer.Add(self.datafileList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) mainSizer.Add(datafilesSizer, 1, wx.ALL|wx.EXPAND, 5) # Add the other options at the bottom otherSizer_1.Add(self.graphCheck, 0) otherSizer_1.Add(self.crossRefCheck, 0) otherSizer_1.Add(self.noStripCheck, 0) otherSizer_1.Add(self.noChdirCheck, 0) otherSizer_1.Add(self.semiStandaloneCheck, 0) otherSizer_1.Add(self.argvEmulationCheck, 0) otherSizer_1.Add(self.usePythonPathCheck, 0) otherSizer_1.Add(self.sitePackagesCheck, 0) otherSizer_1.Add(self.preferPPCCheck, 0) otherSizer_1.Add(self.debugModuleGraphCheck, 0) otherSizer_1.Add(self.skipMacholibCheck, 0) otherSizer_1.AddGrowableCol(0) otherSizer_1.AddGrowableCol(1) otherSizer_1.AddGrowableCol(2) otherSizer_1.AddGrowableCol(3) otherSizer.Add(otherSizer_1, 1, wx.EXPAND|wx.ALL, 5) mainSizer.Add(otherSizer, 0, wx.ALL|wx.EXPAND, 5) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def EnableMacPList(self): """ Checks whether all the imports needed to build the PList editor are available. """ if not _hasMacThings: # It was not possible to import py2app and # other Mac goodies... self.pListChoice.SetValue(0) self.pListChoice.Enable(False) self.pListAddButton.Enable(False) self.pListRemoveButton.Enable(False) def ValidateOptions(self): """ Validates the py2app input options before compiling. """ # check if the script file exists if not os.path.isfile(self.scriptPicker.GetPath()): msg = _("Python main script is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the PList file is not empty and if it exists pListScript = self.pListPicker.GetPath() if pListScript and not os.path.isfile(pListScript): msg = _("PList file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the icon file is not empty and if it exists icon = self.iconPicker.GetPath() if icon and not os.path.isfile(icon): msg = _("Icon file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Generating "%(projectName)s" setup script...')%transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, None, customCode, postCompile) def BuildTargetClass(self, configuration, project, manifestFile, customCode, postCompile): """ Builds the py2app compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) distChoice = self.distChoice.GetValue() pListChoice = self.pListChoice.GetValue() usePListFile = True pListCode = {} if pListChoice: if "plist_code" in configuration: # Get the existing PList code (if any) pListCode = configuration["plist_code"] if pListCode: usePListFile = False plist_code = "plist_code = " + pprint.pformat(pListCode, width=100) # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if key == "dist_dir_choice": continue if key == "script": buildDir, scriptFile = os.path.split(item) item = "r'%s'"%item elif key == "dist_dir": if not item.strip() or not distChoice: item = "dist" if distChoice: self.MainFrame.SendMessage(1, _('Empty dist_dir option. Using default value "dist"')) elif key in ["iconfile", "plist"]: if key == "plist" and not usePListFile: item = "plist_code" else: if not item.strip(): item = None else: item = "r'%s'"%item if isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if type(item) == ListType: # Terrible hack to setup correctly the string to be included # in the setup file item = setupString(key, item, True) setupDict[key] = item if not usePListFile: setupDict["plist_code"] = plist_code else: setupDict["plist_code"] = "# No code for PList" # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Add the post-compilation code (if any) setupDict["postcompilecode"] = (postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Populate the "import" section setupScript = _py2app_imports % importDict # Populate the main section of the setup script setupScript += _py2app_target % setupDict # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Setup script for "%(projectName)s" succesfully created')%transdict) return setupScript, buildDir def OnPListAdd(self, event): """ Launches a custom PList editor. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return programName = self.scriptPicker.GetPath() programName = os.path.split(os.path.splitext(programName)[0])[1] # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() if "plist_code" in project["py2app"]: # Get the existing PList code (if any) pListCode = project["py2app"]["plist_code"] else: pListCode = {} dlg = PListEditor(self.MainFrame, programName, pListFile=self.pListPicker.GetPath().strip(), pListCode=pListCode) if dlg.ShowModal() == wx.ID_CANCEL: # User cancelled the modifications dlg.Destroy() return try: PList = dlg.GetPList() except: self.MainFrame.RunError(2, _("Invalid PList code encountered.")) return project["py2app"]["plist_code"] = PList # Update the icon and the project name on the wx.aui.AuiNotebook tab self.MainFrame.UpdatePageBitmap(project.GetName() + "*", 1) def OnPListRemove(self, event): """ Deletes the PList code (if any) from the project. """ # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() if "plist_code" in project["py2app"]: project["py2app"]["plist_code"] = {} # Update the icon and the project name on the wx.aui.AuiNotebook tab self.MainFrame.UpdatePageBitmap(project.GetName() + "*", 1)
def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="py2exe") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.dllExcludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL Excludes")) self.ignoreSizer_staticbox = wx.StaticBox(self, -1, _("Ignores")) self.datafile_staticbox = wx.StaticBox(self, -1, _("Data Files")) self.icon_staticbox = wx.StaticBox(self, -1, _("Icon Resources")) self.bitmap_staticbox = wx.StaticBox(self, -1, _("Bitmap Resources")) self.other_staticbox = wx.StaticBox(self, -1, _("Other Resources")) self.otherSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.targetSizer_staticbox = wx.StaticBox(self, -1, _("Target Classes")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText( self, -1, _("Py2exe options for: %(projectName)s (Created: %(creationDate)s)" ) % transdict) # These text controls hold data used by VersionInfo in py2exe # A list control for the target classes, scripts self.multipleExe = BaseListCtrl(self, columnNames=[ _("Exe Kind"), _("Python Main Script"), _("Executable Name"), _("Version"), _("Company Name"), _("Copyrights"), _("Program Name") ], name="multipleexe") # Optimization level for py2exe 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "optimize") # Compression level for the zipfile (if any) in py2exe self.compressCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "compressed") # Bundle files option for py2exe. Specifying a level of 2 includes # the .pyd and .dll files into the zip-archive or the executable. Thus, # the dist directory will contain your exe file(s), the library.zip file # (if you haven't specified 'zipfile=None'), and the python dll. The # advantage of this scheme is that the application can still load extension # modules from the file system if you extend sys.path at runtime. # Using a level of 1 includes the .pyd and .dll files into the zip-archive # or the executable itself, and does the same for pythonXY.dll. The advantage # is that you only need to distribute one file per exe, which will however # be quite large. Another advantage is that inproc COM servers will run # completely isolated from other Python interpreters in the same exe. The # disadvantage of this scheme is that it is impossible to load other # extensions from the file system, the application will crash with a fatal # Python error if you try this. self.bundleCombo = MultiComboBox(self, ["1", "2", "3"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "bundle_files") # A checkbox that enables the user to choose a different name for the zipfile # Default is unchecked, that means zipfile=None self.zipfileChoice = wx.CheckBox(self, -1, "Zipfile", name="zipfile_choice") # The name of the zipfile (if enabled by the user) self.zipfileTextCtrl = wx.TextCtrl(self, -1, "None", name="zipfile") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # Allows to skip the archive. If checked, this copies the Python bytecode files # directly into the dist directory and subdirectories - no archive is used. self.skiparchiveChoice = wx.CheckBox(self, -1, "Skip Archive", name="skip_archive") # If checked, embed the XP manifest file directly in the executable self.xpmanifestChoice = wx.CheckBox(self, -1, "XP Manifest File", name="manifest_file") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "dll_excludes" option, a comma separated list of # Windows dlls to include self.dllExcludeList = BaseListCtrl(self, columnNames=[_("DLL Names")], name="dll_excludes") # A list control for the "ignores" option, a comma separated list of # modules to ignores self.ignoreList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="ignores") # A list control for the "data_files" option. "data_files" should contain # a sequence of (target-dir, files) tuples, where files is a sequence of # files to be copied self.datafileList = BaseListCtrl( self, columnNames=[_("Directory") + " " * 15, _("Files Path")], name="data_files") # A list control for the "icon_resources" option self.iconResourceList = BaseListCtrl( self, columnNames=[_("Id "), _("Icon Path")], name="icon_resources") # A list control for the "bitmap_resources" option self.bitmapResourceList = BaseListCtrl( self, columnNames=[_("Id "), _("Bitmap Path")], name="bitmap_resources") # A list control for the "other_resources" option self.otherResourceList = BaseListCtrl( self, columnNames=[_("Type"), _("Id "), _("Path/Value")], name="other_resources") # This command line switch instructs py2exe to create a python module cross # reference and display it in the webbrowser. This allows to answer question # why a certain module has been included, or if you can exclude a certain module # and it's dependencies. Also, the html page includes links which will even # allow to view the source code of a module in the browser, for easy inspection. self.crossRefCheck = wx.CheckBox(self, -1, "Cross-Reference", name="xref") # To prevent unicode encoding error, py2exe now by default includes the codecs # module and the encodings package. If you are sure your program never # implicitely or explicitely has to convert between unicode and ascii strings # this can be prevented by checking this checkbox self.asciiCheck = wx.CheckBox(self, -1, "Ascii", name="ascii") # The following 2 are only for service, com_server and ctypes_com_server self.createExeCheck = wx.CheckBox(self, -1, "Create EXE", name="create_exe") self.createDllCheck = wx.CheckBox(self, -1, "Create DLL", name="create_dll") # By picking a Python script here, this script can do things like installing # a customized stdout blackhole. See py2exe's boot_common.py for examples of # what can be done. The custom boot script is executed during startup of # the executable immediately after boot_common.py is executed self.customBootPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="custom_boot_script") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [ self.includeList, self.packagesList, self.excludeList, self.dllExcludeList, self.ignoreList, self.datafileList, self.iconResourceList, self.bitmapResourceList, self.otherResourceList ] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents()
class Py2ExePanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="py2exe") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.dllExcludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL Excludes")) self.ignoreSizer_staticbox = wx.StaticBox(self, -1, _("Ignores")) self.datafile_staticbox = wx.StaticBox(self, -1, _("Data Files")) self.icon_staticbox = wx.StaticBox(self, -1, _("Icon Resources")) self.bitmap_staticbox = wx.StaticBox(self, -1, _("Bitmap Resources")) self.other_staticbox = wx.StaticBox(self, -1, _("Other Resources")) self.otherSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.targetSizer_staticbox = wx.StaticBox(self, -1, _("Target Classes")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText( self, -1, _("Py2exe options for: %(projectName)s (Created: %(creationDate)s)" ) % transdict) # These text controls hold data used by VersionInfo in py2exe # A list control for the target classes, scripts self.multipleExe = BaseListCtrl(self, columnNames=[ _("Exe Kind"), _("Python Main Script"), _("Executable Name"), _("Version"), _("Company Name"), _("Copyrights"), _("Program Name") ], name="multipleexe") # Optimization level for py2exe 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "optimize") # Compression level for the zipfile (if any) in py2exe self.compressCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "compressed") # Bundle files option for py2exe. Specifying a level of 2 includes # the .pyd and .dll files into the zip-archive or the executable. Thus, # the dist directory will contain your exe file(s), the library.zip file # (if you haven't specified 'zipfile=None'), and the python dll. The # advantage of this scheme is that the application can still load extension # modules from the file system if you extend sys.path at runtime. # Using a level of 1 includes the .pyd and .dll files into the zip-archive # or the executable itself, and does the same for pythonXY.dll. The advantage # is that you only need to distribute one file per exe, which will however # be quite large. Another advantage is that inproc COM servers will run # completely isolated from other Python interpreters in the same exe. The # disadvantage of this scheme is that it is impossible to load other # extensions from the file system, the application will crash with a fatal # Python error if you try this. self.bundleCombo = MultiComboBox(self, ["1", "2", "3"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "bundle_files") # A checkbox that enables the user to choose a different name for the zipfile # Default is unchecked, that means zipfile=None self.zipfileChoice = wx.CheckBox(self, -1, "Zipfile", name="zipfile_choice") # The name of the zipfile (if enabled by the user) self.zipfileTextCtrl = wx.TextCtrl(self, -1, "None", name="zipfile") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # Allows to skip the archive. If checked, this copies the Python bytecode files # directly into the dist directory and subdirectories - no archive is used. self.skiparchiveChoice = wx.CheckBox(self, -1, "Skip Archive", name="skip_archive") # If checked, embed the XP manifest file directly in the executable self.xpmanifestChoice = wx.CheckBox(self, -1, "XP Manifest File", name="manifest_file") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "dll_excludes" option, a comma separated list of # Windows dlls to include self.dllExcludeList = BaseListCtrl(self, columnNames=[_("DLL Names")], name="dll_excludes") # A list control for the "ignores" option, a comma separated list of # modules to ignores self.ignoreList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="ignores") # A list control for the "data_files" option. "data_files" should contain # a sequence of (target-dir, files) tuples, where files is a sequence of # files to be copied self.datafileList = BaseListCtrl( self, columnNames=[_("Directory") + " " * 15, _("Files Path")], name="data_files") # A list control for the "icon_resources" option self.iconResourceList = BaseListCtrl( self, columnNames=[_("Id "), _("Icon Path")], name="icon_resources") # A list control for the "bitmap_resources" option self.bitmapResourceList = BaseListCtrl( self, columnNames=[_("Id "), _("Bitmap Path")], name="bitmap_resources") # A list control for the "other_resources" option self.otherResourceList = BaseListCtrl( self, columnNames=[_("Type"), _("Id "), _("Path/Value")], name="other_resources") # This command line switch instructs py2exe to create a python module cross # reference and display it in the webbrowser. This allows to answer question # why a certain module has been included, or if you can exclude a certain module # and it's dependencies. Also, the html page includes links which will even # allow to view the source code of a module in the browser, for easy inspection. self.crossRefCheck = wx.CheckBox(self, -1, "Cross-Reference", name="xref") # To prevent unicode encoding error, py2exe now by default includes the codecs # module and the encodings package. If you are sure your program never # implicitely or explicitely has to convert between unicode and ascii strings # this can be prevented by checking this checkbox self.asciiCheck = wx.CheckBox(self, -1, "Ascii", name="ascii") # The following 2 are only for service, com_server and ctypes_com_server self.createExeCheck = wx.CheckBox(self, -1, "Create EXE", name="create_exe") self.createDllCheck = wx.CheckBox(self, -1, "Create DLL", name="create_dll") # By picking a Python script here, this script can do things like installing # a customized stdout blackhole. See py2exe's boot_common.py for examples of # what can be done. The custom boot script is executed during startup of # the executable immediately after boot_common.py is executed self.customBootPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="custom_boot_script") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [ self.includeList, self.packagesList, self.excludeList, self.dllExcludeList, self.ignoreList, self.datafileList, self.iconResourceList, self.bitmapResourceList, self.otherResourceList ] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets the properties fro Py2ExePanel and its children widgets. """ # I use all the py2exe default values (where applicable), and my standard # configuration or preferences otherwise. This can easily be changed later # with a user customizable default project options file (or wx.Config) # Defaults (for me) zipfile=None self.zipfileTextCtrl.Enable(False) self.distTextCtrl.Enable(False) self.createExeCheck.SetValue(1) self.createDllCheck.SetValue(1) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance( child, wx.CheckBox): child.SetFont(font) def LayoutItems(self): """ Layouts the widgets using sizers. """ # Create a whole bunch of sizers mainSizer = wx.BoxSizer(wx.VERTICAL) otherSizer = wx.StaticBoxSizer(self.otherSizer_staticbox, wx.VERTICAL) otherSizer_1 = wx.BoxSizer(wx.HORIZONTAL) otherSizer_2 = wx.BoxSizer(wx.VERTICAL) ignoreSizer = wx.StaticBoxSizer(self.ignoreSizer_staticbox, wx.HORIZONTAL) dllExcludesSizer = wx.StaticBoxSizer(self.dllExcludesSizer_staticbox, wx.HORIZONTAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) packagesSizer = wx.StaticBoxSizer(self.packagesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) datafilesSizer = wx.StaticBoxSizer(self.datafile_staticbox, wx.HORIZONTAL) iconSizer = wx.StaticBoxSizer(self.icon_staticbox, wx.HORIZONTAL) bitmapSizer = wx.StaticBoxSizer(self.bitmap_staticbox, wx.HORIZONTAL) otherResSizer = wx.StaticBoxSizer(self.other_staticbox, wx.HORIZONTAL) plusSizer = wx.BoxSizer(wx.HORIZONTAL) minusSizer = wx.BoxSizer(wx.HORIZONTAL) resourceSizer = wx.BoxSizer(wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.VERTICAL) # This grid bag sizer will hold all the list controls and widgets # that display py2exe options commonGridSizer = wx.GridBagSizer(5, 5) commonSizer_7 = wx.BoxSizer(wx.VERTICAL) commonSizer_6 = wx.BoxSizer(wx.VERTICAL) commonSizer_5 = wx.BoxSizer(wx.VERTICAL) commonSizer_4 = wx.BoxSizer(wx.VERTICAL) commonSizer_3 = wx.BoxSizer(wx.VERTICAL) commonSizer_2 = wx.BoxSizer(wx.VERTICAL) commonSizer_1 = wx.BoxSizer(wx.VERTICAL) targetSizer = wx.StaticBoxSizer(self.targetSizer_staticbox, wx.HORIZONTAL) topGridSizer = wx.FlexGridSizer(1, 4, 5, 5) topSizer_4 = wx.BoxSizer(wx.VERTICAL) topSizer_3 = wx.BoxSizer(wx.VERTICAL) topSizer_2 = wx.BoxSizer(wx.VERTICAL) topSizer_1 = wx.BoxSizer(wx.VERTICAL) flag = wx.LEFT | wx.RIGHT | wx.EXPAND flag2 = wx.LEFT | wx.BOTTOM | wx.TOP | wx.EXPAND mainSizer.Add(self.label, 0, wx.ALL, 10) targetSizer.Add(self.multipleExe, 1, flag2, 5) targetSizer.Add(self.multipleExe.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) mainSizer.Add(targetSizer, 0, wx.ALL | wx.EXPAND, 5) optimize = wx.StaticText(self, -1, _("Optimize")) commonSizer_1.Add(optimize, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_1.Add(self.optimizeCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_1, (1, 0), (1, 1), flag, 5) compress = wx.StaticText(self, -1, _("Compressed")) commonSizer_2.Add(compress, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_2.Add(self.compressCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_2, (1, 1), (1, 1), flag, 5) bundle = wx.StaticText(self, -1, _("Bundle Files")) commonSizer_3.Add(bundle, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_3.Add(self.bundleCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_3, (1, 2), (1, 1), flag, 5) commonGridSizer.Add((0, 0), (1, 3), (1, 1), wx.EXPAND) commonSizer_4.Add(self.zipfileChoice, 0, wx.BOTTOM, 2) commonSizer_4.Add(self.zipfileTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_4, (1, 4), (1, 1), flag, 5) commonSizer_5.Add(self.distChoice, 0, wx.BOTTOM, 2) commonSizer_5.Add(self.distTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_5, (1, 5), (1, 1), flag, 5) commonGridSizer.AddGrowableCol(3) commonGridSizer.AddGrowableCol(4) commonGridSizer.AddGrowableCol(5) ## commonGridSizer.AddGrowableCol(6) commonGridSizer.SetEmptyCellSize((0, 0)) commonSizer.Add(commonGridSizer, 1, wx.EXPAND | wx.BOTTOM, 5) mainSizer.Add(commonSizer, 0, wx.ALL | wx.EXPAND, 5) flag = wx.LEFT | wx.TOP | wx.BOTTOM | wx.EXPAND # Add the list controls includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) packagesSizer.Add(self.packagesList, 1, flag, 5) packagesSizer.Add(self.packagesList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) plusSizer.Add(includesSizer, 1, wx.EXPAND) plusSizer.Add(packagesSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(plusSizer, 1, wx.ALL | wx.EXPAND, 5) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) dllExcludesSizer.Add(self.dllExcludeList, 1, flag, 5) dllExcludesSizer.Add(self.dllExcludeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) ignoreSizer.Add(self.ignoreList, 1, flag, 5) ignoreSizer.Add(self.ignoreList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) minusSizer.Add(excludesSizer, 1, wx.EXPAND) minusSizer.Add(dllExcludesSizer, 1, wx.EXPAND | wx.LEFT, 5) minusSizer.Add(ignoreSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(minusSizer, 1, wx.ALL | wx.EXPAND, 5) datafilesSizer.Add(self.datafileList, 1, flag, 5) datafilesSizer.Add(self.datafileList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) mainSizer.Add(datafilesSizer, 1, flag, 5) iconSizer.Add(self.iconResourceList, 1, flag, 5) iconSizer.Add(self.iconResourceList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) bitmapSizer.Add(self.bitmapResourceList, 1, flag, 5) bitmapSizer.Add(self.bitmapResourceList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) otherResSizer.Add(self.otherResourceList, 1, flag, 5) otherResSizer.Add(self.otherResourceList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) resourceSizer.Add(iconSizer, 1, wx.EXPAND) resourceSizer.Add(bitmapSizer, 1, wx.EXPAND | wx.LEFT, 5) resourceSizer.Add(otherResSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(resourceSizer, 0, wx.ALL | wx.EXPAND, 5) # Add the other options at the bottom otherSizer_1.Add(self.xpmanifestChoice, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.crossRefCheck, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.asciiCheck, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.skiparchiveChoice, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.createExeCheck, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.createDllCheck, 0, wx.ALL, 5) customboot = wx.StaticText(self, -1, _("Custom Boot Script")) otherSizer_2.Add(customboot, 0, wx.BOTTOM, 2) otherSizer_2.Add(self.customBootPicker, 0, wx.EXPAND) otherSizer.Add(otherSizer_1, 0, wx.EXPAND) otherSizer.Add(otherSizer_2, 0, wx.ALL | wx.EXPAND, 5) mainSizer.Add(otherSizer, 0, wx.ALL | wx.EXPAND, 5) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def EnableDllAndExe(self): """ Enables or disables the create_exe and create_dll option for py2exe. These options are only available for services, com_servers and ctypes_com_servers. """ # Disable the create_exe and create_dll self.createDllCheck.Enable(False) self.createExeCheck.Enable(False) # Enable the create_exe/create_dll if a service, com_server or ctypes_com_server are there for indx in xrange(self.multipleExe.GetItemCount()): consoleOrWindows = self.multipleExe.GetItem(indx, 1).GetText() if consoleOrWindows in [ "service", "com_server", "ctypes_com_server" ]: # These things accept module *names*, not file names... self.createDllCheck.Enable(True) self.createExeCheck.Enable(True) break def ValidateOptions(self): """ Validates the py2exe input options before compiling. """ # check if the script files exist if self.multipleExe.GetItemCount() == 0: msg = _("No Python scripts have been added.") self.MainFrame.RunError(2, msg, True) return False for indx in xrange(self.multipleExe.GetItemCount()): script = self.multipleExe.GetItem(indx, 2) if not os.path.isfile(script.GetText()): msg = _("Python main script is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the custom boot file is not empty and if it exists customBoot = self.customBootPicker.GetPath() if customBoot and not os.path.isfile(customBoot): msg = _("Custom boot file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Generating "%(projectName)s" setup script...') % transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # See if the user wants the manifest file embedded in the executable manifestFile = self.xpmanifestChoice.GetValue() # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, manifestFile, customCode, postCompile) def BuildTargetClass(self, configuration, project, manifestFile, customCode, postCompile): """ Builds the py2exe compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) # Delete the keys we don't need zipChoice, distChoice = self.zipfileChoice.GetValue( ), self.distChoice.GetValue() createExe, createDll = self.createExeCheck.GetValue( ), self.createDllCheck.GetValue() del configuration["zipfile_choice"], configuration["dist_dir_choice"] if "create_exe" in configuration: del configuration["create_exe"] if "create_dll" in configuration: del configuration["create_dll"] useRelPath = self.MainFrame.relativePaths scriptFile = self.multipleExe.GetItem(0, 2).GetText() # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if key == "custom_boot_script": # I don't know how often this option is used if not item: item = "''" else: item = "r'%s'" % item elif isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if type(item) == ListType and key != "multipleexe": # Terrible hack to setup correctly the string to be included # in the setup file item = setupString(key, item, useRelPath=useRelPath, mainScript=scriptFile) if key == "zipfile": if item and item.strip() and zipChoice: if (os.path.splitext(item)[1]).lower() != ".zip": self.MainFrame.SendMessage( 1, _('zipfile does not have ".zip" extension')) item = "r'%s'" % item else: item = None elif key == "dist_dir": if item and item.strip() and distChoice: item = r'%s' % item else: item = "dist" if distChoice: self.MainFrame.SendMessage( 1, _('Empty dist_dir option. Using default value "dist"' )) setupDict[key] = item targetclass = "" baseName = "GUI2Exe_Target_%d" console, windows, service, com_server, ctypes_com_server = "console = [", "windows = [", \ "service = [", "com_server = [", \ "ctypes_com_server = [" for indx in xrange(self.multipleExe.GetItemCount()): tupleMultiple = (baseName % (indx + 1), ) consoleOrWindows = self.multipleExe.GetItem(indx, 1).GetText() scriptFile = self.multipleExe.GetItem(indx, 2).GetText() buildDir, scriptFile = os.path.split(scriptFile) isSpecial = False realScript = scriptFile if consoleOrWindows in [ "service", "com_server", "ctypes_com_server" ]: # These things accept module *names*, not file names... realScript = os.path.splitext(scriptFile)[0] isSpecial = True if consoleOrWindows == "console": console += tupleMultiple[0] + ", " elif consoleOrWindows == "windows": windows += tupleMultiple[0] + ", " elif consoleOrWindows == "service": service += tupleMultiple[0] + ", " elif consoleOrWindows == "com_server": com_server += tupleMultiple[0] + ", " else: ctypes_com_server += tupleMultiple[0] + ", " tupleMultiple += (realScript, ) for col in xrange(3, self.multipleExe.GetColumnCount()): item = self.multipleExe.GetItem(indx, col) text = item.GetText() if not text.strip(): text = os.path.splitext(scriptFile)[0] self.MainFrame.SendMessage( 1, _('Empty targetName option. Using Python script name')) if col == 3: programName = text.strip() elif col == 4: versionNumber = text.strip() tupleMultiple += (text, ) extraKeywords = self.multipleExe.GetExtraKeywords(indx) if isSpecial: tupleMultiple += (extraKeywords + "\n create_exe = %s, create_dll = %s" % (bool(createExe), bool(createDll)), ) else: tupleMultiple += (extraKeywords, ) if isSpecial: # services, com_servers and ctypes_com_server require a "modules" keyword py2exe_class = _py2exe_class.replace(" script = ", " modules = ") else: py2exe_class = _py2exe_class targetclass += py2exe_class % tupleMultiple # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Look if the user wants to remove the "build" directory removeBuild = (self.MainFrame.deleteBuild and \ ['# Remove the build folder\nshutil.rmtree("build", ignore_errors=True)\n'] or [""])[0] importDict["remove_build"] = removeBuild # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Add the post-compilation code (if any) setupDict["postcompilecode"] = ( postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] # Populate the "import" section setupScript = _py2exe_imports % importDict if manifestFile: # Embed the manifest file setupDict["other_resources"] = setupDict["other_resources"] % "" setupScript += _manifest_template % dict(prog=programName) setupDict["targetclasses"] = targetclass setupDict["console"] = console.rstrip(", ") + "]" setupDict["windows"] = windows.rstrip(", ") + "]" setupDict["service"] = service.rstrip(", ") + "]" setupDict["com_server"] = com_server.rstrip(", ") + "]" setupDict["ctypes_com_server"] = ctypes_com_server.rstrip(", ") + "]" upx, inno = project.GetUseUPX("py2exe"), project.GetBuildInno("py2exe") if upx or inno: upxinno = _upx_inno % (upx, inno, programName, versionNumber) setupDict["upx_inno"] = upxinno setupDict["use_upx_inno"] = 'cmdclass = {"py2exe": Py2exe},' else: setupDict[ "upx_inno"] = "# No custom class for UPX compression or Inno Setup script" setupDict["use_upx_inno"] = "# No UPX or Inno Setup" # Populate the main section of the setup script setupScript += _py2exe_target % setupDict if manifestFile: # Substitute a dummy line with the real one setupScript = setupScript.replace("'manifest_template'", "manifest_template") # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Setup script for "%(projectName)s" succesfully created') % transdict) return setupScript, buildDir