bashzenity

Zenity: How To Get List Selection From Key/Value Associative Array?


How do I take the key/values from an associative array and display them in a Zenity list dialog?

Example:

#!/bin/bash

get_final_bookmarks_choice(){
    if [ ${#matched_bookmarks[@]} -eq 1 ]; then
        # open_bookmarks_command
        return
    fi
    # guard clause.  If no bm found.
    if [ -${#matched_bookmarks[@]} -eq 0 ]; then 
        msg='No bookmarks match found.'
        notify-send "$msg"; echo "$msg"
        return
    fi

    bm_url=$(zenity --entry --title="Multi matches found" \
    --text="Choose bookmark" \
    --column="Name" --column="URL" \

    # Key/value dictionary here.
    )
    # Return the key.
    echo "$key returned here."
}


declare -A matched_bookmarks
matched_bookmarks=(
    ['match 1']='http://match1.com'
    ['match 2']='http://match2.com'
    ['match 3']='http://match3.com'
)

bm_name="$(get_final_bookmarks_choice)"

bm_url="${matched_bookmarks[$bm_name]}"

echo "Bookmarks URL:$bm_url"

Solution

  • You have to use array, not associative array, as argument to zenity command:

    dialogarray=()
    for idx in "${!matched_bookmarks[@]}";do
        dialogarray+=("$idx" "${matched_bookmarks[$idx]}")
    done
    
    zenity --list --title="Multi matches found" --text="Choose bookmark" \
         --column="Name" --column="URL" "${dialogarray[@]}"
    

    Here is my version of your script:

    #!/bin/bash
    
    get_final_bookmarks_choice(){
        local -n Assoc=$1 Result=$2
        case ${#Assoc[@]}  in
            1 ) # open_bookmarks_command
                Result=${!Assoc[*]}
                return
                ;;
            0 ) # guard clause.  If no bm found.
                msg='No bookmarks match found.'
                notify-send "$msg"
                echo "$msg"
                exit 1
                ;;
            * )
                local -a zenDialog=()
                local idx
                for idx in "${!Assoc[@]}";do
                    zenDialog+=("$idx" "${Assoc[$idx]}")
                done
                read -r Result < <(
                    zenity --list --title="Multi matches found" \
                           --text="Choose bookmark" \
                           --column="Name" --column="URL" "${zenDialog[@]}" )
        esac
    }
    
    
    declare -A matched_bookmarks
    matched_bookmarks=(
        ['match 1']='http://match1.com'
        ['match 2']='http://match2.com'
        ['match 3']='http://match3.com'
    )
    
    get_final_bookmarks_choice matched_bookmarks bm_name
    
    bm_url="${matched_bookmarks[$bm_name]}"
    
    echo "Bookmarks URL:$bm_url"
    

    For fun, a SE based version:

    #!/bin/bash
    shopt -s extglob
    get_final_bookmarks_choice(){ local -n Assoc=$1 Result=$2
        case ${#Assoc[@]}  in
            1 ) # open_bookmarks_command
                Result=${!Assoc[*]}
                return  ;;
            0 ) # guard clause.  If no bm found.
                msg='No bookmarks match found.'
                notify-send "$msg"
                echo "$msg"
                return 1  ;;
            * )
                local -a zArgs=(); local idx
                for idx in "${!Assoc[@]}";do
                    zArgs+=("$idx" "${Assoc[$idx]}")
                    while IFS=$'\r\n' read -r idx;do
                        [ "$idx" ]&&[ -z "${idx//*title*}" ]&&break;done< <(
                        wget -qO - "${Assoc[$idx]}")
                    idx=${idx//<*([^>])>}  idx=${idx//&amp;/&} 
                    zArgs+=("$idx")
                done
                read -r Result < <( zenity --list --width 860 --height 200 \
                    --title="Multi matches found" --text="Choose bookmark" \
                    --column="Name" --column="URL" --column="Title" "${zArgs[@]}");;
        esac
    }
    declare -A matched_bookmarks
    matched_bookmarks=( ['Stack Overflow']='https://stackoverflow.com/'
                        ['Code Golf']='https://codegolf.stackexchange.com/'
                        ['Unix & Linux']='https://unix.stackexchange.com/'   )
    get_final_bookmarks_choice matched_bookmarks bm_name &&
        echo "Bookmarks URL:${matched_bookmarks[$bm_name]}"
    

    should produce something like:

    enter image description here