Listview Multiselect GetGadgetText()

Just starting out? Need help? Post your questions and find answers here.
mark5009
User
User
Posts: 22
Joined: Sun Oct 19, 2014 10:47 pm

Listview Multiselect GetGadgetText()

Post by mark5009 »

Hi and Happy New Year! [1]

I want to copy the text from multiple selected items within a Listview gadget to the clipboard.

My original expectation is that an event proc such as

Code: Select all

Procedure log_to_clipboard( EventType )
   Protected txt.s = "" ; holds our cut text
   txt = GetGadgetText( lv1 )
   ClearClipboard()
   SetClipboardText( txt )
   Debug "sent text to clipboard: " + txt
EndProcedure
Would do the trick. However, only the last line of the selected items is copied.
Am I missing something obvious?

Many thanks .. mark.

[1] standard western calendar implied
collectordave
Addict
Addict
Posts: 1310
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Listview Multiselect GetGadgetText()

Post by collectordave »

Happy new year.

It appears only one item is returned by getgadgettext. You need to use getgadgettext on each seleted item in the list box.

A little code below

Code: Select all

          For i = 0 To 9
            If GetGadgetItemState(ListView_0, i) = 1
              Debug GetGadgetItemText(ListView_0, i)
            EndIf
          Next i
          
Try this in your code and it will send all selected items to the debug output. Once happy replace the debug line with your code for clipboard etc.

Hope this helps
Last edited by collectordave on Mon Apr 04, 2016 3:37 pm, edited 1 time in total.
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
mark5009
User
User
Posts: 22
Joined: Sun Oct 19, 2014 10:47 pm

Re: Listview Multiselect GetGadgetText()

Post by mark5009 »

collectordave wrote: It appears only one item is returned by getgadgettext. You need to use getgadgettext on each seleted item in the list box.
...
Hope this helps
Many thanks, collectordave. I suspected this might be the case but was hoping it might not be. Still, given the speed and ease of PB, it is not really much of a problem, just a little unexpected.

Kind regards .. mark.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Listview Multiselect GetGadgetText()

Post by Shardik »

mark5009 wrote:I suspected this might be the case but was hoping it might not be.
Your hope can be satisfied. In Windows it's possible with an API function to obtain an array which contains all selected items:

Code: Select all

#ItemCount = 10

; ----- Create an array that will contain the indices of the selected items
Dim ItemIndex.L(#ItemCount - 1)

OpenWindow(0, 100, 100, 270, 195, "Detect multiselected items")
ListViewGadget(0, 10, 10, 250, 135, #PB_ListView_MultiSelect)
ButtonGadget(1, 70, 155, 120, 25, "List selected items")

For i = 1 To #ItemCount
  AddGadgetItem (0, -1, "Item " + Str(i))
Next

Repeat 
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow 
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        ; ----- Count the selected items
        SelectedItemsCount = SendMessage_(GadgetID(0), #LB_GETSELCOUNT, 0, 0)
        Debug "Number of selected items: " + SelectedItemsCount

        If SelectedItemsCount > 0
          ; ----- Get the selected items and let them pass into the array 
          SendMessage_(GadgetID(0), #LB_GETSELITEMS, SelectedItemsCount, @ItemIndex()) 

          For i = 0 To SelectedItemsCount - 1
            Debug ItemIndex(i) + 1
          Next i
        EndIf
      EndIf
  EndSelect
ForEver
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Listview Multiselect GetGadgetText()

Post by RASHAD »

Using the ClipBoard()

Code: Select all

OpenWindow(0, 100, 100, 270, 195, "Detect multiselected items")
ListViewGadget(0, 10, 10, 250, 135, #PB_ListView_MultiSelect)
ButtonGadget(1, 70, 155, 120, 25, "List selected items")

For i = 1 To 10
  AddGadgetItem (0, -1, "Item " + Str(i))
Next

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
        Text$ = ""
        For item = 0 To CountGadgetItems(0)
            If GetGadgetItemState(0,item) = 1
               Text$ = Text$ + GetGadgetItemText(0,item) + #CRLF$
            EndIf
        Next
        ClearClipboard()
        SetClipboardText(Text$)
        Debug GetClipboardText()
  EndSelect
ForEver

Egypt my love
mark5009
User
User
Posts: 22
Joined: Sun Oct 19, 2014 10:47 pm

Re: Listview Multiselect GetGadgetText()

Post by mark5009 »

Thanks, Rashad.

I am using OSX and there might be a way of doing the same locally, I'd rather not go platform specific if the payoff is minimal. So, I am using the clipboard code, almost identical to the one you posted.

.. mark.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Listview Multiselect GetGadgetText()

Post by Shardik »

mark5009 wrote:I am using OSX
If you would have posted your OS in your signature, I would have posted the API code for OS X... :wink:

I have converted my example from above using Windows API functions to an example using the necessary MacOS API functions.

The native API functions should be much faster than anything you can currently do solely with PureBasic code. Of course this only matters when working with ListViewGadgets containg many items...

I have tested the following example successfully on these MacOS X versions with PB 5.41 x86 and x64:
- 10.6.8 (Snow Leopard)
- 10.11.2 (El Capitan)

Code: Select all

#ItemCount = 10

; ----- Create an array that will contain the indices of the selected items
Dim ItemIndex.I(#ItemCount - 1)

OpenWindow(0, 100, 100, 270, 250, "Detect multiselected items")
ListViewGadget(0, 10, 10, 250, 195, #PB_ListView_MultiSelect)
ButtonGadget(1, 60, 215, 140, 25, "List selected items")

For i = 1 To #ItemCount
  AddGadgetItem (0, -1, "Item " + Str(i))
Next

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        ; ----- Request an NSIndexSet of the indices of the selected items
        IndexSet = CocoaMessage(0, GadgetID(0), "selectedRowIndexes")
        ; ----- Copy the indices of the selected items into array ItemIndex()
        SelectedItemsCount = CocoaMessage(0, IndexSet,
          "getIndexes:", @ItemIndex(),
          "maxCount:", ArraySize(ItemIndex()) + 1,
          "inIndexRange:", 0)
        ; ----- Display number of selected items
        Debug "Number of selected items: " + SelectedItemsCount

        If SelectedItemsCount > 0
          ; ----- Display index of each selected item
          For i = 0 To SelectedItemsCount - 1
            Debug ItemIndex(i) + 1
          Next i
        EndIf
      EndIf
  EndSelect
ForEver
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Listview Multiselect GetGadgetText()

Post by Shardik »

The code example below is true cross-platform while using the fast platform-specific API functions of Linux, MacOS X and Windows to get the indices of all selected rows in a ListViewGadget without having to iterate over each row when using solely PureBasic functions.

I have tested the example successfully on these operating systems:
- MacOS X 10.6.8 (Snow Leopard) with PB 5.41 x86 and x64
- Ubuntu 14.04 x64 with KDE and PB 5.41 x64
- Windows 7 SP1 with PB 5.41 x86 and x64

Code: Select all

EnableExplicit

#RowCount = 10

; ----- Create an array that will contain the indices of the selected items

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  Dim RowIndex.I(#RowCount - 1) ; Has to be Long in x86 and Quad in x64!
CompilerElse
  Dim RowIndex.L(#RowCount - 1)
CompilerEndIf

Procedure.I GetSelectedRows(GadgetID.I)
  Protected SelectedRowsCount.I

  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      Shared RowIndex.L()

      Protected i.I
      Protected IndexList.I
      Protected Path.I
      Protected Selection.I

      Selection = gtk_tree_view_get_selection_(GadgetID(GadgetID))

      If Selection
        IndexList = gtk_tree_selection_get_selected_rows_(Selection, 0)

        If IndexList
          SelectedRowsCount = g_list_length_(IndexList)

          For i = 0 To SelectedRowsCount - 1
            Path = g_list_nth_data_(IndexList, i)
            RowIndex(i) = PeekI(gtk_tree_path_get_indices_(Path))
          Next i

          g_list_free_(IndexList)
        EndIf
      EndIf
    CompilerCase #PB_OS_MacOS
      Shared RowIndex.I()

      Protected IndexSet.I

      IndexSet = CocoaMessage(0, GadgetID(GadgetID), "selectedRowIndexes")
      SelectedRowsCount = CocoaMessage(0, IndexSet,
        "getIndexes:", @RowIndex(),
        "maxCount:", ArraySize(RowIndex()) + 1,
        "inIndexRange:", 0)
    CompilerCase #PB_OS_Windows
      Shared RowIndex.L()

      SelectedRowsCount = SendMessage_(GadgetID(0), #LB_GETSELCOUNT, 0, 0)

      If SelectedRowsCount > 0
        SendMessage_(GadgetID(GadgetID), #LB_GETSELITEMS, SelectedRowsCount,
          @RowIndex())
      EndIf
  CompilerEndSelect

  ProcedureReturn SelectedRowsCount
EndProcedure

Define i.I
Define SelectedRowsCount.I

OpenWindow(0, 100, 100, 270, 195, "Detect multiselected items")
ListViewGadget(0, 10, 10, 250, 135, #PB_ListView_MultiSelect)
ButtonGadget(1, 60, 155, 140, 25, "List selected items")

For i = 1 To #RowCount
  AddGadgetItem (0, -1, "Row " + Str(i))
Next

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        SelectedRowsCount = GetSelectedRows(0)
        Debug "Number of selected rows: " + SelectedRowsCount

        If SelectedRowsCount > 0
          For i = 0 To SelectedRowsCount - 1
            Debug RowIndex(i) + 1
          Next i
        EndIf
      EndIf
  EndSelect
ForEver
mark5009
User
User
Posts: 22
Joined: Sun Oct 19, 2014 10:47 pm

Re: Listview Multiselect GetGadgetText()

Post by mark5009 »

Shardik wrote:
mark5009 wrote:I am using OSX
If you would have posted your OS in your signature, I would have posted the API code for OS X... :wink:

I have converted my example from above using Windows API functions to an example using the necessary MacOS API functions.
Wow! Many thanks, Shardik. Fantastic stuff.

.. mark.
Post Reply