Skip to content

Commit 016789a

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

19 files changed

+924
-637
lines changed
 

‎python/CMakeLists.txt

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

‎python/console.py

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

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

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

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

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

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

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

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

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

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

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

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

‎python/console_output.py

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

‎python/console_sci.py

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def __init__(self, parent=None):
5151

5252
self.buffer = []
5353

54-
self.insertInitText()
54+
#self.insertInitText()
5555
self.displayPrompt(False)
5656

5757
for line in _init_commands:
@@ -69,8 +69,8 @@ def __init__(self, parent=None):
6969
#self.selectToMatchingBrace()
7070

7171
# Current line visible with special background color
72-
self.setCaretLineVisible(True)
73-
self.setCaretLineBackgroundColor(QColor("#ffe4e4"))
72+
#self.setCaretLineVisible(True)
73+
#self.setCaretLineBackgroundColor(QColor("#ffe4e4"))
7474
self.setCaretWidth(2)
7575

7676
# Set Python lexer
@@ -93,12 +93,14 @@ def __init__(self, parent=None):
9393
# Use raw message to Scintilla here (all messages are documented
9494
# here: http://www.scintilla.org/ScintillaDoc.html)
9595
self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0)
96+
self.SendScintilla(QsciScintilla.SCI_SETVSCROLLBAR, 0)
97+
9698

9799
# not too small
98100
#self.setMinimumSize(500, 300)
99-
self.setMinimumHeight(125)
101+
self.setMinimumHeight(32)
100102

101-
self.SendScintilla(QsciScintilla.SCI_SETWRAPMODE, 1)
103+
self.SendScintilla(QsciScintilla.SCI_SETWRAPMODE, 2)
102104
self.SendScintilla(QsciScintilla.SCI_EMPTYUNDOBUFFER)
103105

104106
## Disable command key
@@ -117,20 +119,14 @@ def __init__(self, parent=None):
117119
self.newShortcutCAS.activated.connect(self.showHistory)
118120
self.connect(self, SIGNAL('userListActivated(int, const QString)'),
119121
self.completion_list_selected)
122+
123+
self.createStandardContextMenu()
120124

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

124128
def autoComplete(self):
125129
self.autoCompleteFromAll()
126-
127-
def clearConsole(self):
128-
"""Clear the contents of the console."""
129-
self.SendScintilla(QsciScintilla.SCI_CLEARALL)
130-
#self.setText('')
131-
self.insertInitText()
132-
self.displayPrompt(False)
133-
self.setFocus()
134130

135131
def commandConsole(self, command):
136132
if not self.is_cursor_on_last_line():
@@ -142,23 +138,20 @@ def commandConsole(self, command):
142138
if command == "iface":
143139
"""Import QgisInterface class"""
144140
self.append('from qgis.utils import iface')
145-
self.move_cursor_to_end()
146141
elif command == "sextante":
147142
"""Import Sextante class"""
148143
self.append('from sextante.core.Sextante import Sextante')
149-
self.move_cursor_to_end()
150144
elif command == "cLayer":
151145
"""Retrieve current Layer from map camvas"""
152146
self.append('cLayer = iface.mapCanvas().currentLayer()')
153-
self.move_cursor_to_end()
154147
elif command == "qtCore":
155148
"""Import QtCore class"""
156149
self.append('from PyQt4.QtCore import *')
157-
self.move_cursor_to_end()
158150
elif command == "qtGui":
159151
"""Import QtGui class"""
160152
self.append('from PyQt4.QtGui import *')
161-
self.move_cursor_to_end()
153+
self.entered()
154+
self.move_cursor_to_end()
162155
self.setFocus()
163156

164157
def setLexers(self):
@@ -172,6 +165,10 @@ def setLexers(self):
172165
font = QFont(loadFont)
173166
font.setFixedPitch(True)
174167
font.setPointSize(fontSize)
168+
font.setStyleHint(QFont.TypeWriter)
169+
font.setStretch(QFont.SemiCondensed)
170+
font.setLetterSpacing(QFont.PercentageSpacing, 87.0)
171+
font.setBold(False)
175172

176173
self.lexer.setDefaultFont(font)
177174
self.lexer.setColor(Qt.red, 1)
@@ -209,9 +206,9 @@ def completion_list_selected(self, id, txt):
209206

210207
def insertInitText(self):
211208
#self.setLexers(False)
212-
txtInit = QCoreApplication.translate("PythonConsole",
213-
"## To access Quantum GIS environment from this console\n"
214-
"## use qgis.utils.iface object (instance of QgisInterface class). Read help for more info.\n\n")
209+
txtInit = QCoreApplication.translate("PythonConsole", "## Interactive Python Console for Quantum GIS\n\n")
210+
#"## To access Quantum GIS environment from this console\n"
211+
#"## use qgis.utils.iface object (instance of QgisInterface class). Read help for more info.\n\n")
215212
initText = self.setText(txtInit)
216213

217214
def getText(self):
@@ -413,6 +410,16 @@ def keyPressEvent(self, e):
413410
## TODO: press event for auto-completion file directory
414411
else:
415412
QsciScintilla.keyPressEvent(self, e)
413+
414+
def contextMenuEvent(self, e):
415+
menu = QMenu(self)
416+
copyAction = menu.addAction("Copy CTRL+C")
417+
pasteAction = menu.addAction("Paste CTRL+V")
418+
action = menu.exec_(self.mapToGlobal(e.pos()))
419+
if action == copyAction:
420+
self.copy()
421+
elif action == pasteAction:
422+
self.paste()
416423

417424
def mousePressEvent(self, e):
418425
"""
@@ -458,18 +465,20 @@ def dropEvent(self, e):
458465
def insertFromDropPaste(self, textDP):
459466
pasteList = textDP.split("\n")
460467
for line in pasteList[:-1]:
468+
line.replace(">>> ", "").replace("... ", "")
461469
self.insert(line)
462470
self.move_cursor_to_end()
463-
#self.SendScintilla(QsciScintilla.SCI_DELETEBACK)
464471
self.runCommand(unicode(self.currentCommand()))
465472
if pasteList[-1] != "":
466-
self.insert(unicode(pasteList[-1]))
473+
line = pasteList[-1]
474+
line.replace(">>> ", "").replace("... ", "")
475+
self.insert(unicode(line))
467476
self.move_cursor_to_end()
468477

469-
def getTextFromEditor(self):
470-
text = self.text()
471-
textList = text.split("\n")
472-
return textList
478+
# def getTextFromEditor(self):
479+
# text = self.text()
480+
# textList = text.split("\n")
481+
# return textList
473482

474483
def insertTextFromFile(self, listOpenFile):
475484
for line in listOpenFile[:-1]:
@@ -483,7 +492,7 @@ def insertTextFromFile(self, listOpenFile):
483492

484493
def entered(self):
485494
self.move_cursor_to_end()
486-
self.runCommand( unicode(self.currentCommand()) )
495+
self.runCommand( unicode(self.currentCommand()) )
487496
self.setFocus()
488497
self.move_cursor_to_end()
489498
#self.SendScintilla(QsciScintilla.SCI_EMPTYUNDOBUFFER)
@@ -498,9 +507,14 @@ def currentCommand(self):
498507
return cmd
499508

500509
def runCommand(self, cmd):
510+
self.write_stdout(cmd)
501511
import webbrowser
502512
self.updateHistory(cmd)
503-
self.SendScintilla(QsciScintilla.SCI_NEWLINE)
513+
line, pos = self.getCursorPosition()
514+
selCmdLenght = self.text(line).length()
515+
self.setSelection(line, 0, line, selCmdLenght)
516+
self.removeSelectedText()
517+
#self.SendScintilla(QsciScintilla.SCI_NEWLINE)
504518
if cmd in ('_save', '_clear', '_clearAll', '_pyqgis', '_api'):
505519
if cmd == '_save':
506520
self.writeHistoryFile()
@@ -528,25 +542,21 @@ def runCommand(self, cmd):
528542
elif cmd == '_api':
529543
webbrowser.open( "http://www.qgis.org/api/" )
530544

531-
output = sys.stdout.get_and_clean_data()
532-
if output:
533-
self.append(output)
534545
self.displayPrompt(False)
535546
else:
536547
self.buffer.append(cmd)
537548
src = u"\n".join(self.buffer)
538549
more = self.runsource(src, "<input>")
539550
if not more:
540551
self.buffer = []
541-
output = sys.stdout.get_and_clean_data()
542-
if output:
543-
self.append(output)
544552
self.move_cursor_to_end()
545553
self.displayPrompt(more)
546554

547555
def write(self, txt):
548-
self.SendScintilla(QsciScintilla.SCI_SETSTYLING, len(txt), 1)
549-
self.append(txt)
550-
self.SendScintilla(QsciScintilla.SCI_SETSTYLING, len(txt), 1)
551-
556+
sys.stderr.write(txt)
552557

558+
def write_stdout(self, txt):
559+
if len(txt) > 0:
560+
getCmdString = self.text()
561+
prompt = getCmdString[0:4]
562+
sys.stdout.write(prompt+txt+'\n')

‎python/core/raster/qgsrasterrenderer.sip

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ class QgsRasterRenderer : QgsRasterInterface
5252
void setAlphaBand( int band );
5353
int alphaBand() const;
5454

55-
void setInvertColor( bool invert );
56-
bool invertColor() const;
57-
5855
/**Get symbology items if provided by renderer*/
5956
virtual void legendSymbologyItems( QList< QPair< QString, QColor > >& symbolItems ) const;
6057

‎src/app/qgsrasterlayerproperties.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
195195
tableTransparency->horizontalHeader()->setResizeMode( 1, QHeaderView::Stretch );
196196

197197
//resampling
198+
mResamplingGroupBox->setSaveCheckedState( true );
198199
const QgsRasterRenderer* renderer = mRasterLayer->renderer();
199200
mZoomedInResamplingComboBox->insertItem( 0, tr( "Nearest neighbour" ) );
200201
mZoomedInResamplingComboBox->insertItem( 1, tr( "Bilinear" ) );
@@ -206,12 +207,6 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
206207
//set combo boxes to current resampling types
207208
if ( resampleFilter )
208209
{
209-
//invert color map
210-
if ( renderer->invertColor() )
211-
{
212-
mInvertColorMapCheckBox->setCheckState( Qt::Checked );
213-
}
214-
215210
const QgsRasterResampler* zoomedInResampler = resampleFilter->zoomedInResampler();
216211
if ( zoomedInResampler )
217212
{
@@ -744,9 +739,6 @@ void QgsRasterLayerProperties::apply()
744739

745740
//set global transparency
746741
rasterRenderer->setOpacity(( 255 - sliderTransparency->value() ) / 255.0 );
747-
748-
//invert color map
749-
rasterRenderer->setInvertColor( mInvertColorMapCheckBox->isChecked() );
750742
}
751743

752744
QgsDebugMsg( "processing general tab" );

‎src/core/raster/qgsmultibandcolorrenderer.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ QgsRasterInterface * QgsMultiBandColorRenderer::clone() const
5757
}
5858
renderer->setOpacity( mOpacity );
5959
renderer->setAlphaBand( mAlphaBand );
60-
renderer->setInvertColor( mInvertColor );
6160
renderer->setRasterTransparency( mRasterTransparency );
6261

6362
return renderer;
@@ -136,8 +135,7 @@ QgsRasterBlock* QgsMultiBandColorRenderer::block( int bandNo, QgsRectangle cons
136135
//In some (common) cases, we can simplify the drawing loop considerably and save render time
137136
bool fastDraw = ( !usesTransparency()
138137
&& mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0
139-
&& mAlphaBand < 1 && !mRedContrastEnhancement && !mGreenContrastEnhancement && !mBlueContrastEnhancement
140-
&& !mInvertColor );
138+
&& mAlphaBand < 1 && !mRedContrastEnhancement && !mGreenContrastEnhancement && !mBlueContrastEnhancement );
141139

142140
QSet<int> bands;
143141
if ( mRedBand > 0 )
@@ -290,13 +288,6 @@ QgsRasterBlock* QgsMultiBandColorRenderer::block( int bandNo, QgsRectangle cons
290288
blueVal = mBlueContrastEnhancement->enhanceContrast( blueVal );
291289
}
292290

293-
if ( mInvertColor )
294-
{
295-
redVal = 255 - redVal;
296-
greenVal = 255 - greenVal;
297-
blueVal = 255 - blueVal;
298-
}
299-
300291
//opacity
301292
double currentOpacity = mOpacity;
302293
if ( mRasterTransparency )

‎src/core/raster/qgspalettedrasterrenderer.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ QgsRasterInterface * QgsPalettedRasterRenderer::clone() const
3939
QgsPalettedRasterRenderer * renderer = new QgsPalettedRasterRenderer( 0, mBand, colors(), mNColors );
4040
renderer->setOpacity( mOpacity );
4141
renderer->setAlphaBand( mAlphaBand );
42-
renderer->setInvertColor( mInvertColor );
4342
renderer->setRasterTransparency( mRasterTransparency );
4443
return renderer;
4544
}
@@ -179,14 +178,7 @@ QgsRasterBlock * QgsPalettedRasterRenderer::block( int bandNo, QgsRectangle con
179178
}
180179
QColor& currentColor = mColors[val];
181180

182-
if ( mInvertColor )
183-
{
184-
outputBlock->setColor( i, qRgba( currentOpacity * currentColor.blue(), currentOpacity * currentColor.green(), currentOpacity * currentColor.red(), currentOpacity * 255 ) );
185-
}
186-
else
187-
{
188-
outputBlock->setColor( i, qRgba( currentOpacity * currentColor.red(), currentOpacity * currentColor.green(), currentOpacity * currentColor.blue(), currentOpacity * 255 ) );
189-
}
181+
outputBlock->setColor( i, qRgba( currentOpacity * currentColor.red(), currentOpacity * currentColor.green(), currentOpacity * currentColor.blue(), currentOpacity * 255 ) );
190182
}
191183
}
192184

‎src/core/raster/qgsrasterrenderer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const QRgb QgsRasterRenderer::NODATA_COLOR = qRgba( 0, 0, 0, 0 );
4040
QgsRasterRenderer::QgsRasterRenderer( QgsRasterInterface* input, const QString& type )
4141
: QgsRasterInterface( input )
4242
, mType( type ), mOpacity( 1.0 ), mRasterTransparency( 0 )
43-
, mAlphaBand( -1 ), mInvertColor( false )
43+
, mAlphaBand( -1 ) //, mInvertColor( false )
4444
{
4545
}
4646

@@ -117,7 +117,7 @@ void QgsRasterRenderer::_writeXML( QDomDocument& doc, QDomElement& rasterRendere
117117
rasterRendererElem.setAttribute( "type", mType );
118118
rasterRendererElem.setAttribute( "opacity", QString::number( mOpacity ) );
119119
rasterRendererElem.setAttribute( "alphaBand", mAlphaBand );
120-
rasterRendererElem.setAttribute( "invertColor", mInvertColor );
120+
//rasterRendererElem.setAttribute( "invertColor", mInvertColor );
121121

122122
if ( mRasterTransparency )
123123
{
@@ -135,7 +135,7 @@ void QgsRasterRenderer::readXML( const QDomElement& rendererElem )
135135
mType = rendererElem.attribute( "type" );
136136
mOpacity = rendererElem.attribute( "opacity", "1.0" ).toDouble();
137137
mAlphaBand = rendererElem.attribute( "alphaBand", "-1" ).toInt();
138-
mInvertColor = rendererElem.attribute( "invertColor", "0" ).toInt();
138+
//mInvertColor = rendererElem.attribute( "invertColor", "0" ).toInt();
139139

140140
//todo: read mRasterTransparency
141141
QDomElement rasterTransparencyElem = rendererElem.firstChildElement( "rasterTransparency" );

‎src/core/raster/qgsrasterrenderer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
9292
void setAlphaBand( int band ) { mAlphaBand = band; }
9393
int alphaBand() const { return mAlphaBand; }
9494

95-
void setInvertColor( bool invert ) { mInvertColor = invert; }
96-
bool invertColor() const { return mInvertColor; }
95+
//void setInvertColor( bool invert ) { mInvertColor = invert; }
96+
//bool invertColor() const { return mInvertColor; }
9797

9898
/**Get symbology items if provided by renderer*/
9999
virtual void legendSymbologyItems( QList< QPair< QString, QColor > >& symbolItems ) const { Q_UNUSED( symbolItems ); }
@@ -124,7 +124,7 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
124124
Default: -1 (not set)*/
125125
int mAlphaBand;
126126

127-
bool mInvertColor;
127+
//bool mInvertColor;
128128
};
129129

130130
#endif // QGSRASTERRENDERER_H

‎src/core/raster/qgssinglebandcolordatarenderer.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ QgsRasterInterface * QgsSingleBandColorDataRenderer::clone() const
3636
QgsSingleBandColorDataRenderer * renderer = new QgsSingleBandColorDataRenderer( 0, mBand );
3737
renderer->setOpacity( mOpacity );
3838
renderer->setAlphaBand( mAlphaBand );
39-
renderer->setInvertColor( mInvertColor );
4039
renderer->setRasterTransparency( mRasterTransparency );
4140
return renderer;
4241
}

‎src/core/raster/qgssinglebandgrayrenderer.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <QImage>
2424

2525
QgsSingleBandGrayRenderer::QgsSingleBandGrayRenderer( QgsRasterInterface* input, int grayBand ):
26-
QgsRasterRenderer( input, "singlebandgray" ), mGrayBand( grayBand ), mContrastEnhancement( 0 )
26+
QgsRasterRenderer( input, "singlebandgray" ), mGrayBand( grayBand ), mGradient( BlackToWhite ), mContrastEnhancement( 0 )
2727
{
2828
}
2929

@@ -37,7 +37,6 @@ QgsRasterInterface * QgsSingleBandGrayRenderer::clone() const
3737
QgsSingleBandGrayRenderer * renderer = new QgsSingleBandGrayRenderer( 0, mGrayBand );
3838
renderer->setOpacity( mOpacity );
3939
renderer->setAlphaBand( mAlphaBand );
40-
renderer->setInvertColor( mInvertColor );
4140
renderer->setRasterTransparency( mRasterTransparency );
4241
if ( mContrastEnhancement )
4342
{
@@ -57,6 +56,11 @@ QgsRasterRenderer* QgsSingleBandGrayRenderer::create( const QDomElement& elem, Q
5756
QgsSingleBandGrayRenderer* r = new QgsSingleBandGrayRenderer( input, grayBand );
5857
r->readXML( elem );
5958

59+
if ( elem.attribute( "gradient" ) == "WhiteToBlack" )
60+
{
61+
r->setGradient( WhiteToBlack ); // BlackToWhite is default
62+
}
63+
6064
QDomElement contrastEnhancementElem = elem.firstChildElement( "contrastEnhancement" );
6165
if ( !contrastEnhancementElem.isNull() )
6266
{
@@ -149,7 +153,7 @@ QgsRasterBlock* QgsSingleBandGrayRenderer::block( int bandNo, QgsRectangle cons
149153
grayVal = mContrastEnhancement->enhanceContrast( grayVal );
150154
}
151155

152-
if ( mInvertColor )
156+
if ( mGradient == WhiteToBlack )
153157
{
154158
grayVal = 255 - grayVal;
155159
}
@@ -184,6 +188,18 @@ void QgsSingleBandGrayRenderer::writeXML( QDomDocument& doc, QDomElement& parent
184188
_writeXML( doc, rasterRendererElem );
185189

186190
rasterRendererElem.setAttribute( "grayBand", mGrayBand );
191+
192+
QString gradient;
193+
if ( mGradient == BlackToWhite )
194+
{
195+
gradient = "BlackToWhite";
196+
}
197+
else
198+
{
199+
gradient = "WhiteToBlack";
200+
}
201+
rasterRendererElem.setAttribute( "gradient", gradient );
202+
187203
if ( mContrastEnhancement )
188204
{
189205
QDomElement contrastElem = doc.createElement( "contrastEnhancement" );

‎src/core/raster/qgssinglebandgrayrenderer.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ class QDomElement;
2929
class CORE_EXPORT QgsSingleBandGrayRenderer: public QgsRasterRenderer
3030
{
3131
public:
32+
enum Gradient
33+
{
34+
BlackToWhite,
35+
WhiteToBlack
36+
};
37+
3238
QgsSingleBandGrayRenderer( QgsRasterInterface* input, int grayBand );
3339
~QgsSingleBandGrayRenderer();
3440
QgsRasterInterface * clone() const;
@@ -43,6 +49,9 @@ class CORE_EXPORT QgsSingleBandGrayRenderer: public QgsRasterRenderer
4349
/**Takes ownership*/
4450
void setContrastEnhancement( QgsContrastEnhancement* ce );
4551

52+
void setGradient( Gradient theGradient ) { mGradient = theGradient; }
53+
Gradient gradient() const { return mGradient; }
54+
4655
void writeXML( QDomDocument& doc, QDomElement& parentElem ) const;
4756

4857
void legendSymbologyItems( QList< QPair< QString, QColor > >& symbolItems ) const;
@@ -51,6 +60,7 @@ class CORE_EXPORT QgsSingleBandGrayRenderer: public QgsRasterRenderer
5160

5261
private:
5362
int mGrayBand;
63+
Gradient mGradient;
5464
QgsContrastEnhancement* mContrastEnhancement;
5565
};
5666

‎src/core/raster/qgssinglebandpseudocolorrenderer.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ QgsRasterInterface * QgsSingleBandPseudoColorRenderer::clone() const
6363

6464
renderer->setOpacity( mOpacity );
6565
renderer->setAlphaBand( mAlphaBand );
66-
renderer->setInvertColor( mInvertColor );
6766
renderer->setRasterTransparency( mRasterTransparency );
6867

6968
return renderer;
@@ -165,14 +164,6 @@ QgsRasterBlock* QgsSingleBandPseudoColorRenderer::block( int bandNo, QgsRectangl
165164
continue;
166165
}
167166

168-
if ( mInvertColor )
169-
{
170-
// 1.8 was flipping blue and red
171-
red = 255 - red;
172-
green = 255 - green;
173-
blue = 255 - blue;
174-
}
175-
176167
if ( !hasTransparency )
177168
{
178169
outputBlock->setColor( i, qRgba( red, green, blue, 255 ) );

‎src/gui/raster/qgssinglebandgrayrendererwidget.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ QgsSingleBandGrayRendererWidget::QgsSingleBandGrayRendererWidget( QgsRasterLayer
2323
{
2424
setupUi( this );
2525

26+
mGradientComboBox->insertItem( 0, tr( "Black to white" ), QgsSingleBandGrayRenderer::BlackToWhite );
27+
mGradientComboBox->insertItem( 1, tr( "White to black" ), QgsSingleBandGrayRenderer::WhiteToBlack );
28+
2629
mMinLineEdit->setValidator( new QDoubleValidator( mMinLineEdit ) );
2730
mMaxLineEdit->setValidator( new QDoubleValidator( mMaxLineEdit ) );
2831

@@ -36,7 +39,12 @@ QgsSingleBandGrayRendererWidget::QgsSingleBandGrayRendererWidget( QgsRasterLayer
3639

3740
mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this );
3841
mMinMaxWidget->setExtent( extent );
39-
layout()->addWidget( mMinMaxWidget );
42+
43+
QHBoxLayout *layout = new QHBoxLayout();
44+
layout->setContentsMargins( 0, 0, 0, 0 );
45+
mMinMaxContainerWidget->setLayout( layout );
46+
layout->addWidget( mMinMaxWidget );
47+
4048
connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ),
4149
this, SLOT( loadMinMax( int, double, double, int ) ) );
4250

@@ -84,6 +92,9 @@ QgsRasterRenderer* QgsSingleBandGrayRendererWidget::renderer()
8492

8593
QgsSingleBandGrayRenderer* renderer = new QgsSingleBandGrayRenderer( provider, band );
8694
renderer->setContrastEnhancement( e );
95+
96+
renderer->setGradient(( QgsSingleBandGrayRenderer::Gradient ) mGradientComboBox->itemData( mGradientComboBox->currentIndex() ).toInt() );
97+
8798
return renderer;
8899
}
89100

@@ -127,6 +138,8 @@ void QgsSingleBandGrayRendererWidget::setFromRenderer( const QgsRasterRenderer*
127138
//band
128139
mGrayBandComboBox->setCurrentIndex( mGrayBandComboBox->findData( gr->grayBand() ) );
129140
const QgsContrastEnhancement* ce = gr->contrastEnhancement();
141+
142+
mGradientComboBox->setCurrentIndex( mGradientComboBox->findData( gr->gradient() ) );
130143
//minmax
131144
mMinLineEdit->setText( QString::number( ce->minimumValue() ) );
132145
mMaxLineEdit->setText( QString::number( ce->maximumValue() ) );

‎src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,15 +278,17 @@ void QgsSingleBandPseudoColorRendererWidget::on_mClassifyButton_clicked()
278278
for ( int i = 0; i < numberOfEntries; ++i )
279279
{
280280
QColor currentColor;
281-
currentColor.setRgb( colorDiff*i, 0, 255 - colorDiff * i );
281+
int idx = mInvertCheckBox->isChecked() ? numberOfEntries - i - 1 : i;
282+
currentColor.setRgb( colorDiff*idx, 0, 255 - colorDiff * idx );
282283
entryColors.push_back( currentColor );
283284
}
284285
}
285286
else
286287
{
287288
for ( int i = 0; i < numberOfEntries; ++i )
288289
{
289-
entryColors.push_back( colorRamp->color((( double ) i ) / numberOfEntries ) );
290+
int idx = mInvertCheckBox->isChecked() ? numberOfEntries - i - 1 : i;
291+
entryColors.push_back( colorRamp->color((( double ) idx ) / numberOfEntries ) );
290292
}
291293
}
292294

‎src/ui/qgsrasterlayerpropertiesbase.ui

Lines changed: 555 additions & 504 deletions
Large diffs are not rendered by default.

‎src/ui/qgssinglebandgrayrendererwidgetbase.ui

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>258</width>
10-
<height>203</height>
9+
<width>463</width>
10+
<height>298</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -16,17 +16,17 @@
1616
<layout class="QHBoxLayout" name="horizontalLayout">
1717
<item>
1818
<layout class="QGridLayout" name="gridLayout">
19-
<item row="3" column="0">
19+
<item row="4" column="0">
2020
<widget class="QLabel" name="mContrastEnhancementLabel">
2121
<property name="text">
2222
<string>Contrast enhancement</string>
2323
</property>
2424
</widget>
2525
</item>
26-
<item row="1" column="1">
26+
<item row="2" column="1">
2727
<widget class="QLineEdit" name="mMinLineEdit"/>
2828
</item>
29-
<item row="3" column="1">
29+
<item row="4" column="1">
3030
<widget class="QComboBox" name="mContrastEnhancementComboBox"/>
3131
</item>
3232
<item row="0" column="0">
@@ -36,7 +36,7 @@
3636
</property>
3737
</widget>
3838
</item>
39-
<item row="1" column="0">
39+
<item row="2" column="0">
4040
<widget class="QLabel" name="mMinLabel">
4141
<property name="text">
4242
<string>Min</string>
@@ -46,18 +46,57 @@
4646
<item row="0" column="1">
4747
<widget class="QComboBox" name="mGrayBandComboBox"/>
4848
</item>
49-
<item row="2" column="0">
49+
<item row="3" column="0">
5050
<widget class="QLabel" name="mMaxLabel">
5151
<property name="text">
5252
<string>Max</string>
5353
</property>
5454
</widget>
5555
</item>
56-
<item row="2" column="1">
56+
<item row="3" column="1">
5757
<widget class="QLineEdit" name="mMaxLineEdit"/>
5858
</item>
59+
<item row="1" column="0">
60+
<widget class="QLabel" name="label">
61+
<property name="text">
62+
<string>Color gradient</string>
63+
</property>
64+
</widget>
65+
</item>
66+
<item row="1" column="1">
67+
<widget class="QComboBox" name="mGradientComboBox"/>
68+
</item>
69+
<item row="5" column="0">
70+
<spacer name="verticalSpacer">
71+
<property name="orientation">
72+
<enum>Qt::Vertical</enum>
73+
</property>
74+
<property name="sizeHint" stdset="0">
75+
<size>
76+
<width>20</width>
77+
<height>140</height>
78+
</size>
79+
</property>
80+
</spacer>
81+
</item>
5982
</layout>
6083
</item>
84+
<item>
85+
<widget class="QWidget" name="mMinMaxContainerWidget" native="true">
86+
<property name="sizePolicy">
87+
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
88+
<horstretch>0</horstretch>
89+
<verstretch>0</verstretch>
90+
</sizepolicy>
91+
</property>
92+
<property name="minimumSize">
93+
<size>
94+
<width>200</width>
95+
<height>0</height>
96+
</size>
97+
</property>
98+
</widget>
99+
</item>
61100
</layout>
62101
</widget>
63102
<resources/>

‎src/ui/qgssinglebandpseudocolorrendererwidgetbase.ui

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,13 @@
345345
</item>
346346
</layout>
347347
</item>
348+
<item>
349+
<widget class="QCheckBox" name="mInvertCheckBox">
350+
<property name="text">
351+
<string>Invert colors order</string>
352+
</property>
353+
</widget>
354+
</item>
348355
</layout>
349356
</widget>
350357
</item>
@@ -356,7 +363,6 @@
356363
<verstretch>0</verstretch>
357364
</sizepolicy>
358365
</property>
359-
<zorder>grpGenerateColorMap</zorder>
360366
</widget>
361367
</item>
362368
</layout>

0 commit comments

Comments
 (0)
Please sign in to comment.