PluginProjectWeb.py

branch
eric7
changeset 43
2bed42620c99
parent 41
836c696f9565
child 44
7d124a753853
equal deleted inserted replaced
42:27f43499da60 43:2bed42620c99
16 from EricWidgets.EricApplication import ericApp 16 from EricWidgets.EricApplication import ericApp
17 17
18 import Preferences 18 import Preferences
19 19
20 try: 20 try:
21 from bs4 import BeautifulSoup # __IGNORE_EXCEPTION__ 21 from bs4 import BeautifulSoup # __IGNORE_EXCEPTION__
22
22 BeautifulSoupAvailable = True 23 BeautifulSoupAvailable = True
23 except ImportError: 24 except ImportError:
24 BeautifulSoup = None 25 BeautifulSoup = None
25 BeautifulSoupAvailable = False 26 BeautifulSoupAvailable = False
26 27
41 needsRestart = False 42 needsRestart = False
42 pyqtApi = 2 43 pyqtApi = 2
43 # End-Of-Header 44 # End-Of-Header
44 45
45 error = "" 46 error = ""
46 47
47 48
48 class ProjectWebPlugin(QObject): 49 class ProjectWebPlugin(QObject):
49 """ 50 """
50 Class implementing the Web project plugin. 51 Class implementing the Web project plugin.
51 """ 52 """
53
52 def __init__(self, ui): 54 def __init__(self, ui):
53 """ 55 """
54 Constructor 56 Constructor
55 57
56 @param ui reference to the user interface object 58 @param ui reference to the user interface object
57 @type UserInterface 59 @type UserInterface
58 """ 60 """
59 super().__init__(ui) 61 super().__init__(ui)
60 self.__ui = ui 62 self.__ui = ui
61 self.__initialize() 63 self.__initialize()
62 64
63 self.__translator = None 65 self.__translator = None
64 self.__loadTranslator() 66 self.__loadTranslator()
65 67
66 self.__initMenu() 68 self.__initMenu()
67 69
68 def __initialize(self): 70 def __initialize(self):
69 """ 71 """
70 Private slot to (re)initialize the plugin. 72 Private slot to (re)initialize the plugin.
71 """ 73 """
72 self.__ericProject = ericApp().getObject("Project") 74 self.__ericProject = ericApp().getObject("Project")
73 75
74 self.__editors = {} 76 self.__editors = {}
75 self.__mainActions = [] 77 self.__mainActions = []
76 78
77 def activate(self): 79 def activate(self):
78 """ 80 """
79 Public method to activate this plugin. 81 Public method to activate this plugin.
80 82
81 @return tuple of None and activation status 83 @return tuple of None and activation status
82 @rtype tuple of (None, bool) 84 @rtype tuple of (None, bool)
83 """ 85 """
84 global error 86 global error
85 error = "" # clear previous error 87 error = "" # clear previous error
86 88
87 # it is not registered for a specific programming language 89 # it is not registered for a specific programming language
88 self.__ericProject.registerProjectType( 90 self.__ericProject.registerProjectType(
89 "Web", self.tr("Web"), 91 "Web", self.tr("Web"), self.fileTypesCallback
90 self.fileTypesCallback) 92 )
91 93
92 from Project.ProjectBrowser import ( 94 from Project.ProjectBrowser import (
93 SourcesBrowserFlag, FormsBrowserFlag, OthersBrowserFlag 95 SourcesBrowserFlag,
94 ) 96 FormsBrowserFlag,
97 OthersBrowserFlag,
98 )
99
95 Preferences.setProjectBrowserFlagsDefault( 100 Preferences.setProjectBrowserFlagsDefault(
96 "Web", 101 "Web",
97 SourcesBrowserFlag | FormsBrowserFlag | OthersBrowserFlag, 102 SourcesBrowserFlag | FormsBrowserFlag | OthersBrowserFlag,
98 ) 103 )
99 104
100 self.__ui.showMenu.connect(self.__populateMenu) 105 self.__ui.showMenu.connect(self.__populateMenu)
101 106
102 menu = self.__ui.getMenu("plugin_tools") 107 menu = self.__ui.getMenu("plugin_tools")
103 if menu is not None: 108 if menu is not None:
104 if not menu.isEmpty(): 109 if not menu.isEmpty():
105 act = menu.addSeparator() 110 act = menu.addSeparator()
106 self.__mainActions.append(act) 111 self.__mainActions.append(act)
107 act = menu.addMenu(self.__menu) 112 act = menu.addMenu(self.__menu)
108 self.__mainActions.append(act) 113 self.__mainActions.append(act)
109 114
110 ericApp().getObject("ViewManager").editorOpenedEd.connect( 115 ericApp().getObject("ViewManager").editorOpenedEd.connect(self.__editorOpened)
111 self.__editorOpened) 116 ericApp().getObject("ViewManager").editorClosedEd.connect(self.__editorClosed)
112 ericApp().getObject("ViewManager").editorClosedEd.connect( 117
113 self.__editorClosed)
114
115 for editor in ericApp().getObject("ViewManager").getOpenEditors(): 118 for editor in ericApp().getObject("ViewManager").getOpenEditors():
116 self.__editorOpened(editor) 119 self.__editorOpened(editor)
117 120
118 return None, True 121 return None, True
119 122
120 def deactivate(self): 123 def deactivate(self):
121 """ 124 """
122 Public method to deactivate this plugin. 125 Public method to deactivate this plugin.
123 """ 126 """
124 self.__ericProject.unregisterProjectType("Web") 127 self.__ericProject.unregisterProjectType("Web")
125 128
126 self.__ui.showMenu.disconnect(self.__populateMenu) 129 self.__ui.showMenu.disconnect(self.__populateMenu)
127 130
128 menu = self.__ui.getMenu("plugin_tools") 131 menu = self.__ui.getMenu("plugin_tools")
129 if menu is not None: 132 if menu is not None:
130 for act in self.__mainActions: 133 for act in self.__mainActions:
131 menu.removeAction(act) 134 menu.removeAction(act)
132 self.__mainActions = [] 135 self.__mainActions = []
133 136
134 ericApp().getObject("ViewManager").editorOpenedEd.disconnect( 137 ericApp().getObject("ViewManager").editorOpenedEd.disconnect(
135 self.__editorOpened) 138 self.__editorOpened
139 )
136 ericApp().getObject("ViewManager").editorClosedEd.disconnect( 140 ericApp().getObject("ViewManager").editorClosedEd.disconnect(
137 self.__editorClosed) 141 self.__editorClosed
138 142 )
143
139 for editor, acts in self.__editors.items(): 144 for editor, acts in self.__editors.items():
140 editor.showMenu.disconnect(self.__editorShowMenu) 145 editor.showMenu.disconnect(self.__editorShowMenu)
141 menu = editor.getMenu("Tools") 146 menu = editor.getMenu("Tools")
142 if menu is not None: 147 if menu is not None:
143 for act in acts: 148 for act in acts:
144 menu.removeAction(act) 149 menu.removeAction(act)
145 150
146 self.__initialize() 151 self.__initialize()
147 152
148 def __loadTranslator(self): 153 def __loadTranslator(self):
149 """ 154 """
150 Private method to load the translation file. 155 Private method to load the translation file.
151 """ 156 """
152 if self.__ui is not None: 157 if self.__ui is not None:
153 loc = self.__ui.getLocale() 158 loc = self.__ui.getLocale()
154 if loc and loc != "C": 159 if loc and loc != "C":
155 locale_dir = os.path.join( 160 locale_dir = os.path.join(
156 os.path.dirname(__file__), "ProjectWeb", "i18n") 161 os.path.dirname(__file__), "ProjectWeb", "i18n"
162 )
157 translation = "web_{0}".format(loc) 163 translation = "web_{0}".format(loc)
158 translator = QTranslator(None) 164 translator = QTranslator(None)
159 loaded = translator.load(translation, locale_dir) 165 loaded = translator.load(translation, locale_dir)
160 if loaded: 166 if loaded:
161 self.__translator = translator 167 self.__translator = translator
162 ericApp().installTranslator(self.__translator) 168 ericApp().installTranslator(self.__translator)
163 else: 169 else:
164 print("Warning: translation file '{0}' could not be" 170 print(
165 " loaded.".format(translation)) 171 "Warning: translation file '{0}' could not be"
172 " loaded.".format(translation)
173 )
166 print("Using default.") 174 print("Using default.")
167 175
168 def fileTypesCallback(self): 176 def fileTypesCallback(self):
169 """ 177 """
170 Public method to get the filetype associations of the Web project type. 178 Public method to get the filetype associations of the Web project type.
171 179
172 @return dictionary with file type associations 180 @return dictionary with file type associations
173 @rtype dict 181 @rtype dict
174 """ 182 """
175 if self.__ericProject.getProjectType() == "Web": 183 if self.__ericProject.getProjectType() == "Web":
176 return { 184 return {
178 "*.htm": "FORMS", 186 "*.htm": "FORMS",
179 "*.js": "SOURCES", 187 "*.js": "SOURCES",
180 } 188 }
181 else: 189 else:
182 return {} 190 return {}
183 191
184 def __initMenu(self): 192 def __initMenu(self):
185 """ 193 """
186 Private method to initialize the web tools menu. 194 Private method to initialize the web tools menu.
187 """ 195 """
188 self.__menu = QMenu(self.tr("Web")) 196 self.__menu = QMenu(self.tr("Web"))
189 197
190 self.__html5ToCss3Act = self.__menu.addAction(self.tr( 198 self.__html5ToCss3Act = self.__menu.addAction(
191 "HTML5 to CSS3"), self.__html5ToCss3) 199 self.tr("HTML5 to CSS3"), self.__html5ToCss3
192 self.__html5ToJsAct = self.__menu.addAction(self.tr( 200 )
193 "HTML5 to JavaScript"), self.__html5ToJs) 201 self.__html5ToJsAct = self.__menu.addAction(
202 self.tr("HTML5 to JavaScript"), self.__html5ToJs
203 )
194 self.__menu.addSeparator() 204 self.__menu.addSeparator()
195 self.__html5PrettifyAct = self.__menu.addAction(self.tr( 205 self.__html5PrettifyAct = self.__menu.addAction(
196 "Prettify HTML"), self.__html5Prettify) 206 self.tr("Prettify HTML"), self.__html5Prettify
197 207 )
208
198 self.__menu.aboutToShow.connect(self.__menuAboutToShow) 209 self.__menu.aboutToShow.connect(self.__menuAboutToShow)
199 210
200 def __menuAboutToShow(self): 211 def __menuAboutToShow(self):
201 """ 212 """
202 Private slot to prepare the menu before it is shown. 213 Private slot to prepare the menu before it is shown.
203 """ 214 """
204 editor = ericApp().getObject("ViewManager").activeWindow() 215 editor = ericApp().getObject("ViewManager").activeWindow()
205 selectionAvailable = bool(editor and editor.selectedText() != "") 216 selectionAvailable = bool(editor and editor.selectedText() != "")
206 isHtml = bool(editor and 217 isHtml = bool(editor and editor.getLanguage().lower().startswith("html"))
207 editor.getLanguage().lower().startswith("html")) 218
208
209 self.__html5ToCss3Act.setEnabled( 219 self.__html5ToCss3Act.setEnabled(
210 selectionAvailable and BeautifulSoupAvailable and isHtml) 220 selectionAvailable and BeautifulSoupAvailable and isHtml
221 )
211 self.__html5ToJsAct.setEnabled( 222 self.__html5ToJsAct.setEnabled(
212 selectionAvailable and BeautifulSoupAvailable and isHtml) 223 selectionAvailable and BeautifulSoupAvailable and isHtml
213 self.__html5PrettifyAct.setEnabled( 224 )
214 BeautifulSoupAvailable and isHtml) 225 self.__html5PrettifyAct.setEnabled(BeautifulSoupAvailable and isHtml)
215 226
216 def __populateMenu(self, name, menu): 227 def __populateMenu(self, name, menu):
217 """ 228 """
218 Private slot to populate the tools menu with our entries. 229 Private slot to populate the tools menu with our entries.
219 230
220 @param name name of the menu 231 @param name name of the menu
221 @type str 232 @type str
222 @param menu reference to the menu to be populated 233 @param menu reference to the menu to be populated
223 @type QMenu 234 @type QMenu
224 """ 235 """
225 if name not in ["Tools", "PluginTools"]: 236 if name not in ["Tools", "PluginTools"]:
226 return 237 return
227 238
228 if name == "Tools": 239 if name == "Tools":
229 if not menu.isEmpty(): 240 if not menu.isEmpty():
230 menu.addSeparator() 241 menu.addSeparator()
231 menu.addMenu(self.__menu) 242 menu.addMenu(self.__menu)
232 243
233 def __editorOpened(self, editor): 244 def __editorOpened(self, editor):
234 """ 245 """
235 Private slot called, when a new editor was opened. 246 Private slot called, when a new editor was opened.
236 247
237 @param editor reference to the new editor 248 @param editor reference to the new editor
238 @type Editor 249 @type Editor
239 """ 250 """
240 menu = editor.getMenu("Tools") 251 menu = editor.getMenu("Tools")
241 if menu is not None: 252 if menu is not None:
244 act = menu.addSeparator() 255 act = menu.addSeparator()
245 self.__editors[editor].append(act) 256 self.__editors[editor].append(act)
246 act = menu.addMenu(self.__menu) 257 act = menu.addMenu(self.__menu)
247 self.__editors[editor].append(act) 258 self.__editors[editor].append(act)
248 editor.showMenu.connect(self.__editorShowMenu) 259 editor.showMenu.connect(self.__editorShowMenu)
249 260
250 def __editorClosed(self, editor): 261 def __editorClosed(self, editor):
251 """ 262 """
252 Private slot called, when an editor was closed. 263 Private slot called, when an editor was closed.
253 264
254 @param editor reference to the editor 265 @param editor reference to the editor
255 @type Editor 266 @type Editor
256 """ 267 """
257 with contextlib.suppress(KeyError): 268 with contextlib.suppress(KeyError):
258 del self.__editors[editor] 269 del self.__editors[editor]
259 270
260 def __editorShowMenu(self, menuName, menu, editor): 271 def __editorShowMenu(self, menuName, menu, editor):
261 """ 272 """
262 Private slot called, when the the editor context menu or a submenu is 273 Private slot called, when the the editor context menu or a submenu is
263 about to be shown. 274 about to be shown.
264 275
265 @param menuName name of the menu to be shown 276 @param menuName name of the menu to be shown
266 @type str 277 @type str
267 @param menu reference to the menu 278 @param menu reference to the menu
268 @type QMenu 279 @type QMenu
269 @param editor reference to the editor 280 @param editor reference to the editor
270 @type Editor 281 @type Editor
271 """ 282 """
272 if ( 283 if menuName == "Tools" and self.__menu.menuAction() not in menu.actions():
273 menuName == "Tools" and
274 self.__menu.menuAction() not in menu.actions()
275 ):
276 # Re-add our menu 284 # Re-add our menu
277 self.__editors[editor] = [] 285 self.__editors[editor] = []
278 if not menu.isEmpty(): 286 if not menu.isEmpty():
279 act = menu.addSeparator() 287 act = menu.addSeparator()
280 self.__editors[editor].append(act) 288 self.__editors[editor].append(act)
281 act = menu.addMenu(self.__menu) 289 act = menu.addMenu(self.__menu)
282 self.__editors[editor].append(act) 290 self.__editors[editor].append(act)
283 291
284 def __html5ToCss3(self): 292 def __html5ToCss3(self):
285 """ 293 """
286 Private slot handling the HTML5 to CSS3 conversion. 294 Private slot handling the HTML5 to CSS3 conversion.
287 """ 295 """
288 from ProjectWeb.Html5ToCss3Converter import Html5ToCss3Converter 296 from ProjectWeb.Html5ToCss3Converter import Html5ToCss3Converter
297
289 vm = ericApp().getObject("ViewManager") 298 vm = ericApp().getObject("ViewManager")
290 editor = vm.activeWindow() 299 editor = vm.activeWindow()
291 html = editor.selectedText() 300 html = editor.selectedText()
292 301
293 converter = Html5ToCss3Converter(html) 302 converter = Html5ToCss3Converter(html)
294 css3 = converter.getCss3() 303 css3 = converter.getCss3()
295 304
296 if css3: 305 if css3:
297 vm.newEditor() 306 vm.newEditor()
298 newEditor = vm.activeWindow() 307 newEditor = vm.activeWindow()
299 newEditor.setText(css3) 308 newEditor.setText(css3)
300 newEditor.setLanguage("dummy.css") 309 newEditor.setLanguage("dummy.css")
301 310
302 def __html5ToJs(self): 311 def __html5ToJs(self):
303 """ 312 """
304 Private slot handling the HTML5 to JavaScript conversion. 313 Private slot handling the HTML5 to JavaScript conversion.
305 """ 314 """
306 from ProjectWeb.Html5ToJsConverter import Html5ToJsConverter 315 from ProjectWeb.Html5ToJsConverter import Html5ToJsConverter
316
307 vm = ericApp().getObject("ViewManager") 317 vm = ericApp().getObject("ViewManager")
308 editor = vm.activeWindow() 318 editor = vm.activeWindow()
309 html = editor.selectedText() 319 html = editor.selectedText()
310 320
311 converter = Html5ToJsConverter(html) 321 converter = Html5ToJsConverter(html)
312 js = converter.getJavaScript() 322 js = converter.getJavaScript()
313 323
314 if js: 324 if js:
315 vm.newEditor() 325 vm.newEditor()
316 newEditor = vm.activeWindow() 326 newEditor = vm.activeWindow()
317 newEditor.setText(js) 327 newEditor.setText(js)
318 newEditor.setLanguage("dummy.js") 328 newEditor.setLanguage("dummy.js")
319 329
320 def __html5Prettify(self): 330 def __html5Prettify(self):
321 """ 331 """
322 Private slot handling the Prettify HTML action. 332 Private slot handling the Prettify HTML action.
323 """ 333 """
324 from ProjectWeb.Html5Prettifier import Html5Prettifier 334 from ProjectWeb.Html5Prettifier import Html5Prettifier
335
325 editor = ericApp().getObject("ViewManager").activeWindow() 336 editor = ericApp().getObject("ViewManager").activeWindow()
326 html = editor.text() 337 html = editor.text()
327 338
328 prettifier = Html5Prettifier(html) 339 prettifier = Html5Prettifier(html)
329 newHtml = prettifier.getPrettifiedHtml() 340 newHtml = prettifier.getPrettifiedHtml()
330 341
331 if newHtml and newHtml != html: 342 if newHtml and newHtml != html:
332 cursorLine, cursorIndex = editor.getCursorPosition() 343 cursorLine, cursorIndex = editor.getCursorPosition()
333 344
334 editor.beginUndoAction() 345 editor.beginUndoAction()
335 editor.selectAll() 346 editor.selectAll()
336 editor.replaceSelectedText(newHtml) 347 editor.replaceSelectedText(newHtml)
337 editor.endUndoAction() 348 editor.endUndoAction()
338 349
339 editor.setCursorPosition(cursorLine, cursorIndex) 350 editor.setCursorPosition(cursorLine, cursorIndex)
340 351
341 352
342 def installDependencies(pipInstall): 353 def installDependencies(pipInstall):
343 """ 354 """
344 Function to install dependencies of this plug-in. 355 Function to install dependencies of this plug-in.
345 356
346 @param pipInstall function to be called with a list of package names. 357 @param pipInstall function to be called with a list of package names.
347 @type function 358 @type function
348 """ 359 """
349 try: 360 try:
350 import bs4 # __IGNORE_WARNING__ 361 import bs4 # __IGNORE_WARNING__
351 except ImportError: 362 except ImportError:
352 pipInstall(["beautifulsoup4"]) 363 pipInstall(["beautifulsoup4"])
353 364
365
354 # 366 #
355 # eflag: noqa = M801 367 # eflag: noqa = M801

eric ide

mercurial