#!/bin/bash

# Aufruf des Scripts: list-cmd-edit --list=<Pfad der Quellliste>[ --arg=<Gegenstand der Liste> --head=<Kopfzeile> --icon=<Symbol, falls nicht in Quelldatei enthalten> -winicon=<Fenstersymbol> --parent=<Aufrufendes Programm> --edit=true|false --shut=true|false (Fenster schließt bei Fokusverlust) --opt=<weitere yad-Optionen, durch geschützte Leerzeichen getrennt>]

# Dieses Script stellt eine Liste von Labels dar, die mit einem Befehl und optional einem Symbolbild (Icon)
# verknüpft sind.
# Vollständiges Listenformat: [Iconpfad‖]Befehl/Pfad‖Label

# Diese zwei- oder dreielementige Liste wird von einer Quelldatei, die eine reine Textdatei ist, bereitgestellt.

# Wird das Label mit 'OK' oder doppeltem Mausklick bestätigt, so wird die Datei oder Adresse geöffnet bzw. der Befehl ausgeführt.
# Wird das Label mit 'Edit' aufgerufen, so bietet das Script eine Bearbeitung der Listenzeile, ihre Löschung
# oder nach ihrer Bearbeitung ihre Erstellung als neue Listenzeile an.

Info () {
title="Info"
author="Peter Starfinger"
mail="E-Mail: info@die-starfingers.de"
year="2022"
app="$1"
msgid="The Starbuntu application
<i>\$app</i>
was written by"
info="$(gettext "$msgid" | (export PATH `envsubst --variables "$msgid"`; envsubst "$msgid"))"

sh -c 'wunwa "$title" > /dev/null; xdotool key Home key Down' &
yad --center --fixed --title="$title" --window-icon="info" --image="info" --borders=20 --text="$info"$'\n\n'"$author"$'\n'"$mail"$'\n\n'"$year"$'\n' --text-align=center --selectable-labels --button="OK"
}

reread () {
    IFS=$'\n'
    $duo && exclude="^‖" || exclude="^‖‖"
    dta=($(cat "$list" | grep -v "$exclude"))
    l=${#dta[*]}
    $duo && for ((i=0; i<l; i++)); do dta[$i]=$icon‖${dta[$i]}; done
    unset IFS
    IFS='‖'$'\n'
    data=(${dta[@]})
    length=${#data[@]}
    nr=$(((line-1)*3+2))
}

write_data () {
    [ -e "$list" ] && cp "$list" "$list.bak" && rm "$list"
    $headline && echo "$head" >> "$list"; 
    for ((i=0; i<length; i=i+3)); do
	! $duo && echo -n "${data[$i]}‖" >> "$list"
	echo -n "${data[$((i+1))]}‖" >> "$list"
	echo "${data[$((i+2))]}" >> "$list"
    done
    if [ $button -eq 1 ] && [[ "$cmd" =~ ^\{.*\}$ ]]; then
	id_entries="$(grep "$cmd" "$list")"
	if [ -n "$id_entries" ]; then
	    title="$(echo $"Removal of an identifier")"
	    text="$(echo $"&#9;There are entries under the identifier to be removed.&#10;&#9;Remove entries, too?&#10;&#9;Otherwise they get moved upwards for one identifier level.&#10;")"
	    no=$"No"; yes=$"Yes"
	    yad --center --fixed --title="$title" --window-icon="$winicon" --image="dialog-question" --borders=20 --text="$text" --button="$no":1 --button="$yes":0
	    knopf=$?
	    [ $knopf -eq 0 ] && sed -i "/$cmd/d" $list || sed -i "s/$cmd//g" "$list"
	fi
    fi
}

tip () {
    adv="$(echo $"instead of")"
    alarm="$(echo $"Attention while inserting special characters:")"
    title="$(echo $"Special Characters")"
    conj=$"or"

#    help1=$'\t'"    $adv &amp;&#9;&#9;\'&amp;#38;\'"
    help2=$'\t'"    $adv nbsp&#9;\' \' $conj \'&amp;#160;\'"
    help3=$'\t'"    $adv Tab&#9;\'&#92;t\' $conj \'&amp;#9;\'"
    help4=$'\t'"    $adv Return&#9;\'↵\' $conj \'&#92;n\' $conj \'&amp;#10;\'\n\t\t\t\t("$"also for headers"")"
#    help="    $alarm    &#10;&#10;$help1&#10;$help2&#10;$help3&#10;$help4&#10;"
    help="    $alarm    &#10;&#10;$help2&#10;$help3&#10;$help4&#10;"
    yad --center --fixed --title="$title" --window-icon="/usr/share/icons/gnome/48x48/status/dialog-warning.png" --image="/usr/share/icons/gnome/48x48/status/dialog-warning.png" --image-on-top --borders=20 --text="$help" --selectable-labels --button="OK" &
    wunwa "$title" > /dev/null; xdotool key Home key Down
}

[ "$1" = "tip" ] && tip && exit 0
[ "$1" = "info" ] && Info "$2" && exit 0
IFS=$'\n'
par=($(echo $@ | sed 's/ --/\n--/g'))

if [[ ${par[@]} = "--help" ]] || [[ ${par[@]} = "-h" ]] || [[ -z "${par[@]}" ]]; then
    title="$(basename $0): "$"Call"
    text=$"<b>Call of the script:</b>&#10;&#10;list-cmd-edit &lt;params&gt;&#10;&#10;params:&#10;&#10;--list=&lt;path of the list file&gt;&#10;[ --arg=&lt;topic of the list&gt;&#10;--head=&lt;header&gt;&#10;--icon=&lt;icon, if not already contained in the source file&gt;&#10;--winicon=&lt;window icon&gt;&#10;--parent=&lt;invoking program&gt;&#10;--deco=true|false&#10;--edit=true|false&#10;--shut=true|false (window closes on unfocus)&#10;--opt=&#34;&lt;further yad options (separated by non-breakable spaces)&gt;&#34;]&#10;&#10;Complete list format:&#10;[icon path‖]command/path‖label&#10;Here '‖' serves as delimiter."
    yad --center --fixed --title="$title" --window-icon="org.gnome.Yelp" --borders=20 --text "$text"$'\n' --button="OK":0
    exit 0
fi


for p in ${par[@]}; do
    c="${p%%=*}"
    cont="${p#*=}"
    case "$c" in
	"--list" ) list="$cont"; list="$(echo "$list" | sed 's/~\//\$HOME\//g' | envsubst)" ;;
	"--arg" ) arg="$cont" ;;
	"--head" ) head="$cont"
		   head="${head//\\n/\\\\n}"
		   head="${head//↵/\\\\n}" ;;
	"--icon" ) icon="$cont"; icon="$(echo "$icon" | sed 's/~\//\$HOME\//g' | envsubst)" ;;
	"--winicon" ) winicon="$cont"; winicon="$(echo "$winicon" | sed 's/~\//\$HOME\//g' | envsubst)" ;;
	"--parent" ) parent="$cont" ;;
	"--deco" ) deco="$cont"; if [[ $deco != true ]] &&  [[ $deco != false ]]; then $0; exit 1; fi ;;
	"--edit" ) edit="$cont"; if [[ $edit != true ]] &&  [[ $edit != false ]]; then $0; exit 1; fi ;;
	"--shut" ) shut="$cont"; if [[ $shut != true ]] &&  [[ $shut != false ]]; then $0; exit 1; fi ;;
	"--opt" ) opt="${cont// / }" ;;
	* ) text="$(echo $"Parameter $c unknown!")"
	    yad --center --borders=10 --text="$text" --button="OK":0; exit 1 ;;
    esac
done

icon_theme=$(cat $HOME/.config/gtk-3.0/settings.ini | grep "icon-theme")
icon_theme=${icon_theme#*=}
menu=false
pass=false

if [ -z "$list" ]; then
    text=$'\n\t'$"List source not defined!"
    yad --fixed --title=$"Error" --image="dialog-warning" --borders=10 --text="$text" --button="OK":0
    exit 1
elif [ "${list::1}" != '/' ]; then
    list="$(pwd)/$(basename "$list")"
fi
if [ -z "$arg" ]; then arg="Label"; fi
if [ -z "$parent" ]; then parent="list-cmd-edit"; fi
name="$arg"
dir="${arg% Menu*}"

if [[ "$list" =~ "/menus/" ]]; then
    name="$dir"
    if [ "$dir" != "Apps" ]; then
	[ "$LANGUAGE" != "en" ] && infix="Name\[$LANGUAGE" || infix="Name="
	[ -f "$HOME/.local/share/desktop-directories/$dir.directory" ] && name="$(grep "$infix" $HOME/.local/share/desktop-directories/$dir.directory)" || name="$(grep "$infix" /usr/share/desktop-directories/$dir.directory)"
	name="${name#*=}"
    fi
    [[ "$arg" =~ "Menu" ]] && name=" $name Menu"
    menu=true
    if [[ ! -d "$HOME/.config/menus/$dir" ]]; then
	mkdir "$HOME/.config/menus/$dir"
    fi
    place="$HOME/.config/menus/$dir"
else
    [ -f "/tmp/hsperfdata_$USER/src" ] && nome="$(grep "{$dir}‖" $(cat /tmp/hsperfdata_$USER/src))"
    [ -n "$nome" ] && nome="${nome#*▶ } Menu" && name="$nome"
    [[ "$list" =~ /(notes|files|links)\. ]] && name="@$name"
    mkdir -p "/tmp/hsperfdata_$USER/list-cmd-edit/$arg"
    place="/tmp/hsperfdata_$USER/list-cmd-edit/$arg"
fi
if [ -z "$deco" ]; then deco=false; fi
if [ -z "$edit" ]; then edit=true; fi
if [ -z "$shut" ]; then shut=true; fi
duo=false; bkmks=false; find_app=false
IFS=$'\n'
if [[ ! -f "$list" ]]; then echo "$(echo $"Detail&#58; " | sed -E 's/(.*)\&#58; /<\1>/')‖$(echo $"Label&#58; " | sed -E 's/(.*)\&#58; /<\1>/')" > "$list"; fi
[ "$list" = "$HOME/.config/gtk-3.0/bookmarks" ] && sed -i 's/ /‖/g; s/%20/ /g' "$list"
dt=($(cat "$list"))
unset IFS
IFS='‖'$'\n'
if [ $(echo "${dt[0]}‖" | awk -F"‖" '{print NF-1}') = 2 ] || [[ "$arg" =~ $"Recent" ]]; then
    duo=true
    dt_l=3
    parameters=""
    dt=($(cat "$list" | sed 's/&\#xA0;/ /g; s/&\#xE4;/ä/g; s/&\#xF6;/ö/g; s/&\#xFC;/ü/g; s/&\#xDF;/ß/g'))
    if [ -z "${dt[0]}" ] || [ "${dt[0]}" = '1:' ]; then
	[ -z "$head" ] && head="${dt[1]}" && head="${head//↵/\\\\n}" || sed -i "1s/.*/‖$head/" "$(cat /tmp/hsperfdata_$USER/src)"
	unset dt[0] dt[1]
	dt=(${dt[@]})
    fi
    l=${#dt[@]}
    if [ -z "$icon" ]; then icon="/usr/share/icons/hicolor/16x16/apps/yad.png"; fi
    for ((i=0; i<l; i++)); do
	if [ $((i/2*2)) -eq $i ]; then
	    [[ ! "${dt[$i]}" =~ ^[0-9]*: ]] && [ "${dt[$i]:0:7}" != "file://" ] && dta[$i]="$icon"‖"$((i/2+1)):${dt[$i]}" || dta[$i]="$icon"‖"${dt[$i]}"
	else
	    dta[$i]="${dt[$i]}"
	fi
    done
    data=(${dta[@]})
    convert -background none "$icon" -resize 16x16 "/tmp/hsperfdata_$USER/list-cmd-edit/$arg/resized.png"
    icon="/tmp/hsperfdata_$USER/list-cmd-edit/$arg/resized.png"
    for ((i=0; i<l; i++)); do
	if [ $((i/2*2)) -eq $i ]; then
	    [[ ! "${dt[$i]}" =~ ^[0-9]*: ]] && [ "${dt[$i]:0:7}" != "file://" ] && dt[$i]="$icon"‖"$((i/2+1)):${dt[$i]}" || dt[$i]="$icon"‖"${dt[$i]}"
	else
	    dt[$i]="${dta[$i]}"
	fi
    done
    data_conv=(${dt[@]})
else
    dt_1="$(echo "${dt[0]}" | sed -E 's~.*‖(.*)‖.*~\1~')"
    if [ -z "${dt_1}" ] || [ "${dt_1}" = '1:' ]; then
	[ -z "$head" ] && head="$(echo "${dt[0]}" | sed -E 's~.*‖(.*)~\1~')" && head="${head//↵/\\\\n}" || sed -i "1s/.*/‖‖$head/" "$(cat /tmp/hsperfdata_$USER/src)"
	unset dt[0]
	dt=(${dt[@]})
#	sed -i "1d" $list
    fi
    if [ -f "/tmp/hsperfdata_$USER/menus.lst" ] || [[ "$(pwd)" =~ "/menus" ]]; then edit=false; find_app=true; fi
    if $edit; then
	dt_l=3
	parameters=""
    else
	dt_l=4
    fi
    [ "$(basename "$list")" = "files.lst" ] && png="/usr/share/icons/gnome/48x48/emblems/emblem-favorite.png" || png="$HOME/.icons/webbrowser.png"
    data=($(cat "$list" | grep -v "^‖‖" | sed "s|^‖|$png‖|g"))
    if [ $dt_l -eq 4 ]; then
	for ((k=0; k<${#data[@]}; k++)); do
	    [ "$(($k-$k/3*3))" -eq 2 ] && data[$k]="${data[$k]}‖ "
        done
	data=(${data[@]})
    fi
    data_conv=(${data[@]})
    l=${#data[@]}
    for ((i=0; i<l; i=i+dt_l)); do
	conv=true; pic=""
	data[$i]="$(echo "${data[$i]}" | sed 's/~\//\$HOME\//g' | envsubst)"
	bn=$(basename "${data[$i]}")
	bn=${bn/\.png/}; bn=${bn/\.svg/}
	pic=$(find $HOME/.config/menus -name "$bn\.png" | head -n 1)
	$menu && [ $((i/dt_l*dt_l)) -eq $i ] && data[$((i+1))]="$((i/dt_l+1)):${data[$((i+1))]}"
	if [ -z "$pic" ]; then
	    if [ "$bn" = "${data[$i]}" ]; then
		data[$i]=$(find $HOME/.icons -maxdepth 1 -name "$bn\.png" -o -name "$bn\.svg" | head -n 1)
		if [ -z "${data[$i]}" ]; then
		    data[$i]=$(find /usr/share/icons/$icon_theme -name "$bn\.png" -o -name "$bn\.svg" | grep 48 | head -n 1)
		fi
		if [ -z "${data[$i]}" ]; then
		    data[$i]=$(find /usr/share/icons/gnome -name "$bn\.png" -o -name "$bn\.svg" | grep 48 | head -n 1)
		fi
		if [ -z "${data[$i]}" ]; then
		    data[$i]=$(find /usr/share/icons/hicolor -name "$bn\.png" -o -name "$bn\.svg" | head -n 1)
		fi
		if [ -z "${data[$i]}" ]; then
		    data[$i]=$(find /usr/share/pixmaps -name "$bn\.png" -o -name "$bn\.svg" | head -n 1)
		fi
		if [ -z "${data[$i]}" ]; then
		    bn="application-x-theme"
		    data[$i]=$(find /usr/share/icons/$icon_theme -name "$bn\.png" -o -name "$bn\.svg" | grep 48 | head -n 1)
		fi
	    fi
	else
	    data[$i]="$pic"
	    data_conv[$i]="$pic"
	    conv=false
	fi
	if $conv; then
	    [ "${data[$i]: -4}" = ".svg" ] && prestr="rsvg:" || prestr=""
	    convert -background none "$prestr${data[$i]}" -resize 16x16 "$place/$bn.png"
	    data_conv[$i]="$place/$bn.png"
	elif [ ! -e "$place/$bn.png" ]; then
	    cp "$pic" "$place/$bn.png"
	fi
    done
fi
head="${head//\\\\n/\\n}"

for ((k=0; k<${#data_conv[@]}; k++)); do
    data_conv[$k]="$(sed 's/\&$/\&amp;/g; s/ \&\& / \&amp;\&amp; /g; s/\& /\&amp; /g; s/</\&lt;/g; s/>/\&gt;/g' <<< ${data_conv[$k]})"
    prefix=""
    if [ $(((k+1)/dt_l*dt_l)) -eq $((k+1)) ]; then
	$find_app && n=$((k-1)) || n=$k
	[[ "${data_conv[$n]}" =~ '}' ]] && prefix="${data_conv[$n]%\}*}"
	[ -n "$prefix" ] && prefix="$prefix}"
	reduced_prfx="${prefix%{*}"
	reduced_prfx="${reduced_prfx%{*}"
	data_conv[$n]="${data_conv[$n]##*\}}"
    fi
done

length=${#data_conv[@]}
[ $dt_l -eq 4 ] && ((l=length/4+1)) || ((l=length/3))
[ $l -gt 40 ] && l=40
h=$((l*24+72))

text0=$"Open list item"
text1="$(echo $"Edit / Delete / New Entry")"
text2=$"Alphabetise $arg"
text3=$"Restructure $arg"

if ! $deco; then deco="--undecorated"; else deco=""; fi
if $shut; then close="--close-on-unfocus"; else close=""; fi
if [ -n "$head" ]; then
    headform="--text=<b>$head</b>"
    head_align="--text-align=center"
    lf=$(awk -F"&#10;" '{print NF}' <<< "${headform}")
    [[ "$head" =~ '\n' ]] && lf=$(echo -e "$head" | wc -l)
    ((h=h+20*$lf))
else
    head_align=""
fi
[ $h -gt 1032 ] && h=1032

if [ $dt_l -eq 3 ]; then
    edit_button="--button=Edit"!!"$text1"":1"
    if [[ "$(basename "$list")" =~ bookmarks|marked-directories.lst|recent ]]; then
	[ "$(basename "$list")" = "bookmarks" ] && bkmks=true
	sort=""
	struct=""
	if [[ "$(basename "$list")" =~ recent ]]; then edit_button=""; fi
    else
	sort="--button=Sort!!$text2:2"
	struct="--button=± ▶!!$text3:3"
    fi
    dt=`yad --mouse --title="$name" --height=$h --width=350 --borders=10 $deco --window-icon=$winicon $headform $head_align --always-print-result $close --list --separator="‖" --no-headers --column=Icon:IMG --column=Cmd:HD --column=Label:TIP --tooltip-column=2 --search-column=3 --regex-search ${data_conv[@]} --button=$"Quit":4 $edit_button $struct $sort $opt --button="Info":"$0 info $(basename $parent)" --button="OK!!""$text0":0`
else
    dt=`yad --mouse --title="$name" --height=$h --width=600 --borders=10 $deco --window-icon=$winicon $headform $head_align --always-print-result $close --list --separator="‖" --editable --editable-cols=4 --column=" ":IMG --column=Cmd:HD --column=$" Label: ""								":TIP --column=$" Parameters:  " --tooltip-column=2 --search-column=3 --regex-search ${data_conv[@]} --button=$"Quit":4 --button="Info":"$0 info $(basename $parent)" --button="OK!!""$text0":0`
fi
button="$?"

nfll=false
if [[ "$list" =~ /(notes|files|links|list)\. ]]; then
    nfll=true
    list="$(cat "/tmp/hsperfdata_$USER/src")"
fi
if [ $button -gt 1 ]; then
    if [ $button -eq 2 ]; then
	$duo && m=2 || m=3
	if ! $bkmks; then
	    sed -i 's/‖/‖\!/g' "$list"
	    sorted="$(cat "$list" | grep -v '^‖' | env LC_ALL=C sort -t'!' -k $m)"
	    sed -i '/^[^‖]/d' "$list"
	    echo "$sorted" >> "$list"
	    sed -i 's/‖!/‖/g' "$list"
	else
	    sed -i 's/ /‖\!/g' "$list"
	    sort -t'!' -k $m < "$list" > "$list.sort"
	    sed -i 's/‖\!/ /g' "$list.sort"
	fi
	mv "$list.sort" "$list"
	$parent "$list" & exit 0
    fi
    if [ $button -eq 3 ]; then
	mk-rec-rm-identifier "$list"
	multimenu "$list" &
    fi
    [ -d "/tmp/hsperfdata_$USER/list-cmd-edit" ] && rm -r "/tmp/hsperfdata_$USER/list-cmd-edit"
#    [ "$list" = "$HOME/.config/gtk-3.0/bookmarks" ] && sed -i 's/ /%20/g; s/‖/ /g' "$list"
    [ "$list" = "$HOME/.config/gtk-3.0/bookmarks" ] && sed -i ':a;/[ ].*[ |‖]/s/[ ]/%20/;ta; s/‖/ /g' "$list"
    exit $button
fi

dt=$(sed 's/\&amp;$/\&/g; s/ \&amp;\&amp; / \&\& /g; s/\&amp; /\& /g; s/\&lt;/</g; s/\&gt;/>/g' <<< $dt)
[ -n "$dt" ] && label="${dt::-1}"
if [ $dt_l -eq 3 ]; then
    label="${label##*‖}"
else
    parameters="${label##*‖}"
    label="${label%‖*}"
    label="${label##*‖}"
fi
for ((i=2; i<length; i=i+dt_l)); do
    if [ "$label" = "${data[$i]}" ] || [ "$prefix$label" = "${data[$i]}" ] || [ "$reduced_prfx$label" = "${data[$i]}" ]; then
	nr=$i; icon="${data[$((nr-2))]}"; cmd="${data[$((nr-1))]}"
	if [ "${cmd:0:7}" = "file://" ]; then cmd="${cmd:7}"; fi
	break
    fi
done

text="$(echo $"The text is editable!")"
text1="$(echo $"Apply Changes")"
text2="$(echo $"Delete Entry")"
text3="$(echo $"New!!The new entry will be positioned before the current one.")"
text4="$(echo $"Input of special charakters")"
button4=$"Hints"

line=0
[[ "$cmd" =~ ^[0-9]*: ]] && line="${cmd%%:*}" && cmd="${cmd#*:}"

if [ "$button" = "0" ]; then
    cmd_show=""; cd ~
    regex='^(\"?https?|s?ftp|ssh|davs?|file|mailto):/?/?'
    [[ "$cmd" =~ "\\$" ]] && cmd="$(echo "$cmd" | sed 's!\\$!\$!g')"
    cmd="$(echo "$cmd" | sed "s|\$HOME|$HOME|g; s|~|$HOME|g; s|\$USER|$USER|g; s|\$LOGNAME|$LOGNAME|g; s|\$LANGUAGE|$LANGUAGE|g")"
    if [[ "$cmd" =~ ^\{.*\}$ ]] || [ -f "$HOME/.config/menus/$cmd.lst" ]; then opt="--dclick-action=multimenu"; fi
    if [ -z "$(which "$cmd")" ] && ([ -d "$cmd" ] || [ -f "$cmd" ] || [[ $cmd =~ $regex ]]); then
#	[[ $cmd =~ ${regex/|mailto/} ]] && cmd="all-open \"$cmd\"" || cmd="all-open $cmd"
	cmd="all-open $cmd"
    elif $duo && [[ ! "$cmd" =~ ^\{.*\}$ ]]; then
	if [ -d "$cmd" ] || [ -f "$cmd" ] || ([ -n "$(which "${cmd%% *}")" ] && [[ ! "$list" =~ /notes\. ]]) || [[ $cmd =~ $regex ]]; then
	    if [ -z "$(which "${cmd%% *}")" ] && [[ ! "$(xdg-mime query filetype "${cmd##* }")" =~ $(cat $HOME/.config/gtk-3.0/recent.exceptions | sed 's/ /|/g') ]]; then cmd="all-open ${cmd##* }"
	    fi
	elif [[ ! "$label" =~ "◀" ]]; then
	    label_show="$(echo $label | sed 's/\&\#160;/ /g')"
	    [ "${label_show: -1}" != "?" ] && label_show="$label_show:"
	    cmd_show="$(echo $cmd | sed 's/\&amp;/\&/g; s/\&\#10;/\n/g; s/↵/\n/g; s/\\n/\n/g; s/\&\#9;/\t/g; s/\\t/\t/g; s/\&\#160;/ /g')"
	    len=${#cmd_show}
	    width=$((len+350)); height=$((len+180))
	    [ $width -gt 800 ] && width=800
	    [ $height -gt 600 ] && height=600
	    loop=true; new=false
	    while $loop; do
		edited_text=`yad --center --width=$width --height=$height --title="$name" --text="<b>$text</b>"$'\n' --text-align="center" --window-icon=$winicon --wrap --text-info <<< "$label_show"$'\n'$'\n'"$cmd_show" --editable --fontname="Ubuntu" --borders=20 --button=$"Quit":4 --button="Del"!!"$text2":1 --button="$text3":2 --button="Info":"$0 info $(basename $parent)" --button="OK"!!"$text1":0`
		button=$?
		[ $button -eq 4 ] && exit $button
		if [ $button -eq 2 ]; then
		    label_show=$"Label&#58; "; cmd_show=$"Detail&#58; "; new=true
		    label_show="${label_show/&#58;/:}"; cmd_show="${cmd_show/&#58;/:}"
		else
		    loop=false
		fi
	    done
	    if [ $((button/2*2)) -eq $button ] && [ "$edited_text" != "$label_show"$'\n\n'"$cmd_show" ]; then
		label="$(echo "$edited_text" | head -n 1)"
		[ "${label: -1}" = ":" ] && end_char=":" && label="${label::-1}" || end_char=""
		dt="$prefix$label"'‖'"${edited_text/"$label$end_char"$'\n\n'/}"'‖'
		dt="${dt//$'\n'/\&\#10;}"
		dt="$(echo "$dt" | sed "s/\t/\&\#9;/g; s|\$HOME|$HOME|; s|~/|$HOME/|")"
		pass=true
	    fi
	    [ $button -eq 1 ] && pass=true
	fi
    fi

    if [[ "$opt" =~ "--dclick-action=" ]] && [[ ! "$cmd" =~ "all-open" ]]; then
	if $edit || [ -f "$HOME/.config/menus/$cmd.lst" ] || $find_app; then # [ $dt_l -eq 3 ] ?
	    com="${opt#*--dclick-action=} "
	else
	    com=""
	fi
	if [ -f "$HOME/.config/menus/$cmd.lst" ] || ($find_app && [ -z "$(pgrep -f search-list-item)" ]); then
	    cmd="apps $cmd"
	    cmd="$(echo "$cmd" | sed 's@{@@; s@}@@')"
	elif $edit || $find_app; then # [ $dt_l -eq 3 ]?
	    cmd="'' $cmd"
	fi
	cmd="$com$cmd"
    fi

    [ $dt_l -eq 4 ] && [ -z "$(pgrep -f search-list-item)" ] && [[ "$cmd" =~ "apps" ]] && cd $HOME/.config/menus
    [[ "$parameters" =~ "%" ]] && env="${parameters%\%*} " && parameters="${parameters#*%}" || env=""

    if [ -z "$cmd_show" ]; then
	if [[ "$cmd" =~ " " ]] && [[ ! "$cmd" =~ \%[fFuU] ]]; then
	    part1="${cmd%% *}"
	    part2="${cmd#* }"
	    if [ -n "$(which "$part1")" ]; then
		[ -z "$parameters" ] && params="${part2%%/*}" || params="$parameters "
		if [ "${params: -1}" != " " ] || [[ "${params:1}" =~ $regex ]] || [[ "$params" =~ $regex ]] || [[ "$params" =~ ^\ *$ ]]; then params=""; fi
		path="${part2:${#params}}"
		[[ "${params}" =~ ${regex:1} ]] && params="${params% *}"
		params=$(echo "$params" | sed 's/^\"//g; s/ [a-z]*:.*//g')
		[ -e "$path" ] && path="${path// /\\ }"
		cmd="$part1 $params $path"
	    else
	        cmd="${cmd// /\\ }"
	    fi
	else
	    [[ $parameters =~ ^\ *$ ]] && parameters=""
	    [[ "$parameters" =~ "@" ]] && sep="|" || sep="@"
	    [ $dt_l -eq 4 ] && [ -n "$parameters" ] && cmd="$(echo "$cmd" | sed -E "s$sep([^\\]?)\%[fFuU]$sep\1$parameters$sep")"
	fi
	cmd="$(sed 's/\"/¦"/g; s/\\ /¦ /g; s/\\n/¦n/g; s/\\t/¦t/g' <<< "$cmd")"
	[[ ! $cmd =~ \\%[fFuU] ]] && cmd="$(sed 's/\\//g' <<< "$cmd")"
	cmd="$(sed 's/¦"/\"/g; s/¦ /\\ /g; s/¦n/\\n/g; s/¦t/\\t/g' <<< "$cmd")"
	cmd="$(echo "$cmd" | sed -E 's@([^\\])%[UuFf]@\1@')"
	$bkmks && sed -i ':a;/[ ].*[ |‖]/s/[ ]/%20/;ta; s/‖/ /g' "$list"
	error=$(eval "$env$cmd" 2>&1)
	if [ -n "$error" ] && [[ ! "$error" =~ $(cat $HOME/.config/gtk-3.0/suppress-err-msg | tr ' ' '|') ]]; then
#	    echo "$error" > ~/error
	    error="${error#*: }"; error="${error#*: }"
	    yad --fixed --window-icon="$HOME/.icons/list.png" --image="dialog-warning" --title=$"Report" --text="&#10;&#9;$error&#9;&#10;" --button="OK"
	    exit 1
	fi
    fi
fi

if [ "$button" = "1" ] || $pass; then
  if $nfll; then
	[ "$(cat "$list" | head -n 1 | awk -F"‖" '{print NF-1}')" = 1 ] && duo=true || duo=false
  fi
  [[ "$list" =~ /notes\. ]] && duo=true
  ! $pass && new=false
  if ! $pass; then
    label="${label/▶ /}"
    field1=$"Label&#58; "
    field2=$"Detail&#58; "
    field3=$"Icon: "
    cd $HOME/.icons
    loop=true
    while $loop; do
	if ! $duo; then
	    dt=`yad --center --title="Edit $name" --width=600 --height=200 --borders=10 --window-icon=$winicon --no-escape --always-print-result --form --separator="‖" --field="$field1" "$prefix$label" --field="$field2" "$cmd" --field="$field3":SFL "$icon" --file-filter $"Graphic Files "" | *.jpg *.jpeg *.png *.JPG *.JPEG *.PNG" --add-preview --button=$"Quit":3 --button="Del"!!"$text2":1 --button="$text3":2 --button="$button4!!""$text4":"$0 tip" --button="Info":"$0 info $(basename $parent)" --button="OK"!!"$text1":0`
	else
	    dt=`yad --center --title="Edit $name" --width=600 --height=200 --borders=10 --window-icon=$winicon --no-escape --always-print-result --form --separator="‖" --field="$field1" "$prefix$label" --field="$field2" "$cmd" --button=$"Quit":3 --button="Del"!!"$text2":1 --button="$text3":2 --button="$button4!!""$text4":"$0 tip" --button="Info":"$0 info $(basename $parent)" --button="OK"!!"$text1":0`
	fi
	button=$?
	[ $button -eq 3 ] && exit 0
	if [ $button -eq 2 ]; then
	    label=""; cmd=""; icon=""; new=true
	else
	    loop=false
	fi
    done
    dt="$(echo "$dt" | sed "s|\$HOME|$HOME|; s|~/|$HOME/|")"
    headline=false
    $duo && prefix="‖" || prefix="‖‖"
    [ -z "$head" ] && head="$(head -1 "$list")" || head="$prefix$head"
    $duo && [ "${head::1}" = "‖" ] && headline=true
    ! $duo && [ "${head::2}" = "‖‖" ] && headline=true
    if $duo && [ "${dt: -2}" = "‖‖" ] || [ "${dt: -3}" = "‖‖‖" ]; then
	dt="${dt//‖}"
	if $headline; then
	    [ -z "$dt" ] && sed -i "1d" $list && exit 0
	    $duo && sed -i "1s/.*/‖$dt/" "$list" || sed -i "1s/.*/‖‖$dt/" "$list"
	elif [ -n "$dt" ]; then
	    $duo && sed -i "1i ‖$dt" "$list" || sed -i "1i ‖‖$dt" "$list"
	fi
	exit 0
    fi
  fi
  empty=false
  if $nfll; then
	if [ $line -eq 0 ]; then
	    empty=true
	    line="$(wc -l "$list")"
	    line="${line%% *}"
#	    [ $line -eq 0 ] && dir=""
	    dir=""
	    ((line++))
	fi
  fi
  [ $line -gt 0 ] && reread

  if [ $button -lt 3 ]; then
	if ! $duo; then dt=${dt::-1}; fi
	label=${dt%%‖*}
	if $empty; then
	    ids="$(grep "{$dir}‖" "$list")"
	    ids="${ids##*‖}"
	    ids="${ids%▶ *}"
	    [ -n "$dir" ] && label="$ids{$dir}$label"
	    button=2
	fi
	$new && button=2
	cmd=${dt#*‖}
	cmd=${cmd%%‖*}
	icon=${dt##*‖}
	if [[ "$cmd" =~ ^\{.*\}$ ]] && [[ ! "$label" =~ "▶ " ]]; then
	    $new && while [ -n "$(grep "$cmd" "$list")" ]; do
		cmd="${cmd/\}/_\}}"
	    done
	    [[ "$label" =~ "}" ]] && pre="${label%\}*}}▶ " || pre="▶ "
	    label="$pre${label##*\}}"
	elif [[ "$label" =~ "▶ " ]]; then
	    label="${label/▶ /}"
	fi

	case $button in
	0)  data[$((nr-2))]="$icon"
	    data[$((nr-1))]="$cmd"
	    data[$nr]="$label" ;;
	1)  for ((i=nr-2; i<length; i=i+3)); do
		data[$i]="${data[$((i+3))]}"
		data[$((i+1))]="${data[$((i+4))]}"
		data[$((i+2))]="${data[$((i+5))]}"
	    done
	    ((length=length-3)) ;;
	2)  ((length=length+3))
	    for ((i=length-1; i>nr+2; i=i-3)); do
		data[$i]="${data[$((i-3))]}"
		data[$((i-1))]="${data[$((i-4))]}"
		data[$((i-2))]="${data[$((i-5))]}"
	    done
	    data[$((nr-2))]="$icon"
	    data[$((nr-1))]="$cmd"
	    data[$nr]="$label" ;;
	esac
	if $bkmks && [ $button -ne 1 ]; then data[$((nr-1))]="file://${data[$((nr-1))]}"; fi
	write_data
	if $bkmks; then
	    sed -i 's/ /%20/g; s/‖/ /g' "$list"
#	    sed -i ':a;/[ ].*[ |‖]/s/[ ]/%20/;ta; s/‖/ /g' "$list"
	    bookmarks --rox
	fi
  else
#	$bkmks && sed -i 's/ /%20/g; s/‖/ /g' "$list"
	$bkmks && sed -i ':a;/[ ].*[ |‖]/s/[ ]/%20/;ta; s/‖/ /g' "$list"
  fi
else
#    $bkmks && sed -i 's/ /%20/g; s/‖/ /g' "$list"
    $bkmks && sed -i ':a;/[ ].*[ |‖]/s/[ ]/%20/;ta; s/‖/ /g' "$list"
fi

[ -d "/tmp/hsperfdata_$USER/list-cmd-edit" ] && rm -r "/tmp/hsperfdata_$USER/list-cmd-edit"

exit $button
