<s> import wx <EOL> import git <EOL> import platformspec <EOL> from util import * <EOL> COLW = <NUM_LIT:12> <EOL> LINH = <NUM_LIT:16> <EOL> COMW = <NUM_LIT:8> <EOL> EDGE_COLORS = [ <EOL> ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT:0> , <NUM_LIT> , <NUM_LIT:0> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT:64> , <NUM_LIT:64> , <NUM_LIT:0> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT:64> , <NUM_LIT:0> , <NUM_LIT:64> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT:0> , <NUM_LIT:64> , <NUM_LIT:64> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT:0> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT:0> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT:64> , <NUM_LIT:0> , <NUM_LIT> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT:0> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:200> ) , <EOL> ( <NUM_LIT:0> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:200> ) <EOL> ] <EOL> class CommitList ( wx . ScrolledWindow ) : <EOL> def __init__ ( self , parent , id , allowMultiple = False ) : <EOL> wx . ScrolledWindow . __init__ ( self , parent , - <NUM_LIT:1> , style = wx . SUNKEN_BORDER ) <EOL> self . SetBackgroundColour ( '<STR_LIT>' ) <EOL> self . Bind ( wx . EVT_PAINT , self . OnPaint ) <EOL> self . Bind ( wx . EVT_LEFT_DOWN , self . OnLeftClick ) <EOL> self . Bind ( wx . EVT_LEFT_UP , self . OnLeftRelease ) <EOL> self . Bind ( wx . EVT_RIGHT_DOWN , self . OnRightClick ) <EOL> self . Bind ( wx . EVT_KEY_DOWN , self . OnKeyPressed ) <EOL> self . Bind ( wx . EVT_MOTION , self . OnMouseMove ) <EOL> self . Bind ( wx . EVT_LEAVE_WINDOW , self . OnMouseLeave ) <EOL> self . repo = None <EOL> self . rows = [ ] <EOL> self . selection = [ ] <EOL> self . mainRepo = None <EOL> self . mainRepoSelection = [ ] <EOL> self . allowMultiple = allowMultiple <EOL> self . authorColumnPos = <NUM_LIT:200> <EOL> self . normalCursor = wx . NullCursor <EOL> self . resizeCursor = wx . StockCursor ( wx . CURSOR_SIZEWE ) <EOL> self . currentCursor = self . normalCursor <EOL> self . resizing = False <EOL> def SetRepo ( self , repo ) : <EOL> if self . repo and self . repo == self . mainRepo : <EOL> self . mainRepo = self . repo <EOL> self . mainRepoSelection = [ self . rows [ row ] [ <NUM_LIT:0> ] . commit . sha1 for row in self . selection ] <EOL> repo_changed = ( self . repo != repo ) <EOL> if repo_changed : <EOL> self . selection = [ ] <EOL> self . Scroll ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> if not repo . parent : <EOL> self . mainRepo = repo <EOL> self . repo = repo <EOL> self . commits = self . repo . get_log ( [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> self . CreateLogGraph ( ) <EOL> if repo_changed and self . repo != self . mainRepo : <EOL> for version in self . mainRepoSelection : <EOL> submodule_version = self . repo . parent . get_submodule_version ( self . repo . name , version ) <EOL> if submodule_version : <EOL> rows = [ r for r in self . rows if r [ <NUM_LIT:0> ] . commit . sha1 == submodule_version ] <EOL> if rows : <EOL> self . selection . append ( self . rows . index ( rows [ <NUM_LIT:0> ] ) ) <EOL> self . SetVirtualSize ( ( - <NUM_LIT:1> , ( len ( self . rows ) + <NUM_LIT:1> ) * LINH ) ) <EOL> self . SetScrollRate ( LINH , LINH ) <EOL> self . Refresh ( ) <EOL> def CreateLogGraph ( self ) : <EOL> rows = [ ] <EOL> nodes = { } <EOL> lanes = [ ] <EOL> color = <NUM_LIT:0> <EOL> self . rows = rows <EOL> self . columns = <NUM_LIT:0> <EOL> self . nodes = nodes <EOL> for y in xrange ( len ( self . commits ) ) : <EOL> commit = self . commits [ y ] <EOL> node = GraphNode ( commit ) <EOL> nodes [ commit ] = node <EOL> node . y = y <EOL> rows . append ( ( node , [ ] ) ) <EOL> x = None <EOL> for i in xrange ( len ( lanes ) ) : <EOL> if lanes [ i ] and commit in lanes [ i ] . commit . parents : <EOL> x = i <EOL> node . color = lanes [ i ] . color <EOL> break <EOL> if x == None : <EOL> node . color = color <EOL> color += <NUM_LIT:1> <EOL> if None in lanes : <EOL> x = lanes . index ( None ) <EOL> else : <EOL> x = len ( lanes ) <EOL> lanes . append ( None ) <EOL> node . x = x <EOL> self . columns = max ( self . columns , x ) <EOL> for child_commit in commit . children : <EOL> child = nodes [ child_commit ] <EOL> edge = GraphEdge ( node , child ) <EOL> node . child_edges . append ( edge ) <EOL> child . parent_edges . append ( edge ) <EOL> if child . x == node . x and lanes [ x ] == child : <EOL> edge . style = EDGE_DIRECT <EOL> edge . x = node . x <EOL> edge . color = child . color <EOL> elif len ( child_commit . parents ) == <NUM_LIT:1> : <EOL> edge . style = EDGE_BRANCH <EOL> edge . x = child . x <EOL> edge . color = child . color <EOL> else : <EOL> edge . style = EDGE_MERGE <EOL> edge . color = node . color <EOL> edge . x = max ( node . x , child . x + <NUM_LIT:1> ) <EOL> success = False <EOL> while not success : <EOL> success = True <EOL> for yy in xrange ( node . y , child . y , - <NUM_LIT:1> ) : <EOL> n , edges = rows [ yy ] <EOL> if ( yy < node . y and n . x == edge . x ) or ( len ( edges ) > edge . x and edges [ edge . x ] != None ) : <EOL> edge . x += <NUM_LIT:1> <EOL> success = False <EOL> break <EOL> for yy in xrange ( node . y , child . y , - <NUM_LIT:1> ) : <EOL> n , edges = rows [ yy ] <EOL> if len ( edges ) < edge . x + <NUM_LIT:1> : <EOL> edges += [ None ] * ( edge . x + <NUM_LIT:1> - len ( edges ) ) <EOL> edges [ edge . x ] = edge <EOL> self . columns = max ( self . columns , edge . x ) <EOL> for i in xrange ( len ( lanes ) ) : <EOL> if lanes [ i ] and len ( lanes [ i ] . parent_edges ) == len ( lanes [ i ] . commit . parents ) : <EOL> lanes [ i ] = None <EOL> lanes [ x ] = node <EOL> if self . repo . current_branch : <EOL> self . _add_reference ( self . repo . head , self . repo . current_branch , REF_HEADBRANCH ) <EOL> else : <EOL> self . _add_reference ( self . repo . head , '<STR_LIT>' , REF_DETACHEDHEAD ) <EOL> if self . repo . main_ref : <EOL> self . _add_reference ( self . repo . main_ref , '<STR_LIT>' , REF_MODULE ) <EOL> if self . repo . main_merge_ref : <EOL> self . _add_reference ( self . repo . main_merge_ref , '<STR_LIT>' , REF_MODULE ) <EOL> for branch , commit_id in self . repo . branches . iteritems ( ) : <EOL> if branch != self . repo . current_branch : <EOL> self . _add_reference ( commit_id , branch , REF_BRANCH ) <EOL> for branch , commit_id in self . repo . remote_branches . iteritems ( ) : <EOL> self . _add_reference ( commit_id , branch , REF_REMOTE ) <EOL> for tag , commit_id in self . repo . tags . iteritems ( ) : <EOL> self . _add_reference ( commit_id , tag , REF_TAG ) <EOL> def _add_reference ( self , commit_id , refname , reftype ) : <EOL> if commit_id not in git . commit_pool : <EOL> return <EOL> commit = git . commit_pool [ commit_id ] <EOL> if commit not in self . nodes : <EOL> return <EOL> self . nodes [ commit ] . references . append ( ( refname , reftype ) ) <EOL> def OnPaint ( self , evt ) : <EOL> evt . Skip ( False ) <EOL> if not self . repo : <EOL> return <EOL> pdc = wx . PaintDC ( self ) <EOL> try : <EOL> dc = wx . GCDC ( pdc ) <EOL> except : <EOL> dc = pdc <EOL> dc . BeginDrawing ( ) <EOL> size = self . GetClientSize ( ) <EOL> clientWidth , clientHeight = size . GetWidth ( ) , size . GetHeight ( ) <EOL> x , y , width , height = self . GetUpdateRegion ( ) . GetBox ( ) <EOL> start_x , start_y = self . CalcUnscrolledPosition ( x , y ) <EOL> start_row , end_row = max ( <NUM_LIT:0> , start_y / LINH - <NUM_LIT:1> ) , ( start_y + height ) / LINH + <NUM_LIT:1> <EOL> commit_pen = wx . Pen ( wx . Colour ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:255> ) , width = <NUM_LIT:2> ) <EOL> commit_brush = wx . Brush ( wx . Colour ( <NUM_LIT:255> , <NUM_LIT:255> , <NUM_LIT:255> , <NUM_LIT:255> ) ) <EOL> commit_font = platformspec . Font ( <NUM_LIT:12> ) <EOL> commit_textcolor_normal = wx . SystemSettings_GetColour ( wx . SYS_COLOUR_WINDOWTEXT ) <EOL> commit_textcolor_highlight = wx . SystemSettings_GetColour ( wx . SYS_COLOUR_HIGHLIGHTTEXT ) <EOL> edge_pens = [ wx . Pen ( wx . Colour ( * c ) , width = <NUM_LIT:2> ) for c in EDGE_COLORS ] <EOL> background_pen = wx . NullPen <EOL> background_brush = wx . Brush ( wx . SystemSettings_GetColour ( wx . SYS_COLOUR_WINDOW ) ) <EOL> selection_pen = wx . NullPen <EOL> selection_brush = wx . Brush ( wx . SystemSettings_GetColour ( wx . SYS_COLOUR_HIGHLIGHT ) ) <EOL> separator_pen = wx . Pen ( wx . SystemSettings_GetColour ( wx . SYS_COLOUR_3DLIGHT ) , width = <NUM_LIT:1> ) <EOL> ref_pens = [ <EOL> wx . Pen ( wx . Colour ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:255> ) , width = <NUM_LIT:1> ) , <EOL> wx . Pen ( wx . Colour ( <NUM_LIT:0> , <NUM_LIT:255> , <NUM_LIT:0> , <NUM_LIT:255> ) , width = <NUM_LIT:1> ) , <EOL> wx . Pen ( wx . Colour ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT:0> , <NUM_LIT:255> ) , width = <NUM_LIT:1> ) , <EOL> wx . Pen ( wx . Colour ( <NUM_LIT:255> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:255> ) , width = <NUM_LIT:1> ) , <EOL> wx . Pen ( wx . Colour ( <NUM_LIT:255> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:255> ) , width = <NUM_LIT:1> ) , <EOL> wx . Pen ( wx . Colour ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:255> ) , width = <NUM_LIT:1> ) <EOL> ] <EOL> ref_brushes = [ <EOL> wx . Brush ( wx . Colour ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT:255> , <NUM_LIT:255> ) ) , <EOL> wx . Brush ( wx . Colour ( <NUM_LIT> , <NUM_LIT:255> , <NUM_LIT> , <NUM_LIT:255> ) ) , <EOL> wx . Brush ( wx . Colour ( <NUM_LIT:255> , <NUM_LIT:255> , <NUM_LIT> , <NUM_LIT:255> ) ) , <EOL> wx . Brush ( wx . Colour ( <NUM_LIT:255> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:255> ) ) , <EOL> wx . Brush ( wx . Colour ( <NUM_LIT:255> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:255> ) ) , <EOL> wx . Brush ( wx . Colour ( <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT:255> ) ) <EOL> ] <EOL> ref_font = platformspec . Font ( <NUM_LIT:9> ) <EOL> ref_textcolor = wx . Colour ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:255> ) <EOL> dc . SetPen ( selection_pen ) <EOL> dc . SetBrush ( selection_brush ) <EOL> for row in self . selection : <EOL> if start_row <= row <= end_row : <EOL> x , y = self . CalcScrolledPosition ( <NUM_LIT:0> , ( row + <NUM_LIT:1> ) * LINH ) <EOL> dc . DrawRectangle ( <NUM_LIT:0> , y - LINH / <NUM_LIT:2> , clientWidth , LINH ) <EOL> offx = COLW <EOL> offy = LINH <EOL> edges = set ( ) <EOL> for node , row_edges in self . rows [ start_row : end_row + <NUM_LIT:1> ] : <EOL> edges . update ( row_edges ) <EOL> for edge in edges : <EOL> if not edge : continue <EOL> dc . SetPen ( edge_pens [ edge . color % len ( EDGE_COLORS ) ] ) <EOL> if edge . style == EDGE_DIRECT : <EOL> x1 , y1 = self . CalcScrolledPosition ( edge . src . x * COLW + offx , edge . src . y * LINH + offy ) <EOL> x2 , y2 = self . CalcScrolledPosition ( edge . dst . x * COLW + offx , edge . dst . y * LINH + offy ) <EOL> dc . DrawLine ( x1 , y1 , x2 , y2 ) <EOL> elif edge . style == EDGE_BRANCH : <EOL> x1 , y1 = self . CalcScrolledPosition ( edge . src . x * COLW + offx , edge . src . y * LINH + offy ) <EOL> x2 , y2 = self . CalcScrolledPosition ( edge . dst . x * COLW + offx , edge . src . y * LINH + offy - <NUM_LIT:7> ) <EOL> x3 , y3 = self . CalcScrolledPosition ( edge . dst . x * COLW + offx , edge . dst . y * LINH + offy ) <EOL> dc . DrawLine ( x1 , y1 , x2 , y2 ) <EOL> dc . DrawLine ( x2 , y2 , x3 , y3 ) <EOL> elif edge . style == EDGE_MERGE : <EOL> x1 , y1 = self . CalcScrolledPosition ( edge . src . x * COLW + offx , edge . src . y * LINH + offy ) <EOL> x2 , y2 = self . CalcScrolledPosition ( edge . x * COLW + offx , edge . src . y * LINH + offy - <NUM_LIT:7> ) <EOL> x3 , y3 = self . CalcScrolledPosition ( edge . x * COLW + offx , edge . dst . y * LINH + offy + <NUM_LIT:7> ) <EOL> x4 , y4 = self . CalcScrolledPosition ( edge . dst . x * COLW + offx , edge . dst . y * LINH + offy ) <EOL> dc . DrawLine ( x1 , y1 , x2 , y2 ) <EOL> dc . DrawLine ( x2 , y2 , x3 , y3 ) <EOL> dc . DrawLine ( x3 , y3 , x4 , y4 ) <EOL> dc . SetPen ( commit_pen ) <EOL> dc . SetBrush ( commit_brush ) <EOL> for node , edges in self . rows [ start_row : end_row + <NUM_LIT:1> ] : <EOL> if self . rows . index ( ( node , edges ) ) in self . selection : <EOL> commit_bg_pen = selection_pen <EOL> commit_bg_brush = selection_brush <EOL> else : <EOL> commit_bg_pen = background_pen <EOL> commit_bg_brush = background_brush <EOL> if node . style == NODE_MERGE : <EOL> x = node . x * COLW + offx - COMW / <NUM_LIT:2> <EOL> y = node . y * LINH + offy - COMW / <NUM_LIT:2> <EOL> xx , yy = self . CalcScrolledPosition ( x , y ) <EOL> dc . DrawRectangle ( xx , yy , COMW , COMW ) <EOL> else : <EOL> x = node . x * COLW + offx <EOL> y = node . y * LINH + offy <EOL> xx , yy = self . CalcScrolledPosition ( x , y ) <EOL> dc . DrawCircle ( xx , yy , COMW / <NUM_LIT:2> ) <EOL> if node . y < len ( self . rows ) - <NUM_LIT:1> : <EOL> text_column = max ( len ( edges ) , len ( self . rows [ node . y + <NUM_LIT:1> ] [ <NUM_LIT:1> ] ) ) <EOL> else : <EOL> text_column = len ( edges ) if len ( edges ) > <NUM_LIT:0> else <NUM_LIT:1> <EOL> msg_offset = <NUM_LIT:0> <EOL> for refname , reftype in node . references : <EOL> dc . SetPen ( ref_pens [ reftype ] ) <EOL> dc . SetBrush ( ref_brushes [ reftype ] ) <EOL> dc . SetFont ( ref_font ) <EOL> dc . SetTextForeground ( ref_textcolor ) <EOL> x = text_column * COLW + offx + msg_offset <EOL> y = node . y * LINH + offy - LINH / <NUM_LIT:2> + <NUM_LIT:1> <EOL> width , height = dc . GetTextExtent ( refname ) <EOL> if reftype in [ REF_HEADBRANCH , REF_DETACHEDHEAD , REF_MODULE ] : <EOL> points = [ <EOL> ( x , y + LINH / <NUM_LIT:2> - <NUM_LIT:1> ) , <EOL> ( x + <NUM_LIT:6> , y ) , <EOL> ( x + <NUM_LIT:10> + width , y ) , <EOL> ( x + <NUM_LIT:10> + width , y + LINH - <NUM_LIT:3> ) , <EOL> ( x + <NUM_LIT:6> , y + LINH - <NUM_LIT:3> ) <EOL> ] <EOL> x += <NUM_LIT:6> <EOL> points = [ self . CalcScrolledPosition ( * p ) for p in points ] <EOL> points = [ wx . Point ( * p ) for p in points ] <EOL> dc . DrawPolygon ( points ) <EOL> msg_offset += width + <NUM_LIT> <EOL> else : <EOL> xx , yy = self . CalcScrolledPosition ( x , y ) <EOL> dc . DrawRoundedRectangle ( xx , yy , width + <NUM_LIT:4> , LINH - <NUM_LIT:2> , <NUM_LIT:2> ) <EOL> msg_offset += width + <NUM_LIT:8> <EOL> dc . SetPen ( commit_pen ) <EOL> dc . SetBrush ( commit_brush ) <EOL> xx , yy = self . CalcScrolledPosition ( x + <NUM_LIT:2> , y + <NUM_LIT:1> ) <EOL> dc . DrawText ( safe_unicode ( refname ) , xx , yy ) <EOL> dc . SetFont ( commit_font ) <EOL> x = text_column * COLW + offx + msg_offset <EOL> y = node . y * LINH + offy - LINH / <NUM_LIT:2> <EOL> xx , yy = self . CalcScrolledPosition ( x , y ) <EOL> if self . rows . index ( ( node , edges ) ) in self . selection : <EOL> dc . SetTextForeground ( commit_textcolor_highlight ) <EOL> else : <EOL> dc . SetTextForeground ( commit_textcolor_normal ) <EOL> dc . DrawText ( safe_unicode ( node . commit . short_msg ) , xx , yy ) <EOL> x = clientWidth - self . authorColumnPos <EOL> dc . SetBrush ( commit_bg_brush ) <EOL> dc . SetPen ( commit_bg_pen ) <EOL> xx , yy = self . CalcScrolledPosition ( x , y ) <EOL> dc . DrawRectangle ( xx - <NUM_LIT:4> , yy , clientWidth - x + <NUM_LIT:4> , LINH ) <EOL> dc . SetPen ( separator_pen ) <EOL> dc . DrawLine ( xx , yy , xx , yy + LINH ) <EOL> dc . SetPen ( commit_pen ) <EOL> dc . SetBrush ( commit_brush ) <EOL> author_text = u'<STR_LIT>' % ( safe_unicode ( node . commit . author_name ) , safe_unicode ( node . commit . author_date ) ) <EOL> dc . DrawText ( author_text , xx + <NUM_LIT:4> , yy ) <EOL> dc . EndDrawing ( ) <EOL> def OnMouseMove ( self , e ) : <EOL> if self . resizing : <EOL> self . authorColumnPos = self . GetClientSize ( ) . GetWidth ( ) - e . m_x <EOL> self . Refresh ( ) <EOL> else : <EOL> pos = self . GetClientSize ( ) . GetWidth ( ) - self . authorColumnPos <EOL> if pos - <NUM_LIT:2> <= e . m_x <= pos + <NUM_LIT:2> : <EOL> if self . currentCursor != self . resizeCursor : <EOL> self . SetCursor ( self . resizeCursor ) <EOL> self . currentCursor = self . resizeCursor <EOL> else : <EOL> if self . currentCursor != self . normalCursor : <EOL> self . SetCursor ( self . normalCursor ) <EOL> self . currentCursor = self . normalCursor <EOL> def OnLeftClick ( self , e ) : <EOL> e . StopPropagation ( ) <EOL> self . SetFocus ( ) <EOL> if self . currentCursor == self . resizeCursor : <EOL> self . resizing = True <EOL> return <EOL> x , y = self . CalcUnscrolledPosition ( * ( e . GetPosition ( ) ) ) <EOL> row = self . RowNumberByCoords ( x , y ) <EOL> if row == None : <EOL> return <EOL> old_selection = list ( self . selection ) <EOL> if self . allowMultiple and e . ShiftDown ( ) and len ( old_selection ) >= <NUM_LIT:1> : <EOL> from_row = old_selection [ <NUM_LIT:0> ] <EOL> to_row = row <EOL> if to_row >= from_row : <EOL> self . selection = range ( from_row , to_row + <NUM_LIT:1> ) <EOL> else : <EOL> self . selection = range ( to_row , from_row + <NUM_LIT:1> ) <EOL> self . selection . reverse ( ) <EOL> elif self . allowMultiple and ( e . ControlDown ( ) or e . CmdDown ( ) ) : <EOL> if row not in self . selection : <EOL> self . selection . insert ( <NUM_LIT:0> , row ) <EOL> else : <EOL> self . selection = [ row ] <EOL> event = CommitListEvent ( EVT_COMMITLIST_SELECT_type , self . GetId ( ) ) <EOL> event . SetCurrentRow ( row ) <EOL> event . SetSelection ( self . selection ) <EOL> self . ProcessEvent ( event ) <EOL> self . OnSelectionChanged ( row , self . selection ) <EOL> self . Refresh ( ) <EOL> def OnLeftRelease ( self , e ) : <EOL> e . StopPropagation ( ) <EOL> self . resizing = False <EOL> def OnMouseLeave ( self , e ) : <EOL> e . StopPropagation ( ) <EOL> self . resizing = False <EOL> def OnRightClick ( self , e ) : <EOL> e . StopPropagation ( ) <EOL> self . SetFocus ( ) <EOL> x , y = self . CalcUnscrolledPosition ( * ( e . GetPosition ( ) ) ) <EOL> row = self . RowNumberByCoords ( x , y ) <EOL> if row == None : <EOL> return <EOL> self . SelectRow ( row ) <EOL> event = CommitListEvent ( EVT_COMMITLIST_RIGHTCLICK_type , self . GetId ( ) ) <EOL> event . SetCurrentRow ( row ) <EOL> event . SetSelection ( self . selection ) <EOL> event . SetCoords ( ( e . GetX ( ) , e . GetY ( ) ) ) <EOL> self . ProcessEvent ( event ) <EOL> self . OnRightButtonClicked ( row , self . selection ) <EOL> def OnKeyPressed ( self , e ) : <EOL> key = e . GetKeyCode ( ) <EOL> if key not in [ wx . WXK_UP , wx . WXK_DOWN ] or len ( self . rows ) == <NUM_LIT:0> : <EOL> e . Skip ( ) <EOL> return <EOL> e . StopPropagation ( ) <EOL> start_col , start_row = self . GetViewStart ( ) <EOL> size = self . GetClientSize ( ) <EOL> height = size . GetHeight ( ) / LINH <EOL> if self . selection : <EOL> current_row = self . selection [ <NUM_LIT:0> ] <EOL> if key == wx . WXK_UP : <EOL> next_row = max ( current_row - <NUM_LIT:1> , <NUM_LIT:0> ) <EOL> if key == wx . WXK_DOWN : <EOL> next_row = min ( current_row + <NUM_LIT:1> , len ( self . rows ) - <NUM_LIT:1> ) <EOL> if e . ShiftDown ( ) and self . allowMultiple : <EOL> if next_row in self . selection : <EOL> self . selection . remove ( current_row ) <EOL> else : <EOL> self . selection . insert ( <NUM_LIT:0> , next_row ) <EOL> else : <EOL> self . selection = [ next_row ] <EOL> else : <EOL> next_row = start_row <EOL> if next_row < <NUM_LIT:0> or next_row > len ( self . rows ) : <EOL> return <EOL> self . selection = [ next_row ] <EOL> if next_row < start_row : <EOL> self . Scroll ( start_col , next_row - <NUM_LIT:1> ) <EOL> elif next_row > start_row + height - <NUM_LIT:1> : <EOL> self . Scroll ( start_col , next_row - height + <NUM_LIT:2> ) <EOL> event = CommitListEvent ( EVT_COMMITLIST_SELECT_type , self . GetId ( ) ) <EOL> event . SetCurrentRow ( next_row ) <EOL> event . SetSelection ( self . selection ) <EOL> self . ProcessEvent ( event ) <EOL> self . OnSelectionChanged ( next_row , self . selection ) <EOL> self . Refresh ( ) <EOL> def RowNumberByCoords ( self , x , y ) : <EOL> row = ( y + LINH / <NUM_LIT:2> ) / LINH - <NUM_LIT:1> <EOL> if row < <NUM_LIT:0> or row >= len ( self . rows ) : <EOL> return None <EOL> else : <EOL> return row <EOL> def CommitByRow ( self , row ) : <EOL> return self . rows [ row ] [ <NUM_LIT:0> ] . commit <EOL> def GotoCommit ( self , commit_id ) : <EOL> matching_commits = [ c for c in self . commits if c . sha1 . startswith ( commit_id ) ] <EOL> if len ( matching_commits ) == <NUM_LIT:0> : <EOL> return "<STR_LIT>" % commit_id <EOL> elif len ( matching_commits ) > <NUM_LIT:1> : <EOL> return "<STR_LIT>" % commit_id <EOL> else : <EOL> self . SelectRow ( self . commits . index ( matching_commits [ <NUM_LIT:0> ] ) ) <EOL> return None <EOL> def SelectRow ( self , row ) : <EOL> self . selection = [ row ] <EOL> event = CommitListEvent ( EVT_COMMITLIST_SELECT_type , self . GetId ( ) ) <EOL> event . SetCurrentRow ( row ) <EOL> event . SetSelection ( self . selection ) <EOL> self . ProcessEvent ( event ) <EOL> self . OnSelectionChanged ( row , self . selection ) <EOL> start_col , start_row = self . GetViewStart ( ) <EOL> size = self . GetClientSize ( ) <EOL> height = size . GetHeight ( ) / LINH <EOL> if row < start_row or row > start_row + height - <NUM_LIT:1> : <EOL> self . Scroll ( start_col , max ( row - <NUM_LIT:2> , <NUM_LIT:0> ) ) <EOL> self . Refresh ( ) <EOL> def OnSelectionChanged ( self , row , selection ) : <EOL> pass <EOL> def OnRightButtonClicked ( self , row , selection ) : <EOL> pass <EOL> EVT_COMMITLIST_SELECT_type = wx . NewEventType ( ) <EOL> EVT_COMMITLIST_SELECT = wx . PyEventBinder ( EVT_COMMITLIST_SELECT_type , <NUM_LIT:1> ) <EOL> EVT_COMMITLIST_RIGHTCLICK_type = wx . NewEventType ( ) <EOL> EVT_COMMITLIST_RIGHTCLICK = wx . PyEventBinder ( EVT_COMMITLIST_RIGHTCLICK_type , <NUM_LIT:1> ) <EOL> class CommitListEvent ( wx . PyCommandEvent ) : <EOL> def __init__ ( self , eventType , id ) : <EOL> wx . PyCommandEvent . __init__ ( self , eventType , id ) <EOL> self . selection = None <EOL> self . currentRow = None <EOL> self . coords = ( None , None ) <EOL> def GetCurrentRow ( self ) : <EOL> return self . currentRow <EOL> def SetCurrentRow ( self , currentRow ) : <EOL> self . currentRow = currentRow <EOL> def GetSelection ( self ) : <EOL> return self . selection <EOL> def SetSelection ( self , selection ) : <EOL> self . selection = selection <EOL> def SetCoords ( self , coords ) : <EOL> self . coords = coords <EOL> def GetCoords ( self ) : <EOL> return self . coords <EOL> NODE_NORMAL = <NUM_LIT:0> <EOL> NODE_BRANCH = <NUM_LIT:1> <EOL> NODE_MERGE = <NUM_LIT:2> <EOL> NODE_JUNCTION = <NUM_LIT:3> <EOL> REF_BRANCH = <NUM_LIT:0> <EOL> REF_REMOTE = <NUM_LIT:1> <EOL> REF_TAG = <NUM_LIT:2> <EOL> REF_HEADBRANCH = <NUM_LIT:3> <EOL> REF_DETACHEDHEAD = <NUM_LIT:4> <EOL> REF_MODULE = <NUM_LIT:5> <EOL> class GraphNode ( object ) : <EOL> def __init__ ( self , commit ) : <EOL> self . commit = commit <EOL> self . x = None <EOL> self . y = None <EOL> self . color = None <EOL> self . parent_edges = [ ] <EOL> self . child_edges = [ ] <EOL> self . references = [ ] <EOL> if len ( commit . parents ) > <NUM_LIT:1> and len ( commit . children ) > <NUM_LIT:1> : <EOL> self . style = NODE_JUNCTION <EOL> elif len ( commit . parents ) > <NUM_LIT:1> : <EOL> self . style = NODE_MERGE <EOL> elif len ( commit . children ) > <NUM_LIT:1> : <EOL> self . style = NODE_BRANCH <EOL> else : <EOL> self . style = NODE_NORMAL <EOL> EDGE_DIRECT = <NUM_LIT:0> <EOL> EDGE_BRANCH = <NUM_LIT:1> <EOL> EDGE_MERGE = <NUM_LIT:2> <EOL> class GraphEdge ( object ) : <EOL> def __init__ ( self , src , dst ) : <EOL> self . src = src <EOL> self . dst = dst <EOL> self . style = None <EOL> self . color = None <EOL> self . x = None <EOL> self . color = None </s>
