--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PluginProjectWeb.py Wed Dec 31 19:14:36 2014 +0100 @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the Web project plugin. +""" + +from __future__ import unicode_literals + +import os + +from PyQt5.QtCore import QObject, QTranslator +from PyQt5.QtWidgets import QMenu + +from E5Gui.E5Application import e5App + +import Preferences + +try: + from bs4 import BeautifulSoup # __IGNORE_EXCEPTION__ + BeautifulSoupAvailable = True +except ImportError: + BeautifulSoup = None + BeautifulSoupAvailable = False + +# Start-Of-Header +name = "PluginProjectWeb" +author = "Detlev Offenbach <detlev@die-offenbachs.de>" +autoactivate = True +deactivateable = True +version = "0.1.0" +className = "ProjectWebPlugin" +packageName = "ProjectWeb" +shortDescription = "Support for Web projects and web related tools." +longDescription = ( + """This plug-in provides support for ordinary web projects and some web""" + """ related tools.\n\nIt requires BeautifulSoup4 for some of its""" + """ functionality.""" +) +needsRestart = False +pyqtApi = 2 +python2Compatible = True +# End-Of-Header + +error = "" + + +class ProjectWebPlugin(QObject): + """ + Class implementing the Web project plugin. + """ + def __init__(self, ui): + """ + Constructor + + @param ui reference to the user interface object (UI.UserInterface) + """ + super(ProjectWebPlugin, self).__init__(ui) + self.__ui = ui + self.__initialize() + + self.__translator = None + self.__loadTranslator() + + self.__initMenu() + + def __initialize(self): + """ + Private slot to (re)initialize the plugin. + """ + self.__e5project = e5App().getObject("Project") + + self.__editors = {} + + def activate(self): + """ + Public method to activate this plugin. + + @return tuple of None and activation status (boolean) + """ + global error + error = "" # clear previous error + + if self.__ui.versionIsNewer('6.0.0', '20141229'): + self.__e5project.registerProjectType( + "Web", self.tr("Web"), + self.fileTypesCallback, progLanguages=["JavaScript"]) + else: + self.__e5project.registerProjectType( + "Web", self.tr("Web"), + self.fileTypesCallback) + + from Project.ProjectBrowser import SourcesBrowserFlag, \ + FormsBrowserFlag, OthersBrowserFlag + Preferences.setProjectBrowserFlagsDefault( + "Web", + SourcesBrowserFlag | FormsBrowserFlag | OthersBrowserFlag, + ) + + self.__ui.showMenu.connect(self.__populateMenu) + + e5App().getObject("ViewManager").editorOpenedEd.connect( + self.__editorOpened) + e5App().getObject("ViewManager").editorClosedEd.connect( + self.__editorClosed) + + for editor in e5App().getObject("ViewManager").getOpenEditors(): + self.__editorOpened(editor) + + return None, True + + def deactivate(self): + """ + Public method to deactivate this plugin. + """ + self.__e5project.unregisterProjectType("Django") + + self.__ui.showMenu.disconnect(self.__populateMenu) + + e5App().getObject("ViewManager").editorOpenedEd.disconnect( + self.__editorOpened) + e5App().getObject("ViewManager").editorClosedEd.disconnect( + self.__editorClosed) + + for editor, acts in self.__editors.items(): +## editor.showMenu.disconnect(self.__editorShowMenu) + menu = editor.getMenu("Tools") + if menu is not None: + for act in acts: + menu.removeAction(act) + + self.__initialize() + + def __loadTranslator(self): + """ + Private method to load the translation file. + """ + if self.__ui is not None: + loc = self.__ui.getLocale() + if loc and loc != "C": + locale_dir = os.path.join( + os.path.dirname(__file__), "ProjectWeb", "i18n") + translation = "web_%s" % loc + translator = QTranslator(None) + loaded = translator.load(translation, locale_dir) + if loaded: + self.__translator = translator + e5App().installTranslator(self.__translator) + else: + print("Warning: translation file '{0}' could not be" + " loaded.".format(translation)) + print("Using default.") + + def fileTypesCallback(self): + """ + Public method to get the filetype associations of the Web project type. + + @return dictionary with file type associations + """ + if self.__e5project.getProjectType() == "Web": + fileTypes = { + "*.html": "FORMS", + "*.htm": "FORMS", + "*.js": "SOURCES", + } + else: + fileTypes = {} + return fileTypes + + def __initMenu(self): + """ + Private method to initialize the web tools menu. + """ + self.__menu = QMenu(self.tr("Web")) + + # TODO: add our actions here + self.__html5ToCss3Act = self.__menu.addAction(self.tr( + "HTML5 to CSS3"), self.__htm5ToCss3) + + self.__menu.aboutToShow.connect(self.__menuAboutToShow) + + def __menuAboutToShow(self): + """ + Private slot to prepare the menu before it is shown. + """ + editor = e5App().getObject("ViewManager").activeWindow() + selectionAvailable = bool(editor and editor.selectedText() != "") + + self.__html5ToCss3Act.setEnabled( + selectionAvailable and BeautifulSoupAvailable) + + def __populateMenu(self, name, menu): + """ + Private slot to populate the tools menu with our entries. + + @param name name of the menu (string) + @param menu reference to the menu to be populated (QMenu) + """ + if name != "Tools": + return + +## editor = e5App().getObject("ViewManager").activeWindow() +## + if not menu.isEmpty(): + menu.addSeparator() + + act = menu.addMenu(self.__menu) + # TODO: check this +## act.setEnabled(editor is not None and editor.selectedText() != '') + + def __editorOpened(self, editor): + """ + Private slot called, when a new editor was opened. + + @param editor reference to the new editor (QScintilla.Editor) + """ + menu = editor.getMenu("Tools") + if menu is not None: + self.__editors[editor] = [] + if not menu.isEmpty(): + act = menu.addSeparator() + self.__editors[editor].append(act) + act = menu.addMenu(self.__menu) + self.__editors[editor].append(act) +## editor.showMenu.connect(self.__editorShowMenu) + + def __editorClosed(self, editor): + """ + Private slot called, when an editor was closed. + + @param editor reference to the editor (QScintilla.Editor) + """ + try: + del self.__editors[editor] + except KeyError: + pass + +## def __editorShowMenu(self, menuName, menu, editor): +## """ +## Private slot called, when the the editor context menu or a submenu is +## about to be shown. +## +## @param menuName name of the menu to be shown (string) +## @param menu reference to the menu (QMenu) +## @param editor reference to the editor +## """ +## if menuName == "Tools": +## # TODO: check this +## self.__menu.setEnabled(editor.selectedText() != '') +## + def __htm5ToCss3(self): + """ + Private slot handling the HTML5 to CSS3 conversion. + """ + # TODO: implement this + from ProjectWeb.Html5ToCss3Converter import Html5ToCss3Converter + vm = e5App().getObject("ViewManager") + editor = vm.activeWindow() + html = editor.selectedText() + + converter = Html5ToCss3Converter(html) + + css3 = converter.getCss3() + + if css3: + vm.newEditor() + newEditor = vm.activeWindow() + newEditor.setText(css3) + newEditor.setLanguage("dummy.css")