eric6/Preferences/ConfigurationPages/EditorAPIsPage.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7164
6da6a0a5a448
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2006 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the Editor APIs configuration page.
8 """
9
10 from __future__ import unicode_literals
11
12 from PyQt5.QtCore import QDir, pyqtSlot, QFileInfo
13 from PyQt5.QtWidgets import QInputDialog
14
15 from E5Gui.E5Application import e5App
16 from E5Gui import E5MessageBox
17 from E5Gui.E5PathPicker import E5PathPickerModes
18
19 from .ConfigurationPageBase import ConfigurationPageBase
20 from .Ui_EditorAPIsPage import Ui_EditorAPIsPage
21
22 import Preferences
23 import Utilities
24
25
26 class EditorAPIsPage(ConfigurationPageBase, Ui_EditorAPIsPage):
27 """
28 Class implementing the Editor APIs configuration page.
29 """
30 def __init__(self):
31 """
32 Constructor
33 """
34 super(EditorAPIsPage, self).__init__()
35 self.setupUi(self)
36 self.setObjectName("EditorAPIsPage")
37
38 self.apiFilePicker.setMode(E5PathPickerModes.OpenFileMode)
39 self.apiFilePicker.setToolTip(self.tr(
40 "Press to select an API file via a selection dialog"))
41 self.apiFilePicker.setFilters(self.tr(
42 "API File (*.api);;All Files (*)"))
43
44 self.prepareApiButton.setText(self.tr("Compile APIs"))
45 self.__currentAPI = None
46 self.__inPreparation = False
47
48 # set initial values
49 self.pluginManager = e5App().getObject("PluginManager")
50 self.apiAutoPrepareCheckBox.setChecked(
51 Preferences.getEditor("AutoPrepareAPIs"))
52
53 import QScintilla.Lexers
54 self.apis = {}
55 apiLanguages = sorted(
56 [''] + list(QScintilla.Lexers.getSupportedApiLanguages()))
57 for lang in apiLanguages:
58 self.apiLanguageComboBox.addItem(
59 QScintilla.Lexers.getLanguageIcon(lang, False),
60 lang)
61 apiProjectTypes = sorted(
62 [("", "")] +
63 [(trans, ptype) for ptype, trans in
64 e5App().getObject("Project").getProjectTypes().items()
65 ]
66 )
67 for projectTypeStr, projectType in apiProjectTypes:
68 self.projectTypeComboBox.addItem(projectTypeStr, projectType)
69 self.__currentApiLanguage = ""
70 self.__currentApiProjectTypeIndex = 0
71 self.__currentApiProjectType = ""
72 self.on_apiLanguageComboBox_activated(self.__currentApiLanguage)
73 self.on_projectTypeComboBox_activated(
74 self.__currentApiProjectTypeIndex)
75
76 def __apiKey(self, language, projectType):
77 """
78 Private method to generate a key for the apis dictionary.
79
80 @param language programming language of the API
81 @type str
82 @param projectType project type of the API
83 @type str
84 @return key to be used
85 @rtype str
86 """
87 if projectType:
88 key = (language, projectType)
89 else:
90 key = (language, "")
91 return key
92
93 def save(self):
94 """
95 Public slot to save the Editor APIs configuration.
96 """
97 Preferences.setEditor(
98 "AutoPrepareAPIs",
99 self.apiAutoPrepareCheckBox.isChecked())
100
101 language = self.apiLanguageComboBox.currentText()
102 projectType = self.projectTypeComboBox.itemData(
103 self.projectTypeComboBox.currentIndex())
104 key = self.__apiKey(language, projectType)
105 self.apis[key] = self.__editorGetApisFromApiList()
106
107 for (language, projectType), apis in self.apis.items():
108 Preferences.setEditorAPI(language, projectType, apis)
109
110 @pyqtSlot(int)
111 def on_projectTypeComboBox_activated(self, index):
112 """
113 Private slot to handle the selection of a project type.
114
115 @param index index of the selected entry
116 @type str
117 """
118 if self.__currentApiProjectTypeIndex == index:
119 return
120
121 self.__currentApiProjectTypeIndex = index
122 self.__fillApisList()
123
124 @pyqtSlot(str)
125 def on_apiLanguageComboBox_activated(self, language):
126 """
127 Private slot to fill the api listbox of the api page.
128
129 @param language selected API language (string)
130 """
131 if self.__currentApiLanguage == language:
132 return
133
134 self.__fillApisList()
135
136 def __fillApisList(self):
137 """
138 Private slot to fill the list of API files.
139 """
140 self.apis[self.__apiKey(self.__currentApiLanguage,
141 self.__currentApiProjectType)] = \
142 self.__editorGetApisFromApiList()
143
144 self.__currentApiLanguage = self.apiLanguageComboBox.currentText()
145 self.__currentApiProjectType = self.projectTypeComboBox.itemData(
146 self.projectTypeComboBox.currentIndex())
147 self.apiList.clear()
148
149 if not self.__currentApiLanguage:
150 self.apiGroup.setEnabled(False)
151 return
152
153 self.apiGroup.setEnabled(True)
154 self.deleteApiFileButton.setEnabled(False)
155 self.addApiFileButton.setEnabled(False)
156 self.apiFilePicker.clear()
157
158 key = self.__apiKey(self.__currentApiLanguage,
159 self.__currentApiProjectType)
160 if key not in self.apis:
161 # populate on demand
162 self.apis[key] = Preferences.getEditorAPI(
163 self.__currentApiLanguage,
164 projectType=self.__currentApiProjectType)[:]
165 for api in self.apis[key]:
166 if api:
167 self.apiList.addItem(api)
168 self.prepareApiButton.setEnabled(self.apiList.count() > 0)
169
170 from QScintilla.APIsManager import APIsManager
171 self.__currentAPI = APIsManager().getAPIs(
172 self.__currentApiLanguage,
173 projectType=self.__currentApiProjectType)
174 if self.__currentAPI is not None:
175 self.__currentAPI.apiPreparationFinished.connect(
176 self.__apiPreparationFinished)
177 self.__currentAPI.apiPreparationCancelled.connect(
178 self.__apiPreparationCancelled)
179 self.__currentAPI.apiPreparationStarted.connect(
180 self.__apiPreparationStarted)
181 self.addInstalledApiFileButton.setEnabled(
182 len(self.__currentAPI.installedAPIFiles()) > 0)
183 else:
184 self.addInstalledApiFileButton.setEnabled(False)
185
186 self.addPluginApiFileButton.setEnabled(
187 len(self.pluginManager.getPluginApiFiles(
188 self.__currentApiLanguage)) > 0)
189
190 def __editorGetApisFromApiList(self):
191 """
192 Private slot to retrieve the api filenames from the list.
193
194 @return list of api filenames (list of strings)
195 """
196 apis = []
197 for row in range(self.apiList.count()):
198 apis.append(self.apiList.item(row).text())
199 return apis
200
201 @pyqtSlot()
202 def on_addApiFileButton_clicked(self):
203 """
204 Private slot to add the api file displayed to the listbox.
205 """
206 file = self.apiFilePicker.text()
207 if file:
208 self.apiList.addItem(Utilities.toNativeSeparators(file))
209 self.apiFilePicker.clear()
210 self.prepareApiButton.setEnabled(self.apiList.count() > 0)
211
212 @pyqtSlot()
213 def on_deleteApiFileButton_clicked(self):
214 """
215 Private slot to delete the currently selected file of the listbox.
216 """
217 crow = self.apiList.currentRow()
218 if crow >= 0:
219 itm = self.apiList.takeItem(crow) # __IGNORE_WARNING__
220 del itm
221 self.prepareApiButton.setEnabled(self.apiList.count() > 0)
222
223 @pyqtSlot()
224 def on_addInstalledApiFileButton_clicked(self):
225 """
226 Private slot to add an API file from the list of installed API files
227 for the selected lexer language.
228 """
229 installedAPIFiles = self.__currentAPI.installedAPIFiles()
230 if installedAPIFiles:
231 installedAPIFilesPath = QFileInfo(installedAPIFiles[0]).path()
232 installedAPIFilesShort = []
233 for installedAPIFile in installedAPIFiles:
234 installedAPIFilesShort.append(
235 QFileInfo(installedAPIFile).fileName())
236 file, ok = QInputDialog.getItem(
237 self,
238 self.tr("Add from installed APIs"),
239 self.tr("Select from the list of installed API files"),
240 installedAPIFilesShort,
241 0, False)
242 if ok:
243 self.apiList.addItem(Utilities.toNativeSeparators(
244 QFileInfo(QDir(installedAPIFilesPath), file)
245 .absoluteFilePath()))
246 else:
247 E5MessageBox.warning(
248 self,
249 self.tr("Add from installed APIs"),
250 self.tr("""There are no APIs installed yet."""
251 """ Selection is not available."""))
252 self.addInstalledApiFileButton.setEnabled(False)
253 self.prepareApiButton.setEnabled(self.apiList.count() > 0)
254
255 @pyqtSlot()
256 def on_addPluginApiFileButton_clicked(self):
257 """
258 Private slot to add an API file from the list of API files installed
259 by plugins for the selected lexer language.
260 """
261 pluginAPIFiles = self.pluginManager.getPluginApiFiles(
262 self.__currentApiLanguage)
263 pluginAPIFilesDict = {}
264 for apiFile in pluginAPIFiles:
265 pluginAPIFilesDict[QFileInfo(apiFile).fileName()] = apiFile
266 file, ok = QInputDialog.getItem(
267 self,
268 self.tr("Add from Plugin APIs"),
269 self.tr(
270 "Select from the list of API files installed by plugins"),
271 sorted(pluginAPIFilesDict.keys()),
272 0, False)
273 if ok:
274 self.apiList.addItem(Utilities.toNativeSeparators(
275 pluginAPIFilesDict[file]))
276 self.prepareApiButton.setEnabled(self.apiList.count() > 0)
277
278 @pyqtSlot()
279 def on_prepareApiButton_clicked(self):
280 """
281 Private slot to prepare the API file for the currently selected
282 language.
283 """
284 if self.__inPreparation:
285 self.__currentAPI and self.__currentAPI.cancelPreparation()
286 else:
287 if self.__currentAPI is not None:
288 self.__currentAPI.prepareAPIs(
289 ondemand=True,
290 rawList=self.__editorGetApisFromApiList())
291
292 def __apiPreparationFinished(self):
293 """
294 Private method called after the API preparation has finished.
295 """
296 self.prepareApiProgressBar.reset()
297 self.prepareApiProgressBar.setRange(0, 100)
298 self.prepareApiProgressBar.setValue(0)
299 self.prepareApiButton.setText(self.tr("Compile APIs"))
300 self.__inPreparation = False
301
302 def __apiPreparationCancelled(self):
303 """
304 Private slot called after the API preparation has been cancelled.
305 """
306 self.__apiPreparationFinished()
307
308 def __apiPreparationStarted(self):
309 """
310 Private method called after the API preparation has started.
311 """
312 self.prepareApiProgressBar.setRange(0, 0)
313 self.prepareApiProgressBar.setValue(0)
314 self.prepareApiButton.setText(self.tr("Cancel compilation"))
315 self.__inPreparation = True
316
317 def saveState(self):
318 """
319 Public method to save the current state of the widget.
320
321 @return tuple containing the index of the selected lexer language
322 and the index of the selected project type
323 @rtype tuple of int and int
324 """
325 return (
326 self.apiLanguageComboBox.currentIndex(),
327 self.projectTypeComboBox.currentIndex()
328 )
329
330 def setState(self, state):
331 """
332 Public method to set the state of the widget.
333
334 @param state state data generated by saveState
335 """
336 self.apiLanguageComboBox.setCurrentIndex(state[0])
337 self.projectTypeComboBox.setCurrentIndex(state[1])
338 self.on_apiLanguageComboBox_activated(
339 self.apiLanguageComboBox.currentText())
340 self.on_projectTypeComboBox_activated(state[1])
341
342 @pyqtSlot()
343 def on_apiList_itemSelectionChanged(self):
344 """
345 Private slot to react on changes of API selections.
346 """
347 self.deleteApiFileButton.setEnabled(
348 len(self.apiList.selectedItems()) > 0)
349
350 @pyqtSlot(str)
351 def on_apiFilePicker_textChanged(self, txt):
352 """
353 Private slot to handle the entering of an API file name.
354
355 @param txt text of the line edit (string)
356 """
357 enable = txt != ""
358
359 if enable:
360 # check for already added file
361 for row in range(self.apiList.count()):
362 if txt == self.apiList.item(row).text():
363 enable = False
364 break
365
366 self.addApiFileButton.setEnabled(enable)
367
368
369 def create(dlg):
370 """
371 Module function to create the configuration page.
372
373 @param dlg reference to the configuration dialog
374 @return reference to the instantiated page (ConfigurationPageBase)
375 """
376 page = EditorAPIsPage()
377 return page

eric ide

mercurial