+ wxCHECK_RET( m_current, wxT("invalid m_current") );
+
+ Edit( m_lines.Index( *m_current ) );
+}
+
+void wxListMainWindow::OnRenameAccept()
+{
+ wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT, GetParent()->GetId() );
+ le.SetEventObject( GetParent() );
+ le.m_itemIndex = GetIndexOfLine( m_currentEdit );
+ m_currentEdit->GetItem( 0, le.m_item );
+ le.m_item.m_text = m_renameRes;
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+
+ if (!le.IsAllowed()) return;
+
+ wxListItem info;
+ info.m_mask = wxLIST_MASK_TEXT;
+ info.m_itemId = le.m_itemIndex;
+ info.m_text = m_renameRes;
+ info.SetTextColour(le.m_item.GetTextColour());
+ SetItem( info );
+}
+
+void wxListMainWindow::OnMouse( wxMouseEvent &event )
+{
+ event.SetEventObject( GetParent() );
+ if (GetParent()->GetEventHandler()->ProcessEvent( event)) return;
+
+ if (!m_current) return;
+ if (m_dirty) return;
+ if ( !(event.Dragging() || event.ButtonDown() || event.LeftUp() || event.ButtonDClick()) ) return;
+
+ int x = event.GetX();
+ int y = event.GetY();
+ CalcUnscrolledPosition( x, y, &x, &y );
+
+ /* Did we actually hit an item ? */
+ long hitResult = 0;
+ wxListLineData *line = (wxListLineData *) NULL;
+ for (size_t i = 0; i < m_lines.GetCount(); i++)
+ {
+ line = &m_lines[i];
+ hitResult = line->IsHit( x, y );
+ if (hitResult) break;
+ line = (wxListLineData *) NULL;
+ }
+
+ if (event.Dragging())
+ {
+ if (m_dragCount == 0)
+ m_dragStart = wxPoint(x,y);
+
+ m_dragCount++;
+
+ if (m_dragCount != 3) return;
+
+ int command = event.RightIsDown() ? wxEVT_COMMAND_LIST_BEGIN_RDRAG
+ : wxEVT_COMMAND_LIST_BEGIN_DRAG;
+
+ wxListEvent le( command, GetParent()->GetId() );
+ le.SetEventObject( GetParent() );
+ le.m_pointDrag = m_dragStart;
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+
+ return;
+ }
+ else
+ {
+ m_dragCount = 0;
+ }
+
+ if (!line) return;
+
+ bool forceClick = FALSE;
+ if (event.ButtonDClick())
+ {
+ m_renameTimer->Stop();
+ m_lastOnSame = FALSE;
+
+ if ( line == m_lineBeforeLastClicked )
+ {
+ m_usedKeys = FALSE;
+
+ SendNotify( line, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
+
+ return;
+ }
+ else
+ {
+ // the first click was on another item, so don't interpret this as
+ // a double click, but as a simple click instead
+ forceClick = TRUE;
+ }
+ }
+
+ if (event.LeftUp() && m_lastOnSame)
+ {
+ m_usedKeys = FALSE;
+ if ((line == m_current) &&
+ (hitResult == wxLIST_HITTEST_ONITEMLABEL) &&
+ (m_mode & wxLC_EDIT_LABELS) )
+ {
+ m_renameTimer->Start( 100, TRUE );
+ }
+ m_lastOnSame = FALSE;
+ return;
+ }
+
+ if (event.RightDown())
+ {
+ SendNotify( line, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK,
+ event.GetPosition() );
+ return;
+ }
+
+ if (event.MiddleDown())
+ {
+ SendNotify( line, wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK );
+ return;
+ }
+
+ if ( event.LeftDown() || forceClick )
+ {
+ m_lineBeforeLastClicked = m_lineLastClicked;
+ m_lineLastClicked = line;
+
+ m_usedKeys = FALSE;
+ wxListLineData *oldCurrent = m_current;
+ if (m_mode & wxLC_SINGLE_SEL)
+ {
+ m_current = line;
+ HilightAll( FALSE );
+ m_current->ReverseHilight();
+ RefreshLine( m_current );
+ }
+ else
+ {
+ if (event.ControlDown())
+ {
+ m_current = line;
+ m_current->ReverseHilight();
+ RefreshLine( m_current );
+ }
+ else if (event.ShiftDown())
+ {
+ size_t j;
+
+ m_current = line;
+
+ int numOfCurrent = -1;
+ for (j = 0; j < m_lines.GetCount(); j++)
+ {
+ wxListLineData *test_line = &m_lines[j];
+ numOfCurrent++;
+ if (test_line == oldCurrent) break;
+ }
+
+ int numOfLine = -1;
+
+ for (j = 0; j < m_lines.GetCount(); j++)
+ {
+ wxListLineData *test_line = &m_lines[j];
+ numOfLine++;
+ if (test_line == line) break;
+ }
+
+ if (numOfLine < numOfCurrent)
+ {
+ int i = numOfLine;
+ numOfLine = numOfCurrent;
+ numOfCurrent = i;
+ }
+
+ for (int i = 0; i <= numOfLine-numOfCurrent; i++)
+ {
+ wxListLineData *test_line= &m_lines[numOfCurrent + i];
+ test_line->Hilight(TRUE);
+ RefreshLine( test_line );
+ }
+ }
+ else
+ {
+ m_current = line;
+ HilightAll( FALSE );
+ m_current->ReverseHilight();
+ RefreshLine( m_current );
+ }
+ }
+ if (m_current != oldCurrent)
+ {
+ RefreshLine( oldCurrent );
+ UnfocusLine( oldCurrent );
+ FocusLine( m_current );
+ }
+
+ // forceClick is only set if the previous click was on another item
+ m_lastOnSame = !forceClick && (m_current == oldCurrent);
+
+ return;
+ }
+}
+
+void wxListMainWindow::MoveToFocus()
+{
+ if (!m_current) return;
+
+ int item_x = 0;
+ int item_y = 0;
+ int item_w = 0;
+ int item_h = 0;
+ m_current->GetExtent( item_x, item_y, item_w, item_h );
+
+ int client_w = 0;
+ int client_h = 0;
+ GetClientSize( &client_w, &client_h );
+
+ int view_x = m_xScroll*GetScrollPos( wxHORIZONTAL );
+ int view_y = m_yScroll*GetScrollPos( wxVERTICAL );
+
+ if (m_mode & wxLC_REPORT)
+ {
+ if (item_y < view_y )
+ Scroll( -1, (item_y)/m_yScroll );
+ if (item_y+item_h+5 > view_y+client_h)
+ Scroll( -1, (item_y+item_h-client_h+15)/m_yScroll );
+ }
+ else
+ {
+ if (item_x-view_x < 5)
+ Scroll( (item_x-5)/m_xScroll, -1 );
+ if (item_x+item_w-5 > view_x+client_w)
+ Scroll( (item_x+item_w-client_w+15)/m_xScroll, -1 );
+ }
+}
+
+void wxListMainWindow::OnArrowChar( wxListLineData *newCurrent, bool shiftDown )
+{
+ if ((m_mode & wxLC_SINGLE_SEL) || (m_usedKeys == FALSE)) m_current->Hilight( FALSE );
+ wxListLineData *oldCurrent = m_current;
+ m_current = newCurrent;
+ if (shiftDown || (m_mode & wxLC_SINGLE_SEL)) m_current->Hilight( TRUE );
+ RefreshLine( m_current );
+ RefreshLine( oldCurrent );
+ FocusLine( m_current );
+ UnfocusLine( oldCurrent );
+ MoveToFocus();
+}
+
+void wxListMainWindow::OnKeyDown( wxKeyEvent &event )
+{
+ wxWindow *parent = GetParent();
+
+ /* we propagate the key event up */
+ wxKeyEvent ke( wxEVT_KEY_DOWN );
+ ke.m_shiftDown = event.m_shiftDown;
+ ke.m_controlDown = event.m_controlDown;
+ ke.m_altDown = event.m_altDown;
+ ke.m_metaDown = event.m_metaDown;
+ ke.m_keyCode = event.m_keyCode;
+ ke.m_x = event.m_x;
+ ke.m_y = event.m_y;
+ ke.SetEventObject( parent );
+ if (parent->GetEventHandler()->ProcessEvent( ke )) return;
+
+ event.Skip();
+}
+
+void wxListMainWindow::OnChar( wxKeyEvent &event )
+{
+ wxWindow *parent = GetParent();
+
+ /* we send a list_key event up */
+ if ( m_current )
+ {
+ wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, GetParent()->GetId() );
+ le.m_itemIndex = GetIndexOfLine( m_current );
+ m_current->GetItem( 0, le.m_item );
+ le.m_code = (int)event.KeyCode();
+ le.SetEventObject( parent );
+ parent->GetEventHandler()->ProcessEvent( le );
+ }
+
+ /* we propagate the char event up */
+ wxKeyEvent ke( wxEVT_CHAR );
+ ke.m_shiftDown = event.m_shiftDown;
+ ke.m_controlDown = event.m_controlDown;
+ ke.m_altDown = event.m_altDown;
+ ke.m_metaDown = event.m_metaDown;
+ ke.m_keyCode = event.m_keyCode;
+ ke.m_x = event.m_x;
+ ke.m_y = event.m_y;
+ ke.SetEventObject( parent );
+ if (parent->GetEventHandler()->ProcessEvent( ke )) return;
+
+ if (event.KeyCode() == WXK_TAB)
+ {
+ wxNavigationKeyEvent nevent;
+ nevent.SetWindowChange( event.ControlDown() );
+ nevent.SetDirection( !event.ShiftDown() );
+ nevent.SetEventObject( GetParent()->GetParent() );
+ nevent.SetCurrentFocus( m_parent );
+ if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent )) return;
+ }
+
+ /* no item -> nothing to do */
+ if (!m_current)
+ {
+ event.Skip();
+ return;
+ }
+
+ switch (event.KeyCode())
+ {
+ case WXK_UP:
+ {
+ int index = m_lines.Index(*m_current);
+ if (index != wxNOT_FOUND && index > 0)
+ OnArrowChar( &m_lines[index-1], event.ShiftDown() );
+ break;
+ }
+ case WXK_DOWN:
+ {
+ int index = m_lines.Index(*m_current);
+ if (index != wxNOT_FOUND && (size_t)index < m_lines.GetCount()-1)
+ OnArrowChar( &m_lines[index+1], event.ShiftDown() );
+ break;
+ }
+ case WXK_END:
+ {
+ if (!m_lines.IsEmpty())
+ OnArrowChar( &m_lines.Last(), event.ShiftDown() );
+ break;
+ }
+ case WXK_HOME:
+ {
+ if (!m_lines.IsEmpty())
+ OnArrowChar( &m_lines[0], event.ShiftDown() );
+ break;
+ }
+ case WXK_PRIOR:
+ {
+ int steps = 0;
+ int index = m_lines.Index(*m_current);
+ if (m_mode & wxLC_REPORT)
+ {
+ steps = m_visibleLines-1;
+ }
+ else
+ {
+ steps = index % m_visibleLines;
+ }
+ if (index != wxNOT_FOUND)
+ {
+ index -= steps;
+ if (index < 0) index = 0;
+ OnArrowChar( &m_lines[index], event.ShiftDown() );
+ }
+ break;
+ }
+ case WXK_NEXT:
+ {
+ int steps = 0;
+ int index = m_lines.Index(*m_current);
+ if (m_mode & wxLC_REPORT)
+ {
+ steps = m_visibleLines-1;
+ }
+ else
+ {
+ steps = m_visibleLines-(index % m_visibleLines)-1;
+ }
+
+ if (index != wxNOT_FOUND)
+ {
+ index += steps;
+ if ((size_t)index >= m_lines.GetCount())
+ index = m_lines.GetCount()-1;
+ OnArrowChar( &m_lines[index], event.ShiftDown() );
+ }
+ break;
+ }
+ case WXK_LEFT:
+ {
+ if (!(m_mode & wxLC_REPORT))
+ {
+ int index = m_lines.Index(*m_current);
+ if (index != wxNOT_FOUND)
+ {
+ index -= m_visibleLines;
+ if (index < 0) index = 0;
+ OnArrowChar( &m_lines[index], event.ShiftDown() );
+ }
+ }
+ break;
+ }
+ case WXK_RIGHT:
+ {
+ if (!(m_mode & wxLC_REPORT))
+ {
+ int index = m_lines.Index(*m_current);
+ if (index != wxNOT_FOUND)
+ {
+ index += m_visibleLines;
+ if ((size_t)index >= m_lines.GetCount())
+ index = m_lines.GetCount()-1;
+ OnArrowChar( &m_lines[index], event.ShiftDown() );
+ }
+ }
+ break;
+ }
+ case WXK_SPACE:
+ {
+ if (m_mode & wxLC_SINGLE_SEL)
+ {
+ wxListEvent le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, GetParent()->GetId() );
+ le.SetEventObject( GetParent() );
+ le.m_itemIndex = GetIndexOfLine( m_current );
+ m_current->GetItem( 0, le.m_item );
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+ }
+ else
+ {
+ m_current->ReverseHilight();
+ RefreshLine( m_current );
+ }
+ break;
+ }
+ case WXK_INSERT:
+ {
+ if (!(m_mode & wxLC_SINGLE_SEL))
+ {
+ wxListLineData *oldCurrent = m_current;
+ m_current->ReverseHilight();
+ int index = m_lines.Index( *m_current ) + 1;
+ if ( (size_t)index < m_lines.GetCount() )
+ m_current = &m_lines[index];
+ RefreshLine( oldCurrent );
+ RefreshLine( m_current );
+ UnfocusLine( oldCurrent );
+ FocusLine( m_current );
+ MoveToFocus();
+ }
+ break;
+ }
+ case WXK_RETURN:
+ case WXK_EXECUTE:
+ {
+ wxListEvent le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, GetParent()->GetId() );
+ le.SetEventObject( GetParent() );
+ le.m_itemIndex = GetIndexOfLine( m_current );
+ m_current->GetItem( 0, le.m_item );
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+ break;
+ }
+ default:
+ {
+ event.Skip();
+ return;
+ }
+ }
+ m_usedKeys = TRUE;
+}
+
+#ifdef __WXGTK__
+extern wxWindow *g_focusWindow;
+#endif
+
+void wxListMainWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
+{
+ m_hasFocus = TRUE;
+ RefreshLine( m_current );
+
+ if (!GetParent()) return;
+
+#ifdef __WXGTK__
+ g_focusWindow = GetParent();
+#endif
+
+ wxFocusEvent event( wxEVT_SET_FOCUS, GetParent()->GetId() );
+ event.SetEventObject( GetParent() );
+ GetParent()->GetEventHandler()->ProcessEvent( event );
+}
+
+void wxListMainWindow::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
+{
+ m_hasFocus = FALSE;
+ RefreshLine( m_current );
+}
+
+void wxListMainWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
+{