diff -r 94c11207aa6f -r 6014ef82a98a graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Fri Sep 30 17:16:02 2011 +0200 +++ b/graphics/GraphicCommons.py Sun Oct 09 19:51:14 2011 +0200 @@ -93,7 +93,14 @@ # Color for Highlighting HIGHLIGHTCOLOR = wx.CYAN - + +# Define highlight types +ERROR_HIGHLIGHT = (wx.NamedColour("yellow"), wx.RED) +SEARCH_RESULT_HIGHLIGHT = (wx.NamedColour("orange"), wx.WHITE) + +# Define highlight refresh inhibition period in second +REFRESH_HIGHLIGHT_PERIOD = 0.1 + HANDLE_CURSORS = { (1, 1) : 2, (3, 3) : 2, @@ -531,19 +538,38 @@ event.Skip() #------------------------------------------------------------------------------- -# Helper for highlighting error in drawn text +# Helpers for highlighting text #------------------------------------------------------------------------------- -def HighlightErrorZone(dc, x, y, width, height): +def AddHighlight(highlights, infos): + RemoveHighlight(highlights, infos) + highlights.append(infos) + +def RemoveHighlight(highlights, infos): + if infos in highlights: + highlights.remove(infos) + return True + return False + +def ClearHighlight(highlights, highlight_type=None): + if highlight_type is not None: + return [highlight for highlight in highlights if highlight[2] != highlight_type] + return [] + +def DrawHighlightedText(dc, text, highlights, x, y): + current_pen = dc.GetPen() dc.SetPen(wx.TRANSPARENT_PEN) - dc.SetLogicalFunction(wx.AND) - dc.SetBrush(wx.Brush(wx.Colour(0,255,0))) - dc.DrawRectangle(x, y, width, height) - dc.SetLogicalFunction(wx.XOR) - dc.SetBrush(wx.Brush(wx.Colour(255,0,0))) - dc.DrawRectangle(x, y, width, height) - dc.SetLogicalFunction(wx.COPY) - + for start, end, highlight_type in highlights: + dc.SetBrush(wx.Brush(highlight_type[0])) + offset_width, offset_height = dc.GetTextExtent(text[:start[1]]) + part = text[start[1]:end[1] + 1] + part_width, part_height = dc.GetTextExtent(part) + dc.DrawRectangle(x + offset_width, y, part_width, part_height) + dc.SetTextForeground(highlight_type[1]) + dc.DrawText(part, x + offset_width, y) + dc.SetPen(current_pen) + dc.SetTextForeground(wx.BLACK) + #------------------------------------------------------------------------------- # Graphic element base class #------------------------------------------------------------------------------- @@ -934,7 +960,16 @@ return movex, movey return 0, 0 - def AddError(self, infos, start, end): + # Override this method for defining the method to call for adding an highlight to this element + def AddHighlight(self, infos, start, end, highlight_type): + pass + + # Override this method for defining the method to call for removing an highlight from this element + def RemoveHighlight(self, infos, start, end, highlight_type): + pass + + # Override this method for defining the method to call for removing all the highlights of one particular type from this element + def ClearHighlight(self, highlight_type=None): pass # Override this method for defining the method to call for refreshing the model of this element @@ -1300,7 +1335,7 @@ self.Value = None self.Forced = False self.Selected = False - self.Errors = {} + self.Highlights = [] self.RefreshNameSize() def Flush(self): @@ -1396,7 +1431,7 @@ self.Valid = True for wire, handle in self.Wires: self.Valid &= wire.GetValid() - + def ReceivingCurrent(self): current = False for wire, handle in self.Wires: @@ -1607,21 +1642,50 @@ dc.SetLogicalFunction(wx.COPY) dc.SetUserScale(scalex, scaley) - def AddError(self, infos, start, end): - if len(infos) == 0: + # Adds an highlight to the connector + def AddHighlight(self, infos, start, end, highlight_type): + if highlight_type == ERROR_HIGHLIGHT: for wire, handle in self.Wires: wire.SetValid(False) + AddHighlight(self.Highlights, (start, end, highlight_type)) + + # Removes an highlight from the connector + def RemoveHighlight(self, infos, start, end, highlight_type): + error = False + highlights = [] + for highlight in self.Highlights: + if highlight != (start, end, highlight_type): + highlights.append(highlight) + error |= highlight == ERROR_HIGHLIGHT + self.Highlights = highlights + if not error: + for wire, handle in self.Wires: + wire.SetValid(wire.IsConnectedCompatible()) + + # Removes all the highlights of one particular type from the connector + def ClearHighlight(self, highlight_type=None): + error = False + if highlight_type is None: + self.Highlights = [] else: - self.Errors[infos[0]] = (start, end) + highlights = [] + for highlight in self.Highlights: + if highlight[2] != highlight_type: + highlights.append(highlight) + error |= highlight == ERROR_HIGHLIGHT + self.Highlights = highlights + if not error: + for wire, handle in self.Wires: + wire.SetValid(wire.IsConnectedCompatible()) # Draws the connector def Draw(self, dc): if self.Selected: dc.SetPen(MiterPen(wx.BLUE, 3)) dc.SetBrush(wx.WHITE_BRUSH) - elif len(self.Errors) > 0: - dc.SetPen(MiterPen(wx.RED)) - dc.SetBrush(wx.Brush(wx.Colour(255, 255, 0))) + #elif len(self.Highlights) > 0: + # dc.SetPen(MiterPen(self.Highlights[-1][1])) + # dc.SetBrush(wx.Brush(self.Highlights[-1][0])) else: if not self.Valid: dc.SetPen(MiterPen(wx.RED)) @@ -1672,9 +1736,6 @@ xend = xstart + CONNECTOR_SIZE * self.Direction[0] yend = ystart + CONNECTOR_SIZE * self.Direction[1] dc.DrawLine(xstart + self.Direction[0], ystart + self.Direction[1], xend, yend) - if len(self.Errors) > 0: - dc.SetPen(self.Pen) - dc.SetBrush(wx.WHITE_BRUSH) if self.Direction[0] != 0: ytext = parent_pos[1] + self.Pos.y - name_size[1] / 2 if self.Direction[0] < 0: @@ -1689,7 +1750,8 @@ ytext = parent_pos[1] + self.Pos.y - (name_size[1] + 5) # Draw the text dc.DrawText(self.Name, xtext, ytext) - + if not getattr(dc, "printing", False): + DrawHighlightedText(dc, self.Name, self.Highlights, xtext, ytext) #------------------------------------------------------------------------------- # Common Wire Element @@ -2775,7 +2837,7 @@ if self.EndConnected is not None: self.EndConnected.DrawHighlightment(dc) self.EndConnected.Draw(dc) - + # Draws the wire lines and points def Draw(self, dc): Graphic_Element.Draw(self, dc) @@ -2848,6 +2910,26 @@ # Graphic comment element #------------------------------------------------------------------------------- +def FilterHighlightsByRow(highlights, row, length): + _highlights = [] + for start, end, highlight_type in highlights: + if start[0] <= row and end[0] >= row: + if start[0] < row: + start = (row, 0) + if end[0] > row: + end = (row, length) + _highlights.append((start, end, highlight_type)) + return _highlights + +def FilterHighlightsByColumn(highlights, start_col, end_col): + _highlights = [] + for start, end, highlight_type in highlights: + if end[1] > start_col and start[1] < end_col: + start = (start[0], max(start[1], start_col) - start_col) + end = (end[0], min(end[1], end_col) - start_col) + _highlights.append((start, end, highlight_type)) + return _highlights + """ Class that implements a comment """ @@ -2861,6 +2943,7 @@ self.Content = content self.Pos = wx.Point(0, 0) self.Size = wx.Size(0, 0) + self.Highlights = [] # Make a clone of this comment def Clone(self, parent, id = None, pos = None): @@ -2958,6 +3041,19 @@ # Edit the comment content self.Parent.EditCommentContent(self) + # Adds an highlight to the comment + def AddHighlight(self, infos, start, end, highlight_type): + if infos[0] == "content": + AddHighlight(self.Highlights, (start, end, highlight_type)) + + # Removes an highlight from the comment + def RemoveHighlight(self, infos, start, end, highlight_type): + RemoveHighlight(self.Highlights, (start, end, highlight_type)) + + # Removes all the highlights of one particular type from the comment + def ClearHighlight(self, highlight_type=None): + self.Highlights = ClearHighlights(self.Highlights, highlight_type) + # Draws the highlightment of this element if it is highlighted def DrawHighlightment(self, dc): scalex, scaley = dc.GetUserScale() @@ -2999,32 +3095,46 @@ dc.DrawLines(lines) # Draws the comment content y = self.Pos.y + 10 - for line in self.Content.splitlines(): + for idx, line in enumerate(self.Content.splitlines()): first = True linetext = "" words = line.split(" ") + if not getattr(dc, "printing", False): + highlights = FilterHighlightsByRow(self.Highlights, idx, len(line)) + highlights_offset = 0 for i, word in enumerate(words): if first: - test = word + text = word else: - test = linetext + " " + word - wordwidth, wordheight = dc.GetTextExtent(test) + text = linetext + " " + word + wordwidth, wordheight = dc.GetTextExtent(text) if y + wordheight > self.Pos.y + self.Size[1] - 10: break if wordwidth < self.Size[0] - 20: if i < len(words) - 1: - linetext = test + linetext = text first = False else: - dc.DrawText(test, self.Pos.x + 10, y) + dc.DrawText(text, self.Pos.x + 10, y) + if not getattr(dc, "printing", False): + DrawHighlightedText(dc, text, FilterHighlightsByColumn(highlights, highlights_offset, highlights_offset + len(text)), self.Pos.x + 10, y) + highlights_offset += len(text) + 1 y += wordheight + 5 else: - dc.DrawText(linetext, self.Pos.x + 10, y) - if i == len(words) - 1: - y += wordheight + 5 - if y + wordheight > self.Pos.y + self.Size[1] - 10: - break + if not first: + dc.DrawText(linetext, self.Pos.x + 10, y) + if not getattr(dc, "printing", False): + DrawHighlightedText(dc, linetext, FilterHighlightsByColumn(highlights, highlights_offset, highlights_offset + len(linetext)), self.Pos.x + 10, y) + highlights_offset += len(linetext) + 1 + if first or i == len(words) - 1: + if not first: + y += wordheight + 5 + if y + wordheight > self.Pos.y + self.Size[1] - 10: + break dc.DrawText(word, self.Pos.x + 10, y) + if not getattr(dc, "printing", False): + DrawHighlightedText(dc, word, FilterHighlightsByColumn(highlights, highlights_offset, highlights_offset + len(word)), self.Pos.x + 10, y) + highlights_offset += len(word) + 1 else: linetext = word y += wordheight + 5