20 changes: 13 additions & 7 deletions python/console/console_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(self, shellOut, out=None, style=None):
self.style = style

def write(self, m):
if self.style == "traceback":
if self.style == "_traceback":
# Show errors in red
pos = self.sO.SendScintilla(QsciScintilla.SCI_GETCURRENTPOS)
self.sO.SendScintilla(QsciScintilla.SCI_STARTSTYLING, pos, 31)
Expand Down Expand Up @@ -73,6 +73,8 @@ def __init__(self, parent=None):
self.parent = parent
self.shell = self.parent.shell

self.settings = QSettings()

# Creates layout for message bar
self.layout = QGridLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0)
Expand All @@ -88,7 +90,7 @@ def __init__(self, parent=None):
self.setUtf8(True)

sys.stdout = writeOut(self, sys.stdout)
sys.stderr = writeOut(self, sys.stderr, "traceback")
sys.stderr = writeOut(self, sys.stderr, "_traceback")

self.insertInitText()
self.setLexers()
Expand Down Expand Up @@ -137,9 +139,8 @@ def refreshLexerProperties(self):
def setLexers(self):
self.lexer = QsciLexerPython()

settings = QSettings()
loadFont = settings.value("pythonConsole/fontfamilytext", "Monospace").toString()
fontSize = settings.value("pythonConsole/fontsize", 10).toInt()[0]
loadFont = self.settings.value("pythonConsole/fontfamilytext", "Monospace").toString()
fontSize = self.settings.value("pythonConsole/fontsize", 10).toInt()[0]
font = QFont(loadFont)
font.setFixedPitch(True)
font.setPointSize(fontSize)
Expand All @@ -165,6 +166,7 @@ def contextMenuEvent(self, e):
iconRun = QgsApplication.getThemeIcon("console/iconRunConsole.png")
iconClear = QgsApplication.getThemeIcon("console/iconClearConsole.png")
iconHideTool = QgsApplication.getThemeIcon("console/iconHideToolConsole.png")
iconSettings = QgsApplication.getThemeIcon("console/iconSettingsConsole.png")
hideToolBar = menu.addAction(iconHideTool,
"Hide/Show Toolbar",
self.hideToolBar)
Expand All @@ -187,6 +189,10 @@ def contextMenuEvent(self, e):
selectAllAction = menu.addAction("Select All",
self.selectAll,
QKeySequence.SelectAll)
menu.addSeparator()
settingsDialog = menu.addAction(iconSettings,
"Settings",
self.parent.openSettings)
runAction.setEnabled(False)
clearAction.setEnabled(False)
copyAction.setEnabled(False)
Expand All @@ -208,7 +214,7 @@ def hideToolBar(self):
self.shell.setFocus()

def showEditor(self):
Ed = self.parent.widgetEditor
Ed = self.parent.splitterObj
if not Ed.isVisible():
Ed.show()
self.parent.showEditorButton.setChecked(True)
Expand Down Expand Up @@ -242,4 +248,4 @@ def keyPressEvent(self, e):

def widgetMessageBar(self, iface, text):
timeout = iface.messageTimeout()
self.infoBar.pushMessage('Console', text, QgsMessageBar.INFO, timeout)
self.infoBar.pushMessage(text, QgsMessageBar.INFO, timeout)
53 changes: 38 additions & 15 deletions python/console/console_sci.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ def __init__(self, parent=None):

self.parent = parent

self.settings = QSettings()

# Enable non-ascii chars for editor
self.setUtf8(True)

Expand Down Expand Up @@ -74,8 +76,7 @@ def __init__(self, parent=None):
# Set Python lexer
self.setLexers()

self.setAutoCompletionThreshold(2)
self.setAutoCompletionSource(self.AcsAPIs)
self.settingsShell()

# Don't want to see the horizontal scrollbar at all
# Use raw message to Scintilla here (all messages are documented
Expand Down Expand Up @@ -103,16 +104,41 @@ def __init__(self, parent=None):
self.newShortcutCAS = QShortcut(QKeySequence(Qt.CTRL + Qt.ALT + Qt.Key_Space), self)
self.newShortcutCSS.setContext(Qt.WidgetShortcut)
self.newShortcutCAS.setContext(Qt.WidgetShortcut)
self.newShortcutCAS.activated.connect(self.autoComplete)
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):
self.setLexers()
threshold = self.settings.value("pythonConsole/autoCompThreshold", 2).toInt()[0]
self.setAutoCompletionThreshold(threshold)
radioButtonSource = self.settings.value("pythonConsole/autoCompleteSource", 'fromAPI').toString()
autoCompEnabled = self.settings.value("pythonConsole/autoCompleteEnabled", True).toBool()
self.setAutoCompletionThreshold(threshold)
if autoCompEnabled:
if radioButtonSource == 'fromDoc':
self.setAutoCompletionSource(self.AcsDocument)
elif radioButtonSource == 'fromAPI':
self.setAutoCompletionSource(self.AcsAPIs)
elif radioButtonSource == 'fromDocAPI':
self.setAutoCompletionSource(self.AcsAll)
else:
self.setAutoCompletionSource(self.AcsNone)

def showHistory(self):
self.showUserList(1, QStringList(self.history))

def autoComplete(self):
self.autoCompleteFromAll()
def autoCompleteKeyBinding(self):
radioButtonSource = self.settings.value("pythonConsole/autoCompleteSource").toString()
autoCompEnabled = self.settings.value("pythonConsole/autoCompleteEnabled").toBool()
if autoCompEnabled:
if radioButtonSource == 'fromDoc':
self.autoCompleteFromDocument()
elif radioButtonSource == 'fromAPI':
self.autoCompleteFromAPIs()
elif radioButtonSource == 'fromDocAPI':
self.autoCompleteFromAll()

def commandConsole(self, command):
if not self.is_cursor_on_last_line():
Expand All @@ -136,9 +162,9 @@ def commandConsole(self, command):

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

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

font = QFont(loadFont)
font.setFixedPitch(True)
Expand All @@ -157,11 +183,11 @@ def setLexers(self):
self.lexer.setFont(font, 4)

self.api = QsciAPIs(self.lexer)
chekBoxAPI = settings.value("pythonConsole/preloadAPI", True).toBool()
chekBoxAPI = self.settings.value("pythonConsole/preloadAPI", True).toBool()
if chekBoxAPI:
self.api.loadPrepared( QgsApplication.pkgDataPath() + "/python/qsci_apis/pyqgis_master.pap" )
else:
apiPath = settings.value("pythonConsole/userAPI").toStringList()
apiPath = self.settings.value("pythonConsole/userAPI").toStringList()
for i in range(0, len(apiPath)):
self.api.load(QString(unicode(apiPath[i])))
self.api.prepare()
Expand Down Expand Up @@ -242,9 +268,6 @@ def new_prompt(self, prompt):
self.ensureCursorVisible()
self.ensureLineVisible(line)

def refreshLexerProperties(self):
self.setLexers()

def displayPrompt(self, more=False):
self.append("... ") if more else self.append(">>> ")
self.move_cursor_to_end()
Expand Down Expand Up @@ -461,7 +484,7 @@ def currentCommand(self):
return cmd

def runCommand(self, cmd):
self.write_stdout(cmd)
self.writeCMD(cmd)
import webbrowser
self.updateHistory(cmd)
line, pos = self.getCursorPosition()
Expand Down Expand Up @@ -502,7 +525,7 @@ def runCommand(self, cmd):
def write(self, txt):
sys.stderr.write(txt)

def write_stdout(self, txt):
def writeCMD(self, txt):
if len(txt) > 0:
getCmdString = self.text()
prompt = getCmdString[0:4]
Expand Down
126 changes: 96 additions & 30 deletions python/console/console_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,29 @@ class optionsDialog(QDialog, Ui_SettingsDialogPythonConsole):
def __init__(self, parent):
QDialog.__init__(self, parent)
self.setWindowTitle(QCoreApplication.translate("SettingsDialogPythonConsole", "Settings Python Console"))
#self.iface = iface
self.parent = parent
self.setupUi(self)
#self.show()

self.listPath = []

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

self.lineEdit.setReadOnly(True)

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.autoCompleteEnabled,
SIGNAL("stateChanged(int)"), self.autoCompletionOptions)
self.connect( self.autoCompleteEnabledEditor,
SIGNAL("stateChanged(int)"), self.autoCompletionOptions)
self.connect(self.addAPIpath,
SIGNAL("clicked()"), self.addAPI)
SIGNAL("clicked()"), self.loadAPIFile)
self.connect(self.removeAPIpath,
SIGNAL("clicked()"), self.removeAPI)

Expand All @@ -63,20 +62,41 @@ def initialCheck(self):

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 autoCompletionOptions(self):
if self.autoCompleteEnabled.isChecked():
self.enableDisableAutoCompleteOptions(True)
else:
self.enableDisableAutoCompleteOptions(False)
if self.autoCompleteEnabledEditor.isChecked():
self.enableDisableAutoCompleteOptions(True, editor='editor')
else:
self.enableDisableAutoCompleteOptions(False, editor='editor')

def enableDisableAutoCompleteOptions(self, value, editor=None):
if editor:
self.autoCompFromAPIEditor.setEnabled(value)
self.autoCompFromDocAPIEditor.setEnabled(value)
self.autoCompFromDocEditor.setEnabled(value)
self.autoCompThresholdEditor.setEnabled(value)
else:
self.autoCompFromAPI.setEnabled(value)
self.autoCompFromDocAPI.setEnabled(value)
self.autoCompFromDoc.setEnabled(value)
self.autoCompThreshold.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)
if fileAPI:
self.addAPI(fileAPI)

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

def accept(self):
if not self.preloadAPI.isChecked():
Expand All @@ -88,15 +108,12 @@ def accept(self):
self.listPath = []
QDialog.accept( self )

def addAPI(self):
if self.lineEdit.text() == "":
return
path = self.lineEdit.text()
def addAPI(self, pathAPI):
count = self.tableWidget.rowCount()
self.tableWidget.setColumnCount(2)
self.tableWidget.insertRow(count)
pathItem = QTableWidgetItem(path)
pathSplit = path.split("/")
pathItem = QTableWidgetItem(pathAPI)
pathSplit = pathAPI.split("/")
apiName = pathSplit[-1][0:-4]
apiNameItem = QTableWidgetItem(apiName)
self.tableWidget.setItem(count, 0, apiNameItem)
Expand All @@ -105,40 +122,69 @@ def addAPI(self):
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())
listItemSel = self.tableWidget.selectionModel().selectedRows()
for index in reversed(listItemSel):
self.tableWidget.removeRow(index.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])
self.fontComboBoxEditor.setCurrentIndex(settings.value("pythonConsole/fontfamilyindexEditor").toInt()[0])

def saveSettings(self):
settings = QSettings()
settings.setValue("pythonConsole/preloadAPI", QVariant(self.preloadAPI.isChecked()))
settings.setValue("pythonConsole/autoSaveScript", QVariant(self.autoSaveScript.isChecked()))
fontFamilyIndex = self.fontComboBox.currentIndex()
settings.setValue("pythonConsole/fontfamilyindex", QVariant(fontFamilyIndex))
fontFamilyText = self.fontComboBox.currentText()
settings.setValue("pythonConsole/fontfamilytext", QVariant(fontFamilyText))

fontFamilyIndexEditor = self.fontComboBoxEditor.currentIndex()
settings.setValue("pythonConsole/fontfamilyindexEditor", QVariant(fontFamilyIndexEditor))
fontFamilyTextEditor = self.fontComboBoxEditor.currentText()
settings.setValue("pythonConsole/fontfamilytextEditor", QVariant(fontFamilyTextEditor))

fontSize = self.spinBox.value()
fontSizeEditor = self.spinBoxEditor.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/fontsizeEditor", QVariant(fontSizeEditor))
settings.setValue("pythonConsole/userAPI", QVariant(self.listPath))

settings.setValue("pythonConsole/autoCompThreshold", QVariant(self.autoCompThreshold.value()))
settings.setValue("pythonConsole/autoCompThresholdEditor", QVariant(self.autoCompThresholdEditor.value()))

if self.autoCompFromAPIEditor.isChecked():
settings.setValue("pythonConsole/autoCompleteSourceEditor", QVariant('fromAPI'))
elif self.autoCompFromDocEditor.isChecked():
settings.setValue("pythonConsole/autoCompleteSourceEditor", QVariant('fromDoc'))
elif self.autoCompFromDocAPIEditor.isChecked():
settings.setValue("pythonConsole/autoCompleteSourceEditor", QVariant('fromDocAPI'))

if self.autoCompFromAPI.isChecked():
settings.setValue("pythonConsole/autoCompleteSource", QVariant('fromAPI'))
elif self.autoCompFromDoc.isChecked():
settings.setValue("pythonConsole/autoCompleteSource", QVariant('fromDoc'))
elif self.autoCompFromDocAPI.isChecked():
settings.setValue("pythonConsole/autoCompleteSource", QVariant('fromDocAPI'))

settings.setValue("pythonConsole/autoCompleteEnabledEditor", QVariant(self.autoCompleteEnabledEditor.isChecked()))
settings.setValue("pythonConsole/autoCompleteEnabled", QVariant(self.autoCompleteEnabled.isChecked()))

def restoreSettings(self):
settings = QSettings()
self.spinBox.setValue(settings.value("pythonConsole/fontsize").toInt()[0])
self.preloadAPI.setChecked(settings.value("pythonConsole/preloadAPI", True).toBool())
self.spinBox.setValue(settings.value("pythonConsole/fontsize", 10).toInt()[0])
self.spinBoxEditor.setValue(settings.value("pythonConsole/fontsizeEditor", 10).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)
Expand All @@ -151,7 +197,27 @@ def restoreSettings(self):
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 )
self.autoSaveScript.setChecked(settings.value("pythonConsole/autoSaveScript", False).toBool())

self.autoCompThreshold.setValue(settings.value("pythonConsole/autoCompThreshold", 2).toInt()[0])
self.autoCompThresholdEditor.setValue(settings.value("pythonConsole/autoCompThresholdEditor", 2).toInt()[0])

self.autoCompleteEnabledEditor.setChecked(settings.value("pythonConsole/autoCompleteEnabledEditor", True).toBool())
self.autoCompleteEnabled.setChecked(settings.value("pythonConsole/autoCompleteEnabled", True).toBool())

if settings.value("pythonConsole/autoCompleteSource") == 'fromDoc':
self.autoCompFromDoc.setChecked(True)
elif settings.value("pythonConsole/autoCompleteSource") == 'fromAPI':
self.autoCompFromAPI.setChecked(True)
elif settings.value("pythonConsole/autoCompleteSource") == 'fromDocAPI':
self.autoCompFromDocAPI.setChecked(True)

if settings.value("pythonConsole/autoCompleteSourceEditor") == 'fromDoc':
self.autoCompFromDocEditor.setChecked(True)
elif settings.value("pythonConsole/autoCompleteSourceEditor") == 'fromAPI':
self.autoCompFromAPIEditor.setChecked(True)
elif settings.value("pythonConsole/autoCompleteSourceEditor") == 'fromDocAPI':
self.autoCompFromDocAPIEditor.setChecked(True)

def reject(self):
QDialog.reject(self)
662 changes: 460 additions & 202 deletions python/console/console_settings.ui

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions python/gui/qgisinterface.sip
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,29 @@ class QgisInterface : QObject
//! Add an icon to the plugins toolbar
virtual int addToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the plugins toolbar.
* To remove this widget again, call {@link removeToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addToolBarWidget( QWidget* widget ) = 0;

//! Remove an action (icon) from the plugin toolbar
virtual void removeToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the raster toolbar.
* To remove this widget again, call {@link removeRasterToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addRasterToolBarWidget( QWidget* widget ) = 0;

//! Add an icon to the Raster toolbar
//! @note added in 2.0
virtual int addRasterToolBarIcon( QAction *qAction ) = 0;
Expand All @@ -84,8 +104,19 @@ class QgisInterface : QObject

//! Add an icon to the Vector toolbar
//! @note added in 2.0

virtual int addVectorToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the vector toolbar.
* To remove this widget again, call {@link removeVectorToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addVectorToolBarWidget( QWidget* widget ) = 0;

//! Remove an action (icon) from the Vector toolbar
//! @note added in 2.0
virtual void removeVectorToolBarIcon( QAction *qAction ) = 0;
Expand All @@ -94,6 +125,16 @@ class QgisInterface : QObject
//! @note added in 2.0
virtual int addDatabaseToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the database toolbar.
* To remove this widget again, call {@link removeDatabaseToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addDatabaseToolBarWidget( QWidget* widget ) = 0;

//! Remove an action (icon) from the Database toolbar
//! @note added in 2.0
virtual void removeDatabaseToolBarIcon( QAction *qAction ) = 0;
Expand All @@ -102,6 +143,16 @@ class QgisInterface : QObject
//! @note added in 2.0
virtual int addWebToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the web toolbar.
* To remove this widget again, call {@link removeWebToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addWebToolBarWidget( QWidget* widget ) = 0;

//! Remove an action (icon) from the Web toolbar
//! @note added in 2.0
virtual void removeWebToolBarIcon( QAction *qAction ) = 0;
Expand Down
21 changes: 15 additions & 6 deletions python/plugins/GdalTools/tools/doRasterize.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def __init__(self, iface):
# set the default QSpinBoxes and QProgressBar value
self.widthSpin.setValue(3000)
self.heightSpin.setValue(3000)
self.horizresSpin.setValue(1)
self.vertresSpin.setValue(1)

self.lastEncoding = Utils.getLastUsedEncoding()

Expand All @@ -55,13 +57,16 @@ def __init__(self, iface):
(self.inSelector, SIGNAL("filenameChanged()")),
(self.outSelector, SIGNAL("filenameChanged()")),
(self.attributeComboBox, SIGNAL("currentIndexChanged(int)")),
( [self.widthSpin, self.heightSpin], SIGNAL( "valueChanged(int)" ), self.resizeGroupBox, "1.8.0" ),
( [self.widthSpin, self.heightSpin], SIGNAL( "valueChanged(int)" )),
( [self.horizresSpin, self.vertresSpin], SIGNAL( "valueChanged(double)" ))
]
)

self.connect(self.inSelector, SIGNAL("selectClicked()"), self.fillInputFileEdit)
self.connect(self.outSelector, SIGNAL("selectClicked()"), self.fillOutputFileEdit)
self.connect(self.inSelector, SIGNAL("layerChanged()"), self.fillFieldsCombo)
self.connect(self.radioSetSize, SIGNAL("toggled(bool)"), self.someValueChanged)
self.connect(self.radioSetResolution, SIGNAL("toggled(bool)"), self.someValueChanged)

def onLayersChanged(self):
self.inSelector.setLayers( Utils.LayerRegistry.instance().getVectorLayers() )
Expand Down Expand Up @@ -101,24 +106,28 @@ def fillOutputFileEdit(self):

self.outSelector.setFilename(outputFile)

# required either -ts or -tr to create the output file
# required either -ts or -tr to create the output file
if gdalVersion >= "1.8.0":
if not QFileInfo(outputFile).exists():
QMessageBox.information( self, self.tr( "Output size required" ), self.tr( "The output file doesn't exist. You must set up the output size to create it." ) )
self.resizeGroupBox.setChecked(True)
QMessageBox.information( self, self.tr( "Output size or resolution required" ), self.tr( "The output file doesn't exist. You must set up the output size or resolution to create it." ) )
self.radioSetSize.setChecked(True)

def getArguments(self):
arguments = QStringList()
if self.attributeComboBox.currentIndex() >= 0:
arguments << "-a"
arguments << self.attributeComboBox.currentText()
if self.resizeGroupBox.isChecked():
if self.radioSetSize.isChecked():
arguments << "-ts"
arguments << str( self.widthSpin.value() )
arguments << str( self.heightSpin.value() )
if self.radioSetResolution.isChecked():
arguments << "-tr"
arguments << str( self.horizresSpin.value() )
arguments << str( self.vertresSpin.value() )
inputFn = self.getInputFileName()
if not inputFn.isEmpty():
arguments << "-l"
arguments << "-l"
arguments << QFileInfo( inputFn ).baseName()
arguments << inputFn
arguments << self.getOutputFileName()
Expand Down
168 changes: 155 additions & 13 deletions python/plugins/GdalTools/tools/widgetRasterize.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>509</width>
<height>165</height>
<height>261</height>
</rect>
</property>
<property name="sizePolicy">
Expand Down Expand Up @@ -71,19 +71,42 @@
</layout>
</item>
<item>
<widget class="QGroupBox" name="resizeGroupBox">
<property name="title">
<string>New size (required if output file doens't exist)</string>
<widget class="QRadioButton" name="radioKeepSize">
<property name="text">
<string>Keep existing raster size and resolution</string>
</property>
<property name="checkable">
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioSetSize">
<property name="text">
<string>Raster size in pixels</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="label_11">
</widget>
</item>
<item>
<widget class="QWidget" name="widgetSize" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>30</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelWidth">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
Expand All @@ -95,15 +118,15 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item>
<widget class="QSpinBox" name="widthSpin">
<property name="maximum">
<number>999999</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_12">
<item>
<widget class="QLabel" name="labelHeight">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
Expand All @@ -118,7 +141,7 @@
</property>
</widget>
</item>
<item row="0" column="3">
<item>
<widget class="QSpinBox" name="heightSpin">
<property name="maximum">
<number>999999</number>
Expand All @@ -128,6 +151,92 @@
</layout>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioSetResolution">
<property name="text">
<string>Raster resolution in map units per pixel</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widgetResolution" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>30</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelHorizontal">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Horizontal</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="horizresSpin">
<property name="decimals">
<number>8</number>
</property>
<property name="maximum">
<double>999999999.990000009536743</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelVertical">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Vertical</string>
</property>
<property name="indent">
<number>40</number>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="vertresSpin">
<property name="inputMethodHints">
<set>Qt::ImhNone</set>
</property>
<property name="decimals">
<number>8</number>
</property>
<property name="maximum">
<double>999999999.990000009536743</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
Expand All @@ -139,5 +248,38 @@
</customwidget>
</customwidgets>
<resources/>
<connections/>
<connections>
<connection>
<sender>radioSetSize</sender>
<signal>toggled(bool)</signal>
<receiver>widgetSize</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>254</x>
<y>128</y>
</hint>
<hint type="destinationlabel">
<x>254</x>
<y>163</y>
</hint>
</hints>
</connection>
<connection>
<sender>radioSetResolution</sender>
<signal>toggled(bool)</signal>
<receiver>widgetResolution</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>254</x>
<y>198</y>
</hint>
<hint type="destinationlabel">
<x>254</x>
<y>233</y>
</hint>
</hints>
</connection>
</connections>
</ui>
8 changes: 4 additions & 4 deletions python/plugins/plugin_installer/installer_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ def requestFetching(self,key):
self.mRepositories[key]["state"] = 1
url = QUrl(self.mRepositories[key]["url"])
path = QString(url.toPercentEncoding(url.path(), "!$&'()*+,;=:@/"))
v=str(QGis.QGIS_VERSION_INT)
path += "?qgis=%s" % ('.'.join([str(int(s)) for s in [v[0], v[1:3], v[3:5]]]))
port = url.port()
if port < 0:
port = 80
Expand Down Expand Up @@ -426,14 +428,12 @@ def xmlDownloaded(self,nr,state):
"localdir" : name,
"read-only" : False}
qgisMinimumVersion = pluginNodes.item(i).firstChildElement("qgis_minimum_version").text().simplified()
if not qgisMinimumVersion: qgisMinimumVersion = "0"
# please use the tag below only if really needed! (for example if plugin development is abandoned)
if not qgisMinimumVersion: qgisMinimumVersion = "1"
qgisMaximumVersion = pluginNodes.item(i).firstChildElement("qgis_maximum_version").text().simplified()
if not qgisMaximumVersion: qgisMaximumVersion = "2"
if not qgisMaximumVersion: qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
#if compatible, add the plugin to the list
if not pluginNodes.item(i).firstChildElement("disabled").text().simplified().toUpper() in ["TRUE","YES"]:
if compareVersions(QGIS_VER, qgisMinimumVersion) < 2 and compareVersions(qgisMaximumVersion, QGIS_VER) < 2:
if QGIS_VER[0]==qgisMinimumVersion[0] or (qgisMinimumVersion!="0" and qgisMaximumVersion!="2"): # to be deleted
#add the plugin to the cache
plugins.addFromRepository(plugin)
# set state=2, even if the repo is empty
Expand Down
6 changes: 3 additions & 3 deletions python/plugins/plugin_installer/metadata.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
name=Plugin Installer
description=Downloads and installs QGIS python plugins
category=Plugins
version=1.2.1
qgisMinimumVersion=1.0
version=1.3
qgisMinimumVersion=1.9

author=Borys Jurgiel
email=borysiasty@aster.pl
email=qgis@borysjurgiel.pl

icon=plugin_installer.png

Expand Down
18 changes: 11 additions & 7 deletions python/plugins/sextante/SextantePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ def __init__(self, iface):
Sextante.setInterface(iface)
Sextante.setPlugin(self)

def initGui(self):
def initGui(self):
self.commander = None
self.toolbox = SextanteToolbox(self.iface)
self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox)
self.toolbox.hide()
Sextante.addAlgListListener(self.toolbox)

self.menu = QMenu(self.iface.mainWindow())
self.menu.setTitle(QCoreApplication.translate("SEXTANTE", "Analysis"))

Expand Down Expand Up @@ -100,7 +101,7 @@ def initGui(self):
self.iface.mainWindow())
self.commanderAction.triggered.connect(self.openCommander)
self.menu.addAction(self.commanderAction)
self.iface.registerMainWindowAction(self.commanderAction, "Ctrl+Alt+M")
self.iface.registerMainWindowAction(self.commanderAction, "Ctrl+Alt+M")

def unload(self):
self.toolbox.setVisible(False)
Expand All @@ -112,10 +113,13 @@ def unload(self):

self.iface.unregisterMainWindowAction(self.commanderAction)

def openCommander(self):
dlg = CommanderWindow(self.iface.mainWindow(), self.iface.mapCanvas())
dlg.show()
dlg.exec_()
def openCommander(self):
if self.commander is None:
self.commander = CommanderWindow(self.iface.mainWindow(), self.iface.mapCanvas())
Sextante.addAlgListListener(self.commander)
self.commander.prepareGui()
self.commander.show()
#dlg.exec_()


def openToolbox(self):
Expand Down
52 changes: 31 additions & 21 deletions python/plugins/sextante/commander/CommanderWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class CommanderWindow(QtGui.QDialog):
def __init__(self, parent, canvas):
self.canvas = canvas
QtGui.QDialog.__init__(self, parent, Qt.FramelessWindowHint)
self.setModal(True)
self.commands = imp.load_source("commands", self.commandsFile())
#self.setModal(True)
self.commands = imp.load_source("commands", self.commandsFile())
self.initGui()

def commandsFolder(self):
Expand All @@ -65,29 +65,14 @@ def commandsFile(self):
out.close()
return f

def algsListHasChanged(self):
self.fillCombo()

def initGui(self):
self.combo= ExtendedComboBox()
#add algorithm
for providerName in Sextante.algs.keys():
provider = Sextante.algs[providerName]
algs = provider.values()
for alg in algs:
self.combo.addItem("SEXTANTE algorithm: " + alg.name)
#add functions
for command in dir(self.commands):
if isinstance(self.commands.__dict__.get(command), types.FunctionType):
self.combo.addItem("Command: " + command);
#add menu entries
menuActions = []
actions = Sextante.getInterface().mainWindow().menuBar().actions()
for action in actions:
menuActions.extend(self.getActions(action))
for action in menuActions:
self.combo.addItem("Menu action: " + unicode(action.text()))
self.combo= ExtendedComboBox()
self.fillCombo()

self.combo.setEditable(True)
self.combo.setEditText("")
self.label = QtGui.QLabel("Enter command:")
self.errorLabel = QtGui.QLabel("Enter command:")
self.vlayout = QtGui.QVBoxLayout()
Expand All @@ -104,6 +89,31 @@ def initGui(self):
self.vlayout.addSpacerItem(QtGui.QSpacerItem(0, OFFSET, QSizePolicy.Maximum, QSizePolicy.Expanding));
self.setLayout(self.vlayout)
self.combo.lineEdit().returnPressed.connect(self.run)
self.prepareGui()

def fillCombo(self):
self.combo.clear()
#add algorithms
for providerName in Sextante.algs.keys():
provider = Sextante.algs[providerName]
algs = provider.values()
for alg in algs:
self.combo.addItem("SEXTANTE algorithm: " + alg.name)
#add functions
for command in dir(self.commands):
if isinstance(self.commands.__dict__.get(command), types.FunctionType):
self.combo.addItem("Command: " + command);
#add menu entries
menuActions = []
actions = Sextante.getInterface().mainWindow().menuBar().actions()
for action in actions:
menuActions.extend(self.getActions(action))
for action in menuActions:
self.combo.addItem("Menu action: " + unicode(action.text()))


def prepareGui(self):
self.combo.setEditText("")
self.combo.setMaximumSize(QtCore.QSize(self.canvas.rect().width() - 2 * OFFSET, ITEMHEIGHT))
self.combo.view().setStyleSheet("min-height: 150px")
self.combo.setFocus(Qt.OtherFocusReason)
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextante/gui/HistoryDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
* *
***************************************************************************
"""
from sextante.gui import TestTools

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
Expand All @@ -26,6 +25,7 @@

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from sextante.gui import TestTools
from sextante.core.SextanteLog import SextanteLog
from sextante.ui.ui_DlgHistory import Ui_DlgHistory

Expand Down
85 changes: 81 additions & 4 deletions python/plugins/sextante/gui/help/algclasssification.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,89 @@ gdalogr:merge,USE_ORIGINAL_NAME,Raster/General tools
gdalogr:nearblack,USE_ORIGINAL_NAME,Raster/Analysis
gdalogr:ogr2ogr,Export vector layer,Vector/General tools
gdalogr:ogrinfo,Vector layer information,Vector/Statistics
gdalogr:pct2rgb,USE_ORIGINAL_NAME,Images/Image tools
gdalogr:pct2rgb,PCT to RGB,Images/Image Manipulation
gdalogr:proximity,USE_ORIGINAL_NAME,Raster/Analysis
gdalogr:rgb2pct,USE_ORIGINAL_NAME,Images/Image tools
gdalogr:rgb2pct,RGB to PCT,Images/Image Manipulation
gdalogr:sieve,Remove small pixel clumps (nearest neighbour),Raster/Edition
gdalogr:translateconvertformat,Export raster layer,Raster/General tools
gdalogr:warpreproject,Reproject raster layer,Raster/General tools
otb:bandmath,USE_ORIGINAL_NAME,Images/Miscellaneous
otb:binarymorphologicaloperation,USE_ORIGINAL_NAME,Images/Image Filtering
otb:bundletoperfectsensor,USE_ORIGINAL_NAME,Images/Geometry
otb:cartographictogeographiccoordinatesconversion,USE_ORIGINAL_NAME,Images/Geometry
otb:classificationregularization,USE_ORIGINAL_NAME,Images/Learning
otb:colormapping,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:computeconfusionmatrix,USE_ORIGINAL_NAME,Images/Learning
otb:computeimagessecondorderstatistics,USE_ORIGINAL_NAME,Images/Learning
otb:computepolylinefeaturefromimage,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:concatenate,USE_ORIGINAL_NAME,Images/Vector Data Manipulation
otb:connectedcomponentsegmentation,USE_ORIGINAL_NAME,Images/Segmentation
otb:convertsensorpointtogeographicpoint,USE_ORIGINAL_NAME,Images/Geometry
otb:dimensionalityreductionapplication,USE_ORIGINAL_NAME,Images/Image Filtering
otb:disparitymaptoelevationmap,USE_ORIGINAL_NAME,Images/Stereo
otb:edgeextraction,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:edisonmeanshiftsegmentationlabeledrasteroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:edisonmeanshiftsegmentationlargescalevectoroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:extractroi,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:fineregistration,USE_ORIGINAL_NAME,Images/Stereo
otb:fusionofclassifications,USE_ORIGINAL_NAME,Images/Learning
otb:fuzzymodelestimation,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:grayscalemorphologicaloperation,USE_ORIGINAL_NAME,Images/Image Filtering
otb:gridbasedimageresampling,USE_ORIGINAL_NAME,Images/Geometry
otb:haralicktextureextraction,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:hoovercomparesegmentation,USE_ORIGINAL_NAME,Images/Segmentation
otb:hyperspectraldataunmixing,USE_ORIGINAL_NAME,Images/Miscellaneous
otb:imageconversion,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:imageenvelope,USE_ORIGINAL_NAME,Images/Geometry
otb:imageresamplingwitharigidtransform,USE_ORIGINAL_NAME,Images/Geometry
otb:imagescomparaison,USE_ORIGINAL_NAME,Images/Miscellaneous
otb:imagesconcatenation,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:imagesvmclassification,USE_ORIGINAL_NAME,Images/Learning
otb:imagetokmzexport,USE_ORIGINAL_NAME,Images/Miscellaneous
otb:linesegmentdetection,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:localstatisticextraction,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:maximumautocorrelationfactordecomposition,USE_ORIGINAL_NAME,Images/Image Filtering
otb:meanshiftfiltering,USE_ORIGINAL_NAME,Images/Image Filtering
otb:meanshiftsegmentationlabeledrasteroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:meanshiftsegmentationlargescalevectoroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:morphologicalprofilesbasedsegmentationlabeledrasteroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:morphologicalprofilesbasedsegmentationlargescalevectoroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:multiresolutionpyramid,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:multivariatealterationdetector,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:obtainutmzonefromgeopoint,USE_ORIGINAL_NAME,Images/Miscellaneous
otb:openstreetmaplayersimportationsapplications,USE_ORIGINAL_NAME,Images/Miscellaneous
otb:opticalcalibration,USE_ORIGINAL_NAME,Images/Calibration
otb:orthorectification,USE_ORIGINAL_NAME,Images/Geometry
otb:pansharpening,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:pixelvalue,USE_ORIGINAL_NAME,Images/Miscellaneous
otb:pixelwiseblockmatching,USE_ORIGINAL_NAME,Images/Stereo
otb:pixelwiseblockmatching,USE_ORIGINAL_NAME,Images/Stereo
otb:quicklook,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:radiometricindices,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:rasterization,USE_ORIGINAL_NAME,Images/Vector Data Manipulation
otb:readimageinformation,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:rescaleimage,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:sarradiometriccalibration,USE_ORIGINAL_NAME,Images/Calibration
otb:sfstextureextraction,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:simpleconnectedcomponentssegmentationlabeledrasteroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:simpleconnectedcomponentssegmentationlargescalevectoroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:smoothing,USE_ORIGINAL_NAME,Images/Image Filtering
otb:somclassification,USE_ORIGINAL_NAME,Images/Learning
otb:splitimage,USE_ORIGINAL_NAME,Images/Image Manipulation
otb:stereorectificationdeformationgridgenerator,USE_ORIGINAL_NAME,Images/Geometry
otb:stereosensormodeltoelevationmap,USE_ORIGINAL_NAME,Images/Stereo
otb:superimposesensor,USE_ORIGINAL_NAME,Images/Geometry
otb:trainsvmclassifierfrommultipleimages,USE_ORIGINAL_NAME,Images/Learning
otb:unsupervisedkmeansimageclassification,USE_ORIGINAL_NAME,Images/Learning
otb:validatesvmimagesclassifier,USE_ORIGINAL_NAME,Images/Learning
otb:vectordataextractroi,USE_ORIGINAL_NAME,Images/Vector Data Manipulation
otb:vectordatareprojection,USE_ORIGINAL_NAME,Images/Vector Data Manipulation
otb:vectordatasetfield,USE_ORIGINAL_NAME,Images/Vector Data Manipulation
otb:vectordatatransformation,USE_ORIGINAL_NAME,Images/Vector Data Manipulation
otb:vectordatavalidation,USE_ORIGINAL_NAME,Images/Feature Extraction
otb:vertexcomponentanalysis,USE_ORIGINAL_NAME,Images/Miscellaneous
otb:watershedsegmentationlabeledrasteroutput,USE_ORIGINAL_NAME,Images/Segmentation
otb:watershedsegmentationlargescalevectoroutput,USE_ORIGINAL_NAME,Images/Segmentation
qgis:addautoincrementalfield,USE_ORIGINAL_NAME,Vector/Table tools
qgis:addfieldtoattributestable,USE_ORIGINAL_NAME,Vector/Table tools
qgis:advancedpythonfieldcalculator,USE_ORIGINAL_NAME,Vector/Table tools
Expand Down Expand Up @@ -82,8 +159,8 @@ saga:aggregatepointobservations,USE_ORIGINAL_NAME,Vector/Points
saga:aggregationindex,USE_ORIGINAL_NAME,Raster/Miscellaneous
saga:analyticalhierarchyprocess,USE_ORIGINAL_NAME,Raster/Miscellaneous
saga:analyticalhillshading,USE_ORIGINAL_NAME,Domain specific/Viewsheds\Lighting
saga:bsplineapproximation,USE_ORIGINAL_NAME,Raster - vector/Raster -> Vector
saga:basicterrainanalysis,USE_ORIGINAL_NAME,Domain specific/Terrain analysis and geomorphometry
saga:bsplineapproximation,USE_ORIGINAL_NAME,Raster - vector/Raster -> Vector
saga:burnstreamnetworkintodem,USE_ORIGINAL_NAME,Domain specific/Hydrology
saga:catchmentareaflowtracing,USE_ORIGINAL_NAME,Domain specific/Hydrology
saga:catchmentareamassfluxmethod,USE_ORIGINAL_NAME,Domain specific/Hydrology
Expand Down Expand Up @@ -223,8 +300,8 @@ saga:nearestneighbour,USE_ORIGINAL_NAME,Raster - vector/Vector -> Raster
saga:orderedweightedaveragingowa,USE_ORIGINAL_NAME,Raster/Analysis
saga:ordinarykriging,USE_ORIGINAL_NAME,Raster - vector/Vector -> Raster
saga:ordinarykrigingglobal,USE_ORIGINAL_NAME,Raster - vector/Vector -> Raster
saga:overlandflowkinematicwaved8,USE_ORIGINAL_NAME,Domain specific/Hydrology
saga:overlandflowdistancetochannelnetwork,USE_ORIGINAL_NAME,Domain specific/Hydrology
saga:overlandflowkinematicwaved8,USE_ORIGINAL_NAME,Domain specific/Hydrology
saga:patching,USE_ORIGINAL_NAME,Raster/General tools
saga:patternanalysis,USE_ORIGINAL_NAME,Raster/Analysis
saga:pointsfilter,USE_ORIGINAL_NAME,Vector/Points
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextante/otb/OTBAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def processAlgorithm(self, progress):

for out in self.outputs:
commands.append(out.name)
commands.append(out.value)
commands.append('"' + out.value + '"')
for roiInput, roiFile in self.roiRasters.items():
startX, startY = float(self.roiValues[0]), float(self.roiValues[1])
sizeX = float(self.roiValues[2]) - startX
Expand Down

This file was deleted.

This file was deleted.

17 changes: 17 additions & 0 deletions resources/function_help/color_cmyk-en_US
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

<h3>color_cmyk() function</h3>
Returns a string representation of a color based on its cyan, magenta, yellow and black components

<p><h4>Syntax</h4>
color_cmyk(<i>cyan, magenta, yellow, black</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> cyan</i> &rarr; the cyan component of the color, as a percentage integer value from 0 to 100.<br>
<i> magenta</i> &rarr; the magenta component of the color, as a percentage integer value from 0 to 100.<br>
<i> yellow</i> &rarr; the yellow component of the color, as a percentage integer value from 0 to 100.<br>
<i> black</i> &rarr; the black component of the color, as a percentage integer value from 0 to 100.<br>

<p><h4>Example</h4>
<!-- Show example of function.-->
color_cmyk(100,50,0,10) &rarr; '#0073e6'</p>
18 changes: 18 additions & 0 deletions resources/function_help/color_cmyka-en_US
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

<h3>color_cmyka() function</h3>
Returns a string representation of a color based on its cyan, magenta, yellow, black and alpha (transparency) components

<p><h4>Syntax</h4>
color_cmyka(<i>cyan, magenta, yellow, black, alpha</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> cyan</i> &rarr; the cyan component of the color, as a percentage integer value from 0 to 100.<br>
<i> magenta</i> &rarr; the magenta component of the color, as a percentage integer value from 0 to 100.<br>
<i> yellow</i> &rarr; the yellow component of the color, as a percentage integer value from 0 to 100.<br>
<i> black</i> &rarr; the black component of the color, as a percentage integer value from 0 to 100.<br>
<i> alpha</i> &rarr; the alpha component as an integer value from 0 (completely transparent) to 255 (opaque).<br>

<p><h4>Example</h4>
<!-- Show example of function.-->
color_cmyka(100,50,0,10,200) &rarr; '0,115,230,200'</p>
16 changes: 16 additions & 0 deletions resources/function_help/color_hsl-en_US
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

<h3>color_hsl() function</h3>
Returns a string representation of a color based on its hue, saturation, and lightness attributes

<p><h4>Syntax</h4>
color_hsl(<i>hue, saturation, lightness</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> hue</i> &rarr; the hue of the color, as an integer value from 0 to 360.<br>
<i> saturation</i> &rarr; the saturation percentage of the color as an integer value from 0 to 100.<br>
<i> lightness</i> &rarr; the lightness percentage of the color as an integer value from 0 to 100.<br>

<p><h4>Example</h4>
<!-- Show example of function.-->
color_hsl(100,50,70) &rarr; '#a6d98c'</p>
17 changes: 17 additions & 0 deletions resources/function_help/color_hsla-en_US
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

<h3>color_hsla() function</h3>
Returns a string representation of a color based on its hue, saturation, lightness and alpha (transparency) attributes

<p><h4>Syntax</h4>
color_hsla(<i>hue, saturation, lightness, alpha</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> hue</i> &rarr; the hue of the color, as an integer value from 0 to 360.<br>
<i> saturation</i> &rarr; the saturation percentage of the color as an integer value from 0 to 100.<br>
<i> lightness</i> &rarr; the lightness percentage of the color as an integer value from 0 to 100.<br>
<i> alpha</i> &rarr; the alpha component as an integer value from 0 (completely transparent) to 255 (opaque).<br>

<p><h4>Example</h4>
<!-- Show example of function.-->
color_hsla(100,50,70,200) &rarr; '166,217,140,200'</p>
16 changes: 16 additions & 0 deletions resources/function_help/color_hsv-en_US
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

<h3>color_hsv() function</h3>
Returns a string representation of a color based on its hue, saturation, and value attributes

<p><h4>Syntax</h4>
color_hsv(<i>hue, saturation, value</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> hue</i> &rarr; the hue of the color, as an integer value from 0 to 360.<br>
<i> saturation</i> &rarr; the saturation percentage of the color as an integer value from 0 to 100.<br>
<i> value</i> &rarr; the value percentage of the color as an integer from 0 to 100.<br>

<p><h4>Example</h4>
<!-- Show example of function.-->
color_hsv(40,100,100) &rarr; '#ffaa00'</p>
17 changes: 17 additions & 0 deletions resources/function_help/color_hsva-en_US
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

<h3>color_hsva() function</h3>
Returns a string representation of a color based on its hue, saturation, value and alpha (transparency) attributes

<p><h4>Syntax</h4>
color_hsva(<i>hue, saturation, value, alpha</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> hue</i> &rarr; the hue of the color, as an integer value from 0 to 360.<br>
<i> saturation</i> &rarr; the saturation percentage of the color as an integer value from 0 to 100.<br>
<i> value</i> &rarr; the value percentage of the color as an integer from 0 to 100.<br>
<i> alpha</i> &rarr; the alpha component as an integer value from 0 (completely transparent) to 255 (opaque).<br>

<p><h4>Example</h4>
<!-- Show example of function.-->
color_hsva(40,100,100,200) &rarr; '255,170,0,200'</p>
14 changes: 14 additions & 0 deletions resources/function_help/regexp_match-en_US
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<h3>regexp_match() function</h3>
Returns true if any part of a string matches the supplied regular expression.

<p><h4>Syntax</h4>
regexp_match(<i>string,regex</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> string</i> &rarr; is string. The string to test against the regular expression.<br>
<i> regex</i> &rarr; is string. The regular expression to test against. Backslash characters must be double escaped (eg "\\s" to match a white space character).<br>

<p><h4>Example</h4>
<!-- Show example of function.-->
regexp_match('QGIS ROCKS','\\sROCKS') &rarr; 1</p>
8 changes: 4 additions & 4 deletions resources/function_help/regexp_replace-en_US
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
Returns a string with the supplied regular expression replaced.

<p><h4>Syntax</h4>
replace(<i>string,before,after</i>)</p>
regexp_replace(<i>string,regex,after</i>)</p>

<p><h4>Arguments</h4>
<!-- List args for functions here-->
<i> string</i> &rarr; is string. The start string.<br>
<i> before</i> &rarr; is string. The string to replace.<br>
<i> after</i> &rarr; is string. The string that will replace <i>before</i><br></p>
<i> regex</i> &rarr; is string. The regular expression to replace. Backslash characters must be double escaped (eg "\\s" to match a white space character).<br>
<i> after</i> &rarr; is string. The string that will replace any matching occurences of the supplied regular expression. Captured groups can be inserted into the replacement string using \\1, \\2, etc. <br></p>

<p><h4>Example</h4>
<!-- Show example of function.-->
replace('QGIS SHOULD ROCK','SHOULD','DOES') &rarr; 'QGIS DOES ROCK'</p>
regexp_replace('QGIS SHOULD ROCK','\\sSHOULD\\s',' DOES ') &rarr; 'QGIS DOES ROCK'</p>
25 changes: 25 additions & 0 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7342,6 +7342,11 @@ int QgisApp::addPluginToolBarIcon( QAction * qAction )
return 0;
}

QAction*QgisApp::addPluginToolBarWidget( QWidget* widget )
{
return mPluginToolBar->addWidget( widget );
}

void QgisApp::removePluginToolBarIcon( QAction *qAction )
{
mPluginToolBar->removeAction( qAction );
Expand All @@ -7353,6 +7358,11 @@ int QgisApp::addRasterToolBarIcon( QAction * qAction )
return 0;
}

QAction*QgisApp::addRasterToolBarWidget( QWidget* widget )
{
return mRasterToolBar->addWidget( widget );
}

void QgisApp::removeRasterToolBarIcon( QAction *qAction )
{
mRasterToolBar->removeAction( qAction );
Expand All @@ -7364,6 +7374,11 @@ int QgisApp::addVectorToolBarIcon( QAction * qAction )
return 0;
}

QAction*QgisApp::addVectorToolBarWidget( QWidget* widget )
{
return mVectorToolBar->addWidget( widget );
}

void QgisApp::removeVectorToolBarIcon( QAction *qAction )
{
mVectorToolBar->removeAction( qAction );
Expand All @@ -7375,6 +7390,11 @@ int QgisApp::addDatabaseToolBarIcon( QAction * qAction )
return 0;
}

QAction*QgisApp::addDatabaseToolBarWidget( QWidget* widget )
{
return mDatabaseToolBar->addWidget( widget );
}

void QgisApp::removeDatabaseToolBarIcon( QAction *qAction )
{
mDatabaseToolBar->removeAction( qAction );
Expand All @@ -7386,6 +7406,11 @@ int QgisApp::addWebToolBarIcon( QAction * qAction )
return 0;
}

QAction*QgisApp::addWebToolBarWidget( QWidget* widget )
{
return mWebToolBar->addWidget( widget );
}

void QgisApp::removeWebToolBarIcon( QAction *qAction )
{
mWebToolBar->removeAction( qAction );
Expand Down
45 changes: 45 additions & 0 deletions src/app/qgisapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -724,22 +724,67 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
void removeAddLayerAction( QAction* action );
//! Add an icon to the plugin toolbar
int addPluginToolBarIcon( QAction * qAction );
/**
* Add a widget to the plugins toolbar.
* To remove this widget again, call {@link removeToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addPluginToolBarWidget( QWidget* widget );
//! Remove an icon from the plugin toolbar
void removePluginToolBarIcon( QAction *qAction );
//! Add an icon to the Raster toolbar
int addRasterToolBarIcon( QAction * qAction );
/**
* Add a widget to the raster toolbar.
* To remove this widget again, call {@link removeRasterToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addRasterToolBarWidget( QWidget* widget );
//! Remove an icon from the Raster toolbar
void removeRasterToolBarIcon( QAction *qAction );
//! Add an icon to the Vector toolbar
int addVectorToolBarIcon( QAction * qAction );
/**
* Add a widget to the vector toolbar.
* To remove this widget again, call {@link removeVectorToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addVectorToolBarWidget( QWidget* widget );
//! Remove an icon from the Vector toolbar
void removeVectorToolBarIcon( QAction *qAction );
//! Add an icon to the Database toolbar
int addDatabaseToolBarIcon( QAction * qAction );
/**
* Add a widget to the database toolbar.
* To remove this widget again, call {@link removeDatabaseToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addDatabaseToolBarWidget( QWidget* widget );
//! Remove an icon from the Database toolbar
void removeDatabaseToolBarIcon( QAction *qAction );
//! Add an icon to the Web toolbar
int addWebToolBarIcon( QAction * qAction );
/**
* Add a widget to the web toolbar.
* To remove this widget again, call {@link removeWebToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addWebToolBarWidget( QWidget* widget );
//! Remove an icon from the Web toolbar
void removeWebToolBarIcon( QAction *qAction );
//! Save window state
Expand Down
25 changes: 25 additions & 0 deletions src/app/qgisappinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ int QgisAppInterface::addToolBarIcon( QAction * qAction )
return qgis->addPluginToolBarIcon( qAction );
}

QAction*QgisAppInterface::addToolBarWidget( QWidget* widget )
{
return qgis->addPluginToolBarWidget( widget );
}

void QgisAppInterface::removeToolBarIcon( QAction *qAction )
{
qgis->removePluginToolBarIcon( qAction );
Expand All @@ -213,6 +218,11 @@ int QgisAppInterface::addRasterToolBarIcon( QAction * qAction )
return qgis->addRasterToolBarIcon( qAction );
}

QAction*QgisAppInterface::addRasterToolBarWidget( QWidget* widget )
{
return qgis->addRasterToolBarWidget( widget );
}

void QgisAppInterface::removeRasterToolBarIcon( QAction *qAction )
{
qgis->removeRasterToolBarIcon( qAction );
Expand All @@ -223,6 +233,11 @@ int QgisAppInterface::addVectorToolBarIcon( QAction * qAction )
return qgis->addVectorToolBarIcon( qAction );
}

QAction*QgisAppInterface::addVectorToolBarWidget(QWidget* widget)
{
return qgis->addVectorToolBarWidget( widget );
}

void QgisAppInterface::removeVectorToolBarIcon( QAction *qAction )
{
qgis->removeVectorToolBarIcon( qAction );
Expand All @@ -233,6 +248,11 @@ int QgisAppInterface::addDatabaseToolBarIcon( QAction * qAction )
return qgis->addDatabaseToolBarIcon( qAction );
}

QAction*QgisAppInterface::addDatabaseToolBarWidget(QWidget* widget)
{
return qgis->addDatabaseToolBarWidget( widget );
}

void QgisAppInterface::removeDatabaseToolBarIcon( QAction *qAction )
{
qgis->removeDatabaseToolBarIcon( qAction );
Expand All @@ -243,6 +263,11 @@ int QgisAppInterface::addWebToolBarIcon( QAction * qAction )
return qgis->addWebToolBarIcon( qAction );
}

QAction*QgisAppInterface::addWebToolBarWidget(QWidget* widget)
{
return qgis->addWebToolBarWidget( widget );
}

void QgisAppInterface::removeWebToolBarIcon( QAction *qAction )
{
qgis->removeWebToolBarIcon( qAction );
Expand Down
45 changes: 45 additions & 0 deletions src/app/qgisappinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,22 +80,67 @@ class QgisAppInterface : public QgisInterface

//! Add an icon to the plugins toolbar
int addToolBarIcon( QAction *qAction );
/**
* Add a widget to the plugins toolbar.
* To remove this widget again, call {@link removeToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addToolBarWidget( QWidget* widget );
//! Remove an icon (action) from the plugin toolbar
void removeToolBarIcon( QAction *qAction );
//! Add an icon to the Raster toolbar
int addRasterToolBarIcon( QAction *qAction );
/**
* Add a widget to the raster toolbar.
* To remove this widget again, call {@link removeRasterToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addRasterToolBarWidget( QWidget* widget );
//! Remove an icon (action) from the Raster toolbar
void removeRasterToolBarIcon( QAction *qAction );
//! Add an icon to the Vector toolbar
int addVectorToolBarIcon( QAction *qAction );
/**
* Add a widget to the vector toolbar.
* To remove this widget again, call {@link removeVectorToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addVectorToolBarWidget( QWidget* widget );
//! Remove an icon (action) from the Vector toolbar
void removeVectorToolBarIcon( QAction *qAction );
//! Add an icon to the Database toolbar
int addDatabaseToolBarIcon( QAction *qAction );
/**
* Add a widget to the database toolbar.
* To remove this widget again, call {@link removeDatabaseToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addDatabaseToolBarWidget( QWidget* widget );
//! Remove an icon (action) from the Database toolbar
void removeDatabaseToolBarIcon( QAction *qAction );
//! Add an icon to the Web toolbar
int addWebToolBarIcon( QAction *qAction );
/**
* Add a widget to the web toolbar.
* To remove this widget again, call {@link removeWebToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
QAction* addWebToolBarWidget( QWidget* widget );
//! Remove an icon (action) from the Web toolbar
void removeWebToolBarIcon( QAction *qAction );

Expand Down
150 changes: 149 additions & 1 deletion src/core/qgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,21 @@ static QVariant fcnRegexpReplace( const QVariantList& values, QgsFeature* , QgsE
}
return QVariant( str.replace( re, after ) );
}

static QVariant fcnRegexpMatch( const QVariantList& values, QgsFeature* , QgsExpression* parent )
{
QString str = getStringValue( values.at( 0 ), parent );
QString regexp = getStringValue( values.at( 1 ), parent );

QRegExp re( regexp );
if ( !re.isValid() )
{
parent->setEvalErrorString( QObject::tr( "Invalid regular expression '%1': %2" ).arg( regexp ).arg( re.errorString() ) );
return QVariant();
}
return QVariant( str.contains( re ) ? 1 : 0 );
}

static QVariant fcnSubstr( const QVariantList& values, QgsFeature* , QgsExpression* parent )
{
QString str = getStringValue( values.at( 0 ), parent );
Expand Down Expand Up @@ -1023,6 +1038,130 @@ QVariant fcnRampColor( const QVariantList &values, QgsFeature *, QgsExpression *
return color.name();
}

static QVariant fcnColorHsl( const QVariantList &values, QgsFeature *, QgsExpression *parent )
{
// Hue ranges from 0 - 360
double hue = getIntValue( values.at( 0 ), parent ) / 360.0;
// Saturation ranges from 0 - 100
double saturation = getIntValue( values.at( 1 ), parent ) / 100.0;
// Lightness ranges from 0 - 100
double lightness = getIntValue( values.at( 2 ), parent ) / 100.0;

QColor color = QColor::fromHslF( hue, saturation, lightness );

if ( ! color.isValid() )
{
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( lightness ) );
color = QColor( 0, 0, 0 );
}

return color.name();
}

static QVariant fncColorHsla( const QVariantList &values, QgsFeature *, QgsExpression *parent )
{
// Hue ranges from 0 - 360
double hue = getIntValue( values.at( 0 ), parent ) / 360.0;
// Saturation ranges from 0 - 100
double saturation = getIntValue( values.at( 1 ), parent ) / 100.0;
// Lightness ranges from 0 - 100
double lightness = getIntValue( values.at( 2 ), parent ) / 100.0;
// Alpha ranges from 0 - 255
double alpha = getIntValue( values.at( 3 ), parent ) / 255.0;

QColor color = QColor::fromHslF( hue, saturation, lightness, alpha );
if ( ! color.isValid() )
{
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( lightness ).arg( alpha ) );
color = QColor( 0, 0, 0 );
}
return QgsSymbolLayerV2Utils::encodeColor( color );
}

static QVariant fcnColorHsv( const QVariantList &values, QgsFeature *, QgsExpression *parent )
{
// Hue ranges from 0 - 360
double hue = getIntValue( values.at( 0 ), parent ) / 360.0;
// Saturation ranges from 0 - 100
double saturation = getIntValue( values.at( 1 ), parent ) / 100.0;
// Value ranges from 0 - 100
double value = getIntValue( values.at( 2 ), parent ) / 100.0;

QColor color = QColor::fromHsvF( hue, saturation, value );

if ( ! color.isValid() )
{
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3' to color" ).arg( hue ).arg( saturation ).arg( value ) );
color = QColor( 0, 0, 0 );
}

return color.name();
}

static QVariant fncColorHsva( const QVariantList &values, QgsFeature *, QgsExpression *parent )
{
// Hue ranges from 0 - 360
double hue = getIntValue( values.at( 0 ), parent ) / 360.0;
// Saturation ranges from 0 - 100
double saturation = getIntValue( values.at( 1 ), parent ) / 100.0;
// Value ranges from 0 - 100
double value = getIntValue( values.at( 2 ), parent ) / 100.0;
// Alpha ranges from 0 - 255
double alpha = getIntValue( values.at( 3 ), parent ) / 255.0;

QColor color = QColor::fromHsvF( hue, saturation, value, alpha );
if ( ! color.isValid() )
{
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4' to color" ).arg( hue ).arg( saturation ).arg( value ).arg( alpha ) );
color = QColor( 0, 0, 0 );
}
return QgsSymbolLayerV2Utils::encodeColor( color );
}

static QVariant fcnColorCmyk( const QVariantList &values, QgsFeature *, QgsExpression *parent )
{
// Cyan ranges from 0 - 100
double cyan = getIntValue( values.at( 0 ), parent ) / 100.0;
// Magenta ranges from 0 - 100
double magenta = getIntValue( values.at( 1 ), parent ) / 100.0;
// Yellow ranges from 0 - 100
double yellow = getIntValue( values.at( 2 ), parent ) / 100.0;
// Black ranges from 0 - 100
double black = getIntValue( values.at( 3 ), parent ) / 100.0;

QColor color = QColor::fromCmykF( cyan, magenta, yellow, black );

if ( ! color.isValid() )
{
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ) );
color = QColor( 0, 0, 0 );
}

return color.name();
}

static QVariant fncColorCmyka( const QVariantList &values, QgsFeature *, QgsExpression *parent )
{
// Cyan ranges from 0 - 100
double cyan = getIntValue( values.at( 0 ), parent ) / 100.0;
// Magenta ranges from 0 - 100
double magenta = getIntValue( values.at( 1 ), parent ) / 100.0;
// Yellow ranges from 0 - 100
double yellow = getIntValue( values.at( 2 ), parent ) / 100.0;
// Black ranges from 0 - 100
double black = getIntValue( values.at( 3 ), parent ) / 100.0;
// Alpha ranges from 0 - 255
double alpha = getIntValue( values.at( 4 ), parent ) / 255.0;

QColor color = QColor::fromCmykF( cyan, magenta, yellow, black, alpha );
if ( ! color.isValid() )
{
parent->setEvalErrorString( QObject::tr( "Cannot convert '%1:%2:%3:%4:%5' to color" ).arg( cyan ).arg( magenta ).arg( yellow ).arg( black ).arg( alpha ) );
color = QColor( 0, 0, 0 );
}
return QgsSymbolLayerV2Utils::encodeColor( color );
}

static QVariant fcnSpecialColumn( const QVariantList& values, QgsFeature* /*f*/, QgsExpression* parent )
{
QString varName = getStringValue( values.at( 0 ), parent );
Expand Down Expand Up @@ -1070,14 +1209,16 @@ const QStringList &QgsExpression::BuiltinFunctions()
<< "exp" << "ln" << "log10" << "log"
<< "round" << "toint" << "toreal" << "tostring"
<< "todatetime" << "todate" << "totime" << "tointerval"
<< "coalesce" << "$now" << "age" << "year"
<< "coalesce" << "regexp_match" << "$now" << "age" << "year"
<< "month" << "week" << "day" << "hour"
<< "minute" << "second" << "lower" << "upper"
<< "title" << "length" << "replace" << "regexp_replace"
<< "substr" << "concat" << "strpos" << "left"
<< "right" << "rpad" << "lpad"
<< "format_number" << "format_date"
<< "color_rgb" << "color_rgba" << "ramp_color"
<< "color_hsl" << "color_hsla" << "color_hsv" << "color_hsva"
<< "color_cymk" << "color_cymka"
<< "xat" << "yat" << "$area"
<< "$length" << "$perimeter" << "$x" << "$y"
<< "$rownum" << "$id" << "$scale" << "_specialcol_";
Expand Down Expand Up @@ -1114,6 +1255,7 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "totime", 1, fcnToTime, QObject::tr( "Conversions" ) )
<< new StaticFunction( "tointerval", 1, fcnToInterval, QObject::tr( "Conversions" ) )
<< new StaticFunction( "coalesce", -1, fcnCoalesce, QObject::tr( "Conditionals" ) )
<< new StaticFunction( "regexp_match", 2, fcnRegexpMatch, QObject::tr( "Conditionals" ) )
<< new StaticFunction( "$now", 0, fcnNow, QObject::tr( "Date and Time" ) )
<< new StaticFunction( "age", 2, fcnAge, QObject::tr( "Date and Time" ) )
<< new StaticFunction( "year", 1, fcnYear, QObject::tr( "Date and Time" ) )
Expand Down Expand Up @@ -1142,6 +1284,12 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "color_rgb", 3, fcnColorRgb, QObject::tr( "Color" ) )
<< new StaticFunction( "color_rgba", 4, fncColorRgba, QObject::tr( "Color" ) )
<< new StaticFunction( "ramp_color", 2, fcnRampColor, QObject::tr( "Color" ) )
<< new StaticFunction( "color_hsl", 3, fcnColorHsl, QObject::tr( "Color" ) )
<< new StaticFunction( "color_hsla", 4, fncColorHsla, QObject::tr( "Color" ) )
<< new StaticFunction( "color_hsv", 3, fcnColorHsv, QObject::tr( "Color" ) )
<< new StaticFunction( "color_hsva", 4, fncColorHsva, QObject::tr( "Color" ) )
<< new StaticFunction( "color_cmyk", 4, fcnColorCmyk, QObject::tr( "Color" ) )
<< new StaticFunction( "color_cmyka", 5, fncColorCmyka, QObject::tr( "Color" ) )
<< new StaticFunction( "xat", 1, fcnXat, QObject::tr( "Geometry" ), "", true )
<< new StaticFunction( "yat", 1, fcnYat, QObject::tr( "Geometry" ), "", true )
<< new StaticFunction( "$area", 0, fcnGeomArea, QObject::tr( "Geometry" ), "", true )
Expand Down
51 changes: 51 additions & 0 deletions src/gui/qgisinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,29 @@ class GUI_EXPORT QgisInterface : public QObject
//! Add an icon to the plugins toolbar
virtual int addToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the plugins toolbar.
* To remove this widget again, call {@link removeToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addToolBarWidget( QWidget* widget ) = 0;

//! Remove an action (icon) from the plugin toolbar
virtual void removeToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the raster toolbar.
* To remove this widget again, call {@link removeRasterToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addRasterToolBarWidget( QWidget* widget ) = 0;

//! Add an icon to the Raster toolbar
//! @note added in 2.0
virtual int addRasterToolBarIcon( QAction *qAction ) = 0;
Expand All @@ -129,8 +149,19 @@ class GUI_EXPORT QgisInterface : public QObject

//! Add an icon to the Vector toolbar
//! @note added in 2.0

virtual int addVectorToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the vector toolbar.
* To remove this widget again, call {@link removeVectorToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addVectorToolBarWidget( QWidget* widget ) = 0;

//! Remove an action (icon) from the Vector toolbar
//! @note added in 2.0
virtual void removeVectorToolBarIcon( QAction *qAction ) = 0;
Expand All @@ -139,6 +170,16 @@ class GUI_EXPORT QgisInterface : public QObject
//! @note added in 2.0
virtual int addDatabaseToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the database toolbar.
* To remove this widget again, call {@link removeDatabaseToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addDatabaseToolBarWidget( QWidget* widget ) = 0;

//! Remove an action (icon) from the Database toolbar
//! @note added in 2.0
virtual void removeDatabaseToolBarIcon( QAction *qAction ) = 0;
Expand All @@ -147,6 +188,16 @@ class GUI_EXPORT QgisInterface : public QObject
//! @note added in 2.0
virtual int addWebToolBarIcon( QAction *qAction ) = 0;

/**
* Add a widget to the web toolbar.
* To remove this widget again, call {@link removeWebToolBarIcon}
* with the returned QAction.
*
* @param widget widget to add. The toolbar will take ownership of this widget
* @return the QAction you can use to remove this widget from the toolbar
*/
virtual QAction* addWebToolBarWidget( QWidget* widget ) = 0;

//! Remove an action (icon) from the Web toolbar
//! @note added in 2.0
virtual void removeWebToolBarIcon( QAction *qAction ) = 0;
Expand Down
2 changes: 0 additions & 2 deletions src/gui/qgsrubberband.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,6 @@ void QgsRubberBand::addGeometry( QgsGeometry* geom, QgsVectorLayer* layer )
case QGis::WKBMultiLineString:
case QGis::WKBMultiLineString25D:
{
mPoints.clear();

QgsMultiPolyline mline = geom->asMultiPolyline();
for ( int i = 0; i < mline.size(); ++i, ++idx )
Expand Down Expand Up @@ -347,7 +346,6 @@ void QgsRubberBand::addGeometry( QgsGeometry* geom, QgsVectorLayer* layer )
case QGis::WKBMultiPolygon:
case QGis::WKBMultiPolygon25D:
{
mPoints.clear();

QgsMultiPolygon multipoly = geom->asMultiPolygon();
for ( int i = 0; i < multipoly.size(); ++i, ++idx )
Expand Down
10 changes: 10 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ class TestQgsExpression: public QObject
QTest::newRow( "coalesce null" ) << "coalesce(NULL)" << false << QVariant( );
QTest::newRow( "coalesce mid-null" ) << "coalesce(1, NULL, 3)" << false << QVariant( 1 );
QTest::newRow( "coalesce exp" ) << "coalesce(NULL, 1+1)" << false << QVariant( 2 );
QTest::newRow( "regexp match" ) << "regexp_match('abc','.b.')" << false << QVariant( 1 );
QTest::newRow( "regexp match invalid" ) << "regexp_match('abc DEF','[[[')" << true << QVariant();
QTest::newRow( "regexp match escaped" ) << "regexp_match('abc DEF','\\\\s[A-Z]+')" << false << QVariant( 1 );
QTest::newRow( "regexp match false" ) << "regexp_match('abc DEF','\\\\s[a-z]+')" << false << QVariant( 0 );

// Datetime functions
QTest::newRow( "to date" ) << "todate('2012-06-28')" << false << QVariant( QDate( 2012, 6, 28 ) );
Expand All @@ -319,6 +323,12 @@ class TestQgsExpression: public QObject
QTest::newRow( "ramp color" ) << "ramp_color('Spectral',0.3)" << false << QVariant( "#fdbe73" );
QTest::newRow( "color rgb" ) << "color_rgb(255,127,0)" << false << QVariant( "#ff7f00" );
QTest::newRow( "color rgba" ) << "color_rgba(255,127,0,200)" << false << QVariant( "255,127,0,200" );
QTest::newRow( "color hsl" ) << "color_hsl(100,50,70)" << false << QVariant( "#a6d98c" );
QTest::newRow( "color hsla" ) << "color_hsla(100,50,70,200)" << false << QVariant( "166,217,140,200" );
QTest::newRow( "color hsv" ) << "color_hsv(40,100,100)" << false << QVariant( "#ffaa00" );
QTest::newRow( "color hsva" ) << "color_hsva(40,100,100,200)" << false << QVariant( "255,170,0,200" );
QTest::newRow( "color cmyk" ) << "color_cmyk(100,50,33,10)" << false << QVariant( "#00739a" );
QTest::newRow( "color cmyka" ) << "color_cmyka(50,25,90,60,200)" << false << QVariant( "51,76,10,200" );
}

void evaluation()
Expand Down
33 changes: 19 additions & 14 deletions tests/src/core/testziplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class TestZipLayer: public QObject
// test item(s) in zip item (supply name or test all)
bool testZipItem( QString myFileName, QString myChildName = "", QString myDriverName = "" );
// get layer transparency to test for .qml loading
// int getLayerTransparency( QString myFileName, QString myProviderKey, QString myScanZipSetting = "basic" );
// bool testZipItemTransparency( QString myFileName, QString myProviderKey, int myTarget );
int getLayerTransparency( QString myFileName, QString myProviderKey, QString myScanZipSetting = "basic" );
bool testZipItemTransparency( QString myFileName, QString myProviderKey, int myTarget );

private slots:

Expand All @@ -77,15 +77,16 @@ class TestZipLayer: public QObject
void testTarItemVector();
void testZipItemAll();
void testTarItemAll();
#if 0
// test that styles are loaded from .qml files outside zip files
#if 0
// TODO - find a simple way to test vector style loading
void testZipItemVectorTransparency();
void testTarItemVectorTransparency();
void testGzipItemVectorTransparency();
#endif
void testZipItemRasterTransparency();
void testTarItemRasterTransparency();
void testGzipItemRasterTransparency();
#endif
//make sure items inside subfolders can be read
void testZipItemSubfolder();
void testTarItemSubfolder();
Expand Down Expand Up @@ -154,14 +155,12 @@ bool TestZipLayer::testZipItem( QString myFileName, QString myChildName, QString
if ( myChildren.size() > 0 )
{
QgsDebugMsg( QString( "has %1 items" ).arg( myChildren.size() ) );
QWARN( QString( "has %1 items" ).arg( myChildren.size() ).toLocal8Bit().data() );
foreach ( QgsDataItem* item, myChildren )
{
QgsDebugMsg( QString( "child name=%1" ).arg( item->name() ) );
QgsLayerItem *layerItem = dynamic_cast<QgsLayerItem*>( item );
if ( layerItem )
{
QWARN( QString( "child %1" ).arg( layerItem->path() ).toLocal8Bit().data() );
QgsDebugMsg( QString( "child name=%1 provider=%2 path=%3" ).arg( layerItem->name() ).arg( layerItem->providerKey() ).arg( layerItem->path() ) );
if ( myChildName == "" || myChildName == item->name() )
{
Expand All @@ -177,8 +176,6 @@ bool TestZipLayer::testZipItem( QString myFileName, QString myChildName, QString
{
QWARN( QString( "Invalid layer %1" ).arg( layerItem->path() ).toLocal8Bit().data() );
}
else
QWARN( QString( "Valid layer %1" ).arg( layerItem->path() ).toLocal8Bit().data() );
if ( myChildName == "" )
{
if ( ! ok )
Expand Down Expand Up @@ -217,7 +214,6 @@ bool TestZipLayer::testZipItem( QString myFileName, QString myChildName, QString
return ok;
}

#if 0
int TestZipLayer::getLayerTransparency( QString myFileName, QString myProviderKey, QString myScanZipSetting )
{
int myTransparency = -1;
Expand All @@ -232,7 +228,17 @@ int TestZipLayer::getLayerTransparency( QString myFileName, QString myProviderKe
else
myLayer = getZipLayer( myFileName, "" );
if ( myLayer && myLayer->isValid() )
myTransparency = myLayer->getTransparency();
{
// myTransparency = myLayer->getTransparency();
if ( myLayer->type() == QgsMapLayer::RasterLayer )
{
QgsRasterLayer* layer = dynamic_cast<QgsRasterLayer*>( myLayer );
if ( layer && layer->renderer() )
{
myTransparency = ceil(layer->renderer()->opacity() * 255);
}
}
}
else
QWARN( QString( "Could not open filename %1 using %2 provider" ).arg( myFileName ).arg( myProviderKey ).toLocal8Bit().data() );
if ( myLayer )
Expand All @@ -254,7 +260,6 @@ bool TestZipLayer::testZipItemTransparency( QString myFileName, QString myProvid
}
return true;
}
#endif


// slots
Expand Down Expand Up @@ -425,10 +430,10 @@ void TestZipLayer::testTarItemVector()

void TestZipLayer::testZipItemAll()
{
// test file contains invalid items (tmp1.tif, tmp1.txt and tmp1.xml)
// test for all items inside zip, using zipSetting 3 (Full Scan) which will ignore invalid items
// using zipSetting 2 (Basic Scan) would raise errors, because QgsZipItem would not test for valid items
// and return child names of the invalid items
// test file does not contain invalid items (some of dash tests failed because of them)
QSettings settings;
settings.setValue( mSettingsKey, "full" );
QVERIFY( "full" == settings.value( mSettingsKey ).toString() );
Expand Down Expand Up @@ -470,6 +475,7 @@ void TestZipLayer::testGzipItemVectorTransparency()
#endif
QVERIFY( testZipItemTransparency( mDataDir + "points3.geojson.gz", "ogr", 250 ) );
}
#endif

void TestZipLayer::testZipItemRasterTransparency()
{
Expand All @@ -488,7 +494,6 @@ void TestZipLayer::testGzipItemRasterTransparency()
{
QVERIFY( testZipItemTransparency( mDataDir + "landsat_b1.tif.gz", "gdal", 250 ) );
}
#endif

void TestZipLayer::testZipItemSubfolder()
{
Expand Down Expand Up @@ -526,7 +531,7 @@ void TestZipLayer::testZipItemVRT()
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "landsat.vrt", "gdal" ) );
QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "landsat_b1.vrt", "gdal" ) );
// this file is buggy with gdal svn - skip for now
// QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "points.vrt", "ogr" ) );
}
Expand Down
1 change: 1 addition & 0 deletions tests/src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,5 @@ ADD_QGIS_TEST(histogramtest testqgsrasterhistogram.cpp)
ADD_QGIS_TEST(projectionissues testprojectionissues.cpp)
ADD_QGIS_TEST(scalecombobox testqgsscalecombobox.cpp)
ADD_QGIS_TEST(dualviewtest testqgsdualview.cpp )
ADD_QGIS_TEST(rubberbandtest testqgsrubberband.cpp )

105 changes: 105 additions & 0 deletions tests/src/gui/testqgsrubberband.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/***************************************************************************
testqgsrubberband.cpp
--------------------------------------
Date : 28.4.2013
Copyright : (C) 2013 Vinayan Parameswaran
Email : vinayan123 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. *
* *
***************************************************************************/


#include <QtTest>
#include <QObject>
#include <QString>
#include <QObject>
#include <QCoreApplication>
#include <QWidget>

#include <qgsapplication.h>
#include <qgsmapcanvas.h>
#include <qgsvectorlayer.h>
#include <qgsrubberband.h>
#include <qgslogger.h>

class TestQgsRubberband: public QObject
{
Q_OBJECT;
private slots:
void initTestCase(); // will be called before the first testfunction is executed.
void cleanupTestCase(); // will be called after the last testfunction was executed.
void init(); // will be called before each testfunction is executed.
void cleanup(); // will be called after every testfunction.

void testAddSingleMultiGeometries(); //test for #7728

private:
QgsMapCanvas* mCanvas;
QgsVectorLayer* mPolygonLayer;
QString mTestDataDir;
QgsRubberBand* mRubberband;
};

void TestQgsRubberband::initTestCase()
{
QgsApplication::init();
QgsApplication::initQgis();
QgsApplication::showSettings();

// Setup a map canvas with a vector layer loaded...
QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
mTestDataDir = myDataDir + QDir::separator();

//
// load a vector layer
//
QString myPolygonFileName = mTestDataDir + "polys.shp";
QFileInfo myPolygonFileInfo( myPolygonFileName );
mPolygonLayer = new QgsVectorLayer( myPolygonFileInfo.filePath(),
myPolygonFileInfo.completeBaseName(), "ogr" );

mCanvas = new QgsMapCanvas();
mRubberband = 0;
}

void TestQgsRubberband::cleanupTestCase()
{
delete mRubberband;
delete mPolygonLayer;
delete mCanvas;
}

void TestQgsRubberband::init()
{

}

void TestQgsRubberband::cleanup()
{

}

void TestQgsRubberband::testAddSingleMultiGeometries()
{
mRubberband = new QgsRubberBand( mCanvas, mPolygonLayer->geometryType() );
QgsGeometry* geomSinglePart = QgsGeometry::fromWkt( "POLYGON((-0.00022418 -0.00000279,-0.0001039 0.00002395,-0.00008677 -0.00005313,-0.00020705 -0.00007987,-0.00022418 -0.00000279))" );
QgsGeometry* geomMultiPart = QgsGeometry::fromWkt( "MULTIPOLYGON(((-0.00018203 0.00012178,-0.00009444 0.00014125,-0.00007861 0.00007001,-0.00016619 0.00005054,-0.00018203 0.00012178)),((-0.00030957 0.00009464,-0.00021849 0.00011489,-0.00020447 0.00005184,-0.00029555 0.00003158,-0.00030957 0.00009464)))" );

mRubberband->addGeometry( geomSinglePart, mPolygonLayer );
mRubberband->addGeometry( geomMultiPart, mPolygonLayer );

QVERIFY( mRubberband->numberOfVertices() == 15 );
}

QTEST_MAIN( TestQgsRubberband )
#include "moc_testqgsrubberband.cxx"





Binary file modified tests/testdata/zip/testtar.tgz
Binary file not shown.
Binary file modified tests/testdata/zip/testzip.zip
Binary file not shown.