View Issue Details

IDProjectCategoryView StatusLast Update
0016816LazarusWidgetsetpublic2020-06-06 20:30
ReporterLeo Kijzers Assigned ToLuiz Americo  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
PlatformWindows 32 XPOSXP 
Summary0016816: TComboBox : Select items with different case like "a" and "A" is not possible
DescriptionTComboBox Select items with different case like "a" and "A" is not possible
Steps To Reproduceput a ComboBox on a Form, add items to the Combobox like
A
a
pet
Pet
pEt
a.s.o and try to select A, you get a, or pEt you get pet,
you always get the first item which is equal except for the case
p.s selecting between a and a works fine
TagsNo tags attached.
Fixed in Revision34100
LazTarget1.0
WidgetsetWin32/Win64
Attached Files

Relationships

related to 0020846 closedLuiz Americo Wrong TComboBox.ItemIndex in EditingDone when list has duplicates 
related to 0016412 closedZeljan Rikalo Cannot change lazarus directory 
related to 0020056 closedMartin Friebe DropDown, impossible to enter certain values, due to autoselect of existing entries 

Activities

Bart Broersma

2010-06-30 15:10

developer   ~0038891

OK, this seems to be a win32 issue.

Say the combox is filled like this
aaa
Aaa
ccc

If you first select 'aaa' from the dropdownlist and then 'Aaa' in win32 the following methods of TCustomComboBox get called:

//Select 'aaa'
TCustomComboBox.GetItemIndex: Result = 0
TCustomComboBox.RealSetText: Avalue = aaa I = 0
TCustomComboBox.SetItemIndex: Val = 0
TCustomComboBox.GetItemIndex: Result = 0

//Select 'Aaa'
TCustomComboBox.GetItemIndex: Result = 1
TCustomComboBox.RealSetText: Avalue = Aaa I = 0
  ^^ Here things screw up.
  RealSetText does I := FItems.IndexOf(Value) and IndexOf is case_in_sensitive.
  This value is then passed to SetItemIndex as you can see:
TCustomComboBox.SetItemIndex: Val = 0
TCustomComboBox.GetItemIndex: Result = 1

On Linux, selecting an item from the dropdownlist does not call the consecutive
GetItemIndex->RealSetText->SetItemIndex that occur on win32.

Bart Broersma

2010-06-30 16:30

developer   ~0038892

Last edited: 2010-07-01 09:51

Changing RealSetText to be case-sensitive (when possible) whilst setting ItemIndex may resolve the issue:

procedure TCustomComboBox.RealSetText(const AValue: TCaption);
var
  I,J: integer;
begin
  //Must be case sensitive, because Items may have strings that only differ by case
  //Find first CaseInSesitive occurrence)
  I := 0;
  While (I < FItems.Count) and (CompareText(FItems.Strings[I],AValue) <> 0) do Inc(I);
  //Check if there is a CaseSensitve occurence after this one
  J := I;
  While (J < FItems.Count) and (CompareStr(FItems.Strings[J],AValue) <> 0) do Inc(J);
  if (J < FItems.Count) then I := J;
  if (I = FItems.Count) then I := -1;
  if I >= 0 then
    ItemIndex := I
  else if (not (csLoading in ComponentState)) then
    ItemIndex := -1;
  inherited;
end;

(diff attached)


NB. Even if RealSetText isn't the root cause of this bug, it still makes sense to make RealSetText behave case-sensitive when setting ItemIndex.

2010-06-30 16:32

 

customcombobox.inc.realsettext-casesensitive.diff (975 bytes)   
Index: customcombobox.inc
===================================================================
--- customcombobox.inc	(revision 25303)
+++ customcombobox.inc	(working copy)
@@ -917,9 +917,17 @@
  ------------------------------------------------------------------------------}
 procedure TCustomComboBox.RealSetText(const AValue: TCaption);
 var
-  I: integer;
+  I,J: integer;
 begin
-  I := FItems.IndexOf(AValue);
+  //Must be case sensitive, because Items may have strings that only differ by case
+  //Find first CaseInSesitive occurrence)
+  I := 0;
+  While (I < FItems.Count) and (CompareText(FItems.Strings[I],AValue) <> 0) do Inc(I);
+  //Check if there is a CaseSensitve occurence after this one
+  J := I;
+  While (J < FItems.Count) and (CompareStr(FItems.Strings[J],AValue) <> 0) do Inc(J);
+  if (J < FItems.Count) then I := J;
+  if (I = FItems.Count) then I := -1;
   if I >= 0 then
     ItemIndex := I
   else if (not (csLoading in ComponentState)) then

Bart Broersma

2010-07-14 13:04

developer   ~0039320

B.t.w. Shouldn't the bug's category be LCL (or possibly widgetset) instead of FCL?

Martin Friebe

2010-10-04 00:39

manager   ~0041467

I haven't fully tested how it works in Delphi. But Delphi is also partly case-insensitiv. Delphi seems to auto-complete from the list. eg if you have
abc
A23

and type "A" delphi selects "Abc" (first entry with "a" never mind the case)

Also if a user would *type*[1] "ABc" in the above example, the current behaviour is to set the itemindex to the first match. Breaking that may break existing apps, and would be in many cases causing inconveniences if the user selects an item that way. (I haven't checked if the patch would cause that, but it may?)

[1] Types on the keyboard. A selection from the dropdown must still result in the right item being selected. So selecting "Aaa" and getting "aaa" is still a bug.

Therefore if the patch fails the example of typing, it may not be the correct patch?

Bart Broersma

2010-10-04 19:30

developer   ~0041487

I can only test in Delphi 3 (which is kind of old)

Observed behaviour then:

Style = csDropDownList
Type in control: selects items case sensitive (first character only)
So if i type 'A', it will select A23, if I type 'a', it will select 'abc'.
ItemIndex is updated accordingly.
Set Text: does not seem to alter the text at all. ItemIndex does not change.
Set ItemIndex: Text does not change

Style = csDropDown
Type in control: nothing happens to text typed, ItemIndex is not changed if you type a text that matches an item.
Set Text: text is set, ItemIndex does not change, not even if a match is there
Set ItemIndex: nothing happens, text remains unaltered.

Possibly we are looking it in the wrong way. Why is there a call to RealSetText() in windows if user selects an item from the list, while this does not happen in Linux?

Bart Broersma

2010-12-25 23:53

developer   ~0044589

@Martin

As you can see I cannot reproduce the behaviour you described in note 41467 (probably due to my Delphi version).
I also cannot reproduce this behaviour in Lazarus/Linux/GTK2 b.t.w., but maybe the behaviour you described is typically for Windows, not for GTK2.

Can you attach (or put somewhere on the web) a Delphi compiled example that shows the behaviour you described, preferrably with a list of items where some items only differ by case (and it should run on Win9x preferrably).
If this behaviour depends on the state of AutoComplete, ArrowKeysTravers, AutoSelect or TComboBox.Style, please make them configurable at runtime.

Bart Broersma

2011-07-26 14:40

developer   ~0050178

The issue seems to have been fixed in the mean time.
On my system (Lazarus 0.9.31 r31484M FPC 2.4.4 i386-win32-win32/win64) I cannot reproduce it anymore.

If you select an item from the dropdownlist, RealSetText is not called anymore.

Can you test and report back?

Leo Kijzers

2011-07-28 15:18

reporter   ~0050237

Hi, I tested it with Lazarus 0.9.31 FPC 2.4.5 SVN 31813 Win32 on a XP: it still fails to select with the mouse the corect item, showing always the first in the list after closing, equal but with different case and with Style=csDropDown; with Style=csDropDownList it works fine.

Bart Broersma

2011-07-29 14:07

developer   ~0050264

Yes, you are right.
With Style = csDropDown, after selecting RealSetText is called.

Given the comments of Martin (note 0041467) we really need to know how Delphi behaves.

Give the following setup:

ComboBox items:
aaa
Aaa
aba
abc
bbb

AutoComplete := false;

At startup and at before evry next step in the test set ItemIndex to -1 and clear the text

What happens if when

- In combobox type 'A' (without quotes)
- In combobox type 'aaa'
- In combobox type 'ab'
- Programatticaly set ComboBox.Text to 'Aaa'

Of all these action, what is the effect on ItemIndex and Text that is displayed in the combobox.
Do this for Style = csDropDow, csDropDownList and csSimple

Repeat this with AutoComplete := True


Current Lazarus behaviour (Lazarus 0.9.31 r31810M FPC 2.4.4 i386-win32-win32/win64)

Style = csDropDown and Style = csSimple (same behaviour)

- In combobox type 'A' (without quotes)
-> Text = 'A', ItemIndex = -1

- In combobox type 'aaa'
-> Text = 'aaa', ItemIndex = -1

- In combobox type 'ab'
-> Text = 'ab', ItemIndex = -1

- Programatticaly set ComboBox.Text to 'Aaa'
-> Text = 'Aaa', ItemIndex = 0 (this is internally inconsistent)



With AutoComplete the behaviour becomes erratic with Style = csDropDown or Stle = csSimple.
If, in the empty combobox I type 'a', text becomes 'abc', ItemIndex = -1.




Style = csDropDownList

- In combobox type 'A' (without quotes)
-> Text = 'Aaa', ItemIndex = 0

- In combobox type 'aaa'
-> Text = 'aba', ItemIndex = 2 (Third item starting with an 'a')

- In combobox type 'ab'
-> Text = 'bbb', ItemIndex = 4 (Firts item starting with 'b')

- Programatticaly set ComboBox.Text to 'Aaa'
-> Text = 'aaa', ItemIndex = 0

AutoComplete has no effect when Style = csDropDownList (which seems logical to me)

I have no recent Delphi version available, so I cannot test this.

Leo Kijzers

2011-07-31 21:40

reporter   ~0050318

Hi I tested it with Delphi 6.0 (Build 6.240) Update Pack 2) Personal Edition.
I obtained the following results.

  AutoComplete=false; both Style=csDropDown and csSimple
-1, A / -1, aaa / -1, ab / Prog Aaa (Aaa). no OnChange.
                           After focus and defocus OnExit. -1. Aaa

  AutoComplete=true; both Style=csDropDown and csSimple;
0, Aaa write A, Auto to Aaa. [ItemIndex is WRONG]
0, aaa
2, aba write ab, Auto to aba
Prog Aaa (Aaa). no OnChange.
                After focus and defocus OnExit. -1. Aaa

  AutoComplete=false or true; Style=csDropDownList
Only the first character of an item is possible for selection.
You loop through all items starting with the character (case not important)
you keep pressing and stop at the item you want.
The Itemindex is the correct one.

  I converted the program I used to lazarus

  AutoComplete=false; both Style=csDropDown and csSimple
All the same except : Prog Aaa (Aaa). no OnChange.
                      After focus and defocus OnExit. 0. Aaa

  AutoComplete=true; both Style=csDropDown and csSimple;
0, aaa write A, Auto to aaa. OnChange -1, A
             if defocus then OnExit = 0, aaa
0, aaa OnChange 0,aaa after defocus OnExit -1, aaa
2, aba write ab, auto to aba. OnChange 0, ab
             if defocus then OnExit = 2, aba
Prog Aaa (Aaa). no OnChange.
                After focus and defocus OnExit. 0. Aaa

  AutoComplete=false or true; Style=csDropDownList
Only the first character of an item is possible for selection.
You loop through all items starting with the character (case not important)
No Keypress repeat is necessary.
The Itemindex is the correct one.

Bart Broersma

2011-08-01 20:26

developer   ~0050354

So it seems on Delphi that,
with style = scDropDown or scSimple:
- typing in the control will result in ItemIndex = -1
- setting Text property sets ItemIndex = -1, no OnChange is fired

with style = csDropDownList
- typing in the control will select the next entry starting with the character you typed

What is the result of setting Text property for this case?

All in all, I find the Delphi behaviour not very coherent and not very intuitive.

Leo Kijzers

2011-08-03 22:17

reporter   ~0050411

Hi,
 with csDropDown (Autocomplete=false) Delphi and Lazarus behave equal,
except for Lazarus by prog. writing Aaa it sets Combo.OnExit to 0. Delphi -1,
and both no OnChange. User writng Lazarus and Delphi always -1.

with csDropDown (Autocomplete=true)
  User: with Delphi the OnChange gives the Autofilled string. Lazarus only the
      written strimg.
      At OnExit Delphi gives the autofilled string with the
      correct ItemIndex, except if the Items are equal but for the case
      like Aaa (1) and aaa(0) it gives 0.
      Lazarus gives for A, autofilled Aaa, OnChange -1, A, OnExit 0, aaa
      If property AutoComleteText [bactSearchCaseSensitive] is set to true
      then it gives OnExit 0, Aaa (same as Delphi)
      p.s. in the ObjecInspector the length of the propterty string
           [cbactEnabled,cbactEndOfLineComplete,cbactSearchCaseSensitive,c
           seems to be to long to be completely written?
  Prog: Delphi -1, Aaa / Lazarus 0, Aaa (independent of Autocompletetext)
with csDropDownList
  User: Delphi and Lazarus behave almost equally, except with Delphi you must
      keep pressing the key (if different items start with the same character
      like (Aaa, aaa, abc) to come in the "repeat key mode" else you get always
      the same Item. The Case of the pressed character is not important.
      Lazarus does not need the "repeat key mode".
  Prog: you cannot select an Item. (csDropDownList autoswitches with the
      ReadOnly. Delphi has no ReadOnly.

Bart Broersma

2011-08-04 12:35

developer   ~0050427

I find the general behaviour of this control utterly confusing.

My proposed patch to make RealSetText case sensitive at least solves the original problem, and I don't really see why it cannot be implemented this way.
Currently with csDropDown the control is prety much unusable in the described scenario (on Windows).

The autocomplete code should be fixed in a different ticket.

Bart Broersma

2011-10-12 17:31

developer   ~0052909

Target 0.99 for review of patch.

Luiz Americo

2011-12-09 16:46

developer   ~0054872

Can you check if the fix for 0020846 also fixed this issue?

Bart Broersma

2011-12-11 13:05

developer   ~0054930

@Luiz: the effect of this patch is really strange.
Now when style = csDropDown (this is when it failed before) now the control behaves OK, but when I set style = csDropDownList (which worked OK before), I get the same bug as previously with csDropDown (I cannot select Aaa neither by mouse nor by keyboard).

I think this is even worse, since csDropDownList is used more often to prsent users with a selection.
Also this patch prevents my proposed patch for RealSetText from working.

Luiz Americo

2011-12-11 14:57

developer   ~0054940

@Bart: as you have previously noted only win32 was calling RealSetText, that was wrong.

You can add your code to win32 widgetset but to correctly fix, the first thing to do is discover the root of the bug. I'll take a look.

Luiz Americo

2011-12-11 16:03

developer   ~0054943

I found the root cause: CB_SELECTSTRING, used in SetText does a case insensitive search. May be the cause of the related problems.

Bart Broersma

2011-12-11 17:54

developer   ~0054952

Seems to be fixed.

Issue History

Date Modified Username Field Change
2010-06-30 10:39 Leo Kijzers New Issue
2010-06-30 10:50 Jonas Maebe Project FPC => Lazarus
2010-06-30 15:10 Bart Broersma Note Added: 0038891
2010-06-30 16:30 Bart Broersma Note Added: 0038892
2010-06-30 16:32 Bart Broersma File Added: customcombobox.inc.realsettext-casesensitive.diff
2010-06-30 16:34 Bart Broersma Note Edited: 0038892
2010-07-01 09:51 Bart Broersma Note Edited: 0038892
2010-07-14 13:04 Bart Broersma Note Added: 0039320
2010-07-14 14:51 Vincent Snijders LazTarget => -
2010-07-14 14:51 Vincent Snijders Category FCL => LCL
2010-07-14 14:51 Vincent Snijders Product Version 2.4.1 =>
2010-10-04 00:39 Martin Friebe Note Added: 0041467
2010-10-04 00:42 Martin Friebe LazTarget - => 1.0
2010-10-04 00:42 Martin Friebe Status new => confirmed
2010-10-04 19:30 Bart Broersma Note Added: 0041487
2010-10-17 02:36 Martin Friebe Relationship added related to 0016412
2010-12-25 23:53 Bart Broersma Note Added: 0044589
2011-07-26 14:40 Bart Broersma Note Added: 0050178
2011-07-26 14:40 Bart Broersma Status confirmed => feedback
2011-07-28 15:18 Leo Kijzers Note Added: 0050237
2011-07-29 14:07 Bart Broersma Note Added: 0050264
2011-07-31 21:40 Leo Kijzers Note Added: 0050318
2011-08-01 20:26 Bart Broersma Note Added: 0050354
2011-08-03 22:17 Leo Kijzers Note Added: 0050411
2011-08-04 12:35 Bart Broersma Note Added: 0050427
2011-08-26 02:17 Martin Friebe Relationship added related to 0020056
2011-10-12 17:31 Bart Broersma Note Added: 0052909
2011-10-12 17:31 Bart Broersma Target Version => 0.99.0
2011-12-09 10:36 Vincent Snijders Relationship added related to 0020846
2011-12-09 16:46 Luiz Americo Note Added: 0054872
2011-12-11 13:05 Bart Broersma Note Added: 0054930
2011-12-11 14:57 Luiz Americo Note Added: 0054940
2011-12-11 14:58 Luiz Americo Widgetset => Win32/Win64
2011-12-11 14:58 Luiz Americo Category LCL => Widgetset
2011-12-11 16:03 Luiz Americo Fixed in Revision => 34100
2011-12-11 16:03 Luiz Americo Status feedback => resolved
2011-12-11 16:03 Luiz Americo Resolution open => fixed
2011-12-11 16:03 Luiz Americo Assigned To => Luiz Americo
2011-12-11 16:03 Luiz Americo Note Added: 0054943
2011-12-11 17:54 Bart Broersma Note Added: 0054952