mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -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
|
||||
|
||||
from qgis.core import QgsApplication
|
||||
from ui_console_history_dlg import Ui_HistoryDialog
|
||||
|
||||
_init_commands = ["from qgis.core import *", "import qgis.utils",
|
||||
"from qgis.utils import iface"]
|
||||
@ -69,6 +70,8 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
# Read history command file
|
||||
self.readHistoryFile()
|
||||
|
||||
self.historyDlg = HistoryDialog(self)
|
||||
|
||||
# Brace matching: enable for a brace immediately before or after
|
||||
# the current position
|
||||
self.setBraceMatching(QsciScintilla.SloppyBraceMatch)
|
||||
@ -107,8 +110,6 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
self.newShortcutCAS.setContext(Qt.WidgetShortcut)
|
||||
self.newShortcutCAS.activated.connect(self.autoCompleteKeyBinding)
|
||||
self.newShortcutCSS.activated.connect(self.showHistory)
|
||||
self.connect(self, SIGNAL('userListActivated(int, const QString)'),
|
||||
self.completion_list_selected)
|
||||
|
||||
def settingsShell(self):
|
||||
# Set Python lexer
|
||||
@ -129,7 +130,10 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
self.setAutoCompletionSource(self.AcsNone)
|
||||
|
||||
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):
|
||||
radioButtonSource = self.settings.value("pythonConsole/autoCompleteSource").toString()
|
||||
@ -199,17 +203,6 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
|
||||
## 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):
|
||||
""" Get the text as a unicode string. """
|
||||
value = self.getBytes().decode('utf-8')
|
||||
@ -245,11 +238,6 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
self.ensureCursorVisible()
|
||||
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):
|
||||
"""Return True if cursor is on the last line"""
|
||||
cline, _ = self.getCursorPosition()
|
||||
@ -285,10 +273,19 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
self.historyIndex = len(self.history)
|
||||
|
||||
def writeHistoryFile(self):
|
||||
wH = open(_historyFile, 'w')
|
||||
for s in self.history:
|
||||
wH.write(s + '\n')
|
||||
ok = False
|
||||
try:
|
||||
wH = open(_historyFile, 'w')
|
||||
for s in self.history:
|
||||
wH.write(s + '\n')
|
||||
ok = True
|
||||
except:
|
||||
raise
|
||||
wH.close()
|
||||
if ok:
|
||||
msgText = QCoreApplication.translate('PythonConsole',
|
||||
'History saved successfully.')
|
||||
self.parent.callWidgetMessageBar(msgText)
|
||||
|
||||
def readHistoryFile(self):
|
||||
fileExist = QFile.exists(_historyFile)
|
||||
@ -301,9 +298,27 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
else:
|
||||
return
|
||||
|
||||
def clearHistoryFile(self):
|
||||
cH = open(_historyFile, 'w')
|
||||
def clearHistory(self, clearSession=False):
|
||||
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()
|
||||
if ok:
|
||||
msgText = QCoreApplication.translate('PythonConsole',
|
||||
'History cleared successfully.')
|
||||
self.parent.callWidgetMessageBar(msgText)
|
||||
|
||||
def clearHistorySession(self):
|
||||
self.clearHistory(True)
|
||||
|
||||
def showPrevious(self):
|
||||
if self.historyIndex < len(self.history) and not self.history.isEmpty():
|
||||
@ -402,6 +417,25 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
|
||||
def contextMenuEvent(self, e):
|
||||
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",
|
||||
"Copy"),
|
||||
self.copy, QKeySequence.Copy)
|
||||
@ -460,14 +494,14 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
def insertFromDropPaste(self, textDP):
|
||||
pasteList = str(textDP).splitlines()
|
||||
for line in pasteList[:-1]:
|
||||
line.replace(">>> ", "").replace("... ", "")
|
||||
self.insert(unicode(line))
|
||||
cleanLine = line.replace(">>> ", "").replace("... ", "")
|
||||
self.insert(unicode(cleanLine))
|
||||
self.move_cursor_to_end()
|
||||
self.runCommand(unicode(self.currentCommand()))
|
||||
if pasteList[-1] != "":
|
||||
line = pasteList[-1]
|
||||
line.replace(">>> ", "").replace("... ", "")
|
||||
self.insert(unicode(line))
|
||||
cleanLine = line.replace(">>> ", "").replace("... ", "")
|
||||
self.insert(unicode(cleanLine))
|
||||
self.move_cursor_to_end()
|
||||
|
||||
def insertTextFromFile(self, listOpenFile):
|
||||
@ -485,11 +519,9 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
self.runCommand( unicode(self.currentCommand()) )
|
||||
self.setFocus()
|
||||
self.move_cursor_to_end()
|
||||
#self.SendScintilla(QsciScintilla.SCI_EMPTYUNDOBUFFER)
|
||||
|
||||
def currentCommand(self):
|
||||
linenr, index = self.getCursorPosition()
|
||||
#for i in range(0, linenr):
|
||||
txtLength = self.text(linenr).length()
|
||||
string = self.text()
|
||||
cmdLine = string.right(txtLength - 4)
|
||||
@ -500,18 +532,8 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
self.writeCMD(cmd)
|
||||
import webbrowser
|
||||
self.updateHistory(cmd)
|
||||
if cmd in ('_save', '_clear', '_clearAll', '_pyqgis', '_api'):
|
||||
if cmd == '_save':
|
||||
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':
|
||||
if cmd in ('_pyqgis', '_api'):
|
||||
if cmd == '_pyqgis':
|
||||
webbrowser.open( "http://www.qgis.org/pyqgis-cookbook/" )
|
||||
elif cmd == '_api':
|
||||
webbrowser.open( "http://www.qgis.org/api/" )
|
||||
@ -539,3 +561,32 @@ class ShellScintilla(QsciScintilla, code.InteractiveInterpreter):
|
||||
getCmdString = self.text()
|
||||
prompt = getCmdString[0:4]
|
||||
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