Page 1 of 1

Avoid duplicate keywords in a combobox

Posted: Thu Nov 28, 2013 7:44 am
by flaith
For my project, I need to enter keywords, keep only the last 10 of them and avoid duplicate keywords in my combo.

Here is the code I'm using :

Code: Select all

EnableExplicit

Enumeration
  #SEARCH_WIN
  #SEARCH_COMBO
  #SEARCH_BUTTON_OK
EndEnumeration

Procedure.i CheckAddItem(__Item.s, List __lKeywords.s())
  Protected.i _posItem = 0, _index = 0, _Found = #False, _indexInList = ListSize(__lKeywords())
  
  If _indexInList > 0
    ForEach __lKeywords()
      If __lKeywords() = __Item
        _Found   = #True
        Break
      EndIf
      _posItem + 1
    Next
    
    If Not _Found
      AddElement(__lKeywords())
        __lKeywords() = __Item
    EndIf
  Else
    ; First time use, need to add
    AddElement(__lKeywords())
      __lKeywords() = __Item
  EndIf
  
  ;Populate the combobox  
  ClearGadgetItems(#SEARCH_COMBO)
  
  ;Get the last 10 max keywords in the combobox
  ResetList(__lKeywords())
  For _index = 1 To 10
    If NextElement(__lKeywords())
      AddGadgetItem(#SEARCH_COMBO, -1, __lKeywords())
    EndIf
  Next

  ; Set the item in the combobox if found
  If _Found : Debug _posItem : SetGadgetState(#SEARCH_COMBO, _posItem) : EndIf
  ProcedureReturn _posItem
EndProcedure

Procedure SearchDB()
  Protected.i _Quit = #False, _PosItem = 0
  Protected.s NewList _lKeywords()

  If OpenWindow(#SEARCH_WIN, 0, 0, 270, 180, "Adding unique value inside ComboBox", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ComboBoxGadget(#SEARCH_COMBO, 10, 10, 220, 21, #PB_ComboBox_Editable|#PB_ComboBox_LowerCase)
      AddGadgetItem(#SEARCH_COMBO, -1, "")
    ButtonGadget(#SEARCH_BUTTON_OK, 230, 9, 30, 23, "Ok")

    SetGadgetState(#SEARCH_COMBO, 0)
    SetActiveGadget(#SEARCH_COMBO)

    Repeat 
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          _Quit = #True
        Case #WM_KEYDOWN
          Select EventwParam()
            Case #VK_RETURN
              _PosItem = CheckAddItem(GetGadgetText(#SEARCH_COMBO), _lKeywords())
              SetActiveGadget(#SEARCH_COMBO)
              Debug GetGadgetItemText(#SEARCH_COMBO, _PosItem)
            Case #VK_ESCAPE
              _Quit = #True
          EndSelect
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #SEARCH_BUTTON_OK
              _PosItem = CheckAddItem(GetGadgetText(#SEARCH_COMBO), _lKeywords())
              SetActiveGadget(#SEARCH_COMBO)
              Debug GetGadgetItemText(#SEARCH_COMBO, _PosItem)
          EndSelect
      EndSelect
    Until _Quit
  EndIf
EndProcedure

SearchDB()

Re: Avoid duplicate keywords in a combobox

Posted: Thu Nov 28, 2013 8:58 am
by Kiffi
IMO there is no need to use a linkedlist:

Code: Select all

Procedure CheckAddItem2(NewKeyword.s)
	
	Protected Counter, Found
	
	For Counter = 0 To CountGadgetItems(#SEARCH_COMBO) - 1
		If GetGadgetItemText(#SEARCH_COMBO, Counter) = NewKeyword
			Found = #True
			Break
		EndIf
	Next
	
	If Not Found
		AddGadgetItem(#SEARCH_COMBO, -1, NewKeyword)
		SetGadgetState(#SEARCH_COMBO, 0)
	EndIf
	
EndProcedure
_Greetings ... __Kiffi

Re: Avoid duplicate keywords in a combobox

Posted: Thu Nov 28, 2013 9:32 am
by flaith
:D Thanks a lot Kiffi

Actually, for my project, I need to keep each keywords for the next time we will execute the application, so I keep it in a linked list :wink:

Re: Avoid duplicate keywords in a combobox

Posted: Thu Nov 28, 2013 9:38 am
by netmaestro
Very quick and easy way to avoid duplicates, I usually use it to count actual number of colors used in an image but there are many applications for this simple and fast device:

Code: Select all

Global NewMap words.b()

Procedure CheckAdd(word.s)
  If Not FindMapElement(words(), word)
    words(word) = 1
    AddElement(...[]

Re: Avoid duplicate keywords in a combobox

Posted: Thu Nov 28, 2013 11:54 am
by flaith
Thanks for the tip netmaestro :)
Actually, it seems my code didn't work as expected, means that the itemindex is different.
Because I just want to keep the last 10 keywords.
I select the last keywords inserted and populate the combobox from the last list. So I think I need to do that before checking the new keywords, and add it if he's not in the list. More code to do :oops: :wink:

Re: Avoid duplicate keywords in a combobox

Posted: Fri Nov 29, 2013 5:30 am
by flaith
New version :

Code: Select all

EnableExplicit

#KEEP_MAX_IN_COMBO    = 20

Enumeration
  #SEARCH_WIN
  #SEARCH_COMBO
  #SEARCH_BUTTON_OK
EndEnumeration

Structure CS_KEYWORD
  IndexInList.i
  Keyword.s
EndStructure

Procedure.i CheckAddItem(__Item.s, List __lKeywords.CS_KEYWORD())
  Protected.i _posItem = 0, _index = 0, _Found = #False, _indexInList = ListSize(__lKeywords())
  Protected.s NewList _lTemp.CS_KEYWORD()

  For _posItem = 0 To CountGadgetItems(#SEARCH_COMBO) - 1
    If GetGadgetItemText(#SEARCH_COMBO, _posItem) = __Item
      _Found   = #True
      Break
    EndIf
  Next

  If Not _Found
    AddElement(__lKeywords())
      __lKeywords()\Keyword     = __Item
      __lKeywords()\IndexInList = _indexInList
    AddGadgetItem(#SEARCH_COMBO, -1, __Item)
  EndIf
  SortStructuredList(__lKeywords(), #PB_Sort_Descending, OffsetOf(CS_KEYWORD\IndexInList), TypeOf(CS_KEYWORD\IndexInList))

  ;Get the last #KEEP_MAX_IN_COMBO max keywords in the combobox
  If _indexInList > 0
    ResetList(__lKeywords())
    For _index = 1 To #KEEP_MAX_IN_COMBO
      If NextElement(__lKeywords())
        AddElement(_lTemp())
          _lTemp()\IndexInList = __lKeywords()\IndexInList
          _lTemp()\Keyword     = __lKeywords()\Keyword
      EndIf
    Next

    ;Populate the combobox
    ClearGadgetItems(#SEARCH_COMBO)
    ForEach _lTemp()
      AddGadgetItem(#SEARCH_COMBO, -1, _lTemp()\Keyword)
    Next
  EndIf
  
  ;Need to make a second check with the new items in the combo
  _Found = #False
  For _posItem = 0 To CountGadgetItems(#SEARCH_COMBO) - 1
    If GetGadgetItemText(#SEARCH_COMBO, _posItem) = __Item
      _Found   = #True
      Break
    EndIf
  Next
  
  If Not _Found
    ;Select first item
    SetGadgetState(#SEARCH_COMBO, 0)
  Else
    SetGadgetState(#SEARCH_COMBO, _posItem)
  EndIf
  
  ProcedureReturn _posItem
EndProcedure

Procedure SearchDB()
  Protected.i _Quit = #False, _PosItem = 0
  Protected.s NewList _lKeywords.CS_KEYWORD()

  If OpenWindow(#SEARCH_WIN, 0, 0, 270, 180, "Adding unique value inside ComboBox", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ComboBoxGadget(#SEARCH_COMBO, 10, 10, 220, 21, #PB_ComboBox_Editable|#PB_ComboBox_LowerCase)
      AddGadgetItem(#SEARCH_COMBO, -1, "")
    ButtonGadget(#SEARCH_BUTTON_OK, 230, 9, 30, 23, "Ok")

    SetGadgetState(#SEARCH_COMBO, 0)
    SetActiveGadget(#SEARCH_COMBO)

    Repeat 
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          _Quit = #True
        Case #WM_KEYDOWN
          Select EventwParam()
            Case #VK_RETURN
              _PosItem = CheckAddItem(GetGadgetText(#SEARCH_COMBO), _lKeywords())
              SetActiveGadget(#SEARCH_COMBO)
            Case #VK_ESCAPE
              _Quit = #True
          EndSelect
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #SEARCH_BUTTON_OK
              _PosItem = CheckAddItem(GetGadgetText(#SEARCH_COMBO), _lKeywords())
              SetActiveGadget(#SEARCH_COMBO)
          EndSelect
      EndSelect
    Until _Quit
  EndIf
EndProcedure

SearchDB()
Because I'm late in my project (1 month already :P ), I didn't optimize the code
If you know how, I will be grateful :wink:

Re: Avoid duplicate keywords in a combobox

Posted: Fri Nov 29, 2013 7:24 pm
by Joakim Christiansen
Kiffi wrote:_Greetings ... __Kiffi
:lol:
I see what you did there!

Re: Avoid duplicate keywords in a combobox

Posted: Fri Nov 29, 2013 11:59 pm
by IdeasVacuum
Actually, for my project, I need to keep each keywords for the next time we will execute the application
So, use Kiffy's simple code. on exit from your application, simply save the contents of the combo to a file - which can be read and loaded next time the app is run.

Re: Avoid duplicate keywords in a combobox

Posted: Sun Dec 01, 2013 10:47 am
by flaith
Indeed :wink: