Skip to content

Commit 016789a

Browse files
committed
Merge branch 'master' of https://github.com/qgis/Quantum-GIS
2 parents 9587252 + a8934a2 commit 016789a

19 files changed

+924
-637
lines changed

python/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ SET(PY_FILES
147147
console_sci.py
148148
console_help.py
149149
console_settings.py
150+
console_output.py
150151
utils.py
151152
)
152153
FILE(GLOB UI_FILES *.ui)

python/console.py

+42-32
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from PyQt4.QtGui import *
2424
from qgis.utils import iface
2525
from console_sci import PythonEdit
26+
from console_output import EditorOutput
2627
from console_help import HelpDialog
2728
from console_settings import optionsDialog
2829

@@ -58,20 +59,6 @@ def console_displayhook(obj):
5859
global _console_output
5960
_console_output = obj
6061

61-
class QgisOutputCatcher:
62-
def __init__(self):
63-
self.data = ''
64-
def write(self, stuff):
65-
self.data += stuff
66-
def get_and_clean_data(self):
67-
tmp = self.data
68-
self.data = ''
69-
return tmp
70-
def flush(self):
71-
pass
72-
73-
sys.stdout = QgisOutputCatcher()
74-
7562
class PythonConsole(QDockWidget):
7663
def __init__(self, parent=None):
7764
QDockWidget.__init__(self, parent)
@@ -92,35 +79,32 @@ def activate(self):
9279
self.raise_()
9380
QDockWidget.setFocus(self)
9481

95-
9682
class PythonConsoleWidget(QWidget):
9783
def __init__(self, parent=None):
9884
QWidget.__init__(self, parent)
99-
self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))
100-
85+
self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))
10186
self.widgetButton = QWidget()
87+
#self.widgetEditors = QWidget()
88+
10289
self.options = optionsDialog(self)
10390

10491
self.toolBar = QToolBar()
10592
self.toolBar.setEnabled(True)
106-
#self.toolBar.setFont(font)
10793
self.toolBar.setFocusPolicy(Qt.NoFocus)
10894
self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
10995
self.toolBar.setLayoutDirection(Qt.LeftToRight)
11096
self.toolBar.setIconSize(QSize(24, 24))
11197
self.toolBar.setOrientation(Qt.Vertical)
11298
self.toolBar.setMovable(True)
11399
self.toolBar.setFloatable(True)
114-
#self.toolBar.setAllowedAreas(Qt.LeftToolBarArea)
115-
#self.toolBar.setAllowedAreas(Qt.RightToolBarArea)
116-
#self.toolBar.setObjectName(_fromUtf8("toolMappa"))
117100

118-
self.b = QVBoxLayout(self.widgetButton)
119-
self.e = QHBoxLayout(self)
101+
self.b = QGridLayout(self.widgetButton)
102+
self.f = QGridLayout(self)
120103

121-
self.e.setMargin(0)
122-
self.e.setSpacing(0)
104+
self.f.setMargin(0)
105+
self.f.setSpacing(0)
123106
self.b.setMargin(0)
107+
self.b.setSpacing(0)
124108

125109
## Action for Clear button
126110
clearBt = QCoreApplication.translate("PythonConsole", "Clear console")
@@ -268,12 +252,37 @@ def __init__(self, parent=None):
268252

269253
self.b.addWidget(self.toolBar)
270254
self.edit = PythonEdit()
271-
self.setFocusProxy( self.edit )
272-
273-
self.e.addWidget(self.widgetButton)
274-
self.e.addWidget(self.edit)
255+
self.textEditOut = EditorOutput()
256+
257+
self.setFocusProxy(self.edit)
258+
259+
sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
260+
sizePolicy.setHorizontalStretch(0)
261+
sizePolicy.setVerticalStretch(0)
262+
sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth())
263+
self.widgetButton.setSizePolicy(sizePolicy)
264+
265+
self.consoleFrame = QFrame(self)
266+
self.consoleFrame.setObjectName("consoleFrame")
267+
self.consoleLayout = QVBoxLayout(self.consoleFrame)
268+
self.consoleLayout.setSpacing(0)
269+
self.consoleLayout.setMargin(0)
270+
271+
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
272+
sizePolicy.setHorizontalStretch(0)
273+
sizePolicy.setVerticalStretch(0)
274+
sizePolicy.setHeightForWidth(self.textEditOut.sizePolicy().hasHeightForWidth())
275+
self.textEditOut.setSizePolicy(sizePolicy)
276+
self.consoleLayout.addWidget(self.textEditOut)
277+
278+
self.edit.setMinimumSize(QSize(0, 32))
279+
self.edit.setMaximumSize(QSize(16777215, 32))
280+
self.consoleLayout.addWidget(self.edit)
281+
282+
self.f.addWidget(self.widgetButton, 0, 0)
283+
self.f.addWidget(self.consoleFrame, 0, 1)
275284

276-
self.clearButton.triggered.connect(self.edit.clearConsole)
285+
self.clearButton.triggered.connect(self.textEditOut.clearConsole)
277286
self.optionsButton.triggered.connect(self.openSettings)
278287
self.loadIfaceButton.triggered.connect(self.iface)
279288
self.loadSextanteButton.triggered.connect(self.sextante)
@@ -326,7 +335,7 @@ def saveScriptFile(self):
326335
if not filename.endswith(".py"):
327336
fName += ".py"
328337
sF = open(fName,'w')
329-
listText = self.edit.getTextFromEditor()
338+
listText = self.textEditOut.getTextFromEditor()
330339
is_first_line = True
331340
for s in listText:
332341
if s[0:3] in (">>>", "..."):
@@ -337,7 +346,7 @@ def saveScriptFile(self):
337346
sF.write('\n')
338347
sF.write(s)
339348
sF.close()
340-
349+
341350
def openHelp(self):
342351
dlg = HelpDialog()
343352
dlg.exec_()
@@ -348,6 +357,7 @@ def openSettings(self):
348357

349358
def prefChanged(self):
350359
self.edit.refreshLexerProperties()
360+
self.textEditOut.refreshLexerProperties()
351361

352362
def closeEvent(self, event):
353363
self.edit.writeHistoryFile()

python/console_output.py

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# -*- coding:utf-8 -*-
2+
"""
3+
/***************************************************************************
4+
Python Conosle for QGIS
5+
-------------------
6+
begin : 2012-09-10
7+
copyright : (C) 2012 by Salvatore Larosa
8+
email : lrssvtml (at) gmail (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+
Some portions of code were taken from https://code.google.com/p/pydee/
20+
"""
21+
22+
from PyQt4.QtCore import *
23+
from PyQt4.QtGui import *
24+
from PyQt4.Qsci import (QsciScintilla,
25+
QsciScintillaBase,
26+
QsciLexerPython)
27+
from console_sci import PythonEdit
28+
import sys
29+
30+
class writeOut:
31+
def __init__(self, edit, out=None, style=None):
32+
"""
33+
This class allow to write stdout and stderr
34+
"""
35+
self.editor = edit
36+
self.out = None
37+
self.style = style
38+
39+
def write(self, m):
40+
if self.style == "traceback":
41+
self.editor.SendScintilla(QsciScintilla.SCI_SETSTYLING, len(m), 1)
42+
self.editor.append(m)
43+
self.editor.SendScintilla(QsciScintilla.SCI_SETSTYLING, len(m), 1)
44+
else:
45+
self.editor.append(m)
46+
self.move_cursor_to_end()
47+
48+
if self.out:
49+
self.out.write(m)
50+
51+
def move_cursor_to_end(self):
52+
"""Move cursor to end of text"""
53+
line, index = self.get_end_pos()
54+
self.editor.setCursorPosition(line, index)
55+
self.editor.ensureCursorVisible()
56+
self.editor.ensureLineVisible(line)
57+
58+
def get_end_pos(self):
59+
"""Return (line, index) position of the last character"""
60+
line = self.editor.lines() - 1
61+
return (line, self.editor.text(line).length())
62+
63+
def flush(self):
64+
pass
65+
66+
class EditorOutput(QsciScintilla):
67+
def __init__(self, parent=None):
68+
#QsciScintilla.__init__(self, parent)
69+
super(EditorOutput,self).__init__(parent)
70+
# Enable non-ascii chars for editor
71+
self.setUtf8(True)
72+
73+
sys.stdout = writeOut(self, sys.stdout)
74+
sys.stderr = writeOut(self, sys.stderr, "traceback")
75+
76+
self.edit = PythonEdit()
77+
self.setLexers()
78+
self.setReadOnly(True)
79+
80+
# Set the default font
81+
font = QFont()
82+
font.setFamily('Courier')
83+
font.setFixedPitch(True)
84+
font.setPointSize(10)
85+
self.setFont(font)
86+
self.setMarginsFont(font)
87+
# Margin 0 is used for line numbers
88+
#fm = QFontMetrics(font)
89+
self.setMarginsFont(font)
90+
self.setMarginWidth(1, "00000")
91+
self.setMarginLineNumbers(1, True)
92+
self.setMarginsForegroundColor(QColor("#3E3EE3"))
93+
self.setMarginsBackgroundColor(QColor("#f9f9f9"))
94+
self.setCaretLineVisible(True)
95+
self.setCaretLineBackgroundColor(QColor("#fcf3ed"))
96+
97+
98+
# Folding
99+
#self.setFolding(QsciScintilla.BoxedTreeFoldStyle)
100+
#self.setFoldMarginColors(QColor("#99CC66"),QColor("#333300"))
101+
#self.setWrapMode(QsciScintilla.WrapCharacter)
102+
103+
## Edge Mode : does not seems to work
104+
#self.setEdgeMode(QsciScintilla.EdgeLine)
105+
#self.setEdgeColumn(80)
106+
#self.setEdgeColor(QColor("#FF0000"))
107+
108+
self.SendScintilla(QsciScintilla.SCI_SETWRAPMODE, 2)
109+
self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)
110+
111+
def refreshLexerProperties(self):
112+
self.setLexers()
113+
114+
def setLexers(self):
115+
self.lexer = QsciLexerPython()
116+
117+
settings = QSettings()
118+
loadFont = settings.value("pythonConsole/fontfamilytext").toString()
119+
fontSize = settings.value("pythonConsole/fontsize").toInt()[0]
120+
font = QFont(loadFont)
121+
font.setFixedPitch(True)
122+
font.setPointSize(fontSize)
123+
124+
self.lexer.setDefaultFont(font)
125+
self.lexer.setColor(Qt.red, 1)
126+
self.lexer.setColor(Qt.darkGreen, 5)
127+
self.lexer.setColor(Qt.darkBlue, 15)
128+
self.lexer.setFont(font, 1)
129+
self.lexer.setFont(font, 2)
130+
self.lexer.setFont(font, 3)
131+
self.lexer.setFont(font, 4)
132+
133+
self.setLexer(self.lexer)
134+
135+
def getTextFromEditor(self):
136+
text = self.text()
137+
textList = text.split("\n")
138+
return textList
139+
140+
def clearConsole(self):
141+
#self.SendScintilla(QsciScintilla.SCI_CLEARALL)
142+
self.setText('')
143+
144+
def contextMenuEvent(self, e):
145+
menu = QMenu(self)
146+
runAction = menu.addAction("Enter Selected")
147+
copyAction = menu.addAction("Copy CTRL+C")
148+
runAction.setEnabled(False)
149+
if self.hasSelectedText():
150+
runAction.setEnabled(True)
151+
action = menu.exec_(self.mapToGlobal(e.pos()))
152+
if action == runAction:
153+
cmd = self.selectedText()
154+
self.edit.insertFromDropPaste(cmd)
155+
self.edit.entered()
156+
if action == copyAction:
157+
self.copy()
158+
159+
def copy(self):
160+
"""Copy text to clipboard... or keyboard interrupt"""
161+
if self.hasSelectedText():
162+
text = unicode(self.selectedText())
163+
text = text.replace('>>> ', '').replace('... ', '').strip() # removing prompts
164+
QApplication.clipboard().setText(text)
165+
else:
166+
self.emit(SIGNAL("keyboard_interrupt()"))
167+

0 commit comments

Comments
 (0)