diff --git a/test/style1.txt b/test/style1.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6182a760afdb50d3d4c7e5b15477ce5167364537
--- /dev/null
+++ b/test/style1.txt
@@ -0,0 +1,21 @@
+<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
+<qgis version="2.18.15" minimumScale="inf" maximumScale="1e+08" hasScaleBasedVisibilityFlag="0">
+ <pipe>
+  <rasterrenderer opacity="1" alphaBand="-1" classificationMax="1493" classificationMinMaxOrigin="CumulativeCutFullExtentEstimated" band="1" classificationMin="160" type="singlebandpseudocolor">
+   <rasterTransparency/>
+   <rastershader>
+    <colorrampshader colorRampType="INTERPOLATED" clip="0">
+     <item alpha="255" value="160" label="160" color="#d7191c"/>
+     <item alpha="255" value="493.2" label="493.2" color="#fdae61"/>
+     <item alpha="255" value="826.5" label="826.5" color="#ffffbf"/>
+     <item alpha="255" value="1160" label="1160" color="#abdda4"/>
+     <item alpha="255" value="1493" label="1493" color="#2b83ba"/>
+    </colorrampshader>
+   </rastershader>
+  </rasterrenderer>
+  <brightnesscontrast brightness="0" contrast="0"/>
+  <huesaturation colorizeGreen="128" colorizeOn="0" colorizeRed="255" colorizeBlue="128" grayscaleMode="0" saturation="0" colorizeStrength="100"/>
+  <rasterresampler maxOversampling="2"/>
+ </pipe>
+ <blendMode>0</blendMode>
+</qgis>
diff --git a/test/style2.txt b/test/style2.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d6393bc86b100afad4ae578225b56407ef903739
--- /dev/null
+++ b/test/style2.txt
@@ -0,0 +1,17 @@
+<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
+<qgis version="2.18.15" minimumScale="0" maximumScale="1e+08" hasScaleBasedVisibilityFlag="0">
+ <pipe>
+  <rasterrenderer opacity="1" alphaBand="-1" band="1" type="paletted">
+   <rasterTransparency/>
+   <colorPalette>
+    <paletteEntry value="0" color="#000000" label="unclassified"/>
+    <paletteEntry value="1" color="#ff0000" label="class1"/>
+    <paletteEntry value="2" color="#00ff00" label="class2"/>
+   </colorPalette>
+  </rasterrenderer>
+  <brightnesscontrast brightness="0" contrast="0"/>
+  <huesaturation colorizeGreen="128" colorizeOn="0" colorizeRed="255" colorizeBlue="128" grayscaleMode="0" saturation="0" colorizeStrength="100"/>
+  <rasterresampler maxOversampling="2"/>
+ </pipe>
+ <blendMode>0</blendMode>
+</qgis>
diff --git a/test/style3.txt b/test/style3.txt
new file mode 100644
index 0000000000000000000000000000000000000000..83bb054d04d9fc37a3d8a6b2f3f926e68b5a2ad3
--- /dev/null
+++ b/test/style3.txt
@@ -0,0 +1,93 @@
+<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
+<qgis simplifyDrawingTol="1" labelsEnabled="0" simplifyAlgorithm="0" maxScale="0" readOnly="0" version="3.0.2-Girona" minScale="1e+8" simplifyMaxScale="1" simplifyLocal="1" simplifyDrawingHints="1" hasScaleBasedVisibilityFlag="0">
+ <renderer-v2 enableorderby="0" type="singleSymbol" symbollevels="0" forceraster="0">
+  <symbols>
+   <symbol alpha="1" type="fill" clip_to_extent="1" name="0">
+    <layer pass="0" enabled="1" locked="0" class="SimpleFill">
+     <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
+     <prop v="168,123,178,255" k="color"/>
+     <prop v="bevel" k="joinstyle"/>
+     <prop v="0,0" k="offset"/>
+     <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
+     <prop v="MM" k="offset_unit"/>
+     <prop v="35,35,35,255" k="outline_color"/>
+     <prop v="solid" k="outline_style"/>
+     <prop v="0.26" k="outline_width"/>
+     <prop v="MM" k="outline_width_unit"/>
+     <prop v="solid" k="style"/>
+     <data_defined_properties>
+      <Option type="Map">
+       <Option value="" type="QString" name="name"/>
+       <Option name="properties"/>
+       <Option value="collection" type="QString" name="type"/>
+      </Option>
+     </data_defined_properties>
+    </layer>
+   </symbol>
+  </symbols>
+  <rotation/>
+  <sizescale/>
+ </renderer-v2>
+ <customproperties/>
+ <blendMode>0</blendMode>
+ <featureBlendMode>0</featureBlendMode>
+ <layerOpacity>1</layerOpacity>
+ <fieldConfiguration>
+  <field name="DN">
+   <editWidget type="">
+    <config>
+     <Option/>
+    </config>
+   </editWidget>
+  </field>
+  <field name="class_name">
+   <editWidget type="">
+    <config>
+     <Option/>
+    </config>
+   </editWidget>
+  </field>
+ </fieldConfiguration>
+ <aliases>
+  <alias field="DN" index="0" name=""/>
+  <alias field="class_name" index="1" name=""/>
+ </aliases>
+ <excludeAttributesWMS/>
+ <excludeAttributesWFS/>
+ <defaults>
+  <default expression="" field="DN" applyOnUpdate="0"/>
+  <default expression="" field="class_name" applyOnUpdate="0"/>
+ </defaults>
+ <constraints>
+  <constraint unique_strength="0" exp_strength="0" field="DN" notnull_strength="0" constraints="0"/>
+  <constraint unique_strength="0" exp_strength="0" field="class_name" notnull_strength="0" constraints="0"/>
+ </constraints>
+ <constraintExpressions>
+  <constraint field="DN" exp="" desc=""/>
+  <constraint field="class_name" exp="" desc=""/>
+ </constraintExpressions>
+ <attributeactions>
+  <defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
+ </attributeactions>
+ <attributetableconfig sortExpression="" sortOrder="0" actionWidgetStyle="dropDown">
+  <columns/>
+ </attributetableconfig>
+ <editform></editform>
+ <editforminit/>
+ <editforminitcodesource>0</editforminitcodesource>
+ <editforminitfilepath></editforminitfilepath>
+ <editforminitcode><![CDATA[]]></editforminitcode>
+ <featformsuppress>0</featformsuppress>
+ <editorlayout>generatedlayout</editorlayout>
+ <editable/>
+ <labelOnTop/>
+ <widgets/>
+ <conditionalstyles>
+  <rowstyles/>
+  <fieldstyles/>
+ </conditionalstyles>
+ <expressionfields/>
+ <previewExpression></previewExpression>
+ <mapTip></mapTip>
+ <layerGeometryType>2</layerGeometryType>
+</qgis>
diff --git a/test/style4.txt b/test/style4.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d18e30ec2dbffb6e2af22412cd5805757a56178c
--- /dev/null
+++ b/test/style4.txt
@@ -0,0 +1,257 @@
+<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
+<qgis simplifyDrawingTol="1" labelsEnabled="0" simplifyAlgorithm="0" maxScale="0" readOnly="0" version="3.0.2-Girona" minScale="1e+8" simplifyMaxScale="1" simplifyLocal="1" simplifyDrawingHints="1" hasScaleBasedVisibilityFlag="0">
+ <renderer-v2 attr="class_name" enableorderby="0" type="categorizedSymbol" symbollevels="0" forceraster="0">
+  <categories>
+   <category render="true" value="burnt and tilled pasture" label="burnt and tilled pasture" symbol="0"/>
+   <category render="true" value="burnt pasture" label="burnt pasture" symbol="1"/>
+   <category render="true" value="burnt secondary regrowth" label="burnt secondary regrowth" symbol="2"/>
+   <category render="true" value="tilled pasture" label="tilled pasture" symbol="3"/>
+   <category render="true" value="" label="" symbol="4"/>
+  </categories>
+  <symbols>
+   <symbol alpha="1" type="fill" clip_to_extent="1" name="0">
+    <layer pass="0" enabled="1" locked="0" class="SimpleFill">
+     <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
+     <prop v="228,86,159,255" k="color"/>
+     <prop v="bevel" k="joinstyle"/>
+     <prop v="0,0" k="offset"/>
+     <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
+     <prop v="MM" k="offset_unit"/>
+     <prop v="35,35,35,255" k="outline_color"/>
+     <prop v="solid" k="outline_style"/>
+     <prop v="0.26" k="outline_width"/>
+     <prop v="MM" k="outline_width_unit"/>
+     <prop v="solid" k="style"/>
+     <data_defined_properties>
+      <Option type="Map">
+       <Option value="" type="QString" name="name"/>
+       <Option name="properties"/>
+       <Option value="collection" type="QString" name="type"/>
+      </Option>
+     </data_defined_properties>
+    </layer>
+   </symbol>
+   <symbol alpha="1" type="fill" clip_to_extent="1" name="1">
+    <layer pass="0" enabled="1" locked="0" class="SimpleFill">
+     <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
+     <prop v="102,210,219,255" k="color"/>
+     <prop v="bevel" k="joinstyle"/>
+     <prop v="0,0" k="offset"/>
+     <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
+     <prop v="MM" k="offset_unit"/>
+     <prop v="35,35,35,255" k="outline_color"/>
+     <prop v="solid" k="outline_style"/>
+     <prop v="0.26" k="outline_width"/>
+     <prop v="MM" k="outline_width_unit"/>
+     <prop v="solid" k="style"/>
+     <data_defined_properties>
+      <Option type="Map">
+       <Option value="" type="QString" name="name"/>
+       <Option name="properties"/>
+       <Option value="collection" type="QString" name="type"/>
+      </Option>
+     </data_defined_properties>
+    </layer>
+   </symbol>
+   <symbol alpha="1" type="fill" clip_to_extent="1" name="2">
+    <layer pass="0" enabled="1" locked="0" class="SimpleFill">
+     <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
+     <prop v="102,53,225,255" k="color"/>
+     <prop v="bevel" k="joinstyle"/>
+     <prop v="0,0" k="offset"/>
+     <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
+     <prop v="MM" k="offset_unit"/>
+     <prop v="35,35,35,255" k="outline_color"/>
+     <prop v="solid" k="outline_style"/>
+     <prop v="0.26" k="outline_width"/>
+     <prop v="MM" k="outline_width_unit"/>
+     <prop v="solid" k="style"/>
+     <data_defined_properties>
+      <Option type="Map">
+       <Option value="" type="QString" name="name"/>
+       <Option name="properties"/>
+       <Option value="collection" type="QString" name="type"/>
+      </Option>
+     </data_defined_properties>
+    </layer>
+   </symbol>
+   <symbol alpha="1" type="fill" clip_to_extent="1" name="3">
+    <layer pass="0" enabled="1" locked="0" class="SimpleFill">
+     <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
+     <prop v="129,201,118,255" k="color"/>
+     <prop v="bevel" k="joinstyle"/>
+     <prop v="0,0" k="offset"/>
+     <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
+     <prop v="MM" k="offset_unit"/>
+     <prop v="35,35,35,255" k="outline_color"/>
+     <prop v="solid" k="outline_style"/>
+     <prop v="0.26" k="outline_width"/>
+     <prop v="MM" k="outline_width_unit"/>
+     <prop v="solid" k="style"/>
+     <data_defined_properties>
+      <Option type="Map">
+       <Option value="" type="QString" name="name"/>
+       <Option name="properties"/>
+       <Option value="collection" type="QString" name="type"/>
+      </Option>
+     </data_defined_properties>
+    </layer>
+   </symbol>
+   <symbol alpha="1" type="fill" clip_to_extent="1" name="4">
+    <layer pass="0" enabled="1" locked="0" class="SimpleFill">
+     <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
+     <prop v="232,165,31,255" k="color"/>
+     <prop v="bevel" k="joinstyle"/>
+     <prop v="0,0" k="offset"/>
+     <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
+     <prop v="MM" k="offset_unit"/>
+     <prop v="35,35,35,255" k="outline_color"/>
+     <prop v="solid" k="outline_style"/>
+     <prop v="0.26" k="outline_width"/>
+     <prop v="MM" k="outline_width_unit"/>
+     <prop v="solid" k="style"/>
+     <data_defined_properties>
+      <Option type="Map">
+       <Option value="" type="QString" name="name"/>
+       <Option name="properties"/>
+       <Option value="collection" type="QString" name="type"/>
+      </Option>
+     </data_defined_properties>
+    </layer>
+   </symbol>
+  </symbols>
+  <source-symbol>
+   <symbol alpha="1" type="fill" clip_to_extent="1" name="0">
+    <layer pass="0" enabled="1" locked="0" class="SimpleFill">
+     <prop v="3x:0,0,0,0,0,0" k="border_width_map_unit_scale"/>
+     <prop v="168,123,178,255" k="color"/>
+     <prop v="bevel" k="joinstyle"/>
+     <prop v="0,0" k="offset"/>
+     <prop v="3x:0,0,0,0,0,0" k="offset_map_unit_scale"/>
+     <prop v="MM" k="offset_unit"/>
+     <prop v="35,35,35,255" k="outline_color"/>
+     <prop v="solid" k="outline_style"/>
+     <prop v="0.26" k="outline_width"/>
+     <prop v="MM" k="outline_width_unit"/>
+     <prop v="solid" k="style"/>
+     <data_defined_properties>
+      <Option type="Map">
+       <Option value="" type="QString" name="name"/>
+       <Option name="properties"/>
+       <Option value="collection" type="QString" name="type"/>
+      </Option>
+     </data_defined_properties>
+    </layer>
+   </symbol>
+  </source-symbol>
+  <colorramp type="randomcolors" name="[source]"/>
+  <rotation/>
+  <sizescale/>
+ </renderer-v2>
+ <customproperties>
+  <property key="embeddedWidgets/count" value="0"/>
+  <property key="variableNames"/>
+  <property key="variableValues"/>
+ </customproperties>
+ <blendMode>0</blendMode>
+ <featureBlendMode>0</featureBlendMode>
+ <layerOpacity>1</layerOpacity>
+ <SingleCategoryDiagramRenderer diagramType="Histogram" attributeLegend="1">
+  <DiagramCategory barWidth="5" opacity="1" width="15" enabled="0" penColor="#000000" penAlpha="255" backgroundAlpha="255" backgroundColor="#ffffff" rotationOffset="270" scaleBasedVisibility="0" lineSizeScale="3x:0,0,0,0,0,0" height="15" minimumSize="0" maxScaleDenominator="1e+8" sizeScale="3x:0,0,0,0,0,0" penWidth="0" lineSizeType="MM" sizeType="MM" minScaleDenominator="0" labelPlacementMethod="XHeight" scaleDependency="Area" diagramOrientation="Up">
+   <fontProperties style="" description="MS Shell Dlg 2,8.25,-1,5,50,0,0,0,0,0"/>
+  </DiagramCategory>
+ </SingleCategoryDiagramRenderer>
+ <DiagramLayerSettings linePlacementFlags="18" priority="0" placement="0" zIndex="0" obstacle="0" dist="0" showAll="1">
+  <properties>
+   <Option type="Map">
+    <Option value="" type="QString" name="name"/>
+    <Option name="properties"/>
+    <Option value="collection" type="QString" name="type"/>
+   </Option>
+  </properties>
+ </DiagramLayerSettings>
+ <fieldConfiguration>
+  <field name="DN">
+   <editWidget type="TextEdit">
+    <config>
+     <Option/>
+    </config>
+   </editWidget>
+  </field>
+  <field name="class_name">
+   <editWidget type="TextEdit">
+    <config>
+     <Option/>
+    </config>
+   </editWidget>
+  </field>
+ </fieldConfiguration>
+ <aliases>
+  <alias field="DN" index="0" name=""/>
+  <alias field="class_name" index="1" name=""/>
+ </aliases>
+ <excludeAttributesWMS/>
+ <excludeAttributesWFS/>
+ <defaults>
+  <default expression="" field="DN" applyOnUpdate="0"/>
+  <default expression="" field="class_name" applyOnUpdate="0"/>
+ </defaults>
+ <constraints>
+  <constraint unique_strength="0" exp_strength="0" field="DN" notnull_strength="0" constraints="0"/>
+  <constraint unique_strength="0" exp_strength="0" field="class_name" notnull_strength="0" constraints="0"/>
+ </constraints>
+ <constraintExpressions>
+  <constraint field="DN" exp="" desc=""/>
+  <constraint field="class_name" exp="" desc=""/>
+ </constraintExpressions>
+ <attributeactions>
+  <defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
+ </attributeactions>
+ <attributetableconfig sortExpression="" sortOrder="0" actionWidgetStyle="dropDown">
+  <columns>
+   <column hidden="0" type="field" name="DN" width="-1"/>
+   <column hidden="0" type="field" name="class_name" width="-1"/>
+   <column hidden="1" type="actions" width="-1"/>
+  </columns>
+ </attributetableconfig>
+ <editform></editform>
+ <editforminit/>
+ <editforminitcodesource>0</editforminitcodesource>
+ <editforminitfilepath></editforminitfilepath>
+ <editforminitcode><![CDATA[# -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+	geom = feature.geometry()
+	control = dialog.findChild(QWidget, "MyLineEdit")
+]]></editforminitcode>
+ <featformsuppress>0</featformsuppress>
+ <editorlayout>generatedlayout</editorlayout>
+ <editable>
+  <field name="DN" editable="1"/>
+  <field name="class_name" editable="1"/>
+ </editable>
+ <labelOnTop>
+  <field labelOnTop="0" name="DN"/>
+  <field labelOnTop="0" name="class_name"/>
+ </labelOnTop>
+ <widgets/>
+ <conditionalstyles>
+  <rowstyles/>
+  <fieldstyles/>
+ </conditionalstyles>
+ <expressionfields/>
+ <previewExpression>class_name</previewExpression>
+ <mapTip></mapTip>
+ <layerGeometryType>2</layerGeometryType>
+</qgis>
diff --git a/test/test_mapvisualization.py b/test/test_mapvisualization.py
index ba4c2cb176024fa07feb28269951d71bc9f74454..220d3ad5b7beac3d4e94383e3506cbeea4fa0dd7 100644
--- a/test/test_mapvisualization.py
+++ b/test/test_mapvisualization.py
@@ -22,10 +22,50 @@ from timeseriesviewer.utils import initQgisApplication
 from PyQt5.QtGui import *
 from PyQt5.QtCore import *
 import unittest
+from timeseriesviewer.utils import *
 from timeseriesviewer.mapcanvas import *
-
+from timeseriesviewer.mapvisualization import *
+from example.Images import Img_2014_05_07_LC82270652014127LGN00_BOA
 QGIS_APP = initQgisApplication()
 
+def getChildElements(node):
+    assert isinstance(node, QDomNode)
+    childs = node.childNodes()
+    return [childs.at(i) for i in range(childs.count())]
+
+def compareXML(element1, element2 ):
+
+    assert isinstance(element1, QDomNode)
+    assert isinstance(element2, QDomNode)
+
+    tag1 = element1.nodeName()
+    tag2 = element2.nodeName()
+    if tag1 != tag2:
+        return False
+
+    elts1 = getChildElements(element1);
+    elts2 = getChildElements(element2);
+
+    if len(elts1) != len(elts2):
+        return False
+
+    if len(elts1) == 0:
+
+
+        value1 = element1.nodeValue()
+        value2 = element2.nodeValue()
+
+        if value1 != value2:
+            return False
+        else:
+            return True
+    else:
+        for e1, e2 in zip(elts1, elts2):
+            if not compareXML(e1, e2):
+                return False
+
+        return True
+
 
 class testclassDialogTest(unittest.TestCase):
     """Test rerources work."""
@@ -45,6 +85,142 @@ class testclassDialogTest(unittest.TestCase):
         m.show()
 
 
+    def test_bandselection(self):
+
+        lyr = QgsRasterLayer(Img_2014_05_07_LC82270652014127LGN00_BOA)
+
+        wl, wlu = parseWavelength(lyr)
+        self.assertIsInstance(wl, np.ndarray)
+        self.assertIsInstance(wlu, str)
+        self.assertEqual(wlu, 'um')
+        refWL = [0.49,  0.56,  0.66,  0.84,  1.65,  2.2]
+
+        self.assertEqual(len(wl), len(refWL))
+        for wla, wlb in zip(wl, refWL):
+            self.assertAlmostEqual(wla, wlb)
+
+        self.assertEqual(0, bandClosestToWavelength(lyr, 'B'))
+        s = ""
+
+    def test_renderer(self):
+
+        styleFiles = file_search(os.path.dirname(__file__), 'style*.txt')
+
+        lyr = QgsRasterLayer(Img_2014_05_07_LC82270652014127LGN00_BOA)
+
+        r0 = lyr.renderer()
+        xml0 = rendererToXml(r0)
+        r0b = rendererFromXml(xml0)
+        self.assertTrue(type(r0), type(r0b))
+
+
+
+        rasterRenderer = [QgsMultiBandColorRenderer(r0, 3,2,1, QgsContrastEnhancement(), QgsContrastEnhancement(), QgsContrastEnhancement()),
+                          QgsPalettedRasterRenderer(r0,0, [
+                              QgsPalettedRasterRenderer.Class(0, QColor('black'), 'class1'),
+                              QgsPalettedRasterRenderer.Class(1, QColor('green'), 'class2'),
+                          ] ),
+                          QgsHillshadeRenderer(r0, 0, 0.0, 100.0),
+                          QgsSingleBandPseudoColorRenderer(r0, 0, QgsRasterShader(0.0, 255.0)),
+                          QgsSingleBandColorDataRenderer(r0, 0),
+                          QgsSingleBandGrayRenderer(r0, 0)]
+
+        vectorRenderer = []#[QgsSingleSymbolRenderer(QgsLineSymbol()), QgsPointDistanceRenderer()]
+
+        for r1 in rasterRenderer + vectorRenderer:
+            print('Test {}'.format(r1.__class__.__name__))
+            xml1 = rendererToXml(r1)
+            self.assertIsInstance(xml1, QDomDocument)
+
+
+            r1b = rendererFromXml(xml1)
+            self.assertTrue(type(r1), type(r1b))
+
+            if isinstance(r1, QgsRasterRenderer):
+                self.assertIsInstance(r1b, QgsRasterRenderer)
+            elif isinstance(r1, QgsFeatureRenderer):
+                self.assertIsInstance(r1b, QgsFeatureRenderer)
+
+            xml2 = rendererToXml(r1b)
+            self.assertIsInstance(xml2, QDomDocument)
+            self.assertTrue(xml1.toString() == xml2.toString())
+
+
+            rClone = cloneRenderer(r1)
+            self.assertTrue(type(r1), type(rClone))
+            xmlClone =  rendererToXml(rClone)
+            self.assertIsInstance(xmlClone, QDomDocument)
+
+            similar = compareXML(xml1.firstChild(), xml2.firstChild())
+            self.assertTrue(similar)
+
+
+
+
+
+
+        for path in styleFiles:
+            f = open(path, encoding='utf8')
+            xml = ''.join(f.readlines())
+            f.close()
+
+            renderer = rendererFromXml(xml)
+            self.assertTrue(renderer != None)
+            #self.assertTrue(isinstance(renderer, QgsRasterRenderer) or isinstance(renderer, QgsFeatureRenderer), msg='Unable to read style from {}'.format(path))
+
+
+        print('test_renderer done')
+
+    def test_maprendersettings(self):
+        from example.Images import Img_2014_01_15_LC82270652014015LGN00_BOA
+
+        from timeseriesviewer.timeseries import TimeSeries
+        TS = TimeSeries()
+        TS.addFiles([Img_2014_01_15_LC82270652014015LGN00_BOA])
+        sensor1 = TS.sensors()[0]
+        w = MapViewRenderSettings(sensor1)
+        w.show()
+
+
+        lyr = QgsRasterLayer(Img_2014_01_15_LC82270652014015LGN00_BOA)
+        doc = QDomDocument()
+        err = ''
+        lyr.exportNamedStyle(doc, err)
+        xml0 = doc.toString()
+        self.assertEqual(err, '')
+
+        xml = rendererToXml(lyr.renderer())
+        self.assertIsInstance(xml, QDomDocument)
+        xml = xml.toString()
+        self.assertEqual(xml0, xml)
+
+
+        r0 = lyr.renderer()
+        r = w.rasterRenderer()
+
+        self.assertIsInstance(r, QgsMultiBandColorRenderer)
+
+        r2 = QgsSingleBandGrayRenderer(r, 2)
+        w.setRasterRenderer(r2)
+        self.assertIsInstance(w.currentRenderWidget(), QgsSingleBandGrayRendererWidget)
+        r2b = w.rasterRenderer()
+        self.assertIsInstance(r2b, QgsSingleBandGrayRenderer)
+        xml2, xml2b = rendererToXml(r2).toString(), rendererToXml(r2b).toString()
+        #self.assertEqual(xml2, xml2b)
+
+        r3 = QgsSingleBandPseudoColorRenderer(r,0)
+        r3.setClassificationMin(0)
+        r3.setClassificationMax(100)
+        w.setRasterRenderer(r3)
+        self.assertIsInstance(w.currentRenderWidget(), QgsSingleBandPseudoColorRendererWidget)
+        r3b = w.rasterRenderer()
+        self.assertIsInstance(r3b, QgsSingleBandPseudoColorRenderer)
+        xml3, xml3b = rendererToXml(r3).toString(), rendererToXml(r3b).toString()
+        #self.assertEqual(xml3, xml3b)
+        s = ""
+
+
+
 
 
 
diff --git a/timeseriesviewer/__init__.py b/timeseriesviewer/__init__.py
index c5607b8f9ab730c24ec463a07770058cb4432fd8..275d1d70e9d895a86d6b0810ca9589465f474848 100644
--- a/timeseriesviewer/__init__.py
+++ b/timeseriesviewer/__init__.py
@@ -107,30 +107,8 @@ def icon():
     path = os.path.join(os.path.dirname(__file__), 'icon.png')
     return QIcon(path)
 
-
-def file_search(rootdir, pattern, recursive=False, ignoreCase=False):
-    assert os.path.isdir(rootdir), "Path is not a directory:{}".format(rootdir)
-    regType = type(re.compile('.*'))
-    results = []
-
-    for root, dirs, files in os.walk(rootdir):
-        for file in files:
-            if isinstance(pattern, regType):
-                if pattern.search(file):
-                    path = os.path.join(root, file)
-                    results.append(path)
-
-            elif (ignoreCase and fnmatch.fnmatch(file.lower(), pattern.lower())) \
-                    or fnmatch.fnmatch(file, pattern):
-
-                path = os.path.join(root, file)
-                results.append(path)
-        if not recursive:
-            break
-            pass
-
-    return results
-
+import timeseriesviewer.utils
+file_search = timeseriesviewer.utils.file_search
 
 
 def getFileAndAttributes(file):
diff --git a/timeseriesviewer/dummy_gdal.vrt b/timeseriesviewer/dummy_gdal.vrt
new file mode 100644
index 0000000000000000000000000000000000000000..68af42a2776e5e5d9e867b47648884881eb61824
--- /dev/null
+++ b/timeseriesviewer/dummy_gdal.vrt
@@ -0,0 +1,22 @@
+<VRTDataset rasterXSize="1" rasterYSize="1">
+  <GeoTransform>  0.0000000000000000e+00,  1.0000000000000000e+00,  0.0000000000000000e+00,  0.0000000000000000e+00,  0.0000000000000000e+00, -1.0000000000000000e+00</GeoTransform>
+  <VRTRasterBand dataType="Float32" band="1">
+    <Metadata>
+      <MDI key="STATISTICS_MAXIMUM">0</MDI>
+      <MDI key="STATISTICS_MEAN">0</MDI>
+      <MDI key="STATISTICS_MINIMUM">0</MDI>
+      <MDI key="STATISTICS_STDDEV">0</MDI>
+    </Metadata>
+    <Description>Band 1</Description>
+    <Histograms>
+      <HistItem>
+        <HistMin>0</HistMin>
+        <HistMax>0</HistMax>
+        <BucketCount>1</BucketCount>
+        <IncludeOutOfRange>0</IncludeOutOfRange>
+        <Approximate>0</Approximate>
+        <HistCounts>0</HistCounts>
+      </HistItem>
+    </Histograms>
+  </VRTRasterBand>
+</VRTDataset>
diff --git a/timeseriesviewer/dummy_ogr.vrt b/timeseriesviewer/dummy_ogr.vrt
new file mode 100644
index 0000000000000000000000000000000000000000..936190ccb456719625d3258a6a7d9578221457eb
--- /dev/null
+++ b/timeseriesviewer/dummy_ogr.vrt
@@ -0,0 +1,4 @@
+<OGRVRTDataSource>
+    <OGRVRTLayer name="dummy_layer1">
+    </OGRVRTLayer>
+</OGRVRTDataSource>
\ No newline at end of file
diff --git a/timeseriesviewer/mapcanvas.py b/timeseriesviewer/mapcanvas.py
index ee2e2fe54d179148dbe090a923dbd6ea2ea33202..3b9f404864e1fd2acf3991e94712b48cc465f409 100644
--- a/timeseriesviewer/mapcanvas.py
+++ b/timeseriesviewer/mapcanvas.py
@@ -277,7 +277,9 @@ class MapLayerInfo(object):
            self.mProvider == 'gdal' and isinstance(renderer, QgsRasterRenderer):
             self.mRenderer = renderer
             if self.isInitialized():
+                from timeseriesviewer.mapvisualization import cloneRenderer
                 copyRenderer(self.mRenderer, self.mLayer)
+
                 #self.mLayer.repaintRequested.emit()
 
     def setIsVisible(self, b):
@@ -852,14 +854,27 @@ class MapCanvas(QgsMapCanvas):
 
                 if isinstance(r, QgsMultiBandColorRenderer):
 
+                    #newRenderer = QgsMultiBandColorRenderer(None, r.redBand(), r.greenBand(), r.blueBand())
+                    newRenderer = cloneRenderer(r)
+
+                    ceR = getCE(r.redBand())
+                    ceG = getCE(r.greenBand())
+                    ceB = getCE(r.blueBand())
 
-                    newRenderer = QgsMultiBandColorRenderer(None, r.redBand(), r.greenBand(), r.blueBand())
-                    newRenderer.setRedContrastEnhancement(getCE(r.redBand()))
-                    newRenderer.setGreenContrastEnhancement(getCE(r.greenBand()))
-                    newRenderer.setBlueContrastEnhancement(getCE(r.blueBand()))
+                    if False:
+                        vMin = min(ceR.minimumValue(), ceG.minimumValue(), ceB.minimumValue())
+                        vMax = max(ceR.maximumValue(), ceG.maximumValue(), ceB.maximumValue())
+                        for ce in [ceR, ceG, ceB]:
+                            assert isinstance(ce, QgsContrastEnhancement)
+                            ce.setMaximumValue(vMax)
+                            ce.setMinimumValue(vMin)
+
+                    newRenderer.setRedContrastEnhancement(ceR)
+                    newRenderer.setGreenContrastEnhancement(ceG)
+                    newRenderer.setBlueContrastEnhancement(ceB)
 
                 elif isinstance(r, QgsSingleBandPseudoColorRenderer):
-                    newRenderer = r.clone()
+                    newRenderer = cloneRenderer(r)
                     ce = getCE(newRenderer.band())
                     #stats = dp.bandStatistics(newRenderer.band(), QgsRasterBandStats.All, extent, 500)
 
@@ -868,7 +883,12 @@ class MapCanvas(QgsMapCanvas):
                     newRenderer.setClassificationMin(ce.minimumValue())
                     shader.setMaximumValue(ce.maximumValue())
                     shader.setMinimumValue(ce.minimumValue())
+                elif isinstance(r, QgsSingleBandGrayRenderer):
+                    newRenderer = cloneRenderer(r)
+                    s = ""
+                elif isinstance(r, QgsPalettedRasterRenderer):
                     s = ""
+                    #newRenderer = cloneRenderer(r)
 
                 if newRenderer is not None:
                     self.sigChangeSVRequest.emit(self, newRenderer)
diff --git a/timeseriesviewer/mapvisualization.py b/timeseriesviewer/mapvisualization.py
index 5cbc9c3092f62a3343ddc3c2cddd4558f318a773..4a977b75edb99295e309d45d2088fb498289cb7c 100644
--- a/timeseriesviewer/mapvisualization.py
+++ b/timeseriesviewer/mapvisualization.py
@@ -22,8 +22,6 @@
 
 
 import os, sys, re, fnmatch, collections, copy, traceback, bisect
-import logging
-logger = logging.getLogger(__name__)
 from qgis.core import *
 from qgis.core import QgsContrastEnhancement, QgsRasterShader, QgsColorRampShader,  QgsProject, QgsCoordinateReferenceSystem, \
     QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsMapLayerProxyModel, QgsColorRamp, QgsSingleBandPseudoColorRenderer
@@ -43,6 +41,15 @@ from timeseriesviewer.mapcanvas import MapCanvas
 from timeseriesviewer.crosshair import CrosshairStyle
 
 
+
+#dummyPath = os.path.abspath(os.path.join(os.path.dirname(__file__), 'dummy_gdal.vrt'))
+#assert os.path.isfile(dummyPath)
+#lyr = QgsRasterLayer(dummyPath)
+#assert lyr.isValid()
+DUMMY_RASTERINTERFACE = QgsSingleBandGrayRenderer(None, 0)
+
+
+
 class MapViewUI(QFrame, loadUI('mapviewdefinition.ui')):
 
 
@@ -78,14 +85,18 @@ class MapViewUI(QFrame, loadUI('mapviewdefinition.ui')):
     def addSensor(self, sensor):
         assert isinstance(sensor, SensorInstrument)
 
-        w = MapViewSensorSettings(sensor)
+        #w = MapViewSensorSettings(sensor)
+        w = MapViewRenderSettings(sensor)
         #sizePolicy = QSizePolicy(QSize)
         #w.ui.
-        l = self.renderSettingsLayout
+        #l = self.renderSettingsLayout
+        l = self.gbRasterRendering.layout()
         assert sensor not in self.mSensors.keys()
 
-        lastWidgetIndex = l.count()-1
-        l.insertWidget(lastWidgetIndex, w.ui)
+        i = l.count()-1
+        while i > 0 and not isinstance(l.itemAt(i), QWidget):
+            i -= 1
+        l.insertWidget(i, w, stretch=0, alignment=Qt.AlignTop)
         self.mSensors[sensor] = w
         #self.resize(self.sizeHint())
 
@@ -96,14 +107,889 @@ class MapViewUI(QFrame, loadUI('mapviewdefinition.ui')):
 
         assert isinstance(sensor, SensorInstrument)
         sensorSettings = self.mSensors.pop(sensor)
-        assert isinstance(sensorSettings, MapViewSensorSettings)
+        assert isinstance(sensorSettings, MapViewRenderSettings)
 
-        l = self.renderSettingsLayout
+        #l = self.renderSettingsLayout
+        l = self.gbRasterRendering.layout()
         l.removeWidget(sensorSettings.ui)
         sensorSettings.ui.close()
         #self.resize(self.sizeHint())
 
 
+
+class RendererWidgetModifications(object):
+
+
+    def __init__(self):
+        self.mBandComboBoxes = []
+
+    def modifyGridLayout(self):
+        gridLayoutOld = self.layout().children()[0]
+        self.gridLayout = QGridLayout()
+        while gridLayoutOld.count() > 0:
+            w = gridLayoutOld.takeAt(0)
+            w = w.widget()
+            gridLayoutOld.removeWidget(w)
+            w.setVisible(False)
+            setattr(self, w.objectName(), w)
+        self.layout().removeItem(gridLayoutOld)
+        self.layout().insertItem(0, self.gridLayout)
+        self.gridLayout.setSpacing(2)
+        self.layout().addStretch()
+
+    def connectSliderWithBandComboBox(self, slider, combobox):
+        """
+        Connects a band-selection slider with a band-selection combobox
+        :param widget: QgsRasterRendererWidget
+        :param slider: QSlider to show the band number
+        :param combobox: QComboBox to show the band name
+        :return:
+        """
+        assert isinstance(self, QgsRasterRendererWidget)
+        assert isinstance(slider, QSlider)
+        assert isinstance(combobox, QComboBox)
+
+        # init the slider
+        nb = self.rasterLayer().dataProvider().bandCount()
+        slider.setTickPosition(QSlider.TicksAbove)
+        slider.valueChanged.connect(combobox.setCurrentIndex)
+        slider.setMinimum(1)
+        slider.setMaximum(nb)
+        intervals = [1, 2, 5, 10, 25, 50]
+        for interval in intervals:
+            if nb / interval < 10:
+                break
+        slider.setTickInterval(interval)
+        slider.setPageStep(interval)
+
+        def onBandValueChanged(self, idx, slider):
+            assert isinstance(self, QgsRasterRendererWidget)
+            assert isinstance(idx, int)
+            assert isinstance(slider, QSlider)
+
+            # i = slider.value()
+            slider.blockSignals(True)
+            slider.setValue(idx)
+            slider.blockSignals(False)
+
+            # self.minMaxWidget().setBands(myBands)
+            # self.widgetChanged.emit()
+
+        if self.comboBoxWithNotSetItem(combobox):
+            combobox.currentIndexChanged[int].connect(lambda idx: onBandValueChanged(self, idx, slider))
+        else:
+            combobox.currentIndexChanged[int].connect(lambda idx: onBandValueChanged(self, idx + 1, slider))
+
+    def comboBoxWithNotSetItem(self, cb):
+        assert isinstance(cb, QComboBox)
+        return cb.itemData(0, role=Qt.DisplayRole) == 'not set'
+
+    def setLayoutItemVisibility(self, grid, isVisible):
+        assert isinstance(self, QgsRasterRendererWidget)
+        for i in range(grid.count()):
+            item = grid.itemAt(i)
+            if isinstance(item, QLayout):
+                s = ""
+            elif isinstance(item, QWidgetItem):
+                item.widget().setVisible(isVisible)
+                item.widget().setParent(self)
+            else:
+                s = ""
+
+
+
+
+
+def displayBandNames(provider_or_dataset, bands=None):
+    results = None
+    if isinstance(provider_or_dataset, QgsRasterLayer):
+        return displayBandNames(provider_or_dataset.dataProvider())
+    elif isinstance(provider_or_dataset, QgsRasterDataProvider):
+        if provider_or_dataset.name() == 'gdal':
+            ds = gdal.Open(provider_or_dataset.dataSourceUri())
+            results = displayBandNames(ds, bands=bands)
+        else:
+            # same as in QgsRasterRendererWidget::displayBandName
+            results = []
+            if bands is None:
+                bands = range(1, provider_or_dataset.bandCount() + 1)
+            for band in bands:
+                result = provider_or_dataset.generateBandName(band)
+                colorInterp ='{}'.format(provider_or_dataset.colorInterpretationName(band))
+                if colorInterp != 'Undefined':
+                    result += '({})'.format(colorInterp)
+                results.append(result)
+
+    elif isinstance(provider_or_dataset, gdal.Dataset):
+        results = []
+        if bands is None:
+            bands = range(1, provider_or_dataset.RasterCount+1)
+        for band in bands:
+            b = provider_or_dataset.GetRasterBand(band)
+            descr = b.GetDescription()
+            if len(descr) == 0:
+                descr = 'Band {}'.format(band)
+            results.append(descr)
+
+    return results
+
+class SingleBandGrayRendererWidget(QgsSingleBandGrayRendererWidget, RendererWidgetModifications):
+    @staticmethod
+    def create(layer, extent):
+        return SingleBandGrayRendererWidget(layer, extent)
+
+    def __init__(self, layer, extent):
+        super(SingleBandGrayRendererWidget, self).__init__(layer, extent)
+
+        self.modifyGridLayout()
+        self.mGrayBandSlider = QSlider(Qt.Horizontal)
+        self.mBandComboBoxes.append(self.mGrayBandComboBox)
+        self.fixBandNames(self.mGrayBandComboBox)
+        self.connectSliderWithBandComboBox(self.mGrayBandSlider, self.mGrayBandComboBox)
+
+        self.mBtnBar = QFrame()
+        self.initActionButtons()
+
+        self.gridLayout.addWidget(self.mGrayBandLabel, 0, 0)
+        self.gridLayout.addWidget(self.mBtnBar, 0, 1, 1, 4, Qt.AlignLeft)
+
+        self.gridLayout.addWidget(self.mGrayBandSlider, 1, 1, 1, 2)
+        self.gridLayout.addWidget(self.mGrayBandComboBox, 1, 3,1,2)
+
+        self.gridLayout.addWidget(self.label, 2, 0)
+        self.gridLayout.addWidget(self.mGradientComboBox, 2, 1, 1, 4)
+
+        self.gridLayout.addWidget(self.mMinLabel, 3, 1)
+        self.gridLayout.addWidget(self.mMinLineEdit, 3, 2)
+        self.gridLayout.addWidget(self.mMaxLabel, 3, 3)
+        self.gridLayout.addWidget(self.mMaxLineEdit, 3, 4)
+
+        self.gridLayout.addWidget(self.mContrastEnhancementLabel, 4, 0)
+        self.gridLayout.addWidget(self.mContrastEnhancementComboBox, 4, 1, 1 ,4)
+        self.gridLayout.setSpacing(2)
+
+        self.setLayoutItemVisibility(self.gridLayout, True)
+
+        self.mDefaultRenderer = layer.renderer()
+
+
+    def initActionButtons(self):
+            wl, wlu = parseWavelength(self.rasterLayer())
+            self.wavelengths = wl
+            self.wavelengthUnit = wlu
+
+            self.mBtnBar.setLayout(QHBoxLayout())
+            self.mBtnBar.layout().addStretch()
+            self.mBtnBar.layout().setContentsMargins(0, 0, 0, 0)
+            self.mBtnBar.layout().setSpacing(2)
+
+            self.actionSetDefault = QAction('Default')
+            self.actionSetRed = QAction('R')
+            self.actionSetGreen = QAction('G')
+            self.actionSetBlue = QAction('B')
+            self.actionSetNIR = QAction('nIR')
+            self.actionSetSWIR = QAction('swIR')
+
+            self.actionSetDefault.triggered.connect(lambda: self.setBandSelection('default'))
+            self.actionSetRed.triggered.connect(lambda: self.setBandSelection('R'))
+            self.actionSetGreen.triggered.connect(lambda: self.setBandSelection('G'))
+            self.actionSetBlue.triggered.connect(lambda: self.setBandSelection('B'))
+            self.actionSetNIR.triggered.connect(lambda: self.setBandSelection('nIR'))
+            self.actionSetSWIR.triggered.connect(lambda: self.setBandSelection('swIR'))
+
+
+            def addBtnAction(action):
+                btn = QToolButton()
+                btn.setDefaultAction(action)
+                self.mBtnBar.layout().addWidget(btn)
+                self.insertAction(None, action)
+                return btn
+
+            self.btnDefault = addBtnAction(self.actionSetDefault)
+            self.btnRed = addBtnAction(self.actionSetRed)
+            self.btnGreen = addBtnAction(self.actionSetGreen)
+            self.btnBlue = addBtnAction(self.actionSetRed)
+            self.btnNIR = addBtnAction(self.actionSetNIR)
+            self.btnSWIR = addBtnAction(self.actionSetSWIR)
+
+            b = self.wavelengths is not None
+            for a in [self.actionSetRed, self.actionSetGreen, self.actionSetBlue, self.actionSetNIR, self.actionSetSWIR]:
+                a.setEnabled(b)
+
+
+
+class SingleBandPseudoColorRendererWidget(QgsSingleBandPseudoColorRendererWidget, RendererWidgetModifications):
+    @staticmethod
+    def create(layer, extent):
+        return SingleBandPseudoColorRendererWidget(layer, extent)
+
+    def __init__(self, layer, extent):
+        super(SingleBandPseudoColorRendererWidget, self).__init__(layer, extent)
+
+        self.gridLayout = self.layout()
+        assert isinstance(self.gridLayout, QGridLayout)
+        for i in range(self.gridLayout.count()):
+            w = self.gridLayout.itemAt(i)
+            w = w.widget()
+            if isinstance(w, QWidget):
+                setattr(self, w.objectName(), w)
+
+        toReplace = [self.mBandComboBox,self.mMinLabel,self.mMaxLabel, self.mMinLineEdit, self.mMaxLineEdit ]
+        for w in toReplace:
+            self.gridLayout.removeWidget(w)
+            w.setVisible(False)
+        self.mBandSlider = QSlider(Qt.Horizontal)
+        self.mBandComboBoxes.append(self.mBandComboBox)
+        self.fixBandNames(self.mBandComboBox)
+        self.connectSliderWithBandComboBox(self.mBandSlider, self.mBandComboBox)
+
+        self.mBtnBar = QFrame()
+        self.initActionButtons()
+        grid = QGridLayout()
+        grid.addWidget(self.mBtnBar,0,0,1,4, Qt.AlignLeft)
+        grid.addWidget(self.mBandSlider, 1,0, 1,2)
+        grid.addWidget(self.mBandComboBox, 1,2, 1,2)
+        grid.addWidget(self.mMinLabel, 2, 0)
+        grid.addWidget(self.mMinLineEdit, 2, 1)
+        grid.addWidget(self.mMaxLabel, 2, 2)
+        grid.addWidget(self.mMaxLineEdit, 2, 3)
+        #grid.setContentsMargins(2, 2, 2, 2, )
+        grid.setColumnStretch(0, 0)
+        grid.setColumnStretch(1, 2)
+        grid.setColumnStretch(2, 0)
+        grid.setColumnStretch(3, 2)
+        grid.setSpacing(2)
+        self.gridLayout.addItem(grid, 0,1,2,4)
+        self.gridLayout.setSpacing(2)
+        self.setLayoutItemVisibility(grid, True)
+
+
+    def initActionButtons(self):
+            from enmapbox.gui.utils import parseWavelength
+            wl, wlu = parseWavelength(self.rasterLayer())
+            self.wavelengths = wl
+            self.wavelengthUnit = wlu
+
+            self.mBtnBar.setLayout(QHBoxLayout())
+            self.mBtnBar.layout().addStretch()
+            self.mBtnBar.layout().setContentsMargins(0, 0, 0, 0)
+            self.mBtnBar.layout().setSpacing(2)
+
+            self.actionSetDefault = QAction('Default')
+            self.actionSetRed = QAction('R')
+            self.actionSetGreen = QAction('G')
+            self.actionSetBlue = QAction('B')
+            self.actionSetNIR = QAction('nIR')
+            self.actionSetSWIR = QAction('swIR')
+
+            self.actionSetDefault.triggered.connect(lambda: self.setBandSelection('default'))
+            self.actionSetRed.triggered.connect(lambda: self.setBandSelection('R'))
+            self.actionSetGreen.triggered.connect(lambda: self.setBandSelection('G'))
+            self.actionSetBlue.triggered.connect(lambda: self.setBandSelection('B'))
+            self.actionSetNIR.triggered.connect(lambda: self.setBandSelection('nIR'))
+            self.actionSetSWIR.triggered.connect(lambda: self.setBandSelection('swIR'))
+
+
+            def addBtnAction(action):
+                btn = QToolButton()
+                btn.setDefaultAction(action)
+                self.mBtnBar.layout().addWidget(btn)
+                self.insertAction(None, action)
+                return btn
+
+            self.btnDefault = addBtnAction(self.actionSetDefault)
+            self.btnRed = addBtnAction(self.actionSetRed)
+            self.btnGreen = addBtnAction(self.actionSetGreen)
+            self.btnBlue = addBtnAction(self.actionSetRed)
+            self.btnNIR = addBtnAction(self.actionSetNIR)
+            self.btnSWIR = addBtnAction(self.actionSetSWIR)
+
+            b = self.wavelengths is not None
+            for a in [self.actionSetRed, self.actionSetGreen, self.actionSetBlue, self.actionSetNIR, self.actionSetSWIR]:
+                a.setEnabled(b)
+
+
+
+
+class MultiBandColorRendererWidget(QgsMultiBandColorRendererWidget, RendererWidgetModifications):
+    @staticmethod
+    def create(layer, extent):
+        return MultiBandColorRendererWidget(layer, extent)
+
+    def __init__(self, layer, extent):
+        super(MultiBandColorRendererWidget, self).__init__(layer, extent)
+
+        self.modifyGridLayout()
+
+        self.mRedBandSlider = QSlider(Qt.Horizontal)
+        self.mGreenBandSlider = QSlider(Qt.Horizontal)
+        self.mBlueBandSlider = QSlider(Qt.Horizontal)
+
+        self.mBandComboBoxes.extend([self.mRedBandComboBox, self.mGreenBandComboBox, self.mBlueBandComboBox])
+        self.mSliders = [self.mRedBandSlider, self.mGreenBandSlider, self.mBlueBandSlider]
+        nb = self.rasterLayer().dataProvider().bandCount()
+        for cbox, slider in zip(self.mBandComboBoxes, self.mSliders):
+            self.connectSliderWithBandComboBox(slider, cbox)
+
+
+        self.fixBandNames(self.mRedBandComboBox)
+        self.fixBandNames(self.mGreenBandComboBox)
+        self.fixBandNames(self.mBlueBandComboBox)
+
+        self.mBtnBar = QFrame()
+        self.mBtnBar.setLayout(QHBoxLayout())
+        self.initActionButtons()
+        self.mBtnBar.layout().addStretch()
+        self.mBtnBar.layout().setContentsMargins(0, 0, 0, 0)
+        self.mBtnBar.layout().setSpacing(2)
+
+        #self.gridLayout.deleteLater()
+#        self.gridLayout = newGrid
+        self.gridLayout.addWidget(self.mBtnBar, 0, 1, 1, 3)
+        self.gridLayout.addWidget(self.mRedBandLabel, 1, 0)
+        self.gridLayout.addWidget(self.mRedBandSlider, 1, 1)
+        self.gridLayout.addWidget(self.mRedBandComboBox, 1, 2)
+        self.gridLayout.addWidget(self.mRedMinLineEdit, 1, 3)
+        self.gridLayout.addWidget(self.mRedMaxLineEdit, 1, 4)
+
+        self.gridLayout.addWidget(self.mGreenBandLabel, 2, 0)
+        self.gridLayout.addWidget(self.mGreenBandSlider, 2, 1)
+        self.gridLayout.addWidget(self.mGreenBandComboBox, 2, 2)
+        self.gridLayout.addWidget(self.mGreenMinLineEdit, 2, 3)
+        self.gridLayout.addWidget(self.mGreenMaxLineEdit, 2, 4)
+
+        self.gridLayout.addWidget(self.mBlueBandLabel, 3, 0)
+        self.gridLayout.addWidget(self.mBlueBandSlider, 3, 1)
+        self.gridLayout.addWidget(self.mBlueBandComboBox, 3, 2)
+        self.gridLayout.addWidget(self.mBlueMinLineEdit, 3, 3)
+        self.gridLayout.addWidget(self.mBlueMaxLineEdit, 3, 4)
+
+        self.gridLayout.addWidget(self.mContrastEnhancementAlgorithmLabel, 4, 0, 1, 2)
+        self.gridLayout.addWidget(self.mContrastEnhancementAlgorithmComboBox, 4, 2, 1, 3)
+
+        self.setLayoutItemVisibility(self.gridLayout, True)
+
+
+        self.mRedBandLabel.setText('R')
+        self.mGreenBandLabel.setText('G')
+        self.mBlueBandLabel.setText('B')
+
+        self.mDefaultRenderer = layer.renderer()
+
+
+
+    def initActionButtons(self):
+
+        from enmapbox.gui.utils import parseWavelength
+        wl, wlu = parseWavelength(self.rasterLayer())
+        self.wavelengths = wl
+        self.wavelengthUnit = wlu
+
+        self.actionSetDefault = QAction('Default')
+        self.actionSetTrueColor = QAction('RGB')
+        self.actionSetCIR = QAction('nIR')
+        self.actionSet453 = QAction('swIR')
+
+        self.actionSetDefault.triggered.connect(lambda: self.setBandSelection('default'))
+        self.actionSetTrueColor.triggered.connect(lambda: self.setBandSelection('R,G,B'))
+        self.actionSetCIR.triggered.connect(lambda: self.setBandSelection('nIR,R,G'))
+        self.actionSet453.triggered.connect(lambda: self.setBandSelection('nIR,swIR,R'))
+
+
+        def addBtnAction(action):
+            btn = QToolButton()
+            btn.setDefaultAction(action)
+            self.mBtnBar.layout().addWidget(btn)
+            self.insertAction(None, action)
+            return btn
+
+        self.btnDefault = addBtnAction(self.actionSetDefault)
+        self.btnTrueColor = addBtnAction(self.actionSetTrueColor)
+        self.btnCIR = addBtnAction(self.actionSetCIR)
+        self.btn453 = addBtnAction(self.actionSet453)
+
+        b = self.wavelengths is not None
+        for a in [self.actionSetCIR, self.actionSet453, self.actionSetTrueColor]:
+            a.setEnabled(b)
+
+class RendererWidgetModifications(object):
+
+    def __init__(self, *args):
+        self.initWidgetNames()
+        self.mBandComboBoxes = []
+
+
+    def modifyGridLayout(self):
+
+        gridLayoutOld = self.layout().children()[0]
+        self.gridLayout = QGridLayout()
+        while gridLayoutOld.count() > 0:
+            w = gridLayoutOld.takeAt(0)
+            w = w.widget()
+            gridLayoutOld.removeWidget(w)
+            w.setVisible(False)
+
+        self.gridLayout.setSpacing(2)
+
+        l = self.layout()
+        l.removeItem(gridLayoutOld)
+        if isinstance(l, QBoxLayout):
+            l.insertItem(0, self.gridLayout)
+            self.layout().addStretch()
+        elif isinstance(l, QGridLayout):
+            l.addItem(self.gridLayout, 0, 0)
+
+
+        minMaxWidget = self.minMaxWidget()
+        if isinstance(minMaxWidget, QWidget):
+            minMaxWidget.layout().itemAt(0).widget().collapsedStateChanged.connect(self.onCollapsed)
+
+
+    def initWidgetNames(self):
+        for c in self.children():
+            setattr(self, c.objectName(), c)
+
+    def onCollapsed(self, b):
+        hint = self.sizeHint()
+        self.parent().adjustSize()
+       # self.parent().setFixedSize(hint)
+        self.parent().parent().adjustSize()
+
+    def connectSliderWithBandComboBox(self, slider, combobox):
+        """
+        Connects a band-selection slider with a band-selection combobox
+        :param widget: QgsRasterRendererWidget
+        :param slider: QSlider to show the band number
+        :param combobox: QComboBox to show the band name
+        :return:
+        """
+        assert isinstance(self, QgsRasterRendererWidget)
+        assert isinstance(slider, QSlider)
+        assert isinstance(combobox, QComboBox)
+
+        # init the slider
+        nb = self.rasterLayer().dataProvider().bandCount()
+        slider.setTickPosition(QSlider.TicksAbove)
+        slider.valueChanged.connect(combobox.setCurrentIndex)
+        slider.setMinimum(1)
+        slider.setMaximum(nb)
+        intervals = [1, 2, 5, 10, 25, 50]
+        for interval in intervals:
+            if nb / interval < 10:
+                break
+        slider.setTickInterval(interval)
+        slider.setPageStep(interval)
+
+        def onBandValueChanged(self, idx, slider):
+            assert isinstance(self, QgsRasterRendererWidget)
+            assert isinstance(idx, int)
+            assert isinstance(slider, QSlider)
+
+            # i = slider.value()
+            slider.blockSignals(True)
+            slider.setValue(idx)
+            slider.blockSignals(False)
+
+            # self.minMaxWidget().setBands(myBands)
+            # self.widgetChanged.emit()
+
+        if self.comboBoxWithNotSetItem(combobox):
+            combobox.currentIndexChanged[int].connect(lambda idx: onBandValueChanged(self, idx, slider))
+        else:
+            combobox.currentIndexChanged[int].connect(lambda idx: onBandValueChanged(self, idx + 1, slider))
+
+        s = ""
+
+    def comboBoxWithNotSetItem(self, cb):
+        assert isinstance(cb, QComboBox)
+        return cb.itemData(0, role=Qt.DisplayRole).lower() == 'not set'
+
+    def setLayoutItemVisibility(self, grid, isVisible):
+        assert isinstance(self, QgsRasterRendererWidget)
+        for i in range(grid.count()):
+            item = grid.itemAt(i)
+            if isinstance(item, QLayout):
+                s = ""
+            elif isinstance(item, QWidgetItem):
+                item.widget().setVisible(isVisible)
+                item.widget().setParent(self)
+            else:
+                s = ""
+
+    def setBandSelection(self, key):
+        key = key.upper()
+        if key == 'DEFAULT':
+            bandIndices = defaultBands(self.rasterLayer())
+        else:
+            colors = re.split('[ ,;:]', key)
+
+            bandIndices = [bandClosestToWavelength(self.rasterLayer(), c) for c in colors]
+
+        n = min(len(bandIndices), len(self.mBandComboBoxes))
+        for i in range(n):
+            cb = self.mBandComboBoxes[i]
+            bandIndex = bandIndices[i]
+            if self.comboBoxWithNotSetItem(cb):
+                cb.setCurrentIndex(bandIndex+1)
+            else:
+                cb.setCurrentIndex(bandIndex)
+
+
+    def fixBandNames(self, comboBox):
+        """
+        Changes the QGIS default bandnames ("Band 001") to more meaningfull information including gdal.Dataset.Descriptions.
+        :param widget:
+        :param comboBox:
+        """
+        nb = self.rasterLayer().bandCount()
+
+        assert isinstance(self, QgsRasterRendererWidget)
+        assert isinstance(comboBox, QComboBox)
+        #comboBox.clear()
+        m = comboBox.model()
+        assert isinstance(m, QStandardItemModel)
+        bandNames = displayBandNames(self.rasterLayer())
+
+
+        b = 1 if nb < comboBox.count() else 0
+        for i in range(nb):
+            item = m.item(i+b,0)
+            assert isinstance(item, QStandardItem)
+            item.setData(bandNames[i], Qt.DisplayRole)
+            item.setData('Band {} "{}"'.format(i+1, bandNames[i]), Qt.ToolTipRole)
+
+
+
+def displayBandNames(provider_or_dataset, bands=None):
+    results = None
+    if isinstance(provider_or_dataset, QgsRasterLayer):
+        return displayBandNames(provider_or_dataset.dataProvider())
+    elif isinstance(provider_or_dataset, QgsRasterDataProvider):
+        if provider_or_dataset.name() == 'gdal':
+            ds = gdal.Open(provider_or_dataset.dataSourceUri())
+            results = displayBandNames(ds, bands=bands)
+        else:
+            # same as in QgsRasterRendererWidget::displayBandName
+            results = []
+            if bands is None:
+                bands = range(1, provider_or_dataset.bandCount() + 1)
+            for band in bands:
+                result = provider_or_dataset.generateBandName(band)
+                colorInterp ='{}'.format(provider_or_dataset.colorInterpretationName(band))
+                if colorInterp != 'Undefined':
+                    result += '({})'.format(colorInterp)
+                results.append(result)
+
+    elif isinstance(provider_or_dataset, gdal.Dataset):
+        results = []
+        if bands is None:
+            bands = range(1, provider_or_dataset.RasterCount+1)
+        for band in bands:
+            b = provider_or_dataset.GetRasterBand(band)
+            descr = b.GetDescription()
+            if len(descr) == 0:
+                descr = 'Band {}'.format(band)
+            results.append(descr)
+
+    return results
+
+class SingleBandGrayRendererWidget(QgsSingleBandGrayRendererWidget, RendererWidgetModifications):
+    @staticmethod
+    def create(layer, extent):
+        return SingleBandGrayRendererWidget(layer, extent)
+
+    def __init__(self, layer, extent):
+        super(SingleBandGrayRendererWidget, self).__init__(layer, extent)
+
+        self.modifyGridLayout()
+        self.mGrayBandSlider = QSlider(Qt.Horizontal)
+        self.mBandComboBoxes.append(self.mGrayBandComboBox)
+        self.fixBandNames(self.mGrayBandComboBox)
+        self.connectSliderWithBandComboBox(self.mGrayBandSlider, self.mGrayBandComboBox)
+
+        self.mBtnBar = QFrame()
+        self.initActionButtons()
+
+        self.gridLayout.addWidget(self.mGrayBandLabel, 0, 0)
+        self.gridLayout.addWidget(self.mBtnBar, 0, 1, 1, 4, Qt.AlignLeft)
+
+        self.gridLayout.addWidget(self.mGrayBandSlider, 1, 1, 1, 2)
+        self.gridLayout.addWidget(self.mGrayBandComboBox, 1, 3,1,2)
+
+        self.gridLayout.addWidget(self.label, 2, 0)
+        self.gridLayout.addWidget(self.mGradientComboBox, 2, 1, 1, 4)
+
+        self.gridLayout.addWidget(self.mMinLabel, 3, 1)
+        self.gridLayout.addWidget(self.mMinLineEdit, 3, 2)
+        self.gridLayout.addWidget(self.mMaxLabel, 3, 3)
+        self.gridLayout.addWidget(self.mMaxLineEdit, 3, 4)
+
+        self.gridLayout.addWidget(self.mContrastEnhancementLabel, 4, 0)
+        self.gridLayout.addWidget(self.mContrastEnhancementComboBox, 4, 1, 1 ,4)
+        self.gridLayout.setSpacing(2)
+
+        self.setLayoutItemVisibility(self.gridLayout, True)
+
+        self.mDefaultRenderer = layer.renderer()
+        self.setFromRenderer(self.mDefaultRenderer)
+
+    def initActionButtons(self):
+
+        wl, wlu = parseWavelength(self.rasterLayer())
+        self.wavelengths = wl
+        self.wavelengthUnit = wlu
+
+        self.mBtnBar.setLayout(QHBoxLayout())
+        self.mBtnBar.layout().addStretch()
+        self.mBtnBar.layout().setContentsMargins(0, 0, 0, 0)
+        self.mBtnBar.layout().setSpacing(2)
+
+        self.actionSetDefault = QAction('Default')
+        self.actionSetRed = QAction('R')
+        self.actionSetGreen = QAction('G')
+        self.actionSetBlue = QAction('B')
+        self.actionSetNIR = QAction('nIR')
+        self.actionSetSWIR = QAction('swIR')
+
+        self.actionSetDefault.triggered.connect(lambda: self.setBandSelection('default'))
+        self.actionSetRed.triggered.connect(lambda: self.setBandSelection('R'))
+        self.actionSetGreen.triggered.connect(lambda: self.setBandSelection('G'))
+        self.actionSetBlue.triggered.connect(lambda: self.setBandSelection('B'))
+        self.actionSetNIR.triggered.connect(lambda: self.setBandSelection('nIR'))
+        self.actionSetSWIR.triggered.connect(lambda: self.setBandSelection('swIR'))
+
+
+        def addBtnAction(action):
+            btn = QToolButton()
+            btn.setDefaultAction(action)
+            self.mBtnBar.layout().addWidget(btn)
+            self.insertAction(None, action)
+            return btn
+
+        self.btnDefault = addBtnAction(self.actionSetDefault)
+        self.btnBlue = addBtnAction(self.actionSetBlue)
+        self.btnGreen = addBtnAction(self.actionSetGreen)
+        self.btnRed = addBtnAction(self.actionSetRed)
+        self.btnNIR = addBtnAction(self.actionSetNIR)
+        self.btnSWIR = addBtnAction(self.actionSetSWIR)
+
+        b = self.wavelengths is not None
+        for a in [self.actionSetRed, self.actionSetGreen, self.actionSetBlue, self.actionSetNIR, self.actionSetSWIR]:
+            a.setEnabled(b)
+
+
+
+class SingleBandPseudoColorRendererWidget(QgsSingleBandPseudoColorRendererWidget, RendererWidgetModifications):
+    @staticmethod
+    def create(layer, extent):
+        return SingleBandPseudoColorRendererWidget(layer, extent)
+
+    def __init__(self, layer, extent):
+        super(SingleBandPseudoColorRendererWidget, self).__init__(layer, extent)
+
+        self.mColormapTreeWidget.setMinimumSize(QSize(1,1))
+
+        self.gridLayout = self.layout()
+        assert isinstance(self.gridLayout, QGridLayout)
+        for i in range(self.gridLayout.count()):
+            w = self.gridLayout.itemAt(i)
+            w = w.widget()
+            if isinstance(w, QWidget):
+                setattr(self, w.objectName(), w)
+
+        toReplace = [self.mBandComboBox,self.mMinLabel,self.mMaxLabel, self.mMinLineEdit, self.mMaxLineEdit ]
+        for w in toReplace:
+            self.gridLayout.removeWidget(w)
+            w.setVisible(False)
+        self.mBandSlider = QSlider(Qt.Horizontal)
+        self.mBandComboBoxes.append(self.mBandComboBox)
+        self.fixBandNames(self.mBandComboBox)
+        self.connectSliderWithBandComboBox(self.mBandSlider, self.mBandComboBox)
+
+        self.mBtnBar = QFrame()
+        self.initActionButtons()
+        grid = QGridLayout()
+        grid.addWidget(self.mBtnBar,0,0,1,4, Qt.AlignLeft)
+        grid.addWidget(self.mBandSlider, 1,0, 1,2)
+        grid.addWidget(self.mBandComboBox, 1,2, 1,2)
+        grid.addWidget(self.mMinLabel, 2, 0)
+        grid.addWidget(self.mMinLineEdit, 2, 1)
+        grid.addWidget(self.mMaxLabel, 2, 2)
+        grid.addWidget(self.mMaxLineEdit, 2, 3)
+        #grid.setContentsMargins(2, 2, 2, 2, )
+        grid.setColumnStretch(0, 0)
+        grid.setColumnStretch(1, 2)
+        grid.setColumnStretch(2, 0)
+        grid.setColumnStretch(3, 2)
+        grid.setSpacing(2)
+        self.gridLayout.addItem(grid, 0,1,2,4)
+        self.gridLayout.setSpacing(2)
+        self.setLayoutItemVisibility(grid, True)
+
+        s = ""
+
+    def initActionButtons(self):
+            wl, wlu = parseWavelength(self.rasterLayer())
+            self.wavelengths = wl
+            self.wavelengthUnit = wlu
+
+            self.mBtnBar.setLayout(QHBoxLayout())
+            self.mBtnBar.layout().addStretch()
+            self.mBtnBar.layout().setContentsMargins(0, 0, 0, 0)
+            self.mBtnBar.layout().setSpacing(2)
+
+            self.actionSetDefault = QAction('Default')
+            self.actionSetRed = QAction('R')
+            self.actionSetGreen = QAction('G')
+            self.actionSetBlue = QAction('B')
+            self.actionSetNIR = QAction('nIR')
+            self.actionSetSWIR = QAction('swIR')
+
+            self.actionSetDefault.triggered.connect(lambda: self.setBandSelection('default'))
+            self.actionSetRed.triggered.connect(lambda: self.setBandSelection('R'))
+            self.actionSetGreen.triggered.connect(lambda: self.setBandSelection('G'))
+            self.actionSetBlue.triggered.connect(lambda: self.setBandSelection('B'))
+            self.actionSetNIR.triggered.connect(lambda: self.setBandSelection('nIR'))
+            self.actionSetSWIR.triggered.connect(lambda: self.setBandSelection('swIR'))
+
+
+            def addBtnAction(action):
+                btn = QToolButton()
+                btn.setDefaultAction(action)
+                self.mBtnBar.layout().addWidget(btn)
+                self.insertAction(None, action)
+                return btn
+
+            self.btnDefault = addBtnAction(self.actionSetDefault)
+            self.btnBlue = addBtnAction(self.actionSetBlue)
+            self.btnGreen = addBtnAction(self.actionSetGreen)
+            self.btnRed = addBtnAction(self.actionSetRed)
+            self.btnNIR = addBtnAction(self.actionSetNIR)
+            self.btnSWIR = addBtnAction(self.actionSetSWIR)
+
+            b = self.wavelengths is not None
+            for a in [self.actionSetRed, self.actionSetGreen, self.actionSetBlue, self.actionSetNIR, self.actionSetSWIR]:
+                a.setEnabled(b)
+
+
+class PalettedRendererWidget(QgsPalettedRendererWidget, RendererWidgetModifications):
+    @staticmethod
+    def create(layer, extent):
+        return PalettedRendererWidget(layer, extent)
+
+    def __init__(self, layer, extent):
+        super(PalettedRendererWidget, self).__init__(layer, extent)
+
+        #self.modifyGridLayout()
+
+        self.fixBandNames(self.mBandComboBox)
+        self.mTreeView.setMinimumSize(QSize(10,10))
+        s = ""
+
+
+
+class MultiBandColorRendererWidget(QgsMultiBandColorRendererWidget, RendererWidgetModifications):
+    @staticmethod
+    def create(layer, extent):
+        return MultiBandColorRendererWidget(layer, extent)
+
+
+    def __init__(self, layer, extent):
+        super(MultiBandColorRendererWidget, self).__init__(layer, extent)
+
+        self.modifyGridLayout()
+
+        self.mRedBandSlider = QSlider(Qt.Horizontal)
+        self.mGreenBandSlider = QSlider(Qt.Horizontal)
+        self.mBlueBandSlider = QSlider(Qt.Horizontal)
+
+        self.mBandComboBoxes.extend([self.mRedBandComboBox, self.mGreenBandComboBox, self.mBlueBandComboBox])
+        self.mSliders = [self.mRedBandSlider, self.mGreenBandSlider, self.mBlueBandSlider]
+        nb = self.rasterLayer().dataProvider().bandCount()
+        for cbox, slider in zip(self.mBandComboBoxes, self.mSliders):
+            self.connectSliderWithBandComboBox(slider, cbox)
+
+
+        self.fixBandNames(self.mRedBandComboBox)
+        self.fixBandNames(self.mGreenBandComboBox)
+        self.fixBandNames(self.mBlueBandComboBox)
+
+        self.mBtnBar = QFrame()
+        self.mBtnBar.setLayout(QHBoxLayout())
+        self.initActionButtons()
+        self.mBtnBar.layout().addStretch()
+        self.mBtnBar.layout().setContentsMargins(0, 0, 0, 0)
+        self.mBtnBar.layout().setSpacing(2)
+
+        #self.gridLayout.deleteLater()
+#        self.gridLayout = newGrid
+        self.gridLayout.addWidget(self.mBtnBar, 0, 1, 1, 3)
+        self.gridLayout.addWidget(self.mRedBandLabel, 1, 0)
+        self.gridLayout.addWidget(self.mRedBandSlider, 1, 1)
+        self.gridLayout.addWidget(self.mRedBandComboBox, 1, 2)
+        self.gridLayout.addWidget(self.mRedMinLineEdit, 1, 3)
+        self.gridLayout.addWidget(self.mRedMaxLineEdit, 1, 4)
+
+        self.gridLayout.addWidget(self.mGreenBandLabel, 2, 0)
+        self.gridLayout.addWidget(self.mGreenBandSlider, 2, 1)
+        self.gridLayout.addWidget(self.mGreenBandComboBox, 2, 2)
+        self.gridLayout.addWidget(self.mGreenMinLineEdit, 2, 3)
+        self.gridLayout.addWidget(self.mGreenMaxLineEdit, 2, 4)
+
+        self.gridLayout.addWidget(self.mBlueBandLabel, 3, 0)
+        self.gridLayout.addWidget(self.mBlueBandSlider, 3, 1)
+        self.gridLayout.addWidget(self.mBlueBandComboBox, 3, 2)
+        self.gridLayout.addWidget(self.mBlueMinLineEdit, 3, 3)
+        self.gridLayout.addWidget(self.mBlueMaxLineEdit, 3, 4)
+
+        self.gridLayout.addWidget(self.mContrastEnhancementAlgorithmLabel, 4, 0, 1, 2)
+        self.gridLayout.addWidget(self.mContrastEnhancementAlgorithmComboBox, 4, 2, 1, 3)
+
+        self.setLayoutItemVisibility(self.gridLayout, True)
+
+
+        self.mRedBandLabel.setText('R')
+        self.mGreenBandLabel.setText('G')
+        self.mBlueBandLabel.setText('B')
+
+        self.mDefaultRenderer = layer.renderer()
+
+
+
+    def initActionButtons(self):
+
+        wl, wlu = parseWavelength(self.rasterLayer())
+        self.wavelengths = wl
+        self.wavelengthUnit = wlu
+
+        self.actionSetDefault = QAction('Default')
+        self.actionSetTrueColor = QAction('RGB')
+        self.actionSetCIR = QAction('nIR')
+        self.actionSet453 = QAction('swIR')
+
+        self.actionSetDefault.triggered.connect(lambda: self.setBandSelection('default'))
+        self.actionSetTrueColor.triggered.connect(lambda: self.setBandSelection('R,G,B'))
+        self.actionSetCIR.triggered.connect(lambda: self.setBandSelection('nIR,R,G'))
+        self.actionSet453.triggered.connect(lambda: self.setBandSelection('nIR,swIR,R'))
+
+
+        def addBtnAction(action):
+            btn = QToolButton()
+            btn.setDefaultAction(action)
+            self.mBtnBar.layout().addWidget(btn)
+            self.insertAction(None, action)
+            return btn
+
+        self.btnDefault = addBtnAction(self.actionSetDefault)
+        self.btnTrueColor = addBtnAction(self.actionSetTrueColor)
+        self.btnCIR = addBtnAction(self.actionSetCIR)
+        self.btn453 = addBtnAction(self.actionSet453)
+
+        b = self.wavelengths is not None
+        for a in [self.actionSetCIR, self.actionSet453, self.actionSetTrueColor]:
+            a.setEnabled(b)
+
+
 class MapView(QObject):
 
     sigRemoveMapView = pyqtSignal(object)
@@ -111,7 +997,7 @@ class MapView(QObject):
     #sigVectorVisibility = pyqtSignal(bool)
     #sigRasterVisibility = pyqtSignal(bool)
 
-    sigTitleChanged = pyqtSignal([str],[unicode])
+    sigTitleChanged = pyqtSignal(str)
     sigSensorRendererChanged = pyqtSignal(SensorInstrument, QgsRasterRenderer)
 
     sigCrosshairStyleChanged = pyqtSignal(CrosshairStyle)
@@ -251,9 +1137,14 @@ class MapView(QObject):
         return self.ui.tbName.text()
 
     def refreshMapView(self, *args):
-        for mapCanvas in self.mapCanvases():
-            assert isinstance(mapCanvas, MapCanvas)
-            mapCanvas.refresh()
+
+        for renderSettings in self.mSensorViews.values():
+            assert isinstance(renderSettings, MapViewRenderSettings)
+            renderSettings.applyStyle()
+
+        #for mapCanvas in self.mapCanvases():
+        #    assert isinstance(mapCanvas, MapCanvas)
+        #    mapCanvas.refresh()
 
     def setCrosshairStyle(self, crosshairStyle):
         if isinstance(crosshairStyle, CrosshairStyle):
@@ -330,12 +1221,12 @@ class MapView(QObject):
         assert isinstance(mapCanvas, MapCanvas)
         assert isinstance(sensor, SensorInstrument)
 
-        sensorView = self.mSensorViews[sensor]
-        assert isinstance(sensorView, MapViewSensorSettings)
-        sensorView.registerMapCanvas(mapCanvas)
+        mapViewRenderSettings = self.mSensorViews[sensor]
+        assert isinstance(mapViewRenderSettings, MapViewRenderSettings)
+        mapViewRenderSettings.registerMapCanvas(mapCanvas)
 
         #register signals sensor specific signals
-        mapCanvas.setRenderer(sensorView.rasterLayerRenderer())
+        mapCanvas.setRenderer(mapViewRenderSettings.rasterRenderer())
         mapCanvas.setRenderer(self.vectorLayerRenderer())
 
 
@@ -374,13 +1265,63 @@ class MapView(QObject):
         assert type(sensor) is SensorInstrument
         return self.mSensorViews[sensor]
 
+def displayBandNames(provider_or_dataset, bands=None):
+    results = None
+    if isinstance(provider_or_dataset, QgsRasterLayer):
+        return displayBandNames(provider_or_dataset.dataProvider())
+    elif isinstance(provider_or_dataset, QgsRasterDataProvider):
+        if provider_or_dataset.name() == 'gdal':
+            ds = gdal.Open(provider_or_dataset.dataSourceUri())
+            results = displayBandNames(ds, bands=bands)
+        else:
+            # same as in QgsRasterRendererWidget::displayBandName
+            results = []
+            if bands is None:
+                bands = range(1, provider_or_dataset.bandCount() + 1)
+            for band in bands:
+                result = provider_or_dataset.generateBandName(band)
+                colorInterp ='{}'.format(provider_or_dataset.colorInterpretationName(band))
+                if colorInterp != 'Undefined':
+                    result += '({})'.format(colorInterp)
+                results.append(result)
+
+    elif isinstance(provider_or_dataset, gdal.Dataset):
+        results = []
+        if bands is None:
+            bands = range(1, provider_or_dataset.RasterCount+1)
+        for band in bands:
+            b = provider_or_dataset.GetRasterBand(band)
+            descr = b.GetDescription()
+            if len(descr) == 0:
+                descr = 'Band {}'.format(band)
+            results.append(descr)
 
+    return results
 
-class MapViewRenderSettingsUI(QgsCollapsibleGroupBox, loadUI('mapviewrendersettings.ui')):
 
-    def __init__(self, parent=None):
+class RasterDataProviderMockup(QgsRasterDataProvider):
+
+    def __init__(self):
+        super(RasterDataProviderMockup, self).__init__('')
+
+
+
+
+class MapViewRenderSettings(QgsCollapsibleGroupBox, loadUI('mapviewrendersettings.ui')):
+
+
+    LUT_RENDERER = {QgsMultiBandColorRenderer:QgsMultiBandColorRendererWidget,
+                    QgsSingleBandGrayRenderer:QgsSingleBandGrayRendererWidget,
+                    QgsSingleBandPseudoColorRenderer:QgsSingleBandPseudoColorRendererWidget,
+                    QgsPalettedRasterRenderer:QgsPalettedRendererWidget}
+    LUT_RENDERER[QgsMultiBandColorRenderer]=MultiBandColorRendererWidget
+    LUT_RENDERER[QgsSingleBandPseudoColorRenderer]=SingleBandPseudoColorRendererWidget
+    LUT_RENDERER[QgsSingleBandGrayRenderer]=SingleBandGrayRendererWidget
+    LUT_RENDERER[QgsPalettedRasterRenderer] = PalettedRendererWidget
+
+    def __init__(self, sensor, parent=None):
         """Constructor."""
-        super(MapViewRenderSettingsUI, self).__init__(parent)
+        super(MapViewRenderSettings, self).__init__(parent)
         # Set up the user interface from Designer.
         # After setupUI you can access any designer object by doing
         # self.<objectname>, and you can use autoconnect slots - see
@@ -389,435 +1330,246 @@ class MapViewRenderSettingsUI(QgsCollapsibleGroupBox, loadUI('mapviewrendersetti
 
         self.setupUi(self)
 
-        self.btnDefaultMB.setDefaultAction(self.actionSetDefaultMB)
-        self.btnTrueColor.setDefaultAction(self.actionSetTrueColor)
-        self.btnCIR.setDefaultAction(self.actionSetCIR)
-        self.btn453.setDefaultAction(self.actionSet453)
+        QApplication.clipboard().dataChanged.connect(self.onClipboardChanged)
+
+        assert isinstance(sensor, SensorInstrument)
+        self.mSensor = sensor
+        self.mSensor.sigNameChanged.connect(self.onSensorNameChanged)
+        self.setTitle(self.mSensor.name())
+
+        from timeseriesviewer.models import OptionListModel, Option
+        rasterRendererModel = OptionListModel()
+        #rasterRendererModel.addOption(Option(QgsMultiBandColorRendererWidget, name='multibandcolor (QGIS)', mRenderType = QgsMultiBandColorRenderer))
+        #rasterRendererModel.addOption(Option(QgsPalettedRendererWidget, name='paletted (QGIS)', mRenderType = QgsPalettedRasterRenderer))
+        #rasterRendererModel.addOption(Option(QgsSingleBandGrayRendererWidget, name='singlegray (QGIS)', mRenderType = QgsSingleBandGrayRenderer))
+        #rasterRendererModel.addOption(Option(QgsSingleBandPseudoColorRendererWidget, name='singlebandpseudocolor (QGIS)', mRenderType = QgsSingleBandPseudoColorRenderer))
+
+        rasterRendererModel.addOption(Option(MultiBandColorRendererWidget, name='Multibandcolor', mRenderType=QgsMultiBandColorRenderer))
+        rasterRendererModel.addOption(Option(SingleBandGrayRendererWidget, name='Singlegray', mRenderType=QgsSingleBandGrayRenderer))
+        rasterRendererModel.addOption(Option(SingleBandPseudoColorRendererWidget, name='Singleband Pseudocolor', mRenderType=QgsSingleBandPseudoColorRenderer))
+        rasterRendererModel.addOption(Option(PalettedRendererWidget, name='Paletted', mRenderType=QgsPalettedRasterRenderer))
+        self.mRasterRendererModel = rasterRendererModel
+
+        self.cbRenderType.setModel(self.mRasterRendererModel)
+        assert isinstance(self.stackedWidget, QStackedWidget)
+
+        self.mMockupCanvas = QgsMapCanvas()
+        self.mMockupRasterLayer = QgsRasterLayer(self.mSensor.pathImg)
+        self.mMockupCanvas.setLayers([self.mMockupRasterLayer])
+        for func in rasterRendererModel.optionValues():
+
+            #extent = self.canvas.extent()
+            #w = func.create(self.mMockupRasterLayer, self.mMockupRasterLayer.extent())
+            w = func(self.mMockupRasterLayer, self.mMockupRasterLayer.extent())
+            #w = func(QgsRasterLayer(), QgsRectangle())
+
+            w.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
+            #w.sizeHint = lambda : QSize(300, 50)
+            w.setMapCanvas(self.mMockupCanvas)
+
+            self.stackedWidget.addWidget(w)
+
+        self.mMapCanvases = []
+        self.initActions()
+
+    def initActions(self):
 
-        self.btnSingleBandDef.setDefaultAction(self.actionSetDefaultSB)
-        self.btnSingleBandBlue.setDefaultAction(self.actionSetB)
-        self.btnSingleBandGreen.setDefaultAction(self.actionSetG)
-        self.btnSingleBandRed.setDefaultAction(self.actionSetR)
-        self.btnSingleBandNIR.setDefaultAction(self.actionSetNIR)
-        self.btnSingleBandSWIR.setDefaultAction(self.actionSetSWIR)
 
         self.btnPasteStyle.setDefaultAction(self.actionPasteStyle)
         self.btnCopyStyle.setDefaultAction(self.actionCopyStyle)
         self.btnApplyStyle.setDefaultAction(self.actionApplyStyle)
 
+        clipboardRenderer = rendererFromXml(QApplication.clipboard().mimeData())
+        self.actionPasteStyle.setEnabled(isinstance(clipboardRenderer, QgsRasterRenderer))
+        self.actionPasteStyle.triggered.connect(self.pasteStyleFromClipboard)
+        self.actionCopyStyle.triggered.connect(self.pasteStyleToClipboard)
+        self.actionApplyStyle.triggered.connect(self.applyStyle)
 
+    def mapCanvases(self):
+        return self.mMapCanvases[:]
 
-class MapViewSensorSettings(QObject):
-    """
-    Describes the rendering of images of one Sensor
-    """
+    def registerMapCanvas(self, mapCanvas):
 
-    sigSensorRendererChanged = pyqtSignal(QgsRasterRenderer)
+        assert isinstance(mapCanvas, MapCanvas)
+        self.mMapCanvases.append(mapCanvas)
+        mapCanvas.sigChangeSVRequest.connect(self.onMapCanvasRendererChangeRequest)
 
-    def __init__(self, sensor, parent=None):
-        """Constructor."""
-        super(MapViewSensorSettings, self).__init__(parent)
-        from timeseriesviewer.timeseries import SensorInstrument
-        assert isinstance(sensor, SensorInstrument)
-        self.sensor = sensor
+    def onMapCanvasRendererChangeRequest(self, mapCanvas, renderer):
+        self.setRasterRenderer(renderer)
+        self.applyStyle()
 
-        self.ui = MapViewRenderSettingsUI(parent)
-        self.ui.create()
-        self.ui.stackedWidget.currentChanged.connect(self.updateUi)
-        self.sensor.sigNameChanged.connect(self.onSensorNameChanged)
-        self.onSensorNameChanged(self.sensor.name())
-        self.mMapCanvases = []
-        self.ui.bandNames = sensor.bandNames
-
-        self.multiBandMinValues = [self.ui.tbRedMin, self.ui.tbGreenMin, self.ui.tbBlueMin]
-        self.multiBandMaxValues = [self.ui.tbRedMax, self.ui.tbGreenMax, self.ui.tbBlueMax]
-        self.multiBandSliders = [self.ui.sliderRed, self.ui.sliderGreen, self.ui.sliderBlue]
-
-
-
-        for tb in self.multiBandMinValues + self.multiBandMaxValues + [self.ui.tbSingleBandMin, self.ui.tbSingleBandMax]:
-            assert isinstance(tb, QLineEdit)
-
-            tb.setValidator(QDoubleValidator())
-            tb.textChanged.connect(self.onValuesChanged)
-
-        for sl in self.multiBandSliders + [self.ui.sliderSingleBand]:
-            sl.setMinimum(1)
-            sl.setMaximum(sensor.nb)
-            sl.valueChanged.connect(self.updateUi)
-
-
-
-
-        self.ceAlgs = collections.OrderedDict()
-
-        self.ceAlgs["No enhancement"] = QgsContrastEnhancement.NoEnhancement
-        self.ceAlgs["Stretch to MinMax"] = QgsContrastEnhancement.StretchToMinimumMaximum
-        self.ceAlgs["Stretch and clip to MinMax"] = QgsContrastEnhancement.StretchAndClipToMinimumMaximum
-        self.ceAlgs["Clip to MinMax"] = QgsContrastEnhancement.ClipToMinimumMaximum
-
-        self.colorRampType = collections.OrderedDict()
-        self.colorRampType['Interpolated'] = QgsColorRampShader.Interpolated
-        self.colorRampType['Discrete'] = QgsColorRampShader.Discrete
-        self.colorRampType['Exact'] = QgsColorRampShader.Exact
-
-        self.colorRampClassificationMode = collections.OrderedDict()
-        self.colorRampClassificationMode['Continuous'] = 1
-        self.colorRampClassificationMode['Equal Interval'] = 2
-        self.colorRampClassificationMode['Quantile'] = 3
-
-        def populateCombobox(cb, d):
-            for key, value in d.items():
-                cb.addItem(key, value)
-            cb.setCurrentIndex(0)
+    def onSensorNameChanged(self, newName):
+        self.setTitle(self.mSensor.name())
+        self.actionApplyStyle.setToolTip('Apply style to all map view images from "{}"'.format(self.mSensor.name()))
 
-        populateCombobox(self.ui.comboBoxContrastEnhancement, self.ceAlgs)
-        #populateCombobox(self.ui.cbSingleBandColorRampType, self.colorRampType)
-        populateCombobox(self.ui.cbSingleBandMode, self.colorRampClassificationMode)
 
-        #self.ui.cbSingleBandColorRamp.populate(QgsStyleV2.defaultStyle())
-        self.ui.btnSingleBandColorRamp.setColorRamp(QgsStyle.defaultStyle().colorRamp('Greens'))
+    def currentRenderWidget(self):
+        """
+        Returns the current QgsRasterRendererWidget
+        :return: QgsRasterRendererWidget
+        """
+        return self.stackedWidget.currentWidget()
 
 
-        nb = self.sensor.nb
-        lyr = QgsRasterLayer(self.sensor.pathImg)
+    def setRasterRenderer(self, renderer):
+        assert isinstance(renderer, QgsRasterRenderer)
+        assert isinstance(self.stackedWidget, QStackedWidget)
 
-        #define default renderers:
-        bands = [min([b,nb-1]) for b in range(3)]
-        extent = lyr.extent()
+        self.mMockupRasterLayer.setRenderer(renderer)
 
-        bandStats = [lyr.dataProvider().bandStatistics(b, QgsRasterBandStats.All, extent, 500) for b in range(nb)]
+        #find the widget class that fits
+        cls = None
 
-        def createEnhancement(bandIndex):
-            bandIndex = min([nb - 1, bandIndex])
-            e = QgsContrastEnhancement(self.sensor.bandDataType)
-            e.setMinimumValue(bandStats[bandIndex].Min)
-            e.setMaximumValue(bandStats[bandIndex].Max)
-            e.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchToMinimumMaximum)
-            return e
+        for option in self.mRasterRendererModel:
+            if type(renderer) == option.mRenderType:
+                cls = option.value()
+                break
+        if cls == None:
+            return
 
-        self.defaultMB = QgsMultiBandColorRenderer(lyr.dataProvider(), bands[0], bands[1], bands[2])
-        self.defaultMB.setRedContrastEnhancement(createEnhancement(bands[0]))
-        self.defaultMB.setGreenContrastEnhancement(createEnhancement(bands[1]))
-        self.defaultMB.setBlueContrastEnhancement(createEnhancement(bands[2]))
+        widgets = []
+        for i in range(self.stackedWidget.count()):
+            w = self.stackedWidget.widget(i)
+            if isinstance(w, cls):
+                widgets.append(w)
 
-        self.defaultSB = QgsSingleBandPseudoColorRenderer(lyr.dataProvider(), 0, None)
+        if len(widgets) > 0:
+            for w in widgets:
+                assert isinstance(w, QgsRasterRendererWidget)
 
-        #colorRamp = self.ui.cbSingleBandColorRamp.currentColorRamp()
-        colorRamp = self.ui.btnSingleBandColorRamp.colorRamp()
-        #fix: QGIS 3.0 constructor
-        shaderFunc = QgsColorRampShader(bandStats[0].Min, bandStats[0].Max)
-        shaderFunc.setColorRampType(QgsColorRampShader.Interpolated)
-        shaderFunc.setClip(True)
-        nSteps = 5
-        colorRampItems = []
-        diff = bandStats[0].Max - bandStats[0].Min
-        for  i in range(nSteps+1):
-            f = float(i) / nSteps
-            color = colorRamp.color(f)
-            value = bandStats[0].Min + diff * f
-            colorRampItems.append(QgsColorRampShader.ColorRampItem(value, color))
-        shaderFunc.setColorRampItemList(colorRampItems)
-        shader = QgsRasterShader()
-        shader.setMaximumValue(bandStats[0].Max)
-        shader.setMinimumValue(bandStats[0].Min)
-        shader.setRasterShaderFunction(shaderFunc)
-        self.defaultSB.setShader(shader)
-        self.defaultSB.setClassificationMin(shader.minimumValue())
-        self.defaultSB.setClassificationMax(shader.maximumValue())
-        #init connect signals
-        self.ui.actionSetDefaultMB.triggered.connect(lambda : self.setBandSelection('defaultMB'))
-        self.ui.actionSetTrueColor.triggered.connect(lambda: self.setBandSelection('TrueColor'))
-        self.ui.actionSetCIR.triggered.connect(lambda: self.setBandSelection('CIR'))
-        self.ui.actionSet453.triggered.connect(lambda: self.setBandSelection('453'))
-
-        self.ui.actionSetDefaultSB.triggered.connect(lambda: self.setBandSelection('defaultSB'))
-        self.ui.actionSetB.triggered.connect(lambda: self.setBandSelection('B'))
-        self.ui.actionSetG.triggered.connect(lambda: self.setBandSelection('G'))
-        self.ui.actionSetR.triggered.connect(lambda: self.setBandSelection('R'))
-        self.ui.actionSetNIR.triggered.connect(lambda: self.setBandSelection('nIR'))
-        self.ui.actionSetSWIR.triggered.connect(lambda: self.setBandSelection('swIR'))
-
-        self.ui.actionApplyStyle.triggered.connect(self.applyStyle)
-        self.ui.actionCopyStyle.triggered.connect(lambda : QApplication.clipboard().setMimeData(self.mimeDataStyle()))
-        self.ui.actionPasteStyle.triggered.connect(lambda : self.pasteStyleFromClipboard())
-
-        #self.ui.stackedWidget
-
-        if not self.sensor.wavelengthsDefined():
-            self.ui.btnTrueColor.setEnabled(False)
-            self.ui.btnCIR.setEnabled(False)
-            self.ui.btn453.setEnabled(False)
-
-            self.ui.btnSingleBandBlue.setEnabled(False)
-            self.ui.btnSingleBandGreen.setEnabled(False)
-            self.ui.btnSingleBandRed.setEnabled(False)
-            self.ui.btnSingleBandNIR.setEnabled(False)
-            self.ui.btnSingleBandSWIR.setEnabled(False)
-
-        #apply recent or default renderer
-        renderer = lyr.renderer()
-
-        #set defaults
-        self.setLayerRenderer(self.defaultSB)
-        self.setLayerRenderer(self.defaultMB)
-
-        self.mLastRenderer = renderer
-        if type(renderer) in [QgsMultiBandColorRenderer, QgsSingleBandPseudoColorRenderer]:
-            self.setLayerRenderer(renderer)
-
-
-        QApplication.clipboard().dataChanged.connect(self.onClipboardChange)
-        self.onClipboardChange()
+                #w.setRasterLayer(self.mMockupRasterLayer)
+                #w.setFromRenderer(cloneRenderer(renderer))
+                w.setFromRenderer(renderer)
+                #w.doComputations()
 
-    def mapCanvases(self):
-        return self.mMapCanvases[:]
+            w = widgets[0]
+            self.stackedWidget.setCurrentWidget(w)
 
-    def registerMapCanvas(self, mapCanvas):
+            self.cbRenderType.setCurrentIndex(self.stackedWidget.currentIndex())
 
-        assert isinstance(mapCanvas, MapCanvas)
-        self.mMapCanvases.append(mapCanvas)
-        mapCanvas.sigChangeSVRequest.connect(self.onMapCanvasRendererChangeRequest)
 
+    def rasterRenderer(self):
+
+        return self.stackedWidget.currentWidget().renderer()
+
+
+    def apply(self):
+
+        mRendererWidget = self.currentRenderWidget()
+        mRendererWidget.doComputations()
+
+    def onClipboardChanged(self):
+        mimeData = QApplication.clipboard().mimeData()
+        renderer = rendererFromXml(mimeData)
+        b = isinstance(renderer, QgsRasterRenderer)
+        #if b == False:
+        #    print(mimeData.formats())
+        #    s = ""
+        self.actionPasteStyle.setEnabled(b)
 
-    def onSensorNameChanged(self, newName):
 
-        self.ui.setTitle(self.sensor.name())
-        self.ui.actionApplyStyle.setToolTip('Apply style to all map view images from "{}"'.format(self.sensor.name()))
 
     def pasteStyleFromClipboard(self):
-        utils = TsvMimeDataUtils(QApplication.clipboard().mimeData())
-        if utils.hasRasterStyle():
-            renderer = utils.rasterStyle(self.sensor.bandDataType)
-            if renderer is not None:
-                self.setLayerRenderer(renderer)
+        mimeData = QApplication.clipboard().mimeData()
+        renderer = rendererFromXml(mimeData)
+        if isinstance(renderer, QgsRasterRenderer):
+            self.setRasterRenderer(renderer)
+
+    def pasteStyleToClipboard(self):
+        xml = rendererToXml(self.rasterRenderer())
+        assert isinstance(xml, QDomDocument)
+        md = QMimeData()
+        #['application/qgis.style', 'text/plain']
+
+        md.setData('application/qgis.style', xml.toByteArray())
+        md.setData('text/plain', xml.toByteArray())
+        QApplication.clipboard().setMimeData(md)
 
     def applyStyle(self, *args):
-        r = self.rasterLayerRenderer()
+
+        r = self.rasterRenderer()
         for mapCanvas in self.mMapCanvases:
             assert isinstance(mapCanvas, MapCanvas)
             mapCanvas.layerModel().setRenderer(r)
             mapCanvas.refresh()
 
-    def onClipboardChange(self):
-        utils = TsvMimeDataUtils(QApplication.clipboard().mimeData())
-        self.ui.btnPasteStyle.setEnabled(utils.hasRasterStyle())
 
-    def onMapCanvasRendererChangeRequest(self, mapCanvas, renderer):
-        self.setLayerRenderer(renderer)
 
-    def setBandSelection(self, key):
 
+RENDER_CLASSES = {}
+RENDER_CLASSES['rasterrenderer'] = {
+    'singlebandpseudocolor':QgsSingleBandPseudoColorRenderer,
+    'singlebandgray': QgsSingleBandGrayRenderer,
+    'paletted':QgsPalettedRasterRenderer,
+    'multibandcolor': QgsMultiBandColorRenderer,
+    'hillshade': QgsHillshadeRenderer
+}
+RENDER_CLASSES['renderer-v2'] = {
+    'categorizedSymbol':QgsCategorizedSymbolRenderer,
+    'singleSymbol':QgsSingleSymbolRenderer
+}
 
-        if key == 'defaultMB':
-            bands = [self.defaultMB.redBand(), self.defaultMB.greenBand(), self.defaultMB.blueBand()]
-        elif key == 'defaultSB':
-            bands = [self.defaultSB.band()]
 
-        else:
-            if key in ['R','G','B','nIR','swIR']:
-                colors = [key]
-            elif key == 'TrueColor':
-                colors = ['R','G','B']
-            elif key == 'CIR':
-                colors = ['nIR', 'R', 'G']
-            elif key == '453':
-                colors = ['nIR','swIR', 'R']
-            bands = [self.sensor.bandClosestToWavelength(c) for c in colors]
-
-        if len(bands) == 1:
-            self.ui.sliderSingleBand.setValue(bands[0]+1)
-        elif len(bands) == 3:
-            for i, b in enumerate(bands):
-                self.multiBandSliders[i].setValue(b+1)
-
-
-
-
-    SignalizeImmediately = True
-
-    def onValuesChanged(self, text):
-        styleValid = ""
-        styleInValid = """.QLineEdit {border-color:red;
-                           border-style: outset;
-                           border-width: 2px;
-                           background-color: yellow }
-                        """
-        w = self.sender()
-        if isinstance(w, QLineEdit):
-            validator = w.validator()
-            assert isinstance(validator, QDoubleValidator)
-            res = validator.validate(text, 0)
-            if res[0] == QDoubleValidator.Acceptable:
-                w.setStyleSheet(styleValid)
-            else:
-                w.setStyleSheet(styleInValid)
+def rendererToXml(renderer):
+    doc = QDomDocument()
+    if isinstance(renderer, QgsRasterRenderer):
+        path = os.path.join(os.path.dirname(__file__), 'dummy_gdal.vrt')
+        lyr = QgsRasterLayer(path)
+        lyr.setRenderer(renderer.clone())
 
-    def updateUi(self, *args):
+    elif isinstance(renderer, QgsFeatureRenderer):
+        #todo: distinguish vector type from requested renderer
+        lyr = QgsVectorLayer('Point?crs=epsg:4326&field=id:integer', 'dummy', 'memory')
+        lyr.setRenderer(renderer.clone())
+    else:
+        raise NotImplementedError()
+    err = ''
+    lyr.exportNamedStyle(doc, err)
+    return doc
 
-        cw = self.ui.stackedWidget.currentWidget()
-        text = ''
-        if cw == self.ui.pageMultiBand:
-            text = 'Multiband({} {} {})'.format(
-                self.ui.sliderRed.value(),
-                self.ui.sliderGreen.value(),
-                self.ui.sliderBlue.value()
-            )
-        elif cw == self.ui.pageSingleBand:
-            text = 'Singleband({})'.format(self.ui.sliderSingleBand.value())
 
-        text = '{} - {}'.format(self.sensor.name(), text)
-        self.ui.setTitle(text)
+def rendererFromXml(xml):
+    """
+    Reads a string `text` and returns the first QgsRasterRenderer or QgsFeatureRenderer (if defined).
+    :param text:
+    :return:
+    """
+
+    if isinstance(xml, QMimeData):
+        for format in ['application/qgis.style', 'text/plain']:
+            if format in xml.formats():
+                dom  = QDomDocument()
+                dom.setContent(xml.data(format))
+                return rendererFromXml(dom)
+        return None
+
+    elif isinstance(xml, str):
+        dom = QDomDocument()
+        dom.setContent(xml)
+        return rendererFromXml(dom)
+
+    assert isinstance(xml, QDomDocument)
+    root = xml.documentElement()
+    for baseClass, renderClasses in RENDER_CLASSES.items():
+        elements = root.elementsByTagName(baseClass)
+        if elements.count() > 0:
+            elem = elements.item(0).toElement()
+            typeName = elem.attributes().namedItem('type').nodeValue()
+            if typeName in renderClasses.keys():
+                rClass = renderClasses[typeName]
+                if baseClass == 'rasterrenderer':
+
+                    return rClass.create(elem, DUMMY_RASTERINTERFACE)
+                elif baseClass == 'renderer-v2':
+                    context = QgsReadWriteContext()
+                    return rClass.load(elem, context)
+                    #return rClass.create(elem)
+            else:
+                print(typeName)
+                s =""
+    return None
 
 
-    def setLayerRenderer(self, renderer):
-        ui = self.ui
-        assert isinstance(renderer, QgsRasterRenderer)
-        from timeseriesviewer.utils import niceNumberString
-        updated = False
-        if isinstance(renderer, QgsMultiBandColorRenderer):
-            self.ui.cbRenderType.setCurrentIndex(0)
-            #self.ui.stackedWidget.setcurrentWidget(self.ui.pageMultiBand)
-
-            for s in self.multiBandSliders:
-                s.blockSignals(True)
-            ui.sliderRed.setValue(renderer.redBand())
-            ui.sliderGreen.setValue(renderer.greenBand())
-            ui.sliderBlue.setValue(renderer.blueBand())
-            for s in self.multiBandSliders:
-                s.blockSignals(False)
-
-
-            ceRed = renderer.redContrastEnhancement()
-            ceGreen = renderer.greenContrastEnhancement()
-            ceBlue = renderer.blueContrastEnhancement()
-
-            if ceRed is None:
-                ceRed = ceGreen = ceBlue = QgsContrastEnhancement(self.sensor.bandDataType)
-                s = ""
-            for i, ce in enumerate([ceRed, ceGreen, ceBlue]):
-                vMin = ce.minimumValue()
-                vMax = ce.maximumValue()
-                self.multiBandMinValues[i].setText(niceNumberString(vMin))
-                self.multiBandMaxValues[i].setText(niceNumberString(vMax))
-
-            idx = list(self.ceAlgs.values()).index(ceRed.contrastEnhancementAlgorithm())
-            ui.comboBoxContrastEnhancement.setCurrentIndex(idx)
-
-
-            updated = True
-
-        if isinstance(renderer, QgsSingleBandPseudoColorRenderer):
-            self.ui.cbRenderType.setCurrentIndex(1)
-            #self.ui.stackedWidget.setCurrentWidget(self.ui.pageSingleBand)
-
-            self.ui.sliderSingleBand.setValue(renderer.band())
-            shader = renderer.shader()
-            cmin = shader.minimumValue()
-            cmax = shader.maximumValue()
-            self.ui.tbSingleBandMin.setText(str(cmin))
-            self.ui.tbSingleBandMax.setText(str(cmax))
-
-            shaderFunc = shader.rasterShaderFunction()
-            #self.ui.cbSingleBandColorRampType.setCurrentIndex(shaderFunc.colorRampType())
-            colorRamp = shaderFunc.sourceColorRamp()
-            if isinstance(colorRamp, QgsColorRamp):
-                self.ui.btnSingleBandColorRamp.setColorRamp(colorRamp)
-            updated = True
-
-        self.updateUi()
-        if updated:
-            self.mLastRenderer = self.rasterLayerRenderer()
-
-        if updated and MapViewSensorSettings.SignalizeImmediately:
-            self.sigSensorRendererChanged.emit(renderer.clone())
-            self.applyStyle()
-
-    def mimeDataStyle(self):
-        mimeData = QMimeData()
-        r = self.rasterLayerRenderer()
-        if isinstance(r, QgsRasterRenderer):
-            doc = QDomDocument()
-            lyr = QgsRasterLayer(self.sensor.pathImg)
-            lyr.setRenderer(self.rasterLayerRenderer())
-            err = ''
-            lyr.exportNamedStyle(doc, err)
-            if len(err) == 0:
-                mimeData.setData('application/qgis.style', doc.toByteArray())
-                mimeData.setText(doc.toString())
-        return mimeData
-
-
-
-        return mimeData
-
-    def currentComboBoxItem(self, cb):
-        d = cb.itemData(cb.currentIndex(), Qt.UserRole)
-        return d
-
-    def rasterLayerRenderer(self):
-        ui = self.ui
-        r = None
-        if ui.stackedWidget.currentWidget() == ui.pageMultiBand:
-            r = self.rasterRendererMultiBand(ui)
-
-        if ui.stackedWidget.currentWidget() == ui.pageSingleBand:
-            r = self.rasterRendererSingleBand(ui)
-        return r
-
-    def rasterRendererMultiBand(self, ui):
-        r = QgsMultiBandColorRenderer(None,
-                                      ui.sliderRed.value(), ui.sliderGreen.value(), ui.sliderBlue.value())
-        i = self.ui.comboBoxContrastEnhancement.currentIndex()
-        alg = self.ui.comboBoxContrastEnhancement.itemData(i)
-        if alg == QgsContrastEnhancement.NoEnhancement:
-            r.setRedContrastEnhancement(None)
-            r.setGreenContrastEnhancement(None)
-            r.setBlueContrastEnhancement(None)
-        else:
-            rgbEnhancements = []
-            for i in range(3):
-                e = QgsContrastEnhancement(self.sensor.bandDataType)
-                minmax = [float(self.multiBandMinValues[i].text()), float(self.multiBandMaxValues[i].text())]
-                cmin = min(minmax)
-                cmax = max(minmax)
-                e.setMinimumValue(cmin)
-                e.setMaximumValue(cmax)
-                e.setContrastEnhancementAlgorithm(alg)
-                rgbEnhancements.append(e)
-            r.setRedContrastEnhancement(rgbEnhancements[0])
-            r.setGreenContrastEnhancement(rgbEnhancements[1])
-            r.setBlueContrastEnhancement(rgbEnhancements[2])
-        return r
-
-    def rasterRendererSingleBand(self, ui):
-        r = QgsSingleBandPseudoColorRenderer(None, ui.sliderSingleBand.value(), None)
-        minmax = [float(ui.tbSingleBandMin.text()), float(ui.tbSingleBandMax.text())]
-        cmin = min(minmax)
-        cmax = max(minmax)
-        r.setClassificationMin(cmin)
-        r.setClassificationMax(cmax)
-        #colorRamp = self.ui.cbSingleBandColorRamp.currentColorRamp()
-        colorRamp = self.ui.btnSingleBandColorRamp.colorRamp()
-        # fix: QGIS 3.0 constructor
-        shaderFunc = QgsColorRampShader(cmin, cmax)
-        shaderFunc.setColorRampType(self.currentComboBoxItem(ui.cbSingleBandColorRampType))
-        shaderFunc.setClip(True)
-        nSteps = 10
-        colorRampItems = []
-        diff = cmax - cmin
-        for i in range(nSteps + 1):
-            f = float(i) / nSteps
-            color = colorRamp.color(f)
-            value = cmin + diff * f
-            colorRampItems.append(QgsColorRampShader.ColorRampItem(value, color))
-        shaderFunc.setColorRampItemList(colorRampItems)
-        shader = QgsRasterShader()
-        shader.setMaximumValue(cmax)
-        shader.setMinimumValue(cmin)
-        shader.setRasterShaderFunction(shaderFunc)
-        r.setShader(shader)
-        return r
 
 
 
@@ -1914,29 +2666,39 @@ class MapViewCollectionDock(QgsDockWidget, loadUI('mapviewdock.ui')):
 if __name__ == '__main__':
     from timeseriesviewer import utils
     from timeseriesviewer.mapcanvas import MapCanvas
-    from example.Images import Img_2014_01_15_LC82270652014015LGN00_BOA
+    from example.Images import Img_2014_01_15_LC82270652014015LGN00_BOA, re_2014_06_25
 
 
     from example import  exampleEvents
-    qgsApp = utils.initQgisApplication()
-
-    TS= TimeSeries()
-    dock  = MapViewCollectionDock()
-    dock.setTimeSeries(TS)
-    dock.show()
-    mv1 = dock.createMapView()
-    mv2 = dock.createMapView()
-    dock.setCurrentMapView(mv1)
-    assert dock.currentMapView() == mv1
-    dock.setCurrentMapView(mv2)
-    assert dock.currentMapView() == mv2
-
-    vl = QgsVectorLayer(exampleEvents, 'ogr')
-    QgsProject.instance().addMapLayer(vl)
-    #d = QgsRendererPropertiesDialog(vl, QgsStyle.defaultStyle())
-    #d.show()
-
-    TS.addFiles(Img_2014_01_15_LC82270652014015LGN00_BOA)
+    rDir = r'C:\Users\geo_beja\Repositories\QGIS_Plugins\eo-time-series-viewer\qgisresources'
+    qgsApp = utils.initQgisApplication(qgisResourceDir=rDir)
+    TS = TimeSeries()
+    TS.addFiles([Img_2014_01_15_LC82270652014015LGN00_BOA, re_2014_06_25])
+
+    if False:
+
+        dock  = MapViewCollectionDock()
+        dock.setTimeSeries(TS)
+        dock.show()
+        mv1 = dock.createMapView()
+        mv2 = dock.createMapView()
+        dock.setCurrentMapView(mv1)
+        assert dock.currentMapView() == mv1
+        dock.setCurrentMapView(mv2)
+        assert dock.currentMapView() == mv2
+
+        vl = QgsVectorLayer(exampleEvents, 'ogr')
+        QgsProject.instance().addMapLayer(vl)
+        #d = QgsRendererPropertiesDialog(vl, QgsStyle.defaultStyle())
+        #d.show()
+
+    else:
+
+        w = MapViewRenderSettings(TS.sensors()[0])
+        w.show()
+        w.setRasterRenderer(w.rasterRenderer())
+        #renderer2 = w.rasterRenderer()
+        #print(renderer2)
 
 
     qgsApp.exec_()
\ No newline at end of file
diff --git a/timeseriesviewer/models.py b/timeseriesviewer/models.py
index 7ec06c87f28a090b7c6ca652f3f4623ebb3c92a6..06fa53c8c37e31fed89f395ff5de92749c8ad78d 100644
--- a/timeseriesviewer/models.py
+++ b/timeseriesviewer/models.py
@@ -71,14 +71,18 @@ def setCurrentComboBoxValue(comboBox, value):
 
 class Option(object):
 
-    def __init__(self, value, name=None, tooltip='', icon=QIcon()):
+    def __init__(self, value, name=None, tooltip='', icon=None, **kwargs ):
 
         self.mValue = value
         if name is None:
             name = str(value)
         self.mName = name
         self.mTooltip = tooltip
-        self.mIcon = None
+        self.mIcon = icon
+
+        for k, v in kwargs.items():
+            assert k not in self.__dict__.keys()
+            self.__dict__[k] = v
 
     def value(self):
         return self.mValue
@@ -110,6 +114,10 @@ class OptionListModel(QAbstractListModel):
     def __iter__(self):
         return iter(self.mOptions)
 
+    def __len__(self):
+        return len(self.mOptions)
+
+
     def containsValue(self, value):
         return value in self.optionValues()
 
diff --git a/timeseriesviewer/sandbox.py b/timeseriesviewer/sandbox.py
index df736003fe8bf7ca6668633db7d6fea21a6cc5ee..1e0c054011f07182fe4dab5f208ccf5e32744235 100644
--- a/timeseriesviewer/sandbox.py
+++ b/timeseriesviewer/sandbox.py
@@ -20,7 +20,7 @@
 """
 # noinspection PyPep8Naming
 
-import six, sys, os, gc, re, collections, site, inspect
+import sys, os, gc, re, collections, site, inspect
 from osgeo import gdal, ogr
 from qgis import *
 from qgis.core import *
@@ -352,10 +352,10 @@ if __name__ == '__main__':
     timeseriesviewer.DEBUG = True
     #run tests
     if False: gdal_qgis_benchmark()
-    if True: sandboxQgisBridge()
+    if False: sandboxQgisBridge()
     if False: sandboxGui()
 
-    if False: sandboxTestdata()
+    if True: sandboxTestdata()
     if False: sandboxDemo()
     #close QGIS
     qgsApp.exec_()
diff --git a/timeseriesviewer/timeseries.py b/timeseriesviewer/timeseries.py
index a96a57d009f5b295d29378abbbff7910eec48c78..0d4d8df76803628c8ae73618b4f155b6a32a3584 100644
--- a/timeseriesviewer/timeseries.py
+++ b/timeseriesviewer/timeseries.py
@@ -496,7 +496,7 @@ class TimeSeries(QObject):
     _sep = ';'
 
     def sensors(self):
-        return self.Sensors.keys()
+        return list(self.Sensors.keys())
 
     def loadFromFile(self, path, n_max=None):
 
@@ -745,7 +745,7 @@ class TimeSeriesTableModel(QAbstractTableModel):
         self.dataChanged.emit(idx, idx)
 
     def sensorsChanged(self, sensor):
-        i = self.mColumnNames.index('sensor')
+        i = self.mColumnNames.index(self.cnSensor)
         idx0 = self.createIndex(0, i)
         idx1 = self.createIndex(self.rowCount(), i)
         self.dataChanged.emit(idx0, idx1)
diff --git a/timeseriesviewer/ui/mapviewdefinition.ui b/timeseriesviewer/ui/mapviewdefinition.ui
index 0d86aecfbbdb4fc1cc724bbf72bd884fe3cbf6b9..737e1d80bea6bd0b8162f6719494e50436919a16 100644
--- a/timeseriesviewer/ui/mapviewdefinition.ui
+++ b/timeseriesviewer/ui/mapviewdefinition.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>286</width>
-    <height>339</height>
+    <width>322</width>
+    <height>213</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -18,7 +18,7 @@
   </property>
   <property name="maximumSize">
    <size>
-    <width>290</width>
+    <width>16777215</width>
     <height>16777215</height>
    </size>
   </property>
@@ -75,20 +75,20 @@
        <rect>
         <x>0</x>
         <y>0</y>
-        <width>263</width>
-        <height>333</height>
+        <width>299</width>
+        <height>500</height>
        </rect>
       </property>
       <property name="sizePolicy">
        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-        <horstretch>0</horstretch>
+        <horstretch>2</horstretch>
         <verstretch>2</verstretch>
        </sizepolicy>
       </property>
       <property name="minimumSize">
        <size>
         <width>0</width>
-        <height>0</height>
+        <height>500</height>
        </size>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout_3">
@@ -96,7 +96,7 @@
         <number>2</number>
        </property>
        <property name="sizeConstraint">
-        <enum>QLayout::SetFixedSize</enum>
+        <enum>QLayout::SetNoConstraint</enum>
        </property>
        <property name="leftMargin">
         <number>2</number>
@@ -237,7 +237,7 @@
        <item>
         <widget class="QgsCollapsibleGroupBox" name="gbVectorRendering">
          <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+          <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
@@ -245,7 +245,7 @@
          <property name="minimumSize">
           <size>
            <width>0</width>
-           <height>25</height>
+           <height>35</height>
           </size>
          </property>
          <property name="title">
@@ -328,7 +328,7 @@
          <property name="minimumSize">
           <size>
            <width>0</width>
-           <height>25</height>
+           <height>35</height>
           </size>
          </property>
          <property name="title">
@@ -356,25 +356,6 @@
           <property name="bottomMargin">
            <number>0</number>
           </property>
-          <item>
-           <layout class="QVBoxLayout" name="renderSettingsLayout">
-            <property name="sizeConstraint">
-             <enum>QLayout::SetMinAndMaxSize</enum>
-            </property>
-            <property name="leftMargin">
-             <number>9</number>
-            </property>
-            <property name="topMargin">
-             <number>9</number>
-            </property>
-            <property name="rightMargin">
-             <number>9</number>
-            </property>
-            <property name="bottomMargin">
-             <number>9</number>
-            </property>
-           </layout>
-          </item>
          </layout>
         </widget>
        </item>
@@ -383,10 +364,13 @@
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::MinimumExpanding</enum>
+         </property>
          <property name="sizeHint" stdset="0">
           <size>
            <width>0</width>
-           <height>25</height>
+           <height>0</height>
           </size>
          </property>
         </spacer>
diff --git a/timeseriesviewer/ui/mapviewrendersettings.ui b/timeseriesviewer/ui/mapviewrendersettings.ui
index a5f17f42924ae5cb396d7df179087dea47aa3537..95f46df3d3d7434f48797fe1087ccab5dcc2892b 100644
--- a/timeseriesviewer/ui/mapviewrendersettings.ui
+++ b/timeseriesviewer/ui/mapviewrendersettings.ui
@@ -6,12 +6,12 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>247</width>
-    <height>250</height>
+    <width>335</width>
+    <height>135</height>
    </rect>
   </property>
   <property name="sizePolicy">
-   <sizepolicy hsizetype="Ignored" vsizetype="Preferred">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
     <horstretch>0</horstretch>
     <verstretch>0</verstretch>
    </sizepolicy>
@@ -24,8 +24,8 @@
   </property>
   <property name="maximumSize">
    <size>
-    <width>16000</width>
-    <height>16000</height>
+    <width>16777215</width>
+    <height>16777215</height>
    </size>
   </property>
   <property name="font">
@@ -48,12 +48,12 @@
   <property name="checkable">
    <bool>false</bool>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QVBoxLayout" name="verticalLayout" stretch="1,2,1">
    <property name="spacing">
     <number>2</number>
    </property>
    <property name="sizeConstraint">
-    <enum>QLayout::SetDefaultConstraint</enum>
+    <enum>QLayout::SetNoConstraint</enum>
    </property>
    <property name="leftMargin">
     <number>2</number>
@@ -90,7 +90,7 @@
         <string>Sensor name</string>
        </property>
        <property name="text">
-        <string>Render type</string>
+        <string>Style</string>
        </property>
        <property name="alignment">
         <set>Qt::AlignCenter</set>
@@ -101,7 +101,7 @@
       <widget class="QComboBox" name="cbRenderType">
        <property name="maximumSize">
         <size>
-         <width>100</width>
+         <width>16777215</width>
          <height>16777215</height>
         </size>
        </property>
@@ -110,16 +110,6 @@
          <pointsize>8</pointsize>
         </font>
        </property>
-       <item>
-        <property name="text">
-         <string>Multi</string>
-        </property>
-       </item>
-       <item>
-        <property name="text">
-         <string>Single</string>
-        </property>
-       </item>
       </widget>
      </item>
      <item>
@@ -190,917 +180,31 @@
      <property name="minimumSize">
       <size>
        <width>0</width>
-       <height>130</height>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>16777215</height>
       </size>
      </property>
      <property name="frameShape">
       <enum>QFrame::NoFrame</enum>
      </property>
      <property name="currentIndex">
-      <number>1</number>
+      <number>-1</number>
      </property>
-     <widget class="QWidget" name="pageMultiBand">
-      <property name="sizePolicy">
-       <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
-        <horstretch>0</horstretch>
-        <verstretch>0</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>90</height>
-       </size>
-      </property>
-      <property name="font">
-       <font>
-        <pointsize>10</pointsize>
-       </font>
-      </property>
-      <layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0,2,2,2" columnstretch="0,0,0,0" rowminimumheight="0,0,0,0,0" columnminimumwidth="0,75,0,0">
-       <property name="sizeConstraint">
-        <enum>QLayout::SetMinAndMaxSize</enum>
-       </property>
-       <property name="leftMargin">
-        <number>0</number>
-       </property>
-       <property name="topMargin">
-        <number>2</number>
-       </property>
-       <property name="rightMargin">
-        <number>0</number>
-       </property>
-       <property name="bottomMargin">
-        <number>2</number>
-       </property>
-       <property name="spacing">
-        <number>2</number>
-       </property>
-       <item row="2" column="1">
-        <widget class="QSlider" name="sliderRed">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-           <horstretch>1</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>24</height>
-          </size>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="styleSheet">
-          <string notr="true"/>
-         </property>
-         <property name="minimum">
-          <number>1</number>
-         </property>
-         <property name="maximum">
-          <number>6</number>
-         </property>
-         <property name="value">
-          <number>3</number>
-         </property>
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="tickPosition">
-          <enum>QSlider::TicksAbove</enum>
-         </property>
-         <property name="tickInterval">
-          <number>1</number>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="2">
-        <widget class="QLabel" name="labelMax">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Min</string>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="3">
-        <widget class="QLineEdit" name="tbRedMax">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>5000</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1">
-        <widget class="QSlider" name="sliderGreen">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>24</height>
-          </size>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="styleSheet">
-          <string notr="true"/>
-         </property>
-         <property name="minimum">
-          <number>1</number>
-         </property>
-         <property name="maximum">
-          <number>6</number>
-         </property>
-         <property name="value">
-          <number>2</number>
-         </property>
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="tickPosition">
-          <enum>QSlider::TicksAbove</enum>
-         </property>
-         <property name="tickInterval">
-          <number>1</number>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="0">
-        <widget class="QLabel" name="labelGreen">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="styleSheet">
-          <string notr="true"/>
-         </property>
-         <property name="text">
-          <string>G</string>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="0">
-        <widget class="QLabel" name="labelBlue">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>B</string>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="3">
-        <widget class="QLabel" name="labelMin">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Max</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="3">
-        <widget class="QLineEdit" name="tbGreenMax">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>5000</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="2">
-        <widget class="QLineEdit" name="tbGreenMin">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>0</string>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="3">
-        <widget class="QLineEdit" name="tbBlueMax">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>5000</string>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="2">
-        <widget class="QLineEdit" name="tbBlueMin">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>0</string>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="1">
-        <widget class="QSlider" name="sliderBlue">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>24</height>
-          </size>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="minimum">
-          <number>1</number>
-         </property>
-         <property name="maximum">
-          <number>6</number>
-         </property>
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="tickPosition">
-          <enum>QSlider::TicksAbove</enum>
-         </property>
-         <property name="tickInterval">
-          <number>1</number>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="0">
-        <widget class="QLabel" name="labelRed">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="styleSheet">
-          <string notr="true"/>
-         </property>
-         <property name="text">
-          <string>R</string>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="2">
-        <widget class="QLineEdit" name="tbRedMin">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>0</string>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="0" colspan="4">
-        <layout class="QHBoxLayout" name="horizontalLayout_6">
-         <property name="spacing">
-          <number>2</number>
-         </property>
-         <property name="sizeConstraint">
-          <enum>QLayout::SetMinimumSize</enum>
-         </property>
-         <property name="leftMargin">
-          <number>0</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QToolButton" name="btnDefaultMB">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>0</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-             <italic>false</italic>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>default band selection</string>
-           </property>
-           <property name="text">
-            <string>Def</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="btnTrueColor">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-             <italic>false</italic>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>red-green-blue (true colour)</string>
-           </property>
-           <property name="text">
-            <string>TC</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="btnCIR">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-             <italic>false</italic>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>swIR-red-green (coloured infra-red)</string>
-           </property>
-           <property name="text">
-            <string>cIR</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="btn453">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-             <italic>false</italic>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>swIR-mwIR-red</string>
-           </property>
-           <property name="text">
-            <string>swIR</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer name="horizontalSpacer">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>0</width>
-             <height>0</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item row="1" column="0" colspan="2">
-        <widget class="QLabel" name="labelMax_3">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Bands</string>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </widget>
-     <widget class="QWidget" name="pageSingleBand">
-      <property name="sizePolicy">
-       <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
-        <horstretch>0</horstretch>
-        <verstretch>0</verstretch>
-       </sizepolicy>
-      </property>
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>90</height>
-       </size>
-      </property>
-      <property name="font">
-       <font>
-        <pointsize>10</pointsize>
-       </font>
-      </property>
-      <layout class="QGridLayout" name="gridLayout" columnstretch="1,0,0,0">
-       <property name="leftMargin">
-        <number>0</number>
-       </property>
-       <property name="topMargin">
-        <number>2</number>
-       </property>
-       <property name="rightMargin">
-        <number>0</number>
-       </property>
-       <property name="bottomMargin">
-        <number>2</number>
-       </property>
-       <property name="spacing">
-        <number>2</number>
-       </property>
-       <item row="2" column="0" colspan="2">
-        <widget class="QLabel" name="label_2">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Band</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="3">
-        <widget class="QLineEdit" name="tbSingleBandMax">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>40</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>5000</string>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="3">
-        <widget class="QLabel" name="labelMax_2">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Max</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="2">
-        <widget class="QLineEdit" name="tbSingleBandMin">
-         <property name="minimumSize">
-          <size>
-           <width>40</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>0</string>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="2">
-        <widget class="QLabel" name="labelMin_2">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Min</string>
-         </property>
-        </widget>
-       </item>
-       <item row="0" column="0" colspan="4">
-        <layout class="QHBoxLayout" name="horizontalLayout">
-         <property name="spacing">
-          <number>2</number>
-         </property>
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <widget class="QToolButton" name="btnSingleBandDef">
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-             <italic>false</italic>
-            </font>
-           </property>
-           <property name="text">
-            <string>Def</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="btnSingleBandBlue">
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>Select band from visible blue</string>
-           </property>
-           <property name="text">
-            <string>B</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="btnSingleBandGreen">
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>Select band from visible green</string>
-           </property>
-           <property name="text">
-            <string>G</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="btnSingleBandRed">
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>Select band from visible red</string>
-           </property>
-           <property name="text">
-            <string>R</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="btnSingleBandNIR">
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>Select band from near infra-red</string>
-           </property>
-           <property name="text">
-            <string>nIR</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QToolButton" name="btnSingleBandSWIR">
-           <property name="font">
-            <font>
-             <pointsize>8</pointsize>
-            </font>
-           </property>
-           <property name="toolTip">
-            <string>Select band from shortwave infra-red</string>
-           </property>
-           <property name="text">
-            <string>swIR</string>
-           </property>
-           <property name="autoRaise">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <spacer name="horizontalSpacer_3">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>0</width>
-             <height>0</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
-        </layout>
-       </item>
-       <item row="3" column="0" colspan="2">
-        <widget class="QSlider" name="sliderSingleBand">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>0</height>
-          </size>
-         </property>
-         <property name="maximumSize">
-          <size>
-           <width>16777215</width>
-           <height>16777215</height>
-          </size>
-         </property>
-         <property name="minimum">
-          <number>1</number>
-         </property>
-         <property name="maximum">
-          <number>6</number>
-         </property>
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="tickPosition">
-          <enum>QSlider::TicksAbove</enum>
-         </property>
-         <property name="tickInterval">
-          <number>1</number>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="1" colspan="3">
-        <widget class="QComboBox" name="cbSingleBandColorRampType">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-           <horstretch>1</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="toolTip">
-          <string>Type of color ramp</string>
-         </property>
-        </widget>
-       </item>
-       <item row="4" column="0">
-        <widget class="QLabel" name="label_4">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Interpolation</string>
-         </property>
-        </widget>
-       </item>
-       <item row="6" column="1" colspan="3">
-        <widget class="QComboBox" name="cbSingleBandMode">
-         <property name="sizePolicy">
-          <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-           <horstretch>1</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="toolTip">
-          <string>Color classification</string>
-         </property>
-        </widget>
-       </item>
-       <item row="5" column="0">
-        <widget class="QLabel" name="label_3">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Color</string>
-         </property>
-        </widget>
-       </item>
-       <item row="6" column="0">
-        <widget class="QLabel" name="label_5">
-         <property name="font">
-          <font>
-           <pointsize>8</pointsize>
-          </font>
-         </property>
-         <property name="text">
-          <string>Mode</string>
-         </property>
-        </widget>
-       </item>
-       <item row="5" column="1">
-        <widget class="QgsColorRampButton" name="btnSingleBandColorRamp">
-         <property name="text">
-          <string>...</string>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </widget>
     </widget>
    </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_4">
-     <property name="spacing">
-      <number>2</number>
-     </property>
-     <property name="topMargin">
-      <number>0</number>
-     </property>
-     <property name="bottomMargin">
-      <number>0</number>
-     </property>
-     <item>
-      <widget class="QLabel" name="label">
-       <property name="font">
-        <font>
-         <pointsize>8</pointsize>
-        </font>
-       </property>
-       <property name="text">
-        <string>Contrast 
-enhancement</string>
-       </property>
-       <property name="alignment">
-        <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QComboBox" name="comboBoxContrastEnhancement">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-         <horstretch>1</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="font">
-        <font>
-         <pointsize>8</pointsize>
-        </font>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
    <item>
     <spacer name="verticalSpacer_2">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::MinimumExpanding</enum>
+     </property>
      <property name="sizeHint" stdset="0">
       <size>
        <width>0</width>
@@ -1209,13 +313,6 @@ enhancement</string>
    </property>
   </action>
  </widget>
- <customwidgets>
-  <customwidget>
-   <class>QgsColorRampButton</class>
-   <extends>QToolButton</extends>
-   <header>qgis.gui</header>
-  </customwidget>
- </customwidgets>
  <resources>
   <include location="resources.qrc"/>
  </resources>
diff --git a/timeseriesviewer/ui/mapviewrendersettingsV2.ui b/timeseriesviewer/ui/mapviewrendersettingsV2.ui
new file mode 100644
index 0000000000000000000000000000000000000000..95f46df3d3d7434f48797fe1087ccab5dcc2892b
--- /dev/null
+++ b/timeseriesviewer/ui/mapviewrendersettingsV2.ui
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MapViewRenderSettings</class>
+ <widget class="QGroupBox" name="MapViewRenderSettings">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>335</width>
+    <height>135</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>150</width>
+    <height>0</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>16777215</height>
+   </size>
+  </property>
+  <property name="font">
+   <font>
+    <pointsize>8</pointsize>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>RenderSettings</string>
+  </property>
+  <property name="styleSheet">
+   <string notr="true">QFrame::title{color: rgb(0, 0, 127);}</string>
+  </property>
+  <property name="title">
+   <string>&lt;sensor/product&gt;</string>
+  </property>
+  <property name="flat">
+   <bool>true</bool>
+  </property>
+  <property name="checkable">
+   <bool>false</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout" stretch="1,2,1">
+   <property name="spacing">
+    <number>2</number>
+   </property>
+   <property name="sizeConstraint">
+    <enum>QLayout::SetNoConstraint</enum>
+   </property>
+   <property name="leftMargin">
+    <number>2</number>
+   </property>
+   <property name="topMargin">
+    <number>6</number>
+   </property>
+   <property name="rightMargin">
+    <number>2</number>
+   </property>
+   <property name="bottomMargin">
+    <number>2</number>
+   </property>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <property name="spacing">
+      <number>2</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QLabel" name="labelRenderer">
+       <property name="font">
+        <font>
+         <pointsize>8</pointsize>
+         <weight>50</weight>
+         <italic>false</italic>
+         <bold>false</bold>
+         <kerning>true</kerning>
+        </font>
+       </property>
+       <property name="toolTip">
+        <string>Sensor name</string>
+       </property>
+       <property name="text">
+        <string>Style</string>
+       </property>
+       <property name="alignment">
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QComboBox" name="cbRenderType">
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>16777215</height>
+        </size>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>8</pointsize>
+        </font>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="btnPasteStyle">
+       <property name="text">
+        <string>...</string>
+       </property>
+       <property name="icon">
+        <iconset resource="resources.qrc">
+         <normaloff>:/timeseriesviewer/icons/mActionEditPaste.svg</normaloff>:/timeseriesviewer/icons/mActionEditPaste.svg</iconset>
+       </property>
+       <property name="autoRaise">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="btnCopyStyle">
+       <property name="text">
+        <string>...</string>
+       </property>
+       <property name="icon">
+        <iconset resource="resources.qrc">
+         <normaloff>:/timeseriesviewer/icons/mActionEditCopy.svg</normaloff>:/timeseriesviewer/icons/mActionEditCopy.svg</iconset>
+       </property>
+       <property name="autoRaise">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="btnApplyStyle">
+       <property name="text">
+        <string>...</string>
+       </property>
+       <property name="icon">
+        <iconset resource="resources.qrc">
+         <normaloff>:/timeseriesviewer/icons/mActionRefresh.png</normaloff>:/timeseriesviewer/icons/mActionRefresh.png</iconset>
+       </property>
+       <property name="autoRaise">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_4">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QStackedWidget" name="stackedWidget">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>16777215</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::NoFrame</enum>
+     </property>
+     <property name="currentIndex">
+      <number>-1</number>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeType">
+      <enum>QSizePolicy::MinimumExpanding</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+  <action name="actionSetDefaultMB">
+   <property name="text">
+    <string>Def</string>
+   </property>
+   <property name="toolTip">
+    <string>Set default band selection</string>
+   </property>
+  </action>
+  <action name="actionSetTrueColor">
+   <property name="text">
+    <string>True</string>
+   </property>
+   <property name="toolTip">
+    <string>Set to true color (red-green-blue)</string>
+   </property>
+  </action>
+  <action name="actionSetCIR">
+   <property name="text">
+    <string>CIR1</string>
+   </property>
+   <property name="toolTip">
+    <string>Set to coloured infra red (swIR-red-green)</string>
+   </property>
+  </action>
+  <action name="actionSet453">
+   <property name="text">
+    <string>CIR2</string>
+   </property>
+   <property name="toolTip">
+    <string>Set to swIR-mwIR-red</string>
+   </property>
+  </action>
+  <action name="actionCopyStyle">
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/timeseriesviewer/icons/mActionEditCopy.svg</normaloff>:/timeseriesviewer/icons/mActionEditCopy.svg</iconset>
+   </property>
+   <property name="text">
+    <string>Copy style</string>
+   </property>
+   <property name="toolTip">
+    <string>Copy style to clipboard</string>
+   </property>
+  </action>
+  <action name="actionPasteStyle">
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/timeseriesviewer/icons/mActionEditPaste.svg</normaloff>:/timeseriesviewer/icons/mActionEditPaste.svg</iconset>
+   </property>
+   <property name="text">
+    <string>Paste Style</string>
+   </property>
+   <property name="toolTip">
+    <string>Paste style from clipboard</string>
+   </property>
+  </action>
+  <action name="actionApplyStyle">
+   <property name="icon">
+    <iconset resource="resources.qrc">
+     <normaloff>:/timeseriesviewer/icons/mActionRefresh.png</normaloff>:/timeseriesviewer/icons/mActionRefresh.png</iconset>
+   </property>
+   <property name="text">
+    <string>ApplySettings</string>
+   </property>
+   <property name="toolTip">
+    <string>Apply Style</string>
+   </property>
+  </action>
+  <action name="actionSetR">
+   <property name="text">
+    <string>R</string>
+   </property>
+  </action>
+  <action name="actionSetG">
+   <property name="text">
+    <string>G</string>
+   </property>
+  </action>
+  <action name="actionSetB">
+   <property name="text">
+    <string>B</string>
+   </property>
+  </action>
+  <action name="actionSetNIR">
+   <property name="text">
+    <string>nIR</string>
+   </property>
+  </action>
+  <action name="actionSetSWIR">
+   <property name="text">
+    <string>swIR</string>
+   </property>
+  </action>
+  <action name="actionSetDefaultSB">
+   <property name="text">
+    <string>Def</string>
+   </property>
+  </action>
+ </widget>
+ <resources>
+  <include location="resources.qrc"/>
+ </resources>
+ <connections>
+  <connection>
+   <sender>cbRenderType</sender>
+   <signal>currentIndexChanged(int)</signal>
+   <receiver>stackedWidget</receiver>
+   <slot>setCurrentIndex(int)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>107</x>
+     <y>19</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>144</x>
+     <y>54</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/timeseriesviewer/utils.py b/timeseriesviewer/utils.py
index be586fa73831bbfdd3cc1633711d49aa48b58112..7571f86ca654cfcf440daa348e989bd9248f470f 100644
--- a/timeseriesviewer/utils.py
+++ b/timeseriesviewer/utils.py
@@ -20,7 +20,7 @@
 """
 # noinspection PyPep8Naming
 
-import os, sys, math, re, io
+import os, sys, math, re, io, fnmatch
 
 
 from collections import defaultdict
@@ -58,6 +58,30 @@ def qgisInstance():
         return None
 
 
+def file_search(rootdir, pattern, recursive=False, ignoreCase=False):
+    assert os.path.isdir(rootdir), "Path is not a directory:{}".format(rootdir)
+    regType = type(re.compile('.*'))
+    results = []
+
+    for root, dirs, files in os.walk(rootdir):
+        for file in files:
+            if isinstance(pattern, regType):
+                if pattern.search(file):
+                    path = os.path.join(root, file)
+                    results.append(path)
+
+            elif (ignoreCase and fnmatch.fnmatch(file.lower(), pattern.lower())) \
+                    or fnmatch.fnmatch(file, pattern):
+
+                path = os.path.join(root, file)
+                results.append(path)
+        if not recursive:
+            break
+            pass
+
+    return results
+
+
 def appendItemsToMenu(menu, itemsToAdd):
     """
     Appends items to QMenu "menu"
@@ -555,6 +579,184 @@ class KeepRefs(object):
 
 
 
+def defaultBands(dataset):
+    """
+    Returns a list of 3 default bands
+    :param dataset:
+    :return:
+    """
+    if isinstance(dataset, str):
+        return defaultBands(gdal.Open(dataset))
+    elif isinstance(dataset, QgsRasterDataProvider):
+        return defaultBands(dataset.dataSourceUri())
+    elif isinstance(dataset, QgsRasterLayer):
+        return defaultBands(dataset.source())
+    elif isinstance(dataset, gdal.Dataset):
+
+        db = dataset.GetMetadataItem(str('default_bands'), str('ENVI'))
+        if db != None:
+            db = [int(n) for n in re.findall('\d+')]
+            return db
+        db = [0, 0, 0]
+        cis = [gdal.GCI_RedBand, gdal.GCI_GreenBand, gdal.GCI_BlueBand]
+        for b in range(dataset.RasterCount):
+            band = dataset.GetRasterBand(b + 1)
+            assert isinstance(band, gdal.Band)
+            ci = band.GetColorInterpretation()
+            if ci in cis:
+                db[cis.index(ci)] = b
+        if db != [0, 0, 0]:
+            return db
+
+        rl = QgsRasterLayer(dataset.GetFileList()[0])
+        defaultRenderer = rl.renderer()
+        if isinstance(defaultRenderer, QgsRasterRenderer):
+            db = defaultRenderer.usesBands()
+            if len(db) == 0:
+                return [0, 1, 2]
+            if len(db) > 3:
+                db = db[0:3]
+            db = [b-1 for b in db]
+        return db
+
+    else:
+        raise Exception()
+
+######### Lookup  tables
+METRIC_EXPONENTS = {
+    "nm": -9, "um": -6, u"µm": -6, "mm": -3, "cm": -2, "dm": -1, "m": 0, "hm": 2, "km": 3
+}
+# add synonyms
+METRIC_EXPONENTS['nanometers'] = METRIC_EXPONENTS['nm']
+METRIC_EXPONENTS['micrometers'] = METRIC_EXPONENTS['um']
+METRIC_EXPONENTS['millimeters'] = METRIC_EXPONENTS['mm']
+METRIC_EXPONENTS['centimeters'] = METRIC_EXPONENTS['cm']
+METRIC_EXPONENTS['decimeters'] = METRIC_EXPONENTS['dm']
+METRIC_EXPONENTS['meters'] = METRIC_EXPONENTS['m']
+METRIC_EXPONENTS['hectometers'] = METRIC_EXPONENTS['hm']
+METRIC_EXPONENTS['kilometers'] = METRIC_EXPONENTS['km']
+
+
+LUT_WAVELENGTH = dict({'B': 480,
+                       'G': 570,
+                       'R': 660,
+                       'NIR': 850,
+                       'SWIR': 1650,
+                       'SWIR1': 1650,
+                       'SWIR2': 2150
+                       })
+
+def convertMetricUnit(value, u1, u2):
+    """converts value, given in unit u1, to u2"""
+    assert u1 in METRIC_EXPONENTS.keys()
+    assert u2 in METRIC_EXPONENTS.keys()
+
+    e1 = METRIC_EXPONENTS[u1]
+    e2 = METRIC_EXPONENTS[u2]
+
+    return value * 10 ** (e1 - e2)
+
+def bandClosestToWavelength(dataset, wl, wl_unit='nm'):
+    """
+    Returns the band index (!) of an image dataset closest to wavelength `wl`.
+    :param dataset: str | gdal.Dataset
+    :param wl: wavelength to search the closed band for
+    :param wl_unit: unit of wavelength. Default = nm
+    :return: band index | 0 of wavelength information is not provided
+    """
+    if isinstance(wl, str):
+        assert wl.upper() in LUT_WAVELENGTH.keys(), wl
+        return bandClosestToWavelength(dataset, LUT_WAVELENGTH[wl.upper()], wl_unit='nm')
+    else:
+        try:
+            wl = float(wl)
+            ds_wl, ds_wlu = parseWavelength(dataset)
+
+            if ds_wl is None or ds_wlu is None:
+                return 0
+
+
+            if ds_wlu != wl_unit:
+                wl = convertMetricUnit(wl, wl_unit, ds_wlu)
+            return int(np.argmin(np.abs(ds_wl - wl)))
+        except:
+            pass
+    return 0
+
+def cloneRenderer(renderer):
+
+    assert isinstance(renderer, QgsRasterRenderer)
+    cloned = renderer.clone()
+
+    #handle specific issues if cloning is not exactly the same
+    if isinstance(cloned, QgsSingleBandPseudoColorRenderer):
+        cloned.setClassificationMin(renderer.classificationMin())
+        cloned.setClassificationMax(renderer.classificationMax())
+
+    return cloned
+
+
+def parseWavelength(dataset):
+    """
+    Returns the wavelength + wavelength unit of a dataset
+    :param dataset:
+    :return: (wl, wl_u) or (None, None), if not existing
+    """
+
+    wl = None
+    wlu = None
+
+    if isinstance(dataset, str):
+        return parseWavelength(gdal.Open(dataset))
+    elif isinstance(dataset, QgsRasterDataProvider):
+        return parseWavelength(dataset.dataSourceUri())
+    elif isinstance(dataset, QgsRasterLayer):
+        return parseWavelength(dataset.source())
+    elif isinstance(dataset, gdal.Dataset):
+
+        for domain in dataset.GetMetadataDomainList():
+            # see http://www.harrisgeospatial.com/docs/ENVIHeaderFiles.html for supported wavelength units
+
+            mdDict = dataset.GetMetadata_Dict(domain)
+
+            for key, values in mdDict.items():
+                key = key.lower()
+                if re.search('wavelength$', key, re.I):
+                    tmp = re.findall('\d*\.\d+|\d+', values)  # find floats
+                    if len(tmp) != dataset.RasterCount:
+                        tmp = re.findall('\d+', values)  # find integers
+                    if len(tmp) == dataset.RasterCount:
+                        wl = np.asarray([float(w) for w in tmp])
+
+                if re.search(r'wavelength.units?', key):
+                    if re.search('(Micrometers?|um)', values, re.I):
+                        wlu = 'um'  # fix with python 3 UTF
+                    elif re.search('(Nanometers?|nm)', values, re.I):
+                        wlu = 'nm'
+                    elif re.search('(Millimeters?|mm)', values, re.I):
+                        wlu = 'nm'
+                    elif re.search('(Centimeters?|cm)', values, re.I):
+                        wlu = 'nm'
+                    elif re.search('(Meters?|m)', values, re.I):
+                        wlu = 'nm'
+                    elif re.search('Wavenumber', values, re.I):
+                        wlu = '-'
+                    elif re.search('GHz', values, re.I):
+                        wlu = 'GHz'
+                    elif re.search('MHz', values, re.I):
+                        wlu = 'MHz'
+                    elif re.search('Index', values, re.I):
+                        wlu = '-'
+                    else:
+                        wlu = '-'
+
+        if wl is not None and len(wl) > dataset.RasterCount:
+            wl = wl[0:dataset.RasterCount]
+
+    return wl, wlu
+
+
+
 def filterSubLayers(filePaths, subLayerEndings):
     """
     Returns sub layers endings from all gdal Datasets within filePaths
@@ -580,6 +782,7 @@ def filterSubLayers(filePaths, subLayerEndings):
             pass
     return results
 
+
 def copyRenderer(renderer, targetLayer):
     """
     Copies and applies renderer to targetLayer.
@@ -587,25 +790,14 @@ def copyRenderer(renderer, targetLayer):
     :param targetLayer:
     :return: True, if 'renderer' could be copied and applied to 'targetLayer'
     """
+    from timeseriesviewer.mapvisualization import cloneRenderer
     if isinstance(targetLayer, QgsRasterLayer) and isinstance(renderer, QgsRasterRenderer):
-        if isinstance(renderer, QgsMultiBandColorRenderer):
-            r = renderer.clone()
-            r.setInput(targetLayer.dataProvider())
-            targetLayer.setRenderer(r)
-            return True
-        elif isinstance(renderer, QgsSingleBandPseudoColorRenderer):
-            r = renderer.clone()
-            # r = QgsSingleBandPseudoColorRenderer(None, renderer.band(), None)
-            r.setInput(targetLayer.dataProvider())
-            cmin = renderer.classificationMin()
-            cmax = renderer.classificationMax()
-            r.setClassificationMin(cmin)
-            r.setClassificationMax(cmax)
-            targetLayer.setRenderer(r)
-            return True
+
+        targetLayer.setRenderer(cloneRenderer(renderer))
+        return True
     elif isinstance(targetLayer, QgsVectorLayer) and isinstance(renderer, QgsFeatureRenderer):
-        #todo: add render-specific switches
-        targetLayer.setRenderer(renderer)
+
+        targetLayer.setRenderer(cloneRenderer(renderer))
         return True
 
     return False