Thu, 28 Apr 2011 19:56:40 +0200
Merged remote changes.
24 | 1 | # -*- coding: utf-8 -*- |
2 | ||
3 | # Copyright (c) 2010 - 2011 Detlev Offenbach <detlev@die-offenbachs.de> | |
4 | # | |
5 | ||
6 | """ | |
7 | Module implementing the CxFreeze plugin. | |
8 | """ | |
9 | ||
10 | import os | |
11 | import sys | |
12 | ||
13 | from PyQt4.QtCore import QObject, QTranslator, QCoreApplication | |
14 | from PyQt4.QtGui import QDialog, QMessageBox | |
15 | ||
16 | from E5Gui.E5Action import E5Action | |
17 | from E5Gui.E5Application import e5App | |
18 | ||
19 | from CxFreeze.CxfreezeConfigDialog import CxfreezeConfigDialog | |
20 | from CxFreeze.CxfreezeExecDialog import CxfreezeExecDialog | |
21 | ||
22 | import Utilities | |
23 | ||
24 | # Start-of-Header | |
25 | name = "CxFreeze Plugin" | |
26 | author = "Detlev Offenbach <detlev@die-offenbachs.de>" | |
27 | autoactivate = True | |
28 | deactivateable = True | |
29 | version = "5.0.3" | |
30 | className = "CxFreezePlugin" | |
31 | packageName = "CxFreeze" | |
32 | shortDescription = "Show the CxFreeze dialogs." | |
33 | longDescription = """This plugin implements the CxFreeze dialogs.""" \ | |
34 | """ CxFreeze is used to generate a distribution package.""" | |
35 | needsRestart = False | |
36 | pyqtApi = 2 | |
37 | # End-of-Header | |
38 | ||
39 | error = "" | |
40 | ||
41 | def exeDisplayData(): | |
42 | """ | |
43 | Public method to support the display of some executable info. | |
44 | ||
45 | @return dictionary containing the data to query the presence of | |
46 | the executable | |
47 | """ | |
48 | data = { | |
49 | "programEntry" : True, | |
50 | "header" : QCoreApplication.translate("CxFreezePlugin", | |
51 | "Packagers - cx_freeze"), | |
52 | "exe" : 'dummyfreeze', | |
53 | "versionCommand" : '--version', | |
54 | "versionStartsWith" : 'dummyfreeze', | |
55 | "versionPosition" : -1, | |
56 | "version" : "", | |
57 | "versionCleanup" : None, | |
58 | } | |
59 | ||
60 | exe = _findExecutable() | |
61 | if exe: | |
62 | data["exe"] = exe | |
63 | if "FreezePython" in exe: | |
64 | data["versionStartsWith"] = "FreezePython" | |
65 | elif "cxfreeze" in exe: | |
66 | data["versionStartsWith"] = "cxfreeze" | |
67 | ||
68 | return data | |
69 | ||
70 | def _findExecutable(): | |
71 | """ | |
72 | Restricted function to determine the name of the executable. | |
73 | ||
74 | @return name of the executable (string) | |
75 | """ | |
76 | # step 1: check for version 4.x | |
77 | if Utilities.isWindowsPlatform(): | |
78 | # | |
79 | # Windows | |
80 | # | |
81 | exe = 'cxfreeze.bat' | |
82 | if Utilities.isinpath(exe): | |
83 | return exe | |
84 | try: | |
85 | #only since python 3.2 | |
86 | import sysconfig | |
87 | scripts = sysconfig.get_path('scripts','nt') | |
88 | return os.path.join(scripts, exe) | |
89 | except ImportError: | |
90 | try: | |
91 | import winreg | |
92 | except ImportError: | |
93 | # give up ... | |
94 | return None | |
95 | ||
96 | version = str(sys.version_info.major) + '.' + \ | |
97 | str(sys.version_info.minor) | |
98 | ||
99 | try: | |
100 | software = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'Software') | |
101 | python = winreg.OpenKey(software, 'Python') | |
102 | pcore = winreg.OpenKey(python, 'PythonCore') | |
103 | version = winreg.OpenKey(pcore, version) | |
104 | installpath = winreg.QueryValue(version, 'InstallPath') | |
105 | return os.path.join(installpath, 'Scripts', exe) | |
106 | except WindowsError: # __IGNORE_WARNING__ | |
107 | return None | |
108 | else: | |
109 | # | |
110 | # Linux, Unix ... | |
111 | exe = 'cxfreeze' | |
112 | if Utilities.isinpath(exe): | |
113 | return exe | |
114 | ||
115 | return None | |
116 | ||
117 | def _checkProgram(): | |
118 | """ | |
119 | Restricted function to check the availability of cxfreeze. | |
120 | ||
121 | @return flag indicating availability (boolean) | |
122 | """ | |
123 | global error | |
124 | ||
125 | if _findExecutable() is None: | |
126 | error = QCoreApplication.translate("CxFreezePlugin", | |
127 | "The cxfreeze executable could not be found.") | |
128 | return False | |
129 | else: | |
130 | return True | |
131 | _checkProgram() | |
132 | ||
133 | class CxFreezePlugin(QObject): | |
134 | """ | |
135 | Class implementing the CxFreeze plugin. | |
136 | """ | |
137 | def __init__(self, ui): | |
138 | """ | |
139 | Constructor | |
140 | ||
141 | @param ui reference to the user interface object (UI.UserInterface) | |
142 | """ | |
143 | QObject.__init__(self, ui) | |
144 | self.__ui = ui | |
145 | self.__initialize() | |
146 | _checkProgram() | |
147 | ||
148 | self.__translator = None | |
149 | self.__loadTranslator() | |
150 | ||
151 | def __initialize(self): | |
152 | """ | |
153 | Private slot to (re)initialize the plugin. | |
154 | """ | |
155 | self.__projectAct = None | |
156 | ||
157 | def activate(self): | |
158 | """ | |
159 | Public method to activate this plugin. | |
160 | ||
161 | @return tuple of None and activation status (boolean) | |
162 | """ | |
163 | global error | |
164 | ||
165 | # cxfreeze is only activated if it is available | |
166 | if not _checkProgram(): | |
167 | return None, False | |
168 | ||
169 | menu = e5App().getObject("Project").getMenu("Packagers") | |
170 | if menu: | |
171 | self.__projectAct = E5Action(self.trUtf8('Use cx_freeze'), | |
172 | self.trUtf8('Use cx_&freeze'), 0, 0, | |
173 | self, 'packagers_cxfreeze') | |
174 | self.__projectAct.setStatusTip( | |
175 | self.trUtf8('Generate a distribution package using cx_freeze')) | |
176 | self.__projectAct.setWhatsThis(self.trUtf8( | |
177 | """<b>Use cx_freeze</b>""" | |
178 | """<p>Generate a distribution package using cx_freeze.""" | |
179 | """ The command is executed in the project path. All""" | |
180 | """ files and directories must be given absolute or""" | |
181 | """ relative to the project directory.</p>""" | |
182 | )) | |
183 | self.__projectAct.triggered[()].connect(self.__cxfreeze) | |
184 | e5App().getObject("Project").addE5Actions([self.__projectAct]) | |
185 | menu.addAction(self.__projectAct) | |
186 | ||
187 | error = "" | |
188 | return None, True | |
189 | ||
190 | def deactivate(self): | |
191 | """ | |
192 | Public method to deactivate this plugin. | |
193 | """ | |
194 | menu = e5App().getObject("Project").getMenu("Packagers") | |
195 | if menu: | |
196 | if self.__projectAct: | |
197 | menu.removeAction(self.__projectAct) | |
198 | e5App().getObject("Project").removeE5Actions([self.__projectAct]) | |
199 | self.__initialize() | |
200 | ||
201 | def __loadTranslator(self): | |
202 | """ | |
203 | Private method to load the translation file. | |
204 | """ | |
205 | if self.__ui is not None: | |
206 | loc = self.__ui.getLocale() | |
207 | if loc and loc != "C": | |
208 | locale_dir = \ | |
209 | os.path.join(os.path.dirname(__file__), "CxFreeze", "i18n") | |
210 | translation = "cxfreeze_{0}".format(loc) | |
211 | translator = QTranslator(None) | |
212 | loaded = translator.load(translation, locale_dir) | |
213 | if loaded: | |
214 | self.__translator = translator | |
215 | e5App().installTranslator(self.__translator) | |
216 | else: | |
217 | print("Warning: translation file '{0}' could not be loaded."\ | |
218 | .format(translation)) | |
219 | print("Using default.") | |
220 | ||
221 | def __cxfreeze(self): | |
222 | """ | |
223 | Private slot to handle the cxfreeze execution. | |
224 | """ | |
225 | project = e5App().getObject("Project") | |
226 | if len(project.pdata["MAINSCRIPT"]) == 0: | |
227 | # no main script defined | |
228 | QMessageBox.critical(None, | |
229 | self.trUtf8("cxfreeze"), | |
230 | self.trUtf8( | |
231 | """There is no main script defined for the current project."""), | |
232 | QMessageBox.StandardButtons( | |
233 | QMessageBox.Abort)) | |
234 | return | |
235 | ||
236 | parms = project.getData('PACKAGERSPARMS', "CXFREEZE") | |
237 | exe = _findExecutable() | |
238 | if exe is None: | |
239 | QMessageBox.critical(None, | |
240 | self.trUtf8("cxfreeze"), | |
241 | self.trUtf8("""The cxfreeze executable could not be found.""")) | |
242 | return | |
243 | ||
244 | dlg = CxfreezeConfigDialog(project, exe, parms) | |
245 | if dlg.exec_() == QDialog.Accepted: | |
246 | args, parms = dlg.generateParameters() | |
247 | project.setData('PACKAGERSPARMS', "CXFREEZE", parms) | |
248 | ||
249 | # now do the call | |
250 | dia = CxfreezeExecDialog("cxfreeze") | |
251 | dia.show() | |
252 | res = dia.start(args, | |
253 | os.path.join(project.ppath, project.pdata["MAINSCRIPT"][0])) | |
254 | if res: | |
255 | dia.exec_() | |
256 |