Skip to content

Commit 3b4dfd7

Browse files
committedJun 11, 2013
[FEATURE] [pyqgis-console] Module to generate prepared APIs for calltips and auto-completion
1 parent 3115c30 commit 3b4dfd7

File tree

7 files changed

+376
-92
lines changed

7 files changed

+376
-92
lines changed
 

‎python/console/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SET(PY_CONSOLE_FILES
77
console_settings.py
88
console_output.py
99
console_editor.py
10+
console_compile_apis.py
1011
__init__.py
1112
)
1213

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# -*- coding:utf-8 -*-
2+
"""
3+
/***************************************************************************
4+
Module to generate prepared APIs for calltips and auto-completion.
5+
-------------------
6+
begin : 2012-09-10
7+
copyright : (C) 2012 Larry Shaffer
8+
email : larrys (at) dakotacarto (dot) com
9+
***************************************************************************/
10+
11+
/***************************************************************************
12+
* *
13+
* This program is free software; you can redistribute it and/or modify *
14+
* it under the terms of the GNU General Public License as published by *
15+
* the Free Software Foundation; either version 2 of the License, or *
16+
* (at your option) any later version. *
17+
* *
18+
***************************************************************************/
19+
Portions of this file contain code from Eric4 APIsManager module.
20+
"""
21+
22+
import sys
23+
import os
24+
import shutil
25+
import fnmatch
26+
import glob
27+
28+
from PyQt4.Qsci import *
29+
from PyQt4.QtGui import *
30+
from PyQt4.QtCore import *
31+
32+
from ui_console_compile_apis import Ui_APIsDialogPythonConsole
33+
34+
class PrepareAPIDialog(QDialog):
35+
def __init__(self, api_lexer, api_files, pap_file, parent=None):
36+
QDialog.__init__(self, parent)
37+
self.ui = Ui_APIsDialogPythonConsole()
38+
self.ui.setupUi(self)
39+
self.setWindowTitle(QCoreApplication.translate("PythonConsole","Compile APIs"))
40+
self.ui.plainTextEdit.setVisible(False)
41+
self.ui.textEdit_Qsci.setVisible(False)
42+
self.adjustSize()
43+
self._api = None
44+
self.ui.buttonBox.rejected.connect(self._stopPreparation)
45+
self._api_files = api_files
46+
self._api_lexer = api_lexer
47+
self._pap_file = pap_file
48+
49+
def _clearLexer(self):
50+
# self.ui.textEdit_Qsci.setLexer(0)
51+
self.qlexer = None
52+
53+
def _stopPreparation(self):
54+
if self._api is not None:
55+
self._api.cancelPreparation()
56+
self._api = None
57+
self._clearLexer()
58+
self.close()
59+
60+
def _preparationFinished(self):
61+
self._clearLexer()
62+
if os.path.exists(self._pap_file):
63+
os.remove(self._pap_file)
64+
self.ui.label.setText(QCoreApplication.translate("PythonConsole","Saving prepared file..."))
65+
prepd = self._api.savePrepared(unicode(self._pap_file))
66+
rslt = self.trUtf8("Error")
67+
if prepd:
68+
rslt = QCoreApplication.translate("PythonConsole","Saved")
69+
self.ui.label.setText('{0} {1}'.format(self.ui.label.text(), rslt))
70+
self._api = None
71+
self.ui.progressBar.setVisible(False)
72+
self.ui.buttonBox.button(QDialogButtonBox.Cancel).setText(
73+
QCoreApplication.translate("PythonConsole","Done"))
74+
self.adjustSize()
75+
76+
def prepareAPI(self):
77+
# self.ui.textEdit_Qsci.setLexer(0)
78+
exec 'self.qlexer = {0}(self.ui.textEdit_Qsci)'.format(self._api_lexer)
79+
# self.ui.textEdit_Qsci.setLexer(self.qlexer)
80+
self._api = QsciAPIs(self.qlexer)
81+
self._api.apiPreparationFinished.connect(self._preparationFinished)
82+
for api_file in self._api_files:
83+
self._api.load(unicode(api_file))
84+
try:
85+
self._api.prepare()
86+
except Exception, err:
87+
self._api = None
88+
self._clearLexer()
89+
self.ui.label.setText(QCoreApplication.translate("PythonConsole","Error preparing file..."))
90+
self.ui.progressBar.setVisible(False)
91+
self.ui.plainTextEdit.setVisible(True)
92+
self.ui.plainTextEdit.insertPlainText(err)
93+
self.ui.buttonBox.button(QDialogButtonBox.Cancel).setText(
94+
self.trUtf8("Done"))
95+
self.adjustSize()
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>APIsDialogPythonConsole</class>
4+
<widget class="QDialog" name="APIsDialogPythonConsole">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>320</width>
10+
<height>280</height>
11+
</rect>
12+
</property>
13+
<property name="minimumSize">
14+
<size>
15+
<width>320</width>
16+
<height>0</height>
17+
</size>
18+
</property>
19+
<property name="windowTitle">
20+
<string/>
21+
</property>
22+
<layout class="QVBoxLayout" name="verticalLayout">
23+
<item>
24+
<widget class="QLabel" name="label">
25+
<property name="minimumSize">
26+
<size>
27+
<width>320</width>
28+
<height>0</height>
29+
</size>
30+
</property>
31+
<property name="text">
32+
<string>Generating prepared API file (please wait)...</string>
33+
</property>
34+
</widget>
35+
</item>
36+
<item>
37+
<widget class="QProgressBar" name="progressBar">
38+
<property name="enabled">
39+
<bool>true</bool>
40+
</property>
41+
<property name="maximum">
42+
<number>0</number>
43+
</property>
44+
<property name="value">
45+
<number>-1</number>
46+
</property>
47+
</widget>
48+
</item>
49+
<item>
50+
<widget class="QPlainTextEdit" name="plainTextEdit">
51+
<property name="font">
52+
<font>
53+
<pointsize>12</pointsize>
54+
</font>
55+
</property>
56+
<property name="readOnly">
57+
<bool>true</bool>
58+
</property>
59+
</widget>
60+
</item>
61+
<item>
62+
<widget class="QsciScintilla" name="textEdit_Qsci">
63+
<property name="toolTip">
64+
<string/>
65+
</property>
66+
<property name="whatsThis">
67+
<string/>
68+
</property>
69+
<property name="verticalScrollBarPolicy">
70+
<enum>Qt::ScrollBarAlwaysOff</enum>
71+
</property>
72+
<property name="horizontalScrollBarPolicy">
73+
<enum>Qt::ScrollBarAlwaysOff</enum>
74+
</property>
75+
</widget>
76+
</item>
77+
<item>
78+
<widget class="QDialogButtonBox" name="buttonBox">
79+
<property name="orientation">
80+
<enum>Qt::Horizontal</enum>
81+
</property>
82+
<property name="standardButtons">
83+
<set>QDialogButtonBox::Cancel</set>
84+
</property>
85+
</widget>
86+
</item>
87+
</layout>
88+
</widget>
89+
<customwidgets>
90+
<customwidget>
91+
<class>QsciScintilla</class>
92+
<extends>QFrame</extends>
93+
<header>Qsci/qsciscintilla.h</header>
94+
</customwidget>
95+
</customwidgets>
96+
<resources/>
97+
<connections/>
98+
</ui>

‎python/console/console_editor.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,11 @@ def setLexers(self):
237237

238238
self.api = QsciAPIs(self.lexer)
239239
chekBoxAPI = self.settings.value("pythonConsole/preloadAPI", True, type=bool)
240+
chekBoxPreparedAPI = self.settings.value("pythonConsole/usePreparedAPIFile", False, type=bool)
240241
if chekBoxAPI:
241-
self.api.loadPrepared( QgsApplication.pkgDataPath() + "/python/qsci_apis/pyqgis_master.pap" )
242+
self.api.loadPrepared(QgsApplication.pkgDataPath() + "/python/qsci_apis/pyqgis_master.pap")
243+
elif chekBoxPreparedAPI:
244+
self.api.loadPrepared(self.settings.value("pythonConsole/preparedAPIFile"))
242245
else:
243246
apiPath = self.settings.value("pythonConsole/userAPI")
244247
for i in range(0, len(apiPath)):

‎python/console/console_sci.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,11 @@ def setLexers(self):
189189

190190
self.api = QsciAPIs(self.lexer)
191191
chekBoxAPI = self.settings.value("pythonConsole/preloadAPI", True, type=bool)
192+
chekBoxPreparedAPI = self.settings.value("pythonConsole/usePreparedAPIFile", False, type=bool)
192193
if chekBoxAPI:
193-
self.api.loadPrepared( QgsApplication.pkgDataPath() + "/python/qsci_apis/pyqgis_master.pap" )
194+
self.api.loadPrepared(QgsApplication.pkgDataPath() + "/python/qsci_apis/pyqgis_master.pap")
195+
elif chekBoxPreparedAPI:
196+
self.api.loadPrepared(self.settings.value("pythonConsole/preparedAPIFile"))
194197
else:
195198
apiPath = self.settings.value("pythonConsole/userAPI")
196199
for i in range(0, len(apiPath)):

‎python/console/console_settings.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from PyQt4.QtCore import *
2323
from PyQt4.QtGui import *
24+
from console_compile_apis import PrepareAPIDialog
2425

2526
from ui_console_settings import Ui_SettingsDialogPythonConsole
2627

@@ -32,6 +33,7 @@ def __init__(self, parent):
3233
self.setupUi(self)
3334

3435
self.listPath = []
36+
self.lineEdit.setReadOnly(True)
3537

3638
self.restoreSettings()
3739
self.initialCheck()
@@ -47,6 +49,7 @@ def __init__(self, parent):
4749
SIGNAL("clicked()"), self.loadAPIFile)
4850
self.connect(self.removeAPIpath,
4951
SIGNAL("clicked()"), self.removeAPI)
52+
self.compileAPIs.clicked.connect(self._prepareAPI)
5053

5154
def initialCheck(self):
5255
if self.preloadAPI.isChecked():
@@ -58,6 +61,7 @@ def enableDisable(self, value):
5861
self.tableWidget.setEnabled(value)
5962
self.addAPIpath.setEnabled(value)
6063
self.removeAPIpath.setEnabled(value)
64+
self.groupBoxPreparedAPI.setEnabled(value)
6165

6266
def loadAPIFile(self):
6367
settings = QSettings()
@@ -70,12 +74,41 @@ def loadAPIFile(self):
7074
lastDirPath = QFileInfo(fileAPI).path()
7175
settings.setValue("pythonConsole/lastDirAPIPath", fileAPI)
7276

77+
def _prepareAPI(self):
78+
if self.tableWidget.rowCount() != 0:
79+
pap_file = QFileDialog().getSaveFileName(self,
80+
"",
81+
'*.pap',
82+
"Prepared APIs file (*.pap)")
83+
else:
84+
QMessageBox.information(self, self.tr("Warning!"),
85+
self.tr('You need to add some APIs file in order to compile'))
86+
return
87+
if pap_file:
88+
api_lexer = 'QsciLexerPython'
89+
api_files = []
90+
count = self.tableWidget.rowCount()
91+
for i in range(0, count):
92+
api_files.append(self.tableWidget.item(i, 1).text())
93+
api_dlg = PrepareAPIDialog(api_lexer, api_files, pap_file, self)
94+
api_dlg.show()
95+
api_dlg.activateWindow()
96+
api_dlg.raise_()
97+
api_dlg.prepareAPI()
98+
self.lineEdit.setText(pap_file)
99+
73100
def accept(self):
74-
if not self.preloadAPI.isChecked():
101+
if not self.preloadAPI.isChecked() and \
102+
not self.groupBoxPreparedAPI.isChecked():
75103
if self.tableWidget.rowCount() == 0:
76104
QMessageBox.information(self, self.tr("Warning!"),
77-
self.tr('Please specify API file or check "Use preloaded API files"'))
105+
self.tr('Please specify API file or check "Use preloaded API files"'))
78106
return
107+
if self.groupBoxPreparedAPI.isChecked() and \
108+
not self.lineEdit.text():
109+
QMessageBox.information(self, self.tr("Warning!"),
110+
self.tr('The APIs file was not compiled, click on "Compile APIs..."'))
111+
return
79112
self.saveSettings()
80113
self.listPath = []
81114
QDialog.accept( self )
@@ -122,6 +155,9 @@ def saveSettings(self):
122155
settings.setValue("pythonConsole/autoCompleteEnabledEditor", self.groupBoxAutoCompletionEditor.isChecked())
123156
settings.setValue("pythonConsole/autoCompleteEnabled", self.groupBoxAutoCompletion.isChecked())
124157

158+
settings.setValue("pythonConsole/usePreparedAPIFile", self.groupBoxPreparedAPI.isChecked())
159+
settings.setValue("pythonConsole/preparedAPIFile", self.lineEdit.text())
160+
125161
if self.autoCompFromAPIEditor.isChecked():
126162
settings.setValue("pythonConsole/autoCompleteSourceEditor", 'fromAPI')
127163
elif self.autoCompFromDocEditor.isChecked():
@@ -147,8 +183,9 @@ def restoreSettings(self):
147183
self.fontComboBox.setCurrentFont(QFont(settings.value("pythonConsole/fontfamilytext",
148184
"Monospace")))
149185
self.fontComboBoxEditor.setCurrentFont(QFont(settings.value("pythonConsole/fontfamilytextEditor",
150-
"Monospace")))
186+
"Monospace")))
151187
self.preloadAPI.setChecked(settings.value("pythonConsole/preloadAPI", True, type=bool))
188+
self.lineEdit.setText(settings.value("pythonConsole/preparedAPIFile"))
152189
itemTable = settings.value("pythonConsole/userAPI", [])
153190
if itemTable:
154191
for i in range(len(itemTable)):

‎python/console/console_settings.ui

Lines changed: 134 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
<rect>
1010
<x>0</x>
1111
<y>0</y>
12-
<width>579</width>
13-
<height>563</height>
12+
<width>580</width>
13+
<height>569</height>
1414
</rect>
1515
</property>
1616
<property name="sizePolicy">
@@ -63,7 +63,7 @@
6363
</rect>
6464
</property>
6565
<layout class="QGridLayout" name="gridLayout_2">
66-
<item row="2" column="0">
66+
<item row="1" column="0">
6767
<widget class="QGroupBox" name="groupBox_3">
6868
<property name="title">
6969
<string>Editor</string>
@@ -76,6 +76,91 @@
7676
</property>
7777
</widget>
7878
</item>
79+
<item row="4" column="0">
80+
<widget class="QgsCollapsibleGroupBox" name="groupBoxAutoCompletionEditor">
81+
<property name="title">
82+
<string>Autocompletion</string>
83+
</property>
84+
<property name="checkable">
85+
<bool>true</bool>
86+
</property>
87+
<property name="checked">
88+
<bool>true</bool>
89+
</property>
90+
<property name="collapsed" stdset="0">
91+
<bool>true</bool>
92+
</property>
93+
<property name="saveCheckedState" stdset="0">
94+
<bool>true</bool>
95+
</property>
96+
<property name="saveCollapsedState" stdset="0">
97+
<bool>true</bool>
98+
</property>
99+
<layout class="QGridLayout" name="gridLayout_4">
100+
<item row="1" column="0" colspan="2">
101+
<layout class="QGridLayout" name="layoutRadioButtonEditor">
102+
<item row="0" column="0">
103+
<widget class="QRadioButton" name="autoCompFromDocEditor">
104+
<property name="toolTip">
105+
<string>Get autocompletion from current document</string>
106+
</property>
107+
<property name="text">
108+
<string>from Document</string>
109+
</property>
110+
</widget>
111+
</item>
112+
<item row="0" column="2">
113+
<widget class="QRadioButton" name="autoCompFromDocAPIEditor">
114+
<property name="toolTip">
115+
<string>Get autocompletion from current document and installed APIs</string>
116+
</property>
117+
<property name="text">
118+
<string>from Doc and APIs</string>
119+
</property>
120+
</widget>
121+
</item>
122+
<item row="0" column="1">
123+
<widget class="QRadioButton" name="autoCompFromAPIEditor">
124+
<property name="toolTip">
125+
<string>Get autocompletion from installed APIs</string>
126+
</property>
127+
<property name="text">
128+
<string>from APIs files</string>
129+
</property>
130+
<property name="checked">
131+
<bool>true</bool>
132+
</property>
133+
</widget>
134+
</item>
135+
</layout>
136+
</item>
137+
<item row="0" column="0">
138+
<widget class="QLabel" name="label_2">
139+
<property name="text">
140+
<string>Autocompletion threshold</string>
141+
</property>
142+
</widget>
143+
</item>
144+
<item row="0" column="1">
145+
<widget class="QSpinBox" name="autoCompThresholdEditor">
146+
<property name="maximum">
147+
<number>10</number>
148+
</property>
149+
<property name="value">
150+
<number>2</number>
151+
</property>
152+
</widget>
153+
</item>
154+
</layout>
155+
</widget>
156+
</item>
157+
<item row="5" column="0">
158+
<widget class="QCheckBox" name="autoCloseBracketEditor">
159+
<property name="text">
160+
<string>Automatic parentheses insertion</string>
161+
</property>
162+
</widget>
163+
</item>
79164
<item row="2" column="0">
80165
<layout class="QHBoxLayout" name="horizontalLayout_3">
81166
<item>
@@ -132,81 +217,6 @@
132217
</item>
133218
</layout>
134219
</item>
135-
<item row="4" column="0">
136-
<widget class="QgsCollapsibleGroupBox" name="groupBoxAutoCompletionEditor">
137-
<property name="title">
138-
<string>Autocompletion</string>
139-
</property>
140-
<property name="checkable">
141-
<bool>true</bool>
142-
</property>
143-
<property name="collapsed" stdset="0">
144-
<bool>true</bool>
145-
</property>
146-
<property name="saveCheckedState" stdset="0">
147-
<bool>true</bool>
148-
</property>
149-
<property name="saveCollapsedState" stdset="0">
150-
<bool>true</bool>
151-
</property>
152-
<layout class="QGridLayout" name="gridLayout_4">
153-
<item row="0" column="0">
154-
<widget class="QLabel" name="label_2">
155-
<property name="text">
156-
<string>Autocompletion threshold</string>
157-
</property>
158-
</widget>
159-
</item>
160-
<item row="0" column="1">
161-
<widget class="QSpinBox" name="autoCompThresholdEditor">
162-
<property name="maximum">
163-
<number>10</number>
164-
</property>
165-
<property name="value">
166-
<number>2</number>
167-
</property>
168-
</widget>
169-
</item>
170-
<item row="1" column="0" colspan="2">
171-
<layout class="QGridLayout" name="layoutRadioButtonEditor">
172-
<item row="0" column="0">
173-
<widget class="QRadioButton" name="autoCompFromDocEditor">
174-
<property name="toolTip">
175-
<string>Get autocompletion from current document</string>
176-
</property>
177-
<property name="text">
178-
<string>from Document</string>
179-
</property>
180-
</widget>
181-
</item>
182-
<item row="0" column="1">
183-
<widget class="QRadioButton" name="autoCompFromAPIEditor">
184-
<property name="toolTip">
185-
<string>Get autocompletion from installed APIs</string>
186-
</property>
187-
<property name="text">
188-
<string>from APIs files</string>
189-
</property>
190-
<property name="checked">
191-
<bool>true</bool>
192-
</property>
193-
</widget>
194-
</item>
195-
<item row="0" column="2">
196-
<widget class="QRadioButton" name="autoCompFromDocAPIEditor">
197-
<property name="toolTip">
198-
<string>Get autocompletion from current document and installed APIs</string>
199-
</property>
200-
<property name="text">
201-
<string>from Doc and APIs</string>
202-
</property>
203-
</widget>
204-
</item>
205-
</layout>
206-
</item>
207-
</layout>
208-
</widget>
209-
</item>
210220
<item row="0" column="0">
211221
<widget class="QCheckBox" name="enableObjectInspector">
212222
<property name="text">
@@ -217,13 +227,6 @@
217227
</property>
218228
</widget>
219229
</item>
220-
<item row="5" column="0">
221-
<widget class="QCheckBox" name="autoCloseBracketEditor">
222-
<property name="text">
223-
<string>Automatic parentheses insertion</string>
224-
</property>
225-
</widget>
226-
</item>
227230
</layout>
228231
</widget>
229232
</item>
@@ -304,6 +307,9 @@
304307
<property name="checkable">
305308
<bool>true</bool>
306309
</property>
310+
<property name="checked">
311+
<bool>true</bool>
312+
</property>
307313
<property name="collapsed" stdset="0">
308314
<bool>false</bool>
309315
</property>
@@ -374,12 +380,12 @@
374380
</layout>
375381
</widget>
376382
</item>
377-
<item row="4" column="0">
383+
<item row="2" column="0">
378384
<widget class="QGroupBox" name="groupBox_2">
379385
<property name="title">
380386
<string>APIs</string>
381387
</property>
382-
<layout class="QGridLayout" name="gridLayout_3">
388+
<layout class="QGridLayout" name="gridLayout_7">
383389
<item row="0" column="0">
384390
<widget class="QCheckBox" name="preloadAPI">
385391
<property name="text">
@@ -523,6 +529,47 @@
523529
</item>
524530
</layout>
525531
</item>
532+
<item row="2" column="0">
533+
<widget class="QgsCollapsibleGroupBox" name="groupBoxPreparedAPI">
534+
<property name="title">
535+
<string>Using prepared APIs file</string>
536+
</property>
537+
<property name="checkable">
538+
<bool>true</bool>
539+
</property>
540+
<property name="checked">
541+
<bool>false</bool>
542+
</property>
543+
<property name="collapsed" stdset="0">
544+
<bool>true</bool>
545+
</property>
546+
<property name="saveCollapsedState" stdset="0">
547+
<bool>true</bool>
548+
</property>
549+
<property name="saveCheckedState" stdset="0">
550+
<bool>true</bool>
551+
</property>
552+
<layout class="QGridLayout" name="gridLayout_3">
553+
<item row="0" column="0">
554+
<widget class="QPushButton" name="compileAPIs">
555+
<property name="text">
556+
<string>Compile APIs...</string>
557+
</property>
558+
</widget>
559+
</item>
560+
<item row="0" column="1">
561+
<widget class="QLineEdit" name="lineEdit">
562+
<property name="minimumSize">
563+
<size>
564+
<width>0</width>
565+
<height>27</height>
566+
</size>
567+
</property>
568+
</widget>
569+
</item>
570+
</layout>
571+
</widget>
572+
</item>
526573
</layout>
527574
</widget>
528575
</item>

0 commit comments

Comments
 (0)
Please sign in to comment.