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()
Esempio n. 2
0
    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()
Esempio n. 3
0
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)

        
Esempio n. 5
0
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
Esempio n. 6
0
    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()
Esempio n. 7
0
    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()
Esempio n. 8
0
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
Esempio n. 9
0
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
Esempio n. 10
0
    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)
Esempio n. 11
0
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)            
Esempio n. 12
0
    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()
Esempio n. 13
0
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