1
|
diff --git a/python/console.py b/python/console.py
|
2
|
index b16c61c..e3e18f4 100755
|
3
|
--- a/python/console.py
|
4
|
+++ b/python/console.py
|
5
|
@@ -16,6 +16,14 @@ Has +- the same behaviour as command-line interactive console:
|
6
|
- has command history, accessible using up/down keys
|
7
|
- supports pasting of commands
|
8
|
|
9
|
+Can be opened as a QWidget (top-level window, unowned) or as a QDockWidget;
|
10
|
+/Qgis/dockPythonConsole in the registry controls this; set in Settings, Options, General tab, Open Python console in a dock window
|
11
|
+Takes effect the next time Plugins, Python Console is chosen. It is not necessary to restart QGIS.
|
12
|
+The editor is retained so none of its content is lost.
|
13
|
+- as a QWidget: Plugins, Python Console will show it; it can be hidden by its Close (X) button or minimized
|
14
|
+- as a QDockWidget: Plugins, Python Console toggles show/hide; is hidden (actually, not constructed) on QGIS start up
|
15
|
+ also, this appears in the main window context menu and can be toggled off and on there
|
16
|
+
|
17
|
TODO:
|
18
|
- configuration - init commands, font, ...
|
19
|
- python code highlighting
|
20
|
@@ -33,19 +41,50 @@ import code
|
21
|
_init_commands = ["from qgis.core import *", "import qgis.utils"]
|
22
|
|
23
|
_console = None
|
24
|
+_consoleEditor = None
|
25
|
+_consoleAsDock = None
|
26
|
|
27
|
def show_console():
|
28
|
""" called from QGIS to open the console """
|
29
|
global _console
|
30
|
- if _console is None:
|
31
|
- _console = PythonConsole(iface.mainWindow())
|
32
|
- _console.show() # force show even if it was restored as hidden
|
33
|
+ global _consoleEditor
|
34
|
+ global _consoleAsDock
|
35
|
+
|
36
|
+ s = QSettings()
|
37
|
+ tempConsoleAsDock = s.value("/Qgis/dockPythonConsole",False).toBool()
|
38
|
+
|
39
|
+ if _consoleAsDock != tempConsoleAsDock:
|
40
|
+ if _consoleEditor is None:
|
41
|
+ _consoleEditor = PythonEdit()
|
42
|
+
|
43
|
+ if _console is not None:
|
44
|
+ if _consoleAsDock:
|
45
|
+ iface.mainWindow().removeDockWidget(_console)
|
46
|
+ else:
|
47
|
+ _console.hide()
|
48
|
+
|
49
|
+ if tempConsoleAsDock: # re-parent the editor object
|
50
|
+ newconsole = PythonConsole(_consoleEditor, iface.mainWindow())
|
51
|
+ else:
|
52
|
+ newconsole = PythonConsoleW(_consoleEditor) # unowned window
|
53
|
+
|
54
|
+ newconsole.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))
|
55
|
+
|
56
|
+ _console = None # then delete the old console window
|
57
|
+ _console = newconsole # and remember the new console window
|
58
|
+ _consoleAsDock = tempConsoleAsDock # save current state
|
59
|
+
|
60
|
+ if _consoleAsDock:
|
61
|
+ _console.setVisible(not _console.isVisible()) # toggle on each call if QDockWidget
|
62
|
else:
|
63
|
- _console.setVisible(not _console.isVisible())
|
64
|
+ _console.show() # always show if QWidget
|
65
|
+ _console.raise_()
|
66
|
+ _console.setWindowState( _console.windowState() & ~Qt.WindowMinimized )
|
67
|
+
|
68
|
# set focus to the edit box so the user can start typing
|
69
|
if _console.isVisible():
|
70
|
_console.activateWindow()
|
71
|
- _console.edit.setFocus()
|
72
|
+ _consoleEditor.setFocus()
|
73
|
|
74
|
|
75
|
_old_stdout = sys.stdout
|
76
|
@@ -56,7 +95,7 @@ def clearConsole():
|
77
|
global _console
|
78
|
if _console is None:
|
79
|
return
|
80
|
- _console.edit.clearConsole()
|
81
|
+ _consoleEditor.clearConsole()
|
82
|
|
83
|
|
84
|
# hook for python console so all output will be redirected
|
85
|
@@ -80,26 +119,57 @@ class QgisOutputCatcher:
|
86
|
sys.stdout = QgisOutputCatcher()
|
87
|
|
88
|
class PythonConsole(QDockWidget):
|
89
|
- def __init__(self, parent=None):
|
90
|
+ """ as a QDockWidget """
|
91
|
+ def __init__(self, editor, parent=None):
|
92
|
QDockWidget.__init__(self, parent)
|
93
|
self.setObjectName("Python Console")
|
94
|
self.setAllowedAreas(Qt.BottomDockWidgetArea)
|
95
|
- self.widget = QWidget()
|
96
|
- self.l = QVBoxLayout(self.widget)
|
97
|
- self.l.setContentsMargins(0,0,0,0)
|
98
|
- self.edit = PythonEdit()
|
99
|
- self.l.addWidget(self.edit)
|
100
|
- self.setWidget(self.widget)
|
101
|
- self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))
|
102
|
+ widget = QWidget()
|
103
|
+ l = QVBoxLayout(widget)
|
104
|
+ l.setContentsMargins(0,0,0,0)
|
105
|
+ l.addWidget(editor)
|
106
|
+ self.setWidget(widget)
|
107
|
# try to restore position from stored main window state
|
108
|
if not iface.mainWindow().restoreDockWidget(self):
|
109
|
iface.mainWindow().addDockWidget(Qt.BottomDockWidgetArea, self)
|
110
|
-
|
111
|
+ self.hide() # visibility toggling will show console on first use
|
112
|
+
|
113
|
+ def sizeHint(self):
|
114
|
+ return QSize(500,300)
|
115
|
+
|
116
|
+ def closeEvent(self, event):
|
117
|
+ QWidget.closeEvent(self, event)
|
118
|
+
|
119
|
+class PythonConsoleW(QWidget):
|
120
|
+ """ as a QWidget """
|
121
|
+ def __init__(self, editor, parent=None):
|
122
|
+ QWidget.__init__(self, parent)
|
123
|
+ l = QVBoxLayout()
|
124
|
+ l.addWidget(editor)
|
125
|
+ l.setContentsMargins(0,0,0,0)
|
126
|
+ self.setLayout(l)
|
127
|
+ s = QSettings()
|
128
|
+ self.restoreGeometry(s.value("/python/console/geometry").toByteArray())
|
129
|
+
|
130
|
+ def __del__(self):
|
131
|
+ """
|
132
|
+ note that this isn't called when QGIS exits, so the window geometry
|
133
|
+ is not saved at program exit
|
134
|
+ """
|
135
|
+ s = QSettings()
|
136
|
+ s.setValue("/python/console/geometry", QVariant(self.saveGeometry()))
|
137
|
+ QWidget.__del__(self)
|
138
|
|
139
|
def sizeHint(self):
|
140
|
return QSize(500,300)
|
141
|
|
142
|
def closeEvent(self, event):
|
143
|
+ """
|
144
|
+ save settings here as well as in destructor to handle more
|
145
|
+ situations where the window geometry should be saved
|
146
|
+ """
|
147
|
+ s = QSettings()
|
148
|
+ s.setValue("/python/console/geometry", QVariant(self.saveGeometry()))
|
149
|
QWidget.closeEvent(self, event)
|
150
|
|
151
|
|
152
|
diff --git a/src/app/qgsoptions.cpp b/src/app/qgsoptions.cpp
|
153
|
index 0dd9c4b..0772442 100644
|
154
|
--- a/src/app/qgsoptions.cpp
|
155
|
+++ b/src/app/qgsoptions.cpp
|
156
|
@@ -285,6 +285,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
|
157
|
cbxShowTips->setChecked( settings.value( "/qgis/showTips", true ).toBool() );
|
158
|
cbxAttributeTableDocked->setChecked( settings.value( "/qgis/dockAttributeTable", false ).toBool() );
|
159
|
cbxIdentifyResultsDocked->setChecked( settings.value( "/qgis/dockIdentifyResults", false ).toBool() );
|
160
|
+ cbxPythonConsoleDocked->setChecked( settings.value( "/qgis/dockPythonConsole", false ).toBool() );
|
161
|
cbxSnappingOptionsDocked->setChecked( settings.value( "/qgis/dockSnapping", false ).toBool() );
|
162
|
cbxAddPostgisDC->setChecked( settings.value( "/qgis/addPostgisDC", false ).toBool() );
|
163
|
cbxAddNewLayersToCurrentGroup->setChecked( settings.value( "/qgis/addNewLayersToCurrentGroup", false ).toBool() );
|
164
|
@@ -570,6 +571,7 @@ void QgsOptions::saveOptions()
|
165
|
settings.setValue( "/qgis/dockAttributeTable", cbxAttributeTableDocked->isChecked() );
|
166
|
settings.setValue( "/qgis/attributeTableBehaviour", cmbAttrTableBehaviour->currentIndex() );
|
167
|
settings.setValue( "/qgis/dockIdentifyResults", cbxIdentifyResultsDocked->isChecked() );
|
168
|
+ settings.setValue( "/qgis/dockPythonConsole", cbxPythonConsoleDocked->isChecked() );
|
169
|
settings.setValue( "/qgis/dockSnapping", cbxSnappingOptionsDocked->isChecked() );
|
170
|
settings.setValue( "/qgis/addPostgisDC", cbxAddPostgisDC->isChecked() );
|
171
|
settings.setValue( "/qgis/addNewLayersToCurrentGroup", cbxAddNewLayersToCurrentGroup->isChecked() );
|
172
|
diff --git a/src/ui/qgsoptionsbase.ui b/src/ui/qgsoptionsbase.ui
|
173
|
index 41b7865..90a4fa8 100644
|
174
|
--- a/src/ui/qgsoptionsbase.ui
|
175
|
+++ b/src/ui/qgsoptionsbase.ui
|
176
|
@@ -343,6 +343,13 @@
|
177
|
</widget>
|
178
|
</item>
|
179
|
<item>
|
180
|
+ <widget class="QCheckBox" name="cbxPythonConsoleDocked">
|
181
|
+ <property name="text">
|
182
|
+ <string>Open Python console in a dock window (next time console is opened)</string>
|
183
|
+ </property>
|
184
|
+ </widget>
|
185
|
+ </item>
|
186
|
+ <item>
|
187
|
<widget class="QCheckBox" name="cbxAddPostgisDC">
|
188
|
<property name="text">
|
189
|
<string>Add PostGIS layers with double click and select in extended mode</string>
|
190
|
@@ -1858,6 +1865,7 @@
|
191
|
<tabstop>cbxIdentifyResultsDocked</tabstop>
|
192
|
<tabstop>cbxSnappingOptionsDocked</tabstop>
|
193
|
<tabstop>cbxAttributeTableDocked</tabstop>
|
194
|
+ <tabstop>cbxPythonConsoleDocked</tabstop>
|
195
|
<tabstop>cbxAddPostgisDC</tabstop>
|
196
|
<tabstop>cbxAddNewLayersToCurrentGroup</tabstop>
|
197
|
<tabstop>cmbAttrTableBehaviour</tabstop>
|