mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
[pyqgis-console] uses context menu to handle the command history instead of typing directly the command into the console
- shows history in dialog (much more usable)
This commit is contained in:
parent
eafe5281c1
commit
b805894564
102
python/console/console_history_dlg.ui
Normal file
102
python/console/console_history_dlg.ui
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>HistoryDialog</class>
|
||||||
|
<widget class="QDialog" name="HistoryDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>587</width>
|
||||||
|
<height>375</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Close</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QPushButton" name="reloadHistory">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reload</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QListView" name="listView">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="showDropIndicator" stdset="0">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>HistoryDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>HistoryDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -31,6 +31,7 @@ import os
|
|||||||
import code
|
import code
|
||||||
|
|
||||||
from qgis.core import QgsApplication
|
from qgis.core import QgsApplication
|
||||||
|
from ui_console_history_dlg import Ui_HistoryDialog
|
||||||
|
|
||||||
_init_commands = ["from qgis.core import *", "import qgis.utils",
|
_init_commands = ["from qgis.core import *", "import qgis.utils",
|
||||||
"from qgis.utils import iface"]
|
"from qgis.utils import iface"]
|
||||||
@ -69,6 +70,8 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
# Read history command file
|
# Read history command file
|
||||||
self.readHistoryFile()
|
self.readHistoryFile()
|
||||||
|
|
||||||
|
self.historyDlg = HistoryDialog(self)
|
||||||
|
|
||||||
# Brace matching: enable for a brace immediately before or after
|
# Brace matching: enable for a brace immediately before or after
|
||||||
# the current position
|
# the current position
|
||||||
self.setBraceMatching(QsciScintilla.SloppyBraceMatch)
|
self.setBraceMatching(QsciScintilla.SloppyBraceMatch)
|
||||||
@ -107,8 +110,6 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
self.newShortcutCAS.setContext(Qt.WidgetShortcut)
|
self.newShortcutCAS.setContext(Qt.WidgetShortcut)
|
||||||
self.newShortcutCAS.activated.connect(self.autoCompleteKeyBinding)
|
self.newShortcutCAS.activated.connect(self.autoCompleteKeyBinding)
|
||||||
self.newShortcutCSS.activated.connect(self.showHistory)
|
self.newShortcutCSS.activated.connect(self.showHistory)
|
||||||
self.connect(self, SIGNAL('userListActivated(int, const QString)'),
|
|
||||||
self.completion_list_selected)
|
|
||||||
|
|
||||||
def settingsShell(self):
|
def settingsShell(self):
|
||||||
# Set Python lexer
|
# Set Python lexer
|
||||||
@ -129,7 +130,10 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
self.setAutoCompletionSource(self.AcsNone)
|
self.setAutoCompletionSource(self.AcsNone)
|
||||||
|
|
||||||
def showHistory(self):
|
def showHistory(self):
|
||||||
self.showUserList(1, QStringList(self.history))
|
if not self.historyDlg.isVisible():
|
||||||
|
self.historyDlg.show()
|
||||||
|
self.historyDlg._reloadHistory()
|
||||||
|
self.historyDlg.activateWindow()
|
||||||
|
|
||||||
def autoCompleteKeyBinding(self):
|
def autoCompleteKeyBinding(self):
|
||||||
radioButtonSource = self.settings.value("pythonConsole/autoCompleteSource").toString()
|
radioButtonSource = self.settings.value("pythonConsole/autoCompleteSource").toString()
|
||||||
@ -199,17 +203,6 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
|
|
||||||
## TODO: show completion list for file and directory
|
## TODO: show completion list for file and directory
|
||||||
|
|
||||||
def completion_list_selected(self, id, txt):
|
|
||||||
if id == 1:
|
|
||||||
txt = unicode(txt)
|
|
||||||
# get current cursor position
|
|
||||||
line, pos = self.getCursorPosition()
|
|
||||||
selCmdLength = self.text(line).length()
|
|
||||||
# select typed text
|
|
||||||
self.setSelection(line, 4, line, selCmdLength)
|
|
||||||
self.removeSelectedText()
|
|
||||||
self.insert(txt)
|
|
||||||
|
|
||||||
def getText(self):
|
def getText(self):
|
||||||
""" Get the text as a unicode string. """
|
""" Get the text as a unicode string. """
|
||||||
value = self.getBytes().decode('utf-8')
|
value = self.getBytes().decode('utf-8')
|
||||||
@ -245,11 +238,6 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
self.ensureCursorVisible()
|
self.ensureCursorVisible()
|
||||||
self.ensureLineVisible(line)
|
self.ensureLineVisible(line)
|
||||||
|
|
||||||
#def on_new_line(self):
|
|
||||||
#"""On new input line"""
|
|
||||||
#self.move_cursor_to_end()
|
|
||||||
#self.new_input_line = False
|
|
||||||
|
|
||||||
def is_cursor_on_last_line(self):
|
def is_cursor_on_last_line(self):
|
||||||
"""Return True if cursor is on the last line"""
|
"""Return True if cursor is on the last line"""
|
||||||
cline, _ = self.getCursorPosition()
|
cline, _ = self.getCursorPosition()
|
||||||
@ -285,10 +273,19 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
self.historyIndex = len(self.history)
|
self.historyIndex = len(self.history)
|
||||||
|
|
||||||
def writeHistoryFile(self):
|
def writeHistoryFile(self):
|
||||||
wH = open(_historyFile, 'w')
|
ok = False
|
||||||
for s in self.history:
|
try:
|
||||||
wH.write(s + '\n')
|
wH = open(_historyFile, 'w')
|
||||||
|
for s in self.history:
|
||||||
|
wH.write(s + '\n')
|
||||||
|
ok = True
|
||||||
|
except:
|
||||||
|
raise
|
||||||
wH.close()
|
wH.close()
|
||||||
|
if ok:
|
||||||
|
msgText = QCoreApplication.translate('PythonConsole',
|
||||||
|
'History saved successfully.')
|
||||||
|
self.parent.callWidgetMessageBar(msgText)
|
||||||
|
|
||||||
def readHistoryFile(self):
|
def readHistoryFile(self):
|
||||||
fileExist = QFile.exists(_historyFile)
|
fileExist = QFile.exists(_historyFile)
|
||||||
@ -301,9 +298,27 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
def clearHistoryFile(self):
|
def clearHistory(self, clearSession=False):
|
||||||
cH = open(_historyFile, 'w')
|
if clearSession:
|
||||||
|
self.history = QStringList()
|
||||||
|
msgText = QCoreApplication.translate('PythonConsole',
|
||||||
|
'Session and file history cleared successfully.')
|
||||||
|
self.parent.callWidgetMessageBar(msgText)
|
||||||
|
return
|
||||||
|
ok = False
|
||||||
|
try:
|
||||||
|
cH = open(_historyFile, 'w')
|
||||||
|
ok = True
|
||||||
|
except:
|
||||||
|
raise
|
||||||
cH.close()
|
cH.close()
|
||||||
|
if ok:
|
||||||
|
msgText = QCoreApplication.translate('PythonConsole',
|
||||||
|
'History cleared successfully.')
|
||||||
|
self.parent.callWidgetMessageBar(msgText)
|
||||||
|
|
||||||
|
def clearHistorySession(self):
|
||||||
|
self.clearHistory(True)
|
||||||
|
|
||||||
def showPrevious(self):
|
def showPrevious(self):
|
||||||
if self.historyIndex < len(self.history) and not self.history.isEmpty():
|
if self.historyIndex < len(self.history) and not self.history.isEmpty():
|
||||||
@ -402,6 +417,25 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
|
|
||||||
def contextMenuEvent(self, e):
|
def contextMenuEvent(self, e):
|
||||||
menu = QMenu(self)
|
menu = QMenu(self)
|
||||||
|
subMenu = QMenu(menu)
|
||||||
|
titleHistoryMenu = QCoreApplication.translate("PythonConsole", "Command History")
|
||||||
|
subMenu.setTitle(titleHistoryMenu)
|
||||||
|
showHistoryAction = subMenu.addAction(QCoreApplication.translate("PythonConsole",
|
||||||
|
"Show"),
|
||||||
|
self.showHistory, 'Ctrl+Shift+SPACE')
|
||||||
|
subMenu.addSeparator()
|
||||||
|
saveHistoryAction = subMenu.addAction(QCoreApplication.translate("PythonConsole",
|
||||||
|
"Save"),
|
||||||
|
self.writeHistoryFile)
|
||||||
|
subMenu.addSeparator()
|
||||||
|
clearHistoryAction = subMenu.addAction(QCoreApplication.translate("PythonConsole",
|
||||||
|
"Clear File"),
|
||||||
|
self.clearHistory)
|
||||||
|
clearSessHistoryAction = subMenu.addAction(QCoreApplication.translate("PythonConsole",
|
||||||
|
"Clear Session"),
|
||||||
|
self.clearHistorySession)
|
||||||
|
menu.addMenu(subMenu)
|
||||||
|
menu.addSeparator()
|
||||||
copyAction = menu.addAction(QCoreApplication.translate("PythonConsole",
|
copyAction = menu.addAction(QCoreApplication.translate("PythonConsole",
|
||||||
"Copy"),
|
"Copy"),
|
||||||
self.copy, QKeySequence.Copy)
|
self.copy, QKeySequence.Copy)
|
||||||
@ -460,14 +494,14 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
def insertFromDropPaste(self, textDP):
|
def insertFromDropPaste(self, textDP):
|
||||||
pasteList = str(textDP).splitlines()
|
pasteList = str(textDP).splitlines()
|
||||||
for line in pasteList[:-1]:
|
for line in pasteList[:-1]:
|
||||||
line.replace(">>> ", "").replace("... ", "")
|
cleanLine = line.replace(">>> ", "").replace("... ", "")
|
||||||
self.insert(unicode(line))
|
self.insert(unicode(cleanLine))
|
||||||
self.move_cursor_to_end()
|
self.move_cursor_to_end()
|
||||||
self.runCommand(unicode(self.currentCommand()))
|
self.runCommand(unicode(self.currentCommand()))
|
||||||
if pasteList[-1] != "":
|
if pasteList[-1] != "":
|
||||||
line = pasteList[-1]
|
line = pasteList[-1]
|
||||||
line.replace(">>> ", "").replace("... ", "")
|
cleanLine = line.replace(">>> ", "").replace("... ", "")
|
||||||
self.insert(unicode(line))
|
self.insert(unicode(cleanLine))
|
||||||
self.move_cursor_to_end()
|
self.move_cursor_to_end()
|
||||||
|
|
||||||
def insertTextFromFile(self, listOpenFile):
|
def insertTextFromFile(self, listOpenFile):
|
||||||
@ -485,11 +519,9 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
self.runCommand( unicode(self.currentCommand()) )
|
self.runCommand( unicode(self.currentCommand()) )
|
||||||
self.setFocus()
|
self.setFocus()
|
||||||
self.move_cursor_to_end()
|
self.move_cursor_to_end()
|
||||||
#self.SendScintilla(QsciScintilla.SCI_EMPTYUNDOBUFFER)
|
|
||||||
|
|
||||||
def currentCommand(self):
|
def currentCommand(self):
|
||||||
linenr, index = self.getCursorPosition()
|
linenr, index = self.getCursorPosition()
|
||||||
#for i in range(0, linenr):
|
|
||||||
txtLength = self.text(linenr).length()
|
txtLength = self.text(linenr).length()
|
||||||
string = self.text()
|
string = self.text()
|
||||||
cmdLine = string.right(txtLength - 4)
|
cmdLine = string.right(txtLength - 4)
|
||||||
@ -500,18 +532,8 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
self.writeCMD(cmd)
|
self.writeCMD(cmd)
|
||||||
import webbrowser
|
import webbrowser
|
||||||
self.updateHistory(cmd)
|
self.updateHistory(cmd)
|
||||||
if cmd in ('_save', '_clear', '_clearAll', '_pyqgis', '_api'):
|
if cmd in ('_pyqgis', '_api'):
|
||||||
if cmd == '_save':
|
if cmd == '_pyqgis':
|
||||||
self.writeHistoryFile()
|
|
||||||
msgText = QCoreApplication.translate('PythonConsole', 'History saved successfully.')
|
|
||||||
elif cmd == '_clear':
|
|
||||||
self.clearHistoryFile()
|
|
||||||
msgText = QCoreApplication.translate('PythonConsole', 'History cleared successfully.')
|
|
||||||
elif cmd == '_clearAll':
|
|
||||||
self.history = QStringList()
|
|
||||||
self.clearHistoryFile()
|
|
||||||
msgText = QCoreApplication.translate('PythonConsole', 'Session and file history cleared successfully.')
|
|
||||||
elif cmd == '_pyqgis':
|
|
||||||
webbrowser.open( "http://www.qgis.org/pyqgis-cookbook/" )
|
webbrowser.open( "http://www.qgis.org/pyqgis-cookbook/" )
|
||||||
elif cmd == '_api':
|
elif cmd == '_api':
|
||||||
webbrowser.open( "http://www.qgis.org/api/" )
|
webbrowser.open( "http://www.qgis.org/api/" )
|
||||||
@ -539,3 +561,32 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
|||||||
getCmdString = self.text()
|
getCmdString = self.text()
|
||||||
prompt = getCmdString[0:4]
|
prompt = getCmdString[0:4]
|
||||||
sys.stdout.write(prompt+txt+'\n')
|
sys.stdout.write(prompt+txt+'\n')
|
||||||
|
|
||||||
|
class HistoryDialog(QDialog, Ui_HistoryDialog):
|
||||||
|
def __init__(self, parent):
|
||||||
|
QDialog.__init__(self, parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
self.parent = parent
|
||||||
|
self.setWindowTitle(QCoreApplication.translate("PythonConsole",
|
||||||
|
"Python Console - Command History"))
|
||||||
|
self.listView.setToolTip(QCoreApplication.translate("PythonConsole",
|
||||||
|
"Double click on item to execute"))
|
||||||
|
self.model = QStandardItemModel(self.listView)
|
||||||
|
|
||||||
|
self._reloadHistory()
|
||||||
|
|
||||||
|
self.listView.doubleClicked.connect(self._runHistory)
|
||||||
|
self.reloadHistory.clicked.connect(self._reloadHistory)
|
||||||
|
|
||||||
|
def _runHistory(self, item):
|
||||||
|
cmd = item.data(Qt.DisplayRole).toString()
|
||||||
|
self.parent.runCommand(unicode(cmd))
|
||||||
|
|
||||||
|
def _reloadHistory(self):
|
||||||
|
self.model.clear()
|
||||||
|
for i in self.parent.history:
|
||||||
|
item = QStandardItem(i)
|
||||||
|
self.model.appendRow(item)
|
||||||
|
|
||||||
|
self.listView.setModel(self.model)
|
||||||
|
self.listView.scrollToBottom()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user