Recent

Author Topic: Bug? Missing something?  (Read 358 times)

kpeters58

  • Sr. Member
  • ****
  • Posts: 267
Bug? Missing something?
« on: October 07, 2019, 07:31:34 pm »
I have a form with 2 listboxes on it side by side and a button.
The button invokes MoveAllListBoxItems(LeftListbox, RightListbox).


The copy processs only copies the first four, but not the last item from left to right even though I have issued a SelectAll.

Is this a bug or am I missing something?


And since I am here: Could I safely use DeleteSelected rather than the deletion loop since the attached objects are only simple integers?


Thanks for any help!


Code: Pascal  [Select][+][-]
  1. procedure Tform_NotifyRecipients.MoveListBoxItems(SourceListbox, DestinationListbox: TListBox);
  2. var
  3.   i: Integer;
  4.  
  5. begin
  6.   if (SourceListbox.SelCount = 0) then
  7.     Exit;
  8.   try
  9.     // gain some speed
  10.     SourceListbox.Items.BeginUpdate;
  11.     DestinationListbox.Items.BeginUpdate;
  12.     DestinationListbox.Sorted := False;
  13.     //
  14.     // add selected items to the destination listbox
  15.     for i := 0 to Pred(SourceListbox.Count) do
  16.       if SourceListbox.Selected[i] then
  17.       begin
  18.         Showmessage('in: ' + SourceListbox.Items[i]);
  19.         DestinationListbox.Items.AddObject(SourceListbox.Items[i], TObject(11));
  20.       end
  21.       else
  22.         Showmessage('out: ' + SourceListbox.Items[i]);
  23.     //
  24.     // now delete them from the source listbox
  25.     for i := Pred(SourceListbox.Count) downto 0 do       // need to scan from the back because of the deletions
  26.       if SourceListbox.Selected[i] then
  27.       begin
  28.         if Assigned(SourceListbox.Items.Objects[i]) then // unhook the stored id - necessary? use DeleteSelected instead?
  29.           SourceListbox.Items.Objects[i] := nil;
  30.         //
  31.         SourceListbox.Items.Delete(i);
  32.       end;
  33.   finally
  34.     DestinationListbox.Sorted := True;
  35.     SourceListbox.Items.EndUpdate;
  36.     DestinationListbox.Items.EndUpdate;
  37.     //
  38.     UpdateToolbarsAndCounts();
  39.   end;
  40. end;
  41.  
  42. procedure Tform_NotifyRecipients.LoadListboxes();
  43. begin
  44.   // test data
  45.   listbox_AvailableUsers.Items.AddObject('First item',  TObject(1402));
  46.   listbox_AvailableUsers.Items.AddObject('Second item', TObject(2205));
  47.   listbox_AvailableUsers.Items.AddObject('Third item',  TObject(507));
  48.   listbox_AvailableUsers.Items.AddObject('Fourth item', TObject(2202));
  49.   listbox_AvailableUsers.Items.AddObject('Last One',    TObject(177));
  50.   //
  51. end;
  52.  
  53. procedure Tform_NotifyRecipients.MoveAllListBoxItems(SourceListbox, DestinationListbox: TListBox);
  54. var
  55.   flagM: Boolean;
  56.   flagE: Boolean;
  57.  
  58. begin
  59.   try
  60.     flagE := SourceListbox.ExtendedSelect;
  61.     flagM := SourceListbox.MultiSelect;
  62.     SourceListbox.MultiSelect    := True;
  63.     SourceListbox.ExtendedSelect := True;
  64.     SourceListbox.SelectAll;
  65.     MoveListBoxItems(SourceListbox, DestinationListbox);
  66.   finally
  67.     SourceListbox.ExtendedSelect := flagE;
  68.     SourceListbox.MultiSelect    := flagM;
  69.   end;
  70. end;  
Lazarus 2.0.4/FPC 3.0.4/Win 64

howardpc

  • Hero Member
  • *****
  • Posts: 3549
Re: Bug? Missing something?
« Reply #1 on: October 07, 2019, 08:02:47 pm »
Code: Pascal  [Select][+][-]
  1. procedure TNotifyRecipientsForm.MoveAllListBoxItems(sourceLB, destinationLB: TListBox);
  2. begin
  3.   destinationLB.Items.Assign(sourceLB.Items);
  4.   sourceLB.Items.Clear;
  5. end;

kpeters58

  • Sr. Member
  • ****
  • Posts: 267
Re: Bug? Missing something?
« Reply #2 on: October 07, 2019, 08:16:34 pm »
Thanks - while this certainly works, it does not answer the question.

And, as often, there is more to the story: I use the same code if one or multiple items are selected - just without the prior SelectAll
Lazarus 2.0.4/FPC 3.0.4/Win 64

howardpc

  • Hero Member
  • *****
  • Posts: 3549
Re: Bug? Missing something?
« Reply #3 on: October 07, 2019, 09:01:08 pm »
Code: Pascal  [Select][+][-]
  1. procedure TNotifyRecipientsForm.MoveSelectedItems(sourceLB, destinationLB: TListBox);
  2. var
  3.   i: Integer;
  4. begin
  5.   if not sourceLB.MultiSelect then
  6.     Exit;
  7.   // destinationLB.Clear; you might want this, I don't know
  8.   for i := sourceLB.Items.Count-1 downto 0 do
  9.     if sourceLB.Selected[i] then
  10.       begin
  11.         destinationLB.Items.AddObject(sourceLB.Items[i], sourceLB.Items.Objects[i]);
  12.         sourceLB.Items.Delete(i);
  13.       end;
  14. end;
You can delete listbox items which don't have instantiated objects attached (such as integers cast to TObject) without needing to worry about freeing the attached object(s), since there are no attached objects, just integers masquerading as pointers to object instances.
« Last Edit: October 07, 2019, 09:03:39 pm by howardpc »

Fungus

  • Sr. Member
  • ****
  • Posts: 352
Re: Bug? Missing something?
« Reply #4 on: October 07, 2019, 09:03:07 pm »
Try something like this:

Code: Pascal  [Select][+][-]
  1. //I: Integer;
  2.  
  3. I:= 0;
  4. while I < Source.Items.Count do begin
  5.   if Source.Selected[I] then begin
  6.     Destination.Items.AddObject(Source.Items[I], Source.Items.Objects[I]);
  7.     Source.Items.Delete(i);
  8.   end else Inc(I);
  9. end;

 

TinyPortal © 2005-2018