Continued implementing support for a marker map in the editor.

Wed, 05 Mar 2014 19:52:15 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 05 Mar 2014 19:52:15 +0100
changeset 3329
1ee38e29ed4f
parent 3328
15aaa8d3a840
child 3330
955e15f0ecce

Continued implementing support for a marker map in the editor.

APIs/Python3/eric5.api file | annotate | diff | comparison | revisions
APIs/Python3/eric5.bas file | annotate | diff | comparison | revisions
Documentation/Help/source.qch file | annotate | diff | comparison | revisions
Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
Documentation/Source/eric5.E5Gui.E5MapWidget.html file | annotate | diff | comparison | revisions
Documentation/Source/eric5.QScintilla.EditorMarkerMap.html file | annotate | diff | comparison | revisions
Documentation/Source/index-eric5.QScintilla.html file | annotate | diff | comparison | revisions
E5Gui/E5MapWidget.py file | annotate | diff | comparison | revisions
QScintilla/Editor.py file | annotate | diff | comparison | revisions
QScintilla/EditorMarkerMap.py file | annotate | diff | comparison | revisions
eric5.e4p file | annotate | diff | comparison | revisions
--- a/APIs/Python3/eric5.api	Wed Mar 05 18:40:12 2014 +0100
+++ b/APIs/Python3/eric5.api	Wed Mar 05 19:52:15 2014 +0100
@@ -1290,7 +1290,7 @@
 eric5.E5Gui.E5MapWidget.E5MapWidget.generateIndicatorRect?4(position)
 eric5.E5Gui.E5MapWidget.E5MapWidget.isEnabled?4()
 eric5.E5Gui.E5MapWidget.E5MapWidget.lineDimensions?4()
-eric5.E5Gui.E5MapWidget.E5MapWidget.mousePressEvent?4(event)
+eric5.E5Gui.E5MapWidget.E5MapWidget.mouseReleaseEvent?4(event)
 eric5.E5Gui.E5MapWidget.E5MapWidget.paintEvent?4(event)
 eric5.E5Gui.E5MapWidget.E5MapWidget.position2Value?4(position, slider=False)
 eric5.E5Gui.E5MapWidget.E5MapWidget.scaleFactor?4(slider=False)
@@ -6991,6 +6991,8 @@
 eric5.QScintilla.EditorAssembly.EditorAssembly.getEditor?4()
 eric5.QScintilla.EditorAssembly.EditorAssembly.shutdownTimer?4()
 eric5.QScintilla.EditorAssembly.EditorAssembly?1(dbs, fn=None, vm=None, filetype="", editor=None, tv=None)
+eric5.QScintilla.EditorMarkerMap.EditorMarkerMap._paintIt?5(painter)
+eric5.QScintilla.EditorMarkerMap.EditorMarkerMap?1(parent=None)
 eric5.QScintilla.Exporters.ExporterBase.ExporterBase._getFileName?5(filter)
 eric5.QScintilla.Exporters.ExporterBase.ExporterBase.exportSource?4()
 eric5.QScintilla.Exporters.ExporterBase.ExporterBase?1(editor, parent=None)
--- a/APIs/Python3/eric5.bas	Wed Mar 05 18:40:12 2014 +0100
+++ b/APIs/Python3/eric5.bas	Wed Mar 05 19:52:15 2014 +0100
@@ -212,6 +212,7 @@
 EditorHighlightersPage ConfigurationPageBase Ui_EditorHighlightersPage
 EditorHighlightingStylesPage ConfigurationPageBase Ui_EditorHighlightingStylesPage
 EditorKeywordsPage ConfigurationPageBase Ui_EditorKeywordsPage
+EditorMarkerMap E5MapWidget
 EditorPropertiesPage ConfigurationPageBase Ui_EditorPropertiesPage
 EditorSearchPage ConfigurationPageBase Ui_EditorSearchPage
 EditorSpellCheckingPage ConfigurationPageBase Ui_EditorSpellCheckingPage
Binary file Documentation/Help/source.qch has changed
--- a/Documentation/Help/source.qhp	Wed Mar 05 18:40:12 2014 +0100
+++ b/Documentation/Help/source.qhp	Wed Mar 05 19:52:15 2014 +0100
@@ -886,6 +886,7 @@
             <section title="eric5.QScintilla.APIsManager" ref="eric5.QScintilla.APIsManager.html" />
             <section title="eric5.QScintilla.Editor" ref="eric5.QScintilla.Editor.html" />
             <section title="eric5.QScintilla.EditorAssembly" ref="eric5.QScintilla.EditorAssembly.html" />
+            <section title="eric5.QScintilla.EditorMarkerMap" ref="eric5.QScintilla.EditorMarkerMap.html" />
             <section title="eric5.QScintilla.GotoDialog" ref="eric5.QScintilla.GotoDialog.html" />
             <section title="eric5.QScintilla.MiniEditor" ref="eric5.QScintilla.MiniEditor.html" />
             <section title="eric5.QScintilla.Printer" ref="eric5.QScintilla.Printer.html" />
@@ -3840,7 +3841,7 @@
       <keyword name="E5MapWidget.generateIndicatorRect" id="E5MapWidget.generateIndicatorRect" ref="eric5.E5Gui.E5MapWidget.html#E5MapWidget.generateIndicatorRect" />
       <keyword name="E5MapWidget.isEnabled" id="E5MapWidget.isEnabled" ref="eric5.E5Gui.E5MapWidget.html#E5MapWidget.isEnabled" />
       <keyword name="E5MapWidget.lineDimensions" id="E5MapWidget.lineDimensions" ref="eric5.E5Gui.E5MapWidget.html#E5MapWidget.lineDimensions" />
-      <keyword name="E5MapWidget.mousePressEvent" id="E5MapWidget.mousePressEvent" ref="eric5.E5Gui.E5MapWidget.html#E5MapWidget.mousePressEvent" />
+      <keyword name="E5MapWidget.mouseReleaseEvent" id="E5MapWidget.mouseReleaseEvent" ref="eric5.E5Gui.E5MapWidget.html#E5MapWidget.mouseReleaseEvent" />
       <keyword name="E5MapWidget.paintEvent" id="E5MapWidget.paintEvent" ref="eric5.E5Gui.E5MapWidget.html#E5MapWidget.paintEvent" />
       <keyword name="E5MapWidget.position2Value" id="E5MapWidget.position2Value" ref="eric5.E5Gui.E5MapWidget.html#E5MapWidget.position2Value" />
       <keyword name="E5MapWidget.scaleFactor" id="E5MapWidget.scaleFactor" ref="eric5.E5Gui.E5MapWidget.html#E5MapWidget.scaleFactor" />
@@ -4738,6 +4739,11 @@
       <keyword name="EditorKeywordsPage.on_languageCombo_activated" id="EditorKeywordsPage.on_languageCombo_activated" ref="eric5.Preferences.ConfigurationPages.EditorKeywordsPage.html#EditorKeywordsPage.on_languageCombo_activated" />
       <keyword name="EditorKeywordsPage.on_setSpinBox_valueChanged" id="EditorKeywordsPage.on_setSpinBox_valueChanged" ref="eric5.Preferences.ConfigurationPages.EditorKeywordsPage.html#EditorKeywordsPage.on_setSpinBox_valueChanged" />
       <keyword name="EditorKeywordsPage.save" id="EditorKeywordsPage.save" ref="eric5.Preferences.ConfigurationPages.EditorKeywordsPage.html#EditorKeywordsPage.save" />
+      <keyword name="EditorMarkerMap" id="EditorMarkerMap" ref="eric5.QScintilla.EditorMarkerMap.html#EditorMarkerMap" />
+      <keyword name="EditorMarkerMap (Constructor)" id="EditorMarkerMap (Constructor)" ref="eric5.QScintilla.EditorMarkerMap.html#EditorMarkerMap.__init__" />
+      <keyword name="EditorMarkerMap (Module)" id="EditorMarkerMap (Module)" ref="eric5.QScintilla.EditorMarkerMap.html" />
+      <keyword name="EditorMarkerMap.__drawIndicator" id="EditorMarkerMap.__drawIndicator" ref="eric5.QScintilla.EditorMarkerMap.html#EditorMarkerMap.__drawIndicator" />
+      <keyword name="EditorMarkerMap._paintIt" id="EditorMarkerMap._paintIt" ref="eric5.QScintilla.EditorMarkerMap.html#EditorMarkerMap._paintIt" />
       <keyword name="EditorPropertiesPage" id="EditorPropertiesPage" ref="eric5.Preferences.ConfigurationPages.EditorPropertiesPage.html#EditorPropertiesPage" />
       <keyword name="EditorPropertiesPage (Constructor)" id="EditorPropertiesPage (Constructor)" ref="eric5.Preferences.ConfigurationPages.EditorPropertiesPage.html#EditorPropertiesPage.__init__" />
       <keyword name="EditorPropertiesPage (Module)" id="EditorPropertiesPage (Module)" ref="eric5.Preferences.ConfigurationPages.EditorPropertiesPage.html" />
@@ -14376,6 +14382,7 @@
       <file>eric5.QScintilla.APIsManager.html</file>
       <file>eric5.QScintilla.Editor.html</file>
       <file>eric5.QScintilla.EditorAssembly.html</file>
+      <file>eric5.QScintilla.EditorMarkerMap.html</file>
       <file>eric5.QScintilla.Exporters.ExporterBase.html</file>
       <file>eric5.QScintilla.Exporters.ExporterHTML.html</file>
       <file>eric5.QScintilla.Exporters.ExporterODT.html</file>
--- a/Documentation/Source/eric5.E5Gui.E5MapWidget.html	Wed Mar 05 18:40:12 2014 +0100
+++ b/Documentation/Source/eric5.E5Gui.E5MapWidget.html	Wed Mar 05 19:52:15 2014 +0100
@@ -84,8 +84,8 @@
 <td><a href="#E5MapWidget.lineDimensions">lineDimensions</a></td>
 <td>Public method to get the line (indicator) dimensions.</td>
 </tr><tr>
-<td><a href="#E5MapWidget.mousePressEvent">mousePressEvent</a></td>
-<td>Protected method to handle a mouse button press.</td>
+<td><a href="#E5MapWidget.mouseReleaseEvent">mouseReleaseEvent</a></td>
+<td>Protected method to handle a mouse button release.</td>
 </tr><tr>
 <td><a href="#E5MapWidget.paintEvent">paintEvent</a></td>
 <td>Protected method to handle a paint event.</td>
@@ -223,11 +223,11 @@
 <dd>
 tuple with border width (integer) and line height (integer)
 </dd>
-</dl><a NAME="E5MapWidget.mousePressEvent" ID="E5MapWidget.mousePressEvent"></a>
-<h4>E5MapWidget.mousePressEvent</h4>
-<b>mousePressEvent</b>(<i>event</i>)
+</dl><a NAME="E5MapWidget.mouseReleaseEvent" ID="E5MapWidget.mouseReleaseEvent"></a>
+<h4>E5MapWidget.mouseReleaseEvent</h4>
+<b>mouseReleaseEvent</b>(<i>event</i>)
 <p>
-        Protected method to handle a mouse button press.
+        Protected method to handle a mouse button release.
 </p><dl>
 <dt><i>event</i></dt>
 <dd>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Documentation/Source/eric5.QScintilla.EditorMarkerMap.html	Wed Mar 05 19:52:15 2014 +0100
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric5.QScintilla.EditorMarkerMap</title>
+<meta charset="UTF-8">
+<style>
+body {
+    background: #EDECE6;
+    margin: 0em 1em 10em 1em;
+    color: black;
+}
+
+h1 { color: white; background: #85774A; }
+h2 { color: white; background: #85774A; }
+h3 { color: white; background: #9D936E; }
+h4 { color: white; background: #9D936E; }
+    
+a { color: #BA6D36; }
+
+</style>
+</head>
+<body><a NAME="top" ID="top"></a>
+<h1>eric5.QScintilla.EditorMarkerMap</h1>
+<p>
+Module implementing a class for showing an editor marker map.
+</p>
+<h3>Global Attributes</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+<table>
+<tr>
+<td><a href="#EditorMarkerMap">EditorMarkerMap</a></td>
+<td>Class implementing a class for showing an editor marker map.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr /><hr />
+<a NAME="EditorMarkerMap" ID="EditorMarkerMap"></a>
+<h2>EditorMarkerMap</h2>
+<p>
+    Class implementing a class for showing an editor marker map.
+</p>
+<h3>Derived from</h3>
+E5MapWidget
+<h3>Class Attributes</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+<table>
+<tr>
+<td><a href="#EditorMarkerMap.__init__">EditorMarkerMap</a></td>
+<td>Constructor</td>
+</tr><tr>
+<td><a href="#EditorMarkerMap.__drawIndicator">__drawIndicator</a></td>
+<td>Private method to draw an indicator.</td>
+</tr><tr>
+<td><a href="#EditorMarkerMap._paintIt">_paintIt</a></td>
+<td>Protected method for painting the widget's indicators.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<a NAME="EditorMarkerMap.__init__" ID="EditorMarkerMap.__init__"></a>
+<h4>EditorMarkerMap (Constructor)</h4>
+<b>EditorMarkerMap</b>(<i>parent=None</i>)
+<p>
+        Constructor
+</p><dl>
+<dt><i>parent</i></dt>
+<dd>
+reference to the parent widget (QWidget)
+</dd>
+</dl><a NAME="EditorMarkerMap.__drawIndicator" ID="EditorMarkerMap.__drawIndicator"></a>
+<h4>EditorMarkerMap.__drawIndicator</h4>
+<b>__drawIndicator</b>(<i>line, painter, color</i>)
+<p>
+        Private method to draw an indicator.
+</p><dl>
+<dt><i>line</i></dt>
+<dd>
+line number (integer)
+</dd><dt><i>painter</i></dt>
+<dd>
+reference to the painter (QPainter)
+</dd><dt><i>color</i></dt>
+<dd>
+color to be used (QColor)
+</dd>
+</dl><a NAME="EditorMarkerMap._paintIt" ID="EditorMarkerMap._paintIt"></a>
+<h4>EditorMarkerMap._paintIt</h4>
+<b>_paintIt</b>(<i>painter</i>)
+<p>
+        Protected method for painting the widget's indicators.
+</p><dl>
+<dt><i>painter</i></dt>
+<dd>
+reference to the painter object (QPainter)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- a/Documentation/Source/index-eric5.QScintilla.html	Wed Mar 05 18:40:12 2014 +0100
+++ b/Documentation/Source/index-eric5.QScintilla.html	Wed Mar 05 19:52:15 2014 +0100
@@ -59,6 +59,9 @@
 <td><a href="eric5.QScintilla.EditorAssembly.html">EditorAssembly</a></td>
 <td>Module implementing the editor assembly widget containing the navigation combos and the editor widget.</td>
 </tr><tr>
+<td><a href="eric5.QScintilla.EditorMarkerMap.html">EditorMarkerMap</a></td>
+<td>Module implementing a class for showing an editor marker map.</td>
+</tr><tr>
 <td><a href="eric5.QScintilla.GotoDialog.html">GotoDialog</a></td>
 <td>Module implementing the Goto dialog.</td>
 </tr><tr>
--- a/E5Gui/E5MapWidget.py	Wed Mar 05 18:40:12 2014 +0100
+++ b/E5Gui/E5MapWidget.py	Wed Mar 05 19:52:15 2014 +0100
@@ -24,14 +24,14 @@
         super().__init__(parent)
         self.setAttribute(Qt.WA_OpaquePaintEvent)
         
-        self.__width = 12
-        self.__lineBorder = 2
+        self.__width = 14
+        self.__lineBorder = 1
         self.__lineHeight = 2
-        self.__backgroundColor = QColor(Qt.lightGray).lighter(120)
+        self.__backgroundColor = QColor("#e7e7e7")
         self.__sliderBorderColor = QColor(Qt.black)
         self.__sliderBackgroundColor = QColor(Qt.white)
         
-        self.__master = None
+        self._master = None
         self.__enabled = False
         
         if parent is not None and isinstance(parent, QAbstractScrollArea):
@@ -41,12 +41,12 @@
         """
         Private method to update the master's viewport width.
         """
-        if self.__master:
+        if self._master:
             if self.__enabled:
                 width = self.__width
             else:
                 width = 0
-            self.__master.setViewportMargins(0, 0, width, 0)
+            self._master.setViewportMargins(0, 0, width, 0)
     
     def setMaster(self, master):
         """
@@ -54,8 +54,8 @@
         
         @param master map master widget (QAbstractScrollArea)
         """
-        self.__master = master
-        self.__master.verticalScrollBar().valueChanged.connect(self.repaint)
+        self._master = master
+        self._master.verticalScrollBar().valueChanged.connect(self.repaint)
         self.__updateMasterViewportWidth()
     
     def setWidth(self, width):
@@ -64,7 +64,10 @@
         
         @param width widget width (integer)
         """
-        self.__width = width
+        if width != self.__width:
+            self.__width = max(6, width)    # minimum width 6 pixels
+            self.__updateMasterViewportWidth()
+            self.update()
     
     def width(self):
         """
@@ -81,8 +84,10 @@
         @param border border width on each side in x-direction (integer)
         @param height height of the line in pixels (integer)
         """
-        self.__lineBorder = border
-        self.__lineHeight = max(2, height)  # min height is 2 pixels
+        if border != self.__lineBorder or height != self.__lineHeight:
+            self.__lineBorder = max(1, border)  # min border 1 pixel
+            self.__lineHeight = max(1, height)  # min height 1 pixel
+            self.update()
     
     def lineDimensions(self):
         """
@@ -98,9 +103,10 @@
         
         @param enable flag indicating the enabled state (boolean)
         """
-        self.__enabled = enable
-        self.setVisible(enable)
-        self.__updateMasterViewportWidth()
+        if enable != self.__enabled:
+            self.__enabled = enable
+            self.setVisible(enable)
+            self.__updateMasterViewportWidth()
     
     def isEnabled(self):
         """
@@ -116,7 +122,9 @@
         
         @param color color for the background (QColor)
         """
-        self.__backgroundColor = color
+        if color != self.__backgroundColor:
+            self.__backgroundColor = color
+            self.update()
     
     def backgroundColor(self):
         """
@@ -133,8 +141,11 @@
         @param border border color (QColor)
         @param background background color (QColor)
         """
-        self.__sliderBorderColor = border
-        self.__sliderBackgroundColor = background
+        if border != self.__sliderBorderColor or \
+                background != self.__sliderBackgroundColor:
+            self.__sliderBorderColor = border
+            self.__sliderBackgroundColor = background
+            self.update()
     
     def sliderColors(self):
         """
@@ -168,7 +179,7 @@
         self._paintIt(painter)
         
         # step 3: paint the slider
-        if self.__master:
+        if self._master:
             penColor = self.__sliderBorderColor
             penColor.setAlphaF(0.8)
             painter.setPen(penColor)
@@ -176,7 +187,7 @@
             brushColor.setAlphaF(0.5)
             painter.setBrush(QBrush(brushColor))
             painter.drawRect(self.__generateSliderRange(
-                self.__master.verticalScrollBar()))
+                self._master.verticalScrollBar()))
     
     def _paintIt(self, painter):
         """
@@ -188,29 +199,33 @@
         """
         pass
     
-    def mousePressEvent(self, event):
+    def mouseReleaseEvent(self, event):
         """
-        Protected method to handle a mouse button press.
+        Protected method to handle a mouse button release.
         
         @param event mouse event (QMouseEvent)
         """
-        if event.button() == Qt.LeftButton and self.__master:
-            vsb = self.__master.verticalScrollBar()
+        if event.button() == Qt.LeftButton and self._master:
+            vsb = self._master.verticalScrollBar()
             value = self.position2Value(event.pos().y() - 1)
             vsb.setValue(value - 0.5 * vsb.pageStep())  # center on page
     
+    # TODO: add support for dragging the slider
+    
+    # TODO: add support for mouse wheel
+    
     def calculateGeometry(self):
         """
         Public method to recalculate the map widget's geometry.
         """
-        if self.__master:
-            cr = self.__master.contentsRect()
-            vsb = self.__master.verticalScrollBar()
+        if self._master:
+            cr = self._master.contentsRect()
+            vsb = self._master.verticalScrollBar()
             if vsb.isVisible():
                 vsbw = vsb.contentsRect().width()
             else:
                 vsbw = 0
-            left, top, right, bottom = self.__master.getContentsMargins()
+            left, top, right, bottom = self._master.getContentsMargins()
             if right > vsbw:
                 vsbw = 0
             self.setGeometry(QRect(cr.right() - self.__width - vsbw, cr.top(),
@@ -224,9 +239,9 @@
             (boolean)
         @return scale factor (float)
         """
-        if self.__master:
+        if self._master:
             delta = 0 if slider else 2
-            vsb = self.__master.verticalScrollBar()
+            vsb = self._master.verticalScrollBar()
             posHeight = vsb.height() - delta - 1
             valHeight = vsb.maximum() - vsb.minimum() + vsb.pageStep()
             return posHeight / valHeight
@@ -242,9 +257,9 @@
             (boolean)
         @return position (integer)
         """
-        if self.__master:
+        if self._master:
             offset = 0 if slider else 1
-            vsb = self.__master.verticalScrollBar()
+            vsb = self._master.verticalScrollBar()
             return (value - vsb.minimum()) * self.scaleFactor(slider) + offset
         else:
             return value
@@ -258,9 +273,9 @@
             (boolean)
         @return scrollbar value (integer)
         """
-        if self.__master:
+        if self._master:
             offset = 0 if slider else 1
-            vsb = self.__master.verticalScrollBar()
+            vsb = self._master.verticalScrollBar()
             return vsb.minimum() + max(
                 0, (position - offset) / self.scaleFactor(slider))
         else:
@@ -286,5 +301,4 @@
         pos1 = self.value2Position(scrollbar.value(), slider=True)
         pos2 = self.value2Position(scrollbar.value() + scrollbar.pageStep(),
                                    slider=True)
-        return QRect(1, pos1, self.__width - 2, pos2 - pos1 + 1)
-        # TODO: check slider appearance and adjust to self.__width
+        return QRect(0, pos1, self.__width - 1, pos2 - pos1)
--- a/QScintilla/Editor.py	Wed Mar 05 18:40:12 2014 +0100
+++ b/QScintilla/Editor.py	Wed Mar 05 19:52:15 2014 +0100
@@ -19,9 +19,9 @@
 
 from E5Gui.E5Application import e5App
 from E5Gui import E5FileDialog, E5MessageBox
-from E5Gui.E5MapWidget import E5MapWidget
 
 from .QsciScintillaCompat import QsciScintillaCompat, QSCINTILLA_VERSION
+from .EditorMarkerMap import EditorMarkerMap
 
 import Preferences
 import Utilities
@@ -292,7 +292,7 @@
         self.changeMarkersMask = (1 << self.__changeMarkerSaved) | \
                                  (1 << self.__changeMarkerUnsaved)
         
-        self.__markerMap = E5MapWidget(self)
+        self.__markerMap = EditorMarkerMap(self)
         
         # configure the margins
         self.__setMarginsDisplay()
@@ -444,6 +444,9 @@
                 self.__projectPropertiesChanged)
         
         self.grabGesture(Qt.PinchGesture)
+        
+        self.SCN_ZOOM.connect(self.__markerMap.update)
+        self.__markerMap.update()
     
     def __registerImages(self):
         """
@@ -1654,6 +1657,9 @@
                 pos = self.positionFromLineIndex(self.lastLine, self.lastIndex)
                 self.spell.checkWord(pos)
         
+        if self.lastLine != line:
+            self.__markerMap.update()
+        
         self.lastLine = line
         self.lastIndex = index
         
@@ -1951,6 +1957,7 @@
             self.markerDeleteHandle(handle)
         self.__addBreakPoints(
             QModelIndex(), 0, self.breakpointModel.rowCount() - 1)
+        self.__markerMap.update()
         
     def __deleteBreakPoints(self, parentIndex, start, end):
         """
@@ -2027,6 +2034,7 @@
         
         del self.breaks[handle]
         self.markerDeleteHandle(handle)
+        self.__markerMap.update()
         
     def newBreakpointWithProperties(self, line, properties):
         """
@@ -2047,6 +2055,7 @@
             handle = self.markerAdd(line - 1, marker)
             self.breaks[handle] = (line,) + properties
             self.breakpointToggled.emit(self)
+            self.__markerMap.update()
         
     def __toggleBreakpoint(self, line, temporary=False):
         """
@@ -2270,17 +2279,15 @@
         """
         for handle in self.bookmarks:
             if self.markerLine(handle) == line - 1:
+                self.bookmarks.remove(handle)
+                self.markerDeleteHandle(handle)
                 break
         else:
             # set a new bookmark
             handle = self.markerAdd(line - 1, self.bookmark)
             self.bookmarks.append(handle)
-            self.bookmarkToggled.emit(self)
-            return
-        
-        self.bookmarks.remove(handle)
-        self.markerDeleteHandle(handle)
         self.bookmarkToggled.emit(self)
+        self.__markerMap.update()
         
     def getBookmarks(self):
         """
@@ -2373,6 +2380,7 @@
             self.markerDeleteHandle(handle)
         self.bookmarks = []
         self.bookmarkToggled.emit(self)
+        self.__markerMap.update()
     
     ###########################################################################
     ## Printing methods below
@@ -2545,6 +2553,7 @@
                 if shouldBreak:
                     break
         self.taskMarkersUpdated.emit(self)
+        self.__markerMap.update()
     
     ###########################################################################
     ## Change tracing methods below
@@ -2628,6 +2637,7 @@
         
         if self.__hasChangeMarkers:
             self.changeMarkersUpdated.emit(self)
+            self.__markerMap.update()
         
     def __resetOnlineChangeTraceInfo(self):
         """
@@ -2649,6 +2659,7 @@
         
         if self.__hasChangeMarkers:
             self.changeMarkersUpdated.emit(self)
+            self.__markerMap.update()
         
     def __deleteAllChangeMarkers(self):
         """
@@ -2658,6 +2669,7 @@
         self.markerDeleteAll(self.__changeMarkerSaved)
         self.__hasChangeMarkers = False
         self.changeMarkersUpdated.emit(self)
+        self.__markerMap.update()
         
     def getChangeLines(self):
         """
@@ -5248,7 +5260,8 @@
                 for line in missing:
                     handle = self.markerAdd(line - 1, self.notcovered)
                     self.notcoveredMarkers.append(handle)
-                    self.coverageMarkersShown.emit(True)
+                self.coverageMarkersShown.emit(True)
+                self.__markerMap.update()
             else:
                 if not silent:
                     E5MessageBox.information(
@@ -5273,6 +5286,7 @@
         self.notcoveredMarkers = []
         self.coverageMarkersShown.emit(False)
         self.showingNotcoveredMarkers = False
+        self.__markerMap.update()
         
     def getCoverageLines(self):
         """
@@ -5449,6 +5463,7 @@
                     self.syntaxerrorToggled.emit(self)
         
         self.__setAnnotation(line - 1)
+        self.__markerMap.update()
         
     def getSyntaxErrors(self):
         """
@@ -5576,6 +5591,7 @@
                     self.syntaxerrorToggled.emit(self)
         
         self.__setAnnotation(line - 1)
+        self.__markerMap.update()
     
     def getWarnings(self):
         """
@@ -5687,6 +5703,7 @@
                 self.__setAnnotation(self.markerLine(handle))
                 self.markerDeleteHandle(handle)
         self.syntaxerrorToggled.emit(self)
+        self.__markerMap.update()
     
     def clearWarnings(self):
         """
@@ -5698,6 +5715,7 @@
             self.markerDeleteHandle(handle)
         self.warnings = {}
         self.syntaxerrorToggled.emit(self)
+        self.__markerMap.update()
     
     def __showWarning(self, line=-1):
         """
@@ -6330,6 +6348,8 @@
         self.editorSaved.emit(self.fileName)
         self.__autoSyntaxCheck(useText=False)
         
+        self.__markerMap.update()
+        
         self.refreshed.emit()
         
     def setMonospaced(self, on):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QScintilla/EditorMarkerMap.py	Wed Mar 05 19:52:15 2014 +0100
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a class for showing an editor marker map.
+"""
+
+from PyQt4.QtGui import QColor
+
+from E5Gui.E5MapWidget import E5MapWidget
+
+
+class EditorMarkerMap(E5MapWidget):
+    """
+    Class implementing a class for showing an editor marker map.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (QWidget)
+        """
+        super().__init__(parent)
+        
+        # initialize colors for various markers
+        # TODO: make these colors configurable via Preferences
+        self.__bookmarkColor = QColor("#f8c700")
+        self.__errorColor = QColor("#dd0000")
+        self.__warningColor = QColor("#606000")
+        self.__breakpointColor = QColor("#f55c07")
+        self.__taskColor = QColor("#2278f8")
+        self.__coverageColor = QColor("#ad3636")
+        self.__changeColor = QColor("#00b000")
+        self.__currentLineMarker = QColor("#000000")
+    
+    def __drawIndicator(self, line, painter, color):
+        """
+        Private method to draw an indicator.
+        
+        @param line line number (integer)
+        @param painter reference to the painter (QPainter)
+        @param color color to be used (QColor)
+        """
+        position = self.value2Position(line)
+        painter.setPen(color.darker(120))
+        painter.setBrush(color)
+        painter.drawRect(self.generateIndicatorRect(position))
+    
+    def _paintIt(self, painter):
+        """
+        Protected method for painting the widget's indicators.
+        
+        @param painter reference to the painter object (QPainter)
+        """
+        # draw indicators in reverse order of priority
+        
+        # 1. changes
+        for line in self._master.getChangeLines():
+            self.__drawIndicator(line, painter, self.__changeColor)
+        
+        # 2. coverage
+        for line in self._master.getCoverageLines():
+            self.__drawIndicator(line, painter, self.__coverageColor)
+        
+        # 3. tasks
+        for line in self._master.getTaskLines():
+            self.__drawIndicator(line, painter, self.__taskColor)
+        
+        # 4. breakpoints
+        for line in self._master.getBreakpointLines():
+            self.__drawIndicator(line, painter, self.__breakpointColor)
+        
+        # 5. bookmarks
+        for line in self._master.getBookmarkLines():
+            self.__drawIndicator(line, painter, self.__bookmarkColor)
+        
+        # 6. warnings
+        for line in self._master.getWarningLines():
+            self.__drawIndicator(line, painter, self.__warningColor)
+        
+        # 7. errors
+        for line in self._master.getSyntaxErrorLines():
+            self.__drawIndicator(line, painter, self.__errorColor)
+        
+        # 8. current line
+        self.__drawIndicator(self._master.getCursorPosition()[0], painter,
+                             self.__currentLineMarker)
--- a/eric5.e4p	Wed Mar 05 18:40:12 2014 +0100
+++ b/eric5.e4p	Wed Mar 05 19:52:15 2014 +0100
@@ -1128,6 +1128,7 @@
     <Source>Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/ProjectBrowserHelper.py</Source>
     <Source>Plugins/VcsPlugins/vcsMercurial/LargefilesExtension/LfRevisionsInputDialog.py</Source>
     <Source>E5Gui/E5MapWidget.py</Source>
+    <Source>QScintilla/EditorMarkerMap.py</Source>
   </Sources>
   <Forms>
     <Form>PyUnit/UnittestDialog.ui</Form>

eric ide

mercurial