|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2012 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the Pyramid project plugin. |
|
8 """ |
|
9 |
|
10 import os |
|
11 import glob |
|
12 import fnmatch |
|
13 |
|
14 from PyQt4.QtCore import QCoreApplication, QObject, QTranslator |
|
15 ##from PyQt4.QtGui import QApplication |
|
16 |
|
17 from E5Gui.E5Application import e5App |
|
18 |
|
19 import Preferences |
|
20 |
|
21 from Globals import isWindowsPlatform, isMacPlatform |
|
22 |
|
23 from Project.ProjectBrowser import SourcesBrowserFlag, FormsBrowserFlag, \ |
|
24 TranslationsBrowserFlag, OthersBrowserFlag |
|
25 |
|
26 from ProjectPyramid.Project import Project |
|
27 |
|
28 # Start-of-Header |
|
29 name = "Pyramid Project Plugin" |
|
30 author = "Detlev Offenbach <detlev@die-offenbachs.de>" |
|
31 autoactivate = True |
|
32 deactivateable = True |
|
33 version = "0.1.0" |
|
34 className = "ProjectPyramidPlugin" |
|
35 packageName = "ProjectPyramid" |
|
36 shortDescription = "Project support for Pyramid projects." |
|
37 longDescription = """This plugin implements project support for Pyramid projects.""" |
|
38 needsRestart = False |
|
39 pyqtApi = 2 |
|
40 # End-of-Header |
|
41 |
|
42 error = "" |
|
43 |
|
44 pyramidPluginObject = None |
|
45 |
|
46 def createPyramidPage(configDlg): |
|
47 """ |
|
48 Module function to create the Pyramid configuration page. |
|
49 |
|
50 @return reference to the configuration page |
|
51 """ |
|
52 global pyramidPluginObject |
|
53 from ProjectPyramid.ConfigurationPage.PyramidPage import PyramidPage |
|
54 page = PyramidPage(pyramidPluginObject) |
|
55 return page |
|
56 |
|
57 def getConfigData(): |
|
58 """ |
|
59 Module function returning data as required by the configuration dialog. |
|
60 |
|
61 @return dictionary containing the relevant data |
|
62 """ |
|
63 if e5App().getObject("UserInterface").versionIsNewer('5.0.99', '20120101'): |
|
64 return { |
|
65 "pyramidPage" : \ |
|
66 [QCoreApplication.translate("ProjectPyramidPlugin", "Pyramid"), |
|
67 os.path.join("ProjectPyramid", "icons", |
|
68 "pyramid.png"), |
|
69 createPyramidPage, None, None], |
|
70 } |
|
71 else: |
|
72 return {} |
|
73 |
|
74 def apiFiles(language): |
|
75 """ |
|
76 Module function to return the API files made available by this plugin. |
|
77 |
|
78 @return list of API filenames (list of string) |
|
79 """ |
|
80 if language in ["Python3", "Python2"]: |
|
81 apisDir = \ |
|
82 os.path.join(os.path.dirname(__file__), "ProjectPyramid", "APIs") |
|
83 apis = glob.glob(os.path.join(apisDir, '*.api')) |
|
84 else: |
|
85 apis = [] |
|
86 return apis |
|
87 |
|
88 def prepareUninstall(): |
|
89 """ |
|
90 Module function to prepare for an uninstallation. |
|
91 """ |
|
92 pyramid = ProjectPyramidPlugin(None) |
|
93 pyramid.prepareUninstall() |
|
94 |
|
95 |
|
96 class ProjectPyramidPlugin(QObject): |
|
97 """ |
|
98 Class implementing the Pyramid project plugin. |
|
99 """ |
|
100 lexerAssociations = { |
|
101 "*.mako": "Pygments|HTML+Mako", |
|
102 "*.pt": "Pygments|HTML+Genshi", |
|
103 "*.txt": "Pygments|Genshi", |
|
104 "*.html": "Pygments|HTML+Genshi", |
|
105 "*.htm": "Pygments|HTML+Genshi", |
|
106 } |
|
107 |
|
108 def __init__(self, ui): |
|
109 """ |
|
110 Constructor |
|
111 |
|
112 @param ui reference to the user interface object (UI.UserInterface) |
|
113 """ |
|
114 QObject.__init__(self, ui) |
|
115 self.__ui = ui |
|
116 self.__initialize() |
|
117 |
|
118 # TODO: get rid of the consoles |
|
119 self.__defaults = { |
|
120 "VirtualEnvironmentPy2" : "", |
|
121 "VirtualEnvironmentPy3" : "", |
|
122 "Python2ConsoleType": "python", |
|
123 "Python3ConsoleType": "python", |
|
124 "ServerPort": 0, |
|
125 "PyramidDocUrl": "http://docs.pylonsproject.org/en/latest/docs/pyramid.html", |
|
126 } |
|
127 if isWindowsPlatform(): |
|
128 self.__defaults["ConsoleCommandNoClose"] = "cmd.exe /k" |
|
129 self.__defaults["ConsoleCommand"] = "cmd.exe /c" |
|
130 elif isMacPlatform(): |
|
131 self.__defaults["ConsoleCommandNoClose"] = "xterm -hold -e" |
|
132 self.__defaults["ConsoleCommand"] = "xterm -e" |
|
133 else: |
|
134 self.__defaults["ConsoleCommandNoClose"] = "konsole --noclose -e" |
|
135 self.__defaults["ConsoleCommand"] = "konsole -e" |
|
136 |
|
137 self.__translator = None |
|
138 self.__loadTranslator() |
|
139 |
|
140 def __initialize(self): |
|
141 """ |
|
142 Private slot to (re)initialize the plugin. |
|
143 """ |
|
144 self.__object = None |
|
145 |
|
146 self.__mainAct = None |
|
147 self.__mainMenu = None |
|
148 |
|
149 self.__e5project = e5App().getObject("Project") |
|
150 |
|
151 def __checkVersions(self): |
|
152 """ |
|
153 Private function to check that the eric5 version is ok. |
|
154 |
|
155 @return flag indicating version is ok (boolean) |
|
156 """ |
|
157 global error |
|
158 |
|
159 if self.__ui.versionIsNewer('5.0.99', '20120101'): |
|
160 error = "" |
|
161 else: |
|
162 error = self.trUtf8("eric5 version is too old, {0}, {1} or newer needed.")\ |
|
163 .format("5.1.0", "20120101") |
|
164 return False |
|
165 |
|
166 return True |
|
167 |
|
168 def activate(self): |
|
169 """ |
|
170 Public method to activate this plugin. |
|
171 |
|
172 @return tuple of None and activation status (boolean) |
|
173 """ |
|
174 if not self.__checkVersions(): |
|
175 return None, False |
|
176 |
|
177 global pyramidPluginObject |
|
178 pyramidPluginObject = self |
|
179 |
|
180 self.__object = Project(self, self.__ui) |
|
181 self.__object.initActions() |
|
182 e5App().registerPluginObject("ProjectPyramid", self.__object) |
|
183 |
|
184 self.__mainMenu = self.__object.initMenu() |
|
185 |
|
186 self.__e5project.registerProjectType("Pyramid", self.trUtf8("Pyramid"), |
|
187 self.fileTypesCallback, |
|
188 lexerAssociationCallback = self.lexerAssociationCallback, |
|
189 binaryTranslationsCallback = self.binaryTranslationsCallback) |
|
190 Preferences.setProjectBrowserFlagsDefault("Pyramid", |
|
191 SourcesBrowserFlag | \ |
|
192 FormsBrowserFlag | \ |
|
193 TranslationsBrowserFlag | \ |
|
194 OthersBrowserFlag, |
|
195 ) |
|
196 |
|
197 if self.__e5project.isOpen(): |
|
198 self.__projectOpened() |
|
199 self.__object.projectOpenedHooks() |
|
200 |
|
201 e5App().getObject("Project").projectOpened.connect(self.__projectOpened) |
|
202 e5App().getObject("Project").projectClosed.connect(self.__projectClosed) |
|
203 e5App().getObject("Project").newProject.connect(self.__projectOpened) |
|
204 |
|
205 e5App().getObject("Project").projectOpenedHooks.connect( |
|
206 self.__object.projectOpenedHooks) |
|
207 e5App().getObject("Project").projectClosedHooks.connect( |
|
208 self.__object.projectClosedHooks) |
|
209 e5App().getObject("Project").newProjectHooks.connect( |
|
210 self.__object.projectOpenedHooks) |
|
211 |
|
212 return None, True |
|
213 |
|
214 def deactivate(self): |
|
215 """ |
|
216 Public method to deactivate this plugin. |
|
217 """ |
|
218 e5App().unregisterPluginObject("ProjectPyramid") |
|
219 |
|
220 e5App().getObject("Project").projectOpened.disconnect(self.__projectOpened) |
|
221 e5App().getObject("Project").projectClosed.disconnect(self.__projectClosed) |
|
222 e5App().getObject("Project").newProject.disconnect(self.__projectOpened) |
|
223 |
|
224 e5App().getObject("Project").projectOpenedHooks.disconnect( |
|
225 self.__object.projectOpenedHooks) |
|
226 e5App().getObject("Project").projectClosedHooks.disconnect( |
|
227 self.__object.projectClosedHooks) |
|
228 e5App().getObject("Project").newProjectHooks.disconnect( |
|
229 self.__object.projectOpenedHooks) |
|
230 |
|
231 self.__e5project.unregisterProjectType("Pyramid") |
|
232 |
|
233 self.__object.projectClosedHooks() |
|
234 self.__projectClosed() |
|
235 |
|
236 self.__initialize() |
|
237 |
|
238 def __loadTranslator(self): |
|
239 """ |
|
240 Private method to load the translation file. |
|
241 """ |
|
242 if self.__ui is not None: |
|
243 loc = self.__ui.getLocale() |
|
244 if loc and loc != "C": |
|
245 locale_dir = \ |
|
246 os.path.join(os.path.dirname(__file__), "ProjectPyramid", "i18n") |
|
247 translation = "pyramid_%s" % loc |
|
248 translator = QTranslator(None) |
|
249 loaded = translator.load(translation, locale_dir) |
|
250 if loaded: |
|
251 self.__translator = translator |
|
252 e5App().installTranslator(self.__translator) |
|
253 else: |
|
254 print("Warning: translation file '{0}' could not be loaded.".format( |
|
255 translation)) |
|
256 print("Using default.") |
|
257 |
|
258 def __projectOpened(self): |
|
259 """ |
|
260 Private slot to handle the projectOpened signal. |
|
261 """ |
|
262 if self.__e5project.getProjectType() == "Pyramid": |
|
263 projectAct = self.__ui.getMenuBarAction("project") |
|
264 actions = self.__ui.menuBar().actions() |
|
265 insertAct = actions[actions.index(projectAct) + 1] |
|
266 self.__mainAct = self.__ui.menuBar().insertMenu(insertAct, self.__mainMenu) |
|
267 |
|
268 def __projectClosed(self): |
|
269 """ |
|
270 Private slot to handle the projectClosed signal. |
|
271 """ |
|
272 if self.__mainAct is not None: |
|
273 self.__ui.menuBar().removeAction(self.__mainAct) |
|
274 self.__mainAct = None |
|
275 self.__object.projectClosed() |
|
276 |
|
277 def fileTypesCallback(self): |
|
278 """ |
|
279 Public method get the filetype associations of the Pyramid project type. |
|
280 |
|
281 @return dictionary with file type associations |
|
282 """ |
|
283 if self.__e5project.getProjectType() == "Pyramid": |
|
284 fileTypes = { |
|
285 "*.mako": "FORMS", |
|
286 "*.mak": "FORMS", |
|
287 "*.pt": "FORMS", |
|
288 "*.html": "FORMS", |
|
289 "*.htm": "FORMS", |
|
290 "*.js": "SOURCES", |
|
291 "*.pot": "TRANSLATIONS", |
|
292 "*.po": "TRANSLATIONS", |
|
293 "*.mo": "TRANSLATIONS", |
|
294 } |
|
295 else: |
|
296 fileTypes = {} |
|
297 return fileTypes |
|
298 |
|
299 def lexerAssociationCallback(self, filename): |
|
300 """ |
|
301 Public method to get the lexer association of the Pyramid project type for |
|
302 a file. |
|
303 |
|
304 @param filename name of the file (string) |
|
305 @return name of the lexer (string) (Pygments lexers are prefixed with 'Pygments|') |
|
306 """ |
|
307 for pattern, language in self.lexerAssociations.items(): |
|
308 if fnmatch.fnmatch(filename, pattern): |
|
309 return language |
|
310 |
|
311 return "" |
|
312 |
|
313 def binaryTranslationsCallback(self, filename): |
|
314 """ |
|
315 Public method to determine the filename of a compiled translation file |
|
316 given the translation source file. |
|
317 |
|
318 @param filename name of the translation source file (string) |
|
319 @return name of the binary translation file (string) |
|
320 """ |
|
321 if filename.endswith(".po"): |
|
322 filename = filename.replace(".po", ".mo") |
|
323 return filename |
|
324 |
|
325 def getPreferences(self, key): |
|
326 """ |
|
327 Public method to retrieve the various settings. |
|
328 |
|
329 @param key the key of the value to get |
|
330 @param prefClass preferences class used as the storage area |
|
331 @return the requested setting |
|
332 """ |
|
333 if key == "ServerPort": |
|
334 return int(Preferences.Prefs.settings.value("Pyramid/" + key, |
|
335 self.__defaults[key])) |
|
336 else: |
|
337 return Preferences.Prefs.settings.value("Pyramid/" + key, |
|
338 self.__defaults[key]) |
|
339 |
|
340 def setPreferences(self, key, value): |
|
341 """ |
|
342 Public method to store the various settings. |
|
343 |
|
344 @param key the key of the setting to be set (string) |
|
345 @param value the value to be set |
|
346 @param prefClass preferences class used as the storage area |
|
347 """ |
|
348 Preferences.Prefs.settings.setValue("Pyramid/" + key, value) |
|
349 |
|
350 def prepareUninstall(self): |
|
351 """ |
|
352 Public method to prepare for an uninstallation. |
|
353 """ |
|
354 Preferences.removeProjectBrowserFlags("Pyramid") |
|
355 Preferences.Prefs.settings.remove("Pyramid") |