deleting selected items in a wxListCtrl ... BETTER way? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
mac
Earned some good credits
Earned some good credits
Posts: 103
Joined: Sat Jul 22, 2006 3:15 am

deleting selected items in a wxListCtrl ... BETTER way?

Post by mac »

Hi,

I just converted my listbox deleting code to use a listctrl instead and as this is my first time doing this and i just wrote this myself i'm sure it's not as good as somebody else's code out there so i'd like to compare your better solution please :) If you could post code thanks!

here is what i got working now to delete selected items in a wxListCtrl

Code: Select all

void MyFrame::OnBitmapbuttonMinusClick( wxCommandEvent& event )
{
    // if no files do nothing
    if (filez->GetItemCount() == 0)
    {
        //wxMessageBox(_T("none"),_T("none"));
        return;
    }
    
    // if 1 file delete it even if not selected!
    if (filez->GetItemCount() == 1)
    {
        //wxMessageBox(_T("one"),_T("one"));
        filez->DeleteItem(0);
        
        return;
    }
    
    // listctrl delete all selected...doing REVERSE again
    int total_items = filez->GetItemCount();
    int i = 0;
    
    while (total_items > i)
    {
        if (filez->GetItemState((total_items - 1) - i, wxLIST_STATE_SELECTED) == wxLIST_STATE_SELECTED)
        {
            filez->DeleteItem((total_items - 1) - i);
        }
        i++;
    }
    
}
filez is now a wxListCtrl*

I wanted the same functionality as this post http://forums.wxwidgets.org/viewtopic.php?t=13955 but now I'm using a listctrl instead of a listbox.

Thanks. :)
vista 64bit, OS X 10.4.x, OS X 10.3.9 x 2
(virtualization: vista 32bit, MS XP, MS95, MS98, Debian 3.1, Slackware 12, FreeBSD 6.1, a few more)

wx: 2.8.8/9 (unicode)
compilers: gcc (GTK+2, OS X), vc++6(MSW)
Ugly!
Earned some good credits
Earned some good credits
Posts: 113
Joined: Mon May 09, 2005 5:11 am
Location: Argentina - BS AS

Re: deleting selected items in a wxListCtrl ... BETTER way?

Post by Ugly! »

Use wxListView instead of wxListCtrl. It's the same as wxListCtrl but with some easy to use methods.

Code: Select all

void MyFrame::OnBitmapbuttonMinusClick( wxCommandEvent& event )
{
    long index=filez->GetFirstSelected();
    long count=filez->GetItemCount();

    if(count==1)//if there is only one item in the list, deleted even if not selected
    {
         filez->DeleteItem(0);
         return;
    }
    if (index<0) //No item selected or empty list
    {
        return;
    }
    
    //Delete all selected
    while(index>=0)
   {
         filez->DeleteItem(index);
         index=filez->GetNextSelected();
    }
    
    return;
    
}
Hope this helps...

Regards, Mat
Just a newbie - Too many interests, not too many time.

Windows XP SP2
Kubuntu GNU/Linux - Feisty
wxActiveRecordGenerator (aka wxARG) maintainer
Find it at wxCode
howudodat
Knows some wx things
Knows some wx things
Posts: 28
Joined: Tue May 08, 2007 6:09 pm

Post by howudodat »

Also, expecially with listctrls on windows, It's a good idea to disable redrawing while adding or deleting large amounts of items. From window.h call Freeze() and Thaw() when done.

Peter
mac
Earned some good credits
Earned some good credits
Posts: 103
Joined: Sat Jul 22, 2006 3:15 am

Re: deleting selected items in a wxListCtrl ... BETTER way?

Post by mac »

[quote="Ugly!"]Use wxListView instead of wxListCtrl. It's the same as wxListCtrl but with some easy to use methods.

Code: Select all

void MyFrame::OnBitmapbuttonMinusClick( wxCommandEvent& event )
{
    long index=filez->GetFirstSelected();
    long count=filez->GetItemCount();

    if(count==1)//if there is only one item in the list, deleted even if not selected
    {
         filez->DeleteItem(0);
         return;
    }
    if (index<0) //No item selected or empty list
    {
        return;
    }
    
    //Delete all selected
    while(index>=0)
   {
         filez->DeleteItem(index);
         index=filez->GetNextSelected();
    }
    
    return;
    
}
Hope this helps...

Regards, Mat
vista 64bit, OS X 10.4.x, OS X 10.3.9 x 2
(virtualization: vista 32bit, MS XP, MS95, MS98, Debian 3.1, Slackware 12, FreeBSD 6.1, a few more)

wx: 2.8.8/9 (unicode)
compilers: gcc (GTK+2, OS X), vc++6(MSW)
mac
Earned some good credits
Earned some good credits
Posts: 103
Joined: Sat Jul 22, 2006 3:15 am

Post by mac »

howudodat wrote:Also, expecially with listctrls on windows, It's a good idea to disable redrawing while adding or deleting large amounts of items. From window.h call Freeze() and Thaw() when done.

Peter
I just quickly put in like 50 files and then selected and deleted a third with my code and it worked fine. I don't think people will use what i'm making for more than a couple dozen files at a time anyhow. Are you talking about 10,000s of files?
vista 64bit, OS X 10.4.x, OS X 10.3.9 x 2
(virtualization: vista 32bit, MS XP, MS95, MS98, Debian 3.1, Slackware 12, FreeBSD 6.1, a few more)

wx: 2.8.8/9 (unicode)
compilers: gcc (GTK+2, OS X), vc++6(MSW)
howudodat
Knows some wx things
Knows some wx things
Posts: 28
Joined: Tue May 08, 2007 6:09 pm

Post by howudodat »

With listctrls on windows it's just my habit to SetRedraw(FALSE). Without building a quick test app, I would guess you'll notice a difference if you are adding / deleting 1000's of items, or if you were adding/deleting 100's of items with a resort in between.

Peter
mac
Earned some good credits
Earned some good credits
Posts: 103
Joined: Sat Jul 22, 2006 3:15 am

Re: deleting selected items in a wxListCtrl ... BETTER way?

Post by mac »

mac wrote:Hi,

I just converted my listbox deleting code to use a listctrl instead and as this is my first time doing this and i just wrote this myself i'm sure it's not as good as somebody else's code out there so i'd like to compare your better solution please :) If you could post code thanks!

here is what i got working now to delete selected items in a wxListCtrl

Code: Select all

void MyFrame::OnBitmapbuttonMinusClick( wxCommandEvent& event )
{
    // if no files do nothing
    if (filez->GetItemCount() == 0)
    {
        //wxMessageBox(_T("none"),_T("none"));
        return;
    }
    
    // if 1 file delete it even if not selected!
    if (filez->GetItemCount() == 1)
    {
        //wxMessageBox(_T("one"),_T("one"));
        filez->DeleteItem(0);
        
        return;
    }
    
    // listctrl delete all selected...doing REVERSE again
    int total_items = filez->GetItemCount();
    int i = 0;
    
    while (total_items > i)
    {
        if (filez->GetItemState((total_items - 1) - i, wxLIST_STATE_SELECTED) == wxLIST_STATE_SELECTED)
        {
            filez->DeleteItem((total_items - 1) - i);
        }
        i++;
    }
    
}
filez is now a wxListCtrl*

I wanted the same functionality as this post http://forums.wxwidgets.org/viewtopic.php?t=13955 but now I'm using a listctrl instead of a listbox.

Thanks. :)
Well when I posted this I only wrote it and tested it on XP now I've just checked it and I had to include the imaglist.h for my slackware for it to work...but it DOES NOT work on OS X ppc 10.4.9 =/

??

edit: fixed it :p

I replaced my while loop with basically the sample in the wx help on wxListCtrl::GetNextItem and it works in mac os x now too

Code: Select all

    long item = -1;
    for (;;)
    {
        item = filez->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
        
        if (item == -1)
            break;
            
        filez->DeleteItem(item);
    }
edit 2:
=/

theres a bug in the wx sample code sometimes it leaves a selected item and doesnt delete it...?!

I shouldn't have accepted this yet. *sigh*

edit 3 =)

I'm done with this screw it...

Code: Select all

void MyFrame::OnBitmapbuttonMinusClick( wxCommandEvent& event )
{
    // if no files do nothing
    if (filez->GetItemCount() == 0)
    {
        //wxMessageBox(_T("none"),_T("none"));
        return;
    }
    
    // if 1 file delete it even if not selected!
    if (filez->GetItemCount() == 1)
    {
        //wxMessageBox(_T("one"),_T("one"));
        filez->DeleteItem(0);
        
        return;
    }
    
    // listctrl delete all selected ----------------
#ifdef __WXMAC__    
    // ugly mac fix o.o'
    long item = -1;
    for(;;)
    {
        item = filez->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
        
        if (item == -1)
            break;
            
        filez->DeleteItem(item);
    }
    
    item = -1;
    
    for(;;)
    {
        item = filez->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
        
        if (item == -1)
            break;
            
        filez->DeleteItem(item);
    }
#else
    int total_items = filez->GetItemCount();
    int i = 0;
    
    while (total_items > i)
    {
        if (filez->GetItemState((total_items - 1) - i, wxLIST_STATE_SELECTED) == wxLIST_STATE_SELECTED)
        {
            filez->DeleteItem((total_items - 1) - i);
        }
        i++;
    }
#endif
    // -----------------------------------------
}
This works in linux, msw, and mac ... I know its ugly to repeat code and use #ifdef but the mac one when selecting multiple files to remove would sometimes keep one so this above code works and fixes that I spent too much time on this already :/
vista 64bit, OS X 10.4.x, OS X 10.3.9 x 2
(virtualization: vista 32bit, MS XP, MS95, MS98, Debian 3.1, Slackware 12, FreeBSD 6.1, a few more)

wx: 2.8.8/9 (unicode)
compilers: gcc (GTK+2, OS X), vc++6(MSW)
spartygw
Knows some wx things
Knows some wx things
Posts: 37
Joined: Mon Jul 07, 2008 4:19 pm
Location: georgia, usa

Post by spartygw »

Thanks for following up your posts as you discovered more to your solution. It helps those of us who search the history for similar problems.

-gw
Post Reply