]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/listctrl.cpp
calling insert("") would provoke an assert - now it's just ignored
[wxWidgets.git] / src / generic / listctrl.cpp
index 13075f33dfa3e4c2d3fd28ad7ad33b82ceb0d69b..84e0770e144deb81ba1e0cc8178edb89373b7ef4 100644 (file)
@@ -439,7 +439,7 @@ long wxListLineData::IsHit( int x, int y )
     wxListItemData *item = (wxListItemData*)node->Data();
     if (item->HasImage() && IsInRect( x, y, m_bound_icon )) return wxLIST_HITTEST_ONITEMICON;
     if (item->HasText() && IsInRect( x, y, m_bound_label )) return wxLIST_HITTEST_ONITEMLABEL;
-    if (!(item->HasImage() || item->HasText())) return 0;
+//    if (!(item->HasImage() || item->HasText())) return 0;
   };
   // if there is no icon or text = empty
   if (IsInRect( x, y, m_bound_all )) return wxLIST_HITTEST_ONITEMICON;
@@ -770,6 +770,59 @@ void wxListRenameTimer::Notify()
   m_owner->OnRenameTimer();
 };
 
+//-----------------------------------------------------------------------------
+// wxListTextCtrl (internal)
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl,wxTextCtrl);
+    
+BEGIN_EVENT_TABLE(wxListTextCtrl,wxTextCtrl)
+  EVT_CHAR           (wxListTextCtrl::OnChar)
+  EVT_KILL_FOCUS     (wxListTextCtrl::OnKillFocus)
+END_EVENT_TABLE()
+
+wxListTextCtrl::wxListTextCtrl( wxWindow *parent, const wxWindowID id, 
+    bool *accept, wxString *res, wxListMainWindow *owner,
+    const wxString &value, const wxPoint &pos, const wxSize &size,
+    int style, const wxValidator& validator, const wxString &name ) :
+  wxTextCtrl( parent, id, value, pos, size, style, validator, name )
+{
+  m_res = res;
+  m_accept = accept;
+  m_owner = owner;
+}
+
+void wxListTextCtrl::OnChar( wxKeyEvent &event )
+{
+  if (event.m_keyCode == WXK_RETURN)
+  {
+    (*m_accept) = TRUE;
+    (*m_res) = GetValue();
+    m_owner->OnRenameAccept();
+//  Show( FALSE );
+    Destroy();
+    return;
+  }
+  if (event.m_keyCode == WXK_ESCAPE)
+  { 
+    (*m_accept) = FALSE;
+    (*m_res) = "";
+//  Show( FALSE );
+    Destroy();
+    return;
+  }
+  event.Skip();
+}
+
+void wxListTextCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) )
+{
+  (*m_accept) = FALSE;
+  (*m_res) = "";
+//   Show( FALSE );
+   Destroy();
+   return;
+}
+
 //-----------------------------------------------------------------------------
 //  wxListMainWindow
 //-----------------------------------------------------------------------------
@@ -804,9 +857,10 @@ wxListMainWindow::wxListMainWindow( void )
   m_hasFocus = FALSE;
   m_usedKeys = TRUE;
   m_lastOnSame = FALSE;
-//  m_renameTimer = new wxRenameTimer( this );
+//  m_renameTimer = new wxListRenameTimer( this );
+  m_renameTimer = NULL;
   m_isCreated = FALSE;
-  m_isDragging = FALSE;
+  m_dragCount = 0;
 };
 
 wxListMainWindow::wxListMainWindow( wxWindow *parent, wxWindowID id, 
@@ -828,7 +882,7 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent, wxWindowID id,
 //  AllowDoubleClick( TRUE );
   m_myFont = wxNORMAL_FONT;
   m_hasFocus = FALSE;
-  m_isDragging = FALSE;
+  m_dragCount = 0;
   m_isCreated = FALSE;
   wxSize sz = size;
   sz.y = 25;
@@ -853,11 +907,6 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent, wxWindowID id,
 //  m_text->Show( FALSE );
 
   SetBackgroundColour( *wxWHITE );
-  
-/*
-  char *accepted_drop_types[] = { "text/plain" };
-  gtk_widget_dnd_drag_set( m_wxwindow, TRUE, accepted_drop_types, 1 );
-*/  
 };
 
 wxListMainWindow::~wxListMainWindow( void )
@@ -977,9 +1026,17 @@ void wxListMainWindow::DeleteLine( wxListLineData *line )
   SendNotify( line, wxEVT_COMMAND_LIST_DELETE_ITEM );
 };
 
+void wxListMainWindow::StartLabelEdit( wxListLineData *line )
+{
+  SendNotify( line, wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT );
+};
+
 void wxListMainWindow::RenameLine( wxListLineData *line, const wxString &newName )
 {
-  wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT );
+  if (!m_parent) return;
+  
+  wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT, m_parent->GetId() );
+  le.SetEventObject( m_parent );
   le.m_code = 0;
   le.m_itemIndex = GetIndexOfLine( line );
   le.m_col = 0;
@@ -990,7 +1047,7 @@ void wxListMainWindow::RenameLine( wxListLineData *line, const wxString &newName
 
 void wxListMainWindow::OnRenameTimer()
 {
-  return;
+  StartLabelEdit( m_current );
   wxString s;
   m_current->GetText( 0, s );
   int x = 0;
@@ -998,16 +1055,15 @@ void wxListMainWindow::OnRenameTimer()
   int w = 0;
   int h = 0;
   m_current->GetLabelExtent( x, y, w, h );
-  int dx = 0;
-  int dy = 0;
-  GetPosition( &dx, &dy );
-  x += dx;
-  y += dy;
-/*
-  wxRawListTextCtrl *text = new wxRawListTextCtrl( 
-    GetParent(), s, &m_renameAccept, &m_renameRes, this, x+2, y+2, w+8, h+8 );
+  
+  wxClientDC dc(this);
+  PrepareDC( dc );
+  x = dc.LogicalToDeviceX( x );
+  y = dc.LogicalToDeviceY( y );
+  
+  wxListTextCtrl *text = new wxListTextCtrl( 
+    this, -1, &m_renameAccept, &m_renameRes, this, s, wxPoint(x-4,y-4), wxSize(w+11,h+8) );
   text->SetFocus();
-*/
 /*
   m_text->SetSize( x+3, y+3, w+6, h+6 );
   m_text->SetValue( s );
@@ -1015,7 +1071,7 @@ void wxListMainWindow::OnRenameTimer()
   m_text->SetFocus();
 */
 /*
-  char *res = wxGetTextFromUser( "Enter new name:", "", s );
+  char *res = wxGetTextFromUser( _("Enter new name:"), "", s );
   if (res)
   {
     m_dirty = TRUE;
@@ -1032,9 +1088,10 @@ void wxListMainWindow::OnRenameAccept()
 
 void wxListMainWindow::OnMouse( wxMouseEvent &event )
 {
+  if (m_parent->ProcessEvent( event)) return;
+
   if (!m_current) return;
   if (m_dirty) return;
-//  wxDragCanvas::OnEvent( event );
 
   wxClientDC dc(this);
   PrepareDC(dc);
@@ -1053,11 +1110,14 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
     node = node->Next();
   };
   
-  if (!event.Dragging()) m_isDragging = FALSE;
+  if (!event.Dragging())
+    m_dragCount = 0;
+  else
+    m_dragCount++;
   
-  if (event.Dragging() && (!m_isDragging))
+  if (event.Dragging() && (m_dragCount > 3))
   {
-    m_isDragging = TRUE;
+    m_dragCount = 0;
     wxListEvent le( wxEVT_COMMAND_LIST_BEGIN_DRAG, m_parent->GetId() );
     le.SetEventObject( this );
     le.m_code = 0;
@@ -1084,7 +1144,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
         (hitResult == wxLIST_HITTEST_ONITEMLABEL) /* && 
        (m_mode & wxLC_ICON) */  )
     {
-      m_renameTimer->Start( 330, TRUE );
+      m_renameTimer->Start( 100, TRUE );
     };
     m_lastOnSame = FALSE;
     return;
@@ -1094,15 +1154,67 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
   {
     m_usedKeys = FALSE;
     wxListLineData *oldCurrent = m_current;
-    m_current = line;
-    if (!event.ShiftDown() || (m_mode & wxLC_SINGLE_SEL)) HilightAll( FALSE );
-    m_current->ReverseHilight();
-    RefreshLine( m_current );
+    if (m_mode & wxLC_SINGLE_SEL)
+    {
+      m_current = line;
+      HilightAll( FALSE );
+      m_current->ReverseHilight();
+      RefreshLine( m_current );
+    }
+    else
+    {
+      if (event.ShiftDown())
+      {
+        m_current = line;
+        m_current->ReverseHilight();
+        RefreshLine( m_current );
+      }
+      else if (event.ControlDown())
+      {
+        m_current = line;
+        int numOfCurrent = -1;
+        node = m_lines.First();
+        while (node)
+        {
+          wxListLineData *test_line = (wxListLineData*)node->Data();
+         numOfCurrent++;
+         if (test_line == oldCurrent) break;
+          node = node->Next();
+        };
+        int numOfLine = -1;
+        node = m_lines.First();
+        while (node)
+        {
+          wxListLineData *test_line = (wxListLineData*)node->Data();
+         numOfLine++;
+         if (test_line == line) break;
+          node = node->Next();
+        };
+       
+       if (numOfLine < numOfCurrent) 
+         { int i = numOfLine; numOfLine = numOfCurrent; numOfCurrent = i; }
+       wxNode *node = m_lines.Nth( numOfCurrent );
+       for (int i = 0; i <= numOfLine-numOfCurrent; i++)
+       {
+         wxListLineData *test_line= (wxListLineData*)node->Data();
+         test_line->Hilight(TRUE);
+         RefreshLine( test_line );
+         node = node->Next();
+       }
+      }
+      else 
+      {
+        m_current = line;
+        HilightAll( FALSE );
+        m_current->ReverseHilight();
+        RefreshLine( m_current );
+      }
+    }
     if (m_current != oldCurrent)
     {
+      RefreshLine( oldCurrent );
       UnfocusLine( oldCurrent );
       FocusLine( m_current );
-      RefreshLine( oldCurrent );
     };
     m_lastOnSame = (m_current == oldCurrent);
     return;
@@ -1143,15 +1255,15 @@ void wxListMainWindow::MoveToFocus( void )
 
 void wxListMainWindow::OnArrowChar( wxListLineData *newCurrent, bool shiftDown )
 {
-  UnfocusLine( m_current );
   if ((m_mode & wxLC_SINGLE_SEL) || (m_usedKeys == FALSE)) m_current->Hilight( FALSE );
   wxListLineData *oldCurrent = m_current;
   m_current = newCurrent;
   MoveToFocus();
   if (shiftDown || (m_mode & wxLC_SINGLE_SEL)) m_current->Hilight( TRUE );
-  FocusLine( m_current );
   RefreshLine( m_current );
   RefreshLine( oldCurrent );
+  FocusLine( m_current );
+  UnfocusLine( oldCurrent );
 };
 
 void wxListMainWindow::OnChar( wxKeyEvent &event )
@@ -1244,19 +1356,25 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
       };
       break;
     };
+    case WXK_SPACE:
+    {
+      m_current->ReverseHilight();
+      RefreshLine( m_current );
+    };
+    break;
     case WXK_INSERT:
     {
       if (!(m_mode & wxLC_SINGLE_SEL))
       {
         wxListLineData *oldCurrent = m_current;
-        UnfocusLine( m_current );
         m_current->ReverseHilight();
         wxNode *node = m_lines.Member( m_current )->Next();       
         if (node) m_current = (wxListLineData*)node->Data();
         MoveToFocus();
-        FocusLine( m_current );
-       RefreshLine( m_current );
        RefreshLine( oldCurrent );
+       RefreshLine( m_current );
+        UnfocusLine( oldCurrent );
+        FocusLine( m_current );
       };
     };
     break;
@@ -1314,12 +1432,12 @@ void wxListMainWindow::DrawImage( int index, wxPaintDC *dc, int x, int y )
 {
   if ((m_mode & wxLC_ICON) && (m_normal_image_list))
   {
-    m_normal_image_list->Draw( index, *dc, x, y );
+    m_normal_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
     return;
   };
   if ((m_mode & wxLC_SMALL_ICON) && (m_small_image_list))
   {
-    m_small_image_list->Draw( index, *dc, x, y );
+    m_small_image_list->Draw( index, *dc, x, y, wxIMAGELIST_DRAW_TRANSPARENT );
   };
 };
 
@@ -1555,6 +1673,25 @@ void wxListMainWindow::GetItemRect( long index, wxRectangle &rect )
   };
 };
 
+bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos)
+{
+  wxNode *node = m_lines.Nth( item );
+  if (node) 
+  {
+    wxRectangle rect;
+    wxListLineData *line = (wxListLineData*)node->Data();
+    line->GetRect( rect );
+    pos.x = rect.x;
+    pos.y = rect.y;
+  }
+  else
+  {
+    pos.x = 0;
+    pos.y = 0;
+  };
+  return TRUE;
+};
+
 int wxListMainWindow::GetSelectedItemCount( void )
 {
   int ret = 0;
@@ -1732,6 +1869,7 @@ void wxListMainWindow::DeleteItem( long index )
   if (node)
   {
     wxListLineData *line = (wxListLineData*)node->Data();
+    if (m_current == line) m_current = NULL;
     DeleteLine( line );
     m_lines.DeleteNode( node );
   };
@@ -1747,6 +1885,7 @@ void wxListMainWindow::DeleteColumn( int col )
 void wxListMainWindow::DeleteAllItems( void )
 {
   m_dirty = TRUE;
+  m_current = NULL;
   wxNode *node = m_lines.First();
   while (node)
   {
@@ -1755,12 +1894,12 @@ void wxListMainWindow::DeleteAllItems( void )
     node = node->Next();
   };
   m_lines.Clear();
-  m_current = NULL;
 };
 
 void wxListMainWindow::DeleteEverything( void )
 {
   m_dirty = TRUE;
+  m_current = NULL;
   wxNode *node = m_lines.First();
   while (node)
   {
@@ -2065,13 +2204,6 @@ void wxListCtrl::SetWindowStyleFlag( long flag )
   wxWindow::SetWindowStyleFlag( flag );
 };
 
-void wxListCtrl::SetBackgroundColour(const wxColour& col)
-{
-  // This is from Julian. You know.
-  // Not in wxWin 1.xx ???
-  wxWindow::SetBackgroundColour( (wxColour&)col );
-};
-
 bool wxListCtrl::GetColumn(int col, wxListItem &item) 
 {
   m_mainWin->GetColumn( col, item );
@@ -2197,9 +2329,10 @@ bool wxListCtrl::GetItemRect( long item, wxRectangle &rect,  int WXUNUSED(code)
   return TRUE;
 };
 
-bool wxListCtrl::GetItemPosition( long WXUNUSED(item), wxPoint& WXUNUSED(pos) ) const
+bool wxListCtrl::GetItemPosition( long item, wxPoint& pos )
 {
-  return 0;
+  m_mainWin->GetItemPosition( item, pos );
+  return TRUE;
 };
 
 bool wxListCtrl::SetItemPosition( long WXUNUSED(item), const wxPoint& WXUNUSED(pos) )
@@ -2212,6 +2345,11 @@ int wxListCtrl::GetItemCount(void)
   return m_mainWin->GetItemCount();
 };
 
+void wxListCtrl::SetItemSpacing( int spacing, bool isSmall )
+{
+  m_mainWin->SetItemSpacing( spacing, isSmall );
+};
+
 int wxListCtrl::GetItemSpacing( bool isSmall )
 {
   return m_mainWin->GetItemSpacing( isSmall );
@@ -2237,7 +2375,7 @@ long wxListCtrl::GetTopItem(void)
   return 0;
 };
 
-long wxListCtrl::GetNextItem( long item, int geom, int state )
+long wxListCtrl::GetNextItem( long item, int geom, int state ) const
 {
   return m_mainWin->GetNextItem( item, geom, state );
 };
@@ -2398,7 +2536,7 @@ bool wxListCtrl::SortItems( wxListCtrlCompare fn, long data )
   return TRUE;
 };
 
-void wxListCtrl::OnIdle( wxIdleEvent &event )
+void wxListCtrl::OnIdle( wxIdleEvent &WXUNUSED(event) )
 {
   if (!m_mainWin->m_dirty) return;