71 changes: 44 additions & 27 deletions python/console_sci.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def __init__(self, parent=None):
# Set Python lexer
# Set style for Python comments (style number 1) to a fixed-width
# courier.
self.setLexers(True)
self.setLexers()

# Indentation
#self.setAutoIndent(True)
Expand Down Expand Up @@ -120,10 +120,11 @@ def showHistory(self):

def autoComplete(self):
self.autoCompleteFromAll()

def clearConsole(self):
"""Clear the contents of the console."""
self.setText('')
self.SendScintilla(QsciScintilla.SCI_CLEARALL)
#self.setText('')
self.insertInitText()
self.displayPrompt(False)
self.setFocus()
Expand Down Expand Up @@ -156,32 +157,39 @@ def commandConsole(self, command):
self.append('from PyQt4.QtGui import *')
self.move_cursor_to_end()
self.setFocus()
def setLexers(self, lexer):

def setLexers(self):
from qgis.core import QgsApplication
if lexer:
font = QFont()
font.setFamily('Mono') ## Courier New
font.setFixedPitch(True)
## check platform for font size
if sys.platform.startswith('darwin'):
font.setPointSize(13)
else:
font.setPointSize(10)
self.setFont(font)
self.setMarginsFont(font)
self.lexer = QsciLexerPython()
self.lexer.setDefaultFont(font)
self.lexer.setColor(Qt.red, 1)
self.lexer.setColor(Qt.darkGreen, 5)
self.lexer.setColor(Qt.darkBlue, 15)
self.lexer.setFont(font, 1)
self.lexer.setFont(font, 3)
self.lexer.setFont(font, 4)
self.api = QsciAPIs(self.lexer)

self.lexer = QsciLexerPython()
settings = QSettings()
loadFont = settings.value("pythonConsole/fontfamilytext", "Monospace").toString()
fontSize = settings.value("pythonConsole/fontsize", 10).toInt()[0]

font = QFont(loadFont)
font.setFixedPitch(True)
font.setPointSize(fontSize)

self.lexer.setDefaultFont(font)
self.lexer.setColor(Qt.red, 1)
self.lexer.setColor(Qt.darkGreen, 5)
self.lexer.setColor(Qt.darkBlue, 15)
self.lexer.setFont(font, 1)
self.lexer.setFont(font, 3)
self.lexer.setFont(font, 4)

self.api = QsciAPIs(self.lexer)
chekBoxAPI = settings.value( "pythonConsole/preloadAPI" ).toBool()
if chekBoxAPI:
self.api.loadPrepared( QgsApplication.pkgDataPath() + "/python/qsci_apis/pyqgis_master.pap" )
else:
apiPath = settings.value("pythonConsole/userAPI").toStringList()
for i in range(0, len(apiPath)):
self.api.load(QString(unicode(apiPath[i])))
self.api.prepare()
self.lexer.setAPIs(self.api)

self.setLexer(self.lexer)
self.setLexer(self.lexer)

## TODO: show completion list for file and directory

Expand Down Expand Up @@ -263,6 +271,9 @@ def new_prompt(self, prompt):
self.ensureCursorVisible()
self.ensureLineVisible(line)

def refreshLexerProperties(self):
self.setLexers()

# def check_selection(self):
# """
# Check if selected text is r/w,
Expand Down Expand Up @@ -484,9 +495,10 @@ def currentCommand(self):
return cmd

def runCommand(self, cmd):
import webbrowser
self.updateHistory(cmd)
self.SendScintilla(QsciScintilla.SCI_NEWLINE)
if cmd in ('_save', '_clear', '_clearAll'):
if cmd in ('_save', '_clear', '_clearAll', '_pyqgis', '_api'):
if cmd == '_save':
self.writeHistoryFile()
print QCoreApplication.translate("PythonConsole",
Expand All @@ -508,6 +520,11 @@ def runCommand(self, cmd):
self.clearHistoryFile()
print QCoreApplication.translate("PythonConsole",
"## History cleared successfully ##")
elif cmd == '_pyqgis':
webbrowser.open( "http://www.qgis.org/pyqgis-cookbook/" )
elif cmd == '_api':
webbrowser.open( "http://www.qgis.org/api/" )

output = sys.stdout.get_and_clean_data()
if output:
self.append(output)
Expand Down
161 changes: 161 additions & 0 deletions python/console_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# -*- coding:utf-8 -*-
"""
/***************************************************************************
Python Conosle for QGIS
-------------------
begin : 2012-09-10
copyright : (C) 2012 by Salvatore Larosa
email : lrssvtml (at) gmail (dot) com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
Some portions of code were taken from https://code.google.com/p/pydee/
"""

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from ui_console_settings import Ui_SettingsDialog

class optionsDialog(QDialog, Ui_SettingsDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Settings Python Console"))
#self.iface = iface
self.parent = parent
self.setupUi(self)
#self.show()

self.listPath = []

self.restoreSettings()
self.initialCheck()
self.fontConfig()

self.lineEdit.setReadOnly(True)
self.tabWidget.setTabText(0, QCoreApplication.translate("PythonConsole", "General"))
self.tabWidget.setTabIcon(0, QIcon(":/images/themes/default/propertyicons/general.png"))
self.tabWidget.setTabText(1, QCoreApplication.translate("PythonConsole", "About"))
self.tabWidget.setTabIcon(1, QIcon(":/images/console/iconAboutConsole.png"))

self.addAPIpath.setIcon(QIcon(":/images/themes/default/symbologyAdd.png"))
self.addAPIpath.setToolTip(QCoreApplication.translate("PythonConsole", "Add API path"))
self.removeAPIpath.setIcon(QIcon(":/images/themes/default/symbologyRemove.png"))
self.removeAPIpath.setToolTip(QCoreApplication.translate("PythonConsole", "Remove API path"))

self.connect( self.preloadAPI,
SIGNAL("stateChanged(int)"), self.initialCheck)
self.connect(self.browseButton,
SIGNAL("clicked()"), self.loadAPIFile)
self.connect(self.addAPIpath,
SIGNAL("clicked()"), self.addAPI)
self.connect(self.removeAPIpath,
SIGNAL("clicked()"), self.removeAPI)

def initialCheck(self):
if self.preloadAPI.isChecked():
self.enableDisable(False)
else:
self.enableDisable(True)

def enableDisable(self, value):
self.tableWidget.setEnabled(value)
self.lineEdit.setEnabled(value)
self.browseButton.setEnabled(value)
self.addAPIpath.setEnabled(value)
self.removeAPIpath.setEnabled(value)

def loadAPIFile(self):
settings = QSettings()
lastDirPath = settings.value("pythonConsole/lastDirAPIPath").toString()
fileAPI = QFileDialog.getOpenFileName(
self, "Open API File", lastDirPath, "API file (*.api)")
self.lineEdit.setText(fileAPI)

lastDirPath = QFileInfo(fileAPI).path()
settings.setValue("pythonConsole/lastDirAPIPath", QVariant(fileAPI))

def accept(self):
if not self.preloadAPI.isChecked():
if self.tableWidget.rowCount() == 0:
QMessageBox.information(self, self.tr("Warning!"),
self.tr('Please specify API file or check "Use preloaded API files"'))
return
self.saveSettings()
self.listPath = []
QDialog.accept( self )

def addAPI(self):
if self.lineEdit.text() == "":
return
path = self.lineEdit.text()
count = self.tableWidget.rowCount()
self.tableWidget.setColumnCount(2)
self.tableWidget.insertRow(count)
pathItem = QTableWidgetItem(path)
pathSplit = path.split("/")
apiName = pathSplit[-1][0:-4]
apiNameItem = QTableWidgetItem(apiName)
self.tableWidget.setItem(count, 0, apiNameItem)
self.tableWidget.setItem(count, 1, pathItem)
self.tableWidget.setHorizontalHeaderLabels([self.tr("API"), self.tr("PATH")])
self.tableWidget.horizontalHeader().setResizeMode(0, QHeaderView.ResizeToContents)
self.tableWidget.horizontalHeader().show()
self.tableWidget.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)
#self.tableWidget.resizeRowsToContents()
self.lineEdit.clear()

def removeAPI(self):
listItemSel = self.tableWidget.selectedIndexes()
#row = self.tableWidget.currentRow()
for indx in listItemSel:
self.tableWidget.removeRow(indx.row())

def fontConfig(self):
#fontFamily = ['Courier','Monospace','Aurulent Sans','Bitstream Vera Serif']
#for i in range(0, len(fontFamily)):
#self.comboBox.addItem(fontFamily[i])
settings = QSettings()
self.fontComboBox.setCurrentIndex(settings.value("pythonConsole/fontfamilyindex").toInt()[0])

def saveSettings(self):
settings = QSettings()
settings.setValue("pythonConsole/preloadAPI", QVariant(self.preloadAPI.isChecked()))
fontFamilyIndex = self.fontComboBox.currentIndex()
settings.setValue("pythonConsole/fontfamilyindex", QVariant(fontFamilyIndex))
fontFamilyText = self.fontComboBox.currentText()
settings.setValue("pythonConsole/fontfamilytext", QVariant(fontFamilyText))
fontSize = self.spinBox.value()
for i in range(0, self.tableWidget.rowCount()):
text = self.tableWidget.item(i, 1).text()
self.listPath.append(text)
settings.setValue("pythonConsole/fontsize", QVariant(fontSize))
settings.setValue("pythonConsole/userAPI", QVariant(self.listPath))

def restoreSettings(self):
settings = QSettings()
self.spinBox.setValue(settings.value("pythonConsole/fontsize").toInt()[0])
self.preloadAPI.setChecked(settings.value( "pythonConsole/preloadAPI" ).toBool())
itemTable = settings.value("pythonConsole/userAPI").toStringList()
for i in range(len(itemTable)):
self.tableWidget.insertRow(i)
self.tableWidget.setColumnCount(2)
pathSplit = itemTable[i].split("/")
apiName = pathSplit[-1][0:-4]
self.tableWidget.setItem(i, 0, QTableWidgetItem(apiName))
self.tableWidget.setItem(i, 1, QTableWidgetItem(itemTable[i]))
self.tableWidget.setHorizontalHeaderLabels([self.tr("API"), self.tr("PATH")])
self.tableWidget.horizontalHeader().setResizeMode(0, QHeaderView.ResizeToContents)
self.tableWidget.horizontalHeader().show()
self.tableWidget.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)
#self.comboBox.setCurrentIndex(settings.value("pythonConsole/fontfamilyindex").toInt()[0])

def reject( self ):
QDialog.reject( self )
297 changes: 297 additions & 0 deletions python/console_settings.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SettingsDialog</class>
<widget class="QDialog" name="SettingsDialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>472</width>
<height>388</height>
</rect>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tabGeneral">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<item row="1" column="0">
<widget class="QCheckBox" name="preloadAPI">
<property name="text">
<string>Use preloaded API file</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="3">
<widget class="QSpinBox" name="spinBox">
<property name="minimumSize">
<size>
<width>51</width>
<height>26</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>51</width>
<height>26</height>
</size>
</property>
<property name="minimum">
<number>6</number>
</property>
<property name="maximum">
<number>15</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Font</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QFontComboBox" name="fontComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="addAPIpath">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="removeAPIpath">
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QTableWidget" name="tableWidget">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerItem</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="rowCount">
<number>0</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>API file</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="browseButton">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabAbout">
<attribute name="title">
<string>Tab 2</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QTextEdit" name="textEdit">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Aurulent Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;Python Console for QGIS&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Developed by Salvatore Larosa&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;---------------------------&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SettingsDialog</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>SettingsDialog</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>