1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4#
5
6"""
7Module implementing the Ericapi plugin.
8"""
9
10import os
11
12from PyQt5.QtCore import QObject, QCoreApplication
13from PyQt5.QtWidgets import QDialog
14
15from E5Gui.E5Application import e5App
16
17from E5Gui.E5Action import E5Action
18
19import Utilities
20import UI.Info
21
22from eric6config import getConfig
23
24# Start-Of-Header
25name = "Ericapi Plugin"
26author = "Detlev Offenbach <detlev@die-offenbachs.de>"
27autoactivate = True
28deactivateable = True
29version = UI.Info.VersionOnly
30className = "EricapiPlugin"
31packageName = "__core__"
32shortDescription = "Show the Ericapi dialogs."
33longDescription = (
34    """This plugin implements the Ericapi dialogs."""
35    """ Ericapi is used to generate a QScintilla API file for Python and"""
36    """ Ruby projects."""
37)
38pyqtApi = 2
39# End-Of-Header
40
41error = ""
42
43
44def exeDisplayData():
45    """
46    Public method to support the display of some executable info.
47
48    @return dictionary containing the data to query the presence of
49        the executable
50    """
51    exe = 'eric6_api'
52    if Utilities.isWindowsPlatform():
53        exe = os.path.join(getConfig("bindir"), exe + '.cmd')
54        if not os.path.exists(exe):
55            exe = os.path.join(getConfig("bindir"), exe + '.bat')
56    else:
57        exe = os.path.join(getConfig("bindir"), exe)
58
59    data = {
60        "programEntry": True,
61        "header": QCoreApplication.translate(
62            "EricapiPlugin", "eric API File Generator"),
63        "exe": exe,
64        "versionCommand": '--version',
65        "versionStartsWith": 'eric6_',
66        "versionPosition": -3,
67        "version": "",
68        "versionCleanup": None,
69    }
70
71    return data
72
73
74class EricapiPlugin(QObject):
75    """
76    Class implementing the Ericapi plugin.
77    """
78    def __init__(self, ui):
79        """
80        Constructor
81
82        @param ui reference to the user interface object (UI.UserInterface)
83        """
84        super().__init__(ui)
85        self.__ui = ui
86        self.__initialize()
87
88    def __initialize(self):
89        """
90        Private slot to (re)initialize the plugin.
91        """
92        self.__projectAct = None
93
94    def activate(self):
95        """
96        Public method to activate this plugin.
97
98        @return tuple of None and activation status (boolean)
99        """
100        menu = e5App().getObject("Project").getMenu("Apidoc")
101        if menu:
102            self.__projectAct = E5Action(
103                self.tr('Generate API file (eric6_api)'),
104                self.tr('Generate &API file (eric6_api)'), 0, 0,
105                self, 'doc_eric6_api')
106            self.__projectAct.setStatusTip(self.tr(
107                'Generate an API file using eric6_api'))
108            self.__projectAct.setWhatsThis(self.tr(
109                """<b>Generate API file</b>"""
110                """<p>Generate an API file using eric6_api.</p>"""
111            ))
112            self.__projectAct.triggered.connect(self.__doEricapi)
113            e5App().getObject("Project").addE5Actions([self.__projectAct])
114            menu.addAction(self.__projectAct)
115
116        e5App().getObject("Project").showMenu.connect(self.__projectShowMenu)
117
118        return None, True
119
120    def deactivate(self):
121        """
122        Public method to deactivate this plugin.
123        """
124        e5App().getObject("Project").showMenu.disconnect(
125            self.__projectShowMenu)
126
127        menu = e5App().getObject("Project").getMenu("Apidoc")
128        if menu:
129            menu.removeAction(self.__projectAct)
130            e5App().getObject("Project").removeE5Actions([self.__projectAct])
131        self.__initialize()
132
133    def __projectShowMenu(self, menuName, menu):
134        """
135        Private slot called, when the the project menu or a submenu is
136        about to be shown.
137
138        @param menuName name of the menu to be shown (string)
139        @param menu reference to the menu (QMenu)
140        """
141        if menuName == "Apidoc" and self.__projectAct is not None:
142            self.__projectAct.setEnabled(
143                e5App().getObject("Project").getProjectLanguage() in
144                ["Python", "Python3", "Ruby", "MicroPython"])
145
146    def __doEricapi(self):
147        """
148        Private slot to perform the eric6_api api generation.
149        """
150        from DocumentationPlugins.Ericapi.EricapiConfigDialog import (
151            EricapiConfigDialog
152        )
153        eolTranslation = {
154            '\r': 'cr',
155            '\n': 'lf',
156            '\r\n': 'crlf',
157        }
158        project = e5App().getObject("Project")
159        parms = project.getData('DOCUMENTATIONPARMS', "ERIC4API")
160        dlg = EricapiConfigDialog(project, parms)
161        if dlg.exec() == QDialog.DialogCode.Accepted:
162            args, parms = dlg.generateParameters()
163            project.setData('DOCUMENTATIONPARMS', "ERIC4API", parms)
164
165            # add parameter for the eol setting
166            if not project.useSystemEol():
167                args.append(
168                    "--eol={0}".format(eolTranslation[project.getEolString()]))
169
170            # now do the call
171            from DocumentationPlugins.Ericapi.EricapiExecDialog import (
172                EricapiExecDialog
173            )
174            dia = EricapiExecDialog("Ericapi")
175            res = dia.start(args, project.ppath)
176            if res:
177                dia.exec()
178
179            outputFileName = Utilities.toNativeSeparators(parms['outputFile'])
180
181            # add output files to the project data, if they aren't in already
182            for progLanguage in parms['languages']:
183                if "%L" in outputFileName:
184                    outfile = outputFileName.replace("%L", progLanguage)
185                else:
186                    if len(parms['languages']) == 1:
187                        outfile = outputFileName
188                    else:
189                        root, ext = os.path.splitext(outputFileName)
190                        outfile = "{0}-{1}{2}".format(
191                            root, progLanguage.lower(), ext)
192
193                outfile = project.getRelativePath(outfile)
194                if outfile not in project.pdata['OTHERS']:
195                    project.pdata['OTHERS'].append(outfile)
196                    project.setDirty(True)
197                    project.othersAdded(outfile)
198