#!/bin/bash
# Adds/Removes icons to the IceWM desktop toolbar- antiX Linux (adding icons is done using the info from the app's .desktop file) 
# By PPC, 6/12/2020 adapted from many, many on-line examples
# GPL licence - feel free to improve/adapt this script - but keep the lines about the license and author
# localisation and minor changes added by anticapitalista - 10-12-2020

TEXTDOMAINDIR=/usr/share/locale
TEXTDOMAIN=icewm-quick-personal-menu-manager

###Check if the current desktop is IceWM, if not, exit
desktop=$(wmctrl -m)
if [[ $desktop == *"icewm"* ]]; then
  echo $"You are running an IceWM desktop"
    else 
   yad --title=$"Warning" --text=$"This script is meant to be run only in an IceWM desktop" --timeout=10 --no-buttons --center
 exit
fi

###Create list of availables apps, with localized names- this takes a few seconds on low powered devices:
export bashvar=100

###Create need python script for python v3
cat << EOF > /tmp/pythonscript-v3.py
#!/usr/bin/python
import subprocess
from gi.repository import Gio

all_apps = Gio.AppInfo.get_all()  # Returns a list of DesktopAppInfo objects (see docs)

# For example, print display name of all apps and description, using "|" to devide the fields
for app in all_apps:
    print(app.get_display_name(), app.get_filename(), sep=' -- ')
    ### did not implement  app.get_description()
EOF

chmod 755 /tmp/pythonscript-v3.py


###Create need python script for python v2 (older, for antiX 19 and previous versions):
cat << EOF > /tmp/pythonscript-v2.py
#!/usr/bin/python
import subprocess
from gi.repository import Gio

all_apps = Gio.AppInfo.get_all()  # Returns a list of DesktopAppInfo objects (see docs)

# For example, print display name of all apps with description and .desktop file name, using "|" to divide the fields
for app in all_apps:
    print(app.get_display_name()) , "--",  (app.get_filename())
    ### did not implement  app.get_description()

EOF


chmod 755 /tmp/pythonscript-v2.py

python_version="$(python -V | awk '{print $2}'|cut -f 1 -d "." 2>&1)"
###Check current Python version that's being used:
echo $python_version

###Run correct python script according to the available python version:
if [ $python_version -ge 3 ]; then /tmp/pythonscript-v3.py > /tmp/applist.txt

else
/tmp/pythonscript-v2.py > /tmp/applist.txt

fi

###Order the output file alphabetically:
cat /tmp/applist.txt| sort > ~/.apps.txt
###


help()
{
		###Function to display help
		yad --center --form --window-icon=/usr/share/pixmaps/icewm_peditor.png --title=$"Personal Menu Ultra Fast Manager" --field=$"Help::TXT" $"What is this?\nThis utility adds and removes application icons from IceWm's 'personal' list.\nApplication icons are created from an application's .desktop file.\nWhat are .desktop files?\nUsually a .desktop file is created during an application's installation process to allow the system easy access to relevant information, such as the app's full name, commands to be executed, icon to be used, where it should be placed in the OS menu, etc.\n.\n Buttons:\n 'ADD ICON' - select, from the list, application you want to add to your 'personal' list and it instantly shows up in the menu or submenu.\nIf, for some reason, the correct icon for your application is not found, a 'gears' icon will be used, so that you can still click it to access the application.\nYou can click the 'Advanced' button to manually edit the relevant entry and change the application's icon.\n'UNDO LAST STEP' - every time an icon is added or removed from the toolbar, A backup file is created. If you click this button, a restore is performed from that backup file, without any confirmation.\n'REMOVE ICON' - this shows a list of all applications that have icons on your 'personal' list. Double left click any application to remove its icon from the list\n'ADVANCED' - allows for editing the text configuration file that stores all of the entries in your  'personal' list. Manually editing this file allows users to rearrange the order of the icons and delete or add any icon. A brief explanation about the inner workings of the text configuration file is displayed before the file is opened for edition.\n Warnings: only manually edit a configuration file if you are sure of what you are doing! Always make a back up copy before editing a configuration file!"  --center --width=600 --height=700 --button=" x":1
		###END of Function to display help
}

advanced()
{
		###Function to manually manage icons (ADVANCED management)
		cp ~/.icewm/personal ~/.icewm/toolbar.bak &&	
		yad --center --form --window-icon=/usr/share/pixmaps/icewm_peditor.png --title=$"Personal Menu Ultra Fast Manager" --field=$"Warning::TXT" $"If you click to continue, the 'personal' configuration file will be opened for manual edition.\n
How-to:\nEach icon is identified by a line starting with 'prog' followed by the application name, icon and the application executable file.\n Move, edit or delete the entire line referring to each entry.\nNote: Lines starting with # are comments only and will be ignored.\nThere can be empty lines.\nAny changes appear instantly on the menu.\nYou can undo the last change from UNDO LAST STEP button." --width=400 --height=360 --button=" x ":1 --button=gtk-ok:0 && geany ~/.icewm/personal
		###END of Function to manually arrange icons
}		

delete_icon()
{
		###Function to delete  icon
		#create backup file before changes
		cp ~/.icewm/personal ~/.icewm/toolbar.bak
		### Select any application whose icon you want to remove from the toolbar:
		#display only application names
		sed '/.*\"\(.*\)\".*/ s//\1/g' ~/.icewm/personal > /tmp/toolbar-test-edit0.txt
		# do not show commented lines
		egrep -v '^(;|#|//)' /tmp/toolbar-test-edit0.txt > /tmp/toolbar-test-edit.txt
		#choose application to delete
		EXEC=$(yad --window-icon=/usr/share/pixmaps/icewm_peditor.png --title=$"Personal Menu Ultra Fast Manager" --width=450 --height=480 --center --separator=" " --list  --column=$"Double click any Application to remove its icon:"  < /tmp/toolbar-test-edit.txt --button=$"Remove":4)
		
		# exit if no application selected- avoids creating empty toolbar bug reported by Caprea (that also happens in personal's config file):
if [ -z "$EXEC" ]; then exit
fi
		
		text=$(echo $EXEC) #I know, wierd, but grep does not work directly with the $EXEC variable, sometimes...
		#remove any matching lines from ~/.icewm/toolbar and save change to a temporary file called tempo
	    echo "$(grep -v "$text" ~/.icewm/toolbar.bak)" > ~/.tempo 
		# copy that temp file to antiX's icewm toolbar file, delete the temp file and restart to see changes BUT only if "toolbar" file is not rendered completly empty after changes (fail safe to avoid deleting the entire toolbar icon's content, in case a icon has a description with \|/*, etc.)
         if [[ -s ~/.tempo ]];
			then echo $"file has something";
     #file is not empty
					cp ~/.tempo ~/.icewm/personal ;
					rm ~/.tempo ;
					exit
				else echo $"file is empty";
      #file is empty
					yad --window-icon=/usr/share/pixmaps/icewm_editor.png --title=$"Warning" --text=$"No changes were made!\nTIP: you can always try the Advanced buttton." --timeout=3 --no-buttons --center
		 fi
        	exit
		###END of Function to delete last icon
}		

move_icon()
{
	
		#display only application names
		sed '/.*\"\(.*\)\".*/ s//\1/g' ~/.icewm/personal > /tmp/toolbar-test-edit0.txt
		# do not show commented lines
		egrep -v '^(;|#|//)' /tmp/toolbar-test-edit0.txt > /tmp/toolbar-test-edit.txt
		#choose icon to be moved:
		EXEC=$(yad --window-icon=/usr/share/pixmaps/icewm_peditor.png --title=$"Personal Menu Ultra Fast Manager" --width=450 --height=480 --center --separator=" " --list  --column=$"Double click any Application to move its icon:"  < /tmp/toolbar-test-edit.txt --button=$"Move":4)
		#get line number(s) where the choosen application is
		x=$(echo $EXEC)
		 Line=$(cat  ~/.icewm/personal | grep -n "$x" | cut -f1 -d: | sort -u |head -1)
		 #get number of lines in file
		 number_of_lines=$(wc -l < ~/.icewm/personal)

#only do something if a icon was selected :
if test -z "$x" 
then
      echo $"nothing was selected"
else

file_name=~/.icewm/personal
a=$Line

#this performs an infinite loop, so the Move window is ALWAYS open unless the user clicks "Cancel"
	while :
	do

yad --center --undecorated --title=$"Personal Menu Ultra Fast Manager" --text=$"Choose what do to with $EXEC icon" \
--button=" x ":1 \
--button=" ↑ ":2 \
--button=" ↓ ":3 

foo=$?
Line_to_the_left=line_number=$((line_number-1))
line_number=$a

if [[ $foo -eq 1 ]]; then exit
fi

#move icon to the left:
if [[ $foo -eq 2 ]]; then
b=$(($a-1))
	if [ $b -gt 0 ]; then
sed -n "$b{h; :a; n; $a{p;x;bb}; H; ba}; :b; p" ${file_name} > test2.txt
#create backup file before changes
cp ~/.icewm/personal ~/.icewm/toolbar.bak
    cp test2.txt  ~/.icewm/personal
 sleep .3
 rm -f test2.txt
a=$(($a-1))   # update selected icon's position, just in case the user wants to move it again
	fi
fi

#move icon to the right
if [[ $foo -eq 3 ]]; then
a=$(($a+1))
number_of_lines=$(wc -l < ~/.icewm/toolbar)
b=$(($a-1))
    if [[ $line_number -ge  $number_of_lines ]]; then 
  exit 
  else
  sed -n "$b{h; :a; n; $a{p;x;bb}; H; ba}; :b; p" ${file_name} > test2.txt
#create backup file before changes 
cp ~/.icewm/personal ~/.icewm/toolbar.bak
    cp test2.txt  ~/.icewm/personal
    sleep .3
    rm -f test2.txt
# There's no need to update selected icon's position, just in case the user wants to move it again, because moving right just moves the icon to the right of the select icon to the left, so, it updates instantly the selected icon's position
  fi
fi

	done

fi ### ends if cicle that checks if user selected icon to move in the main Move icon window

	}	

restore_icon()
{
		###Function to restore last backup
cp ~/.icewm/toolbar.bak ~/.icewm/personal
		###END Function to restore last backup
}

add_icon()
{
		###Function to add a new icon
####begin infinite loop
for (( ; ; ))
do

# Use a Yad window to select file to be added to the menu
 DADOS=$(yad --button=" x ":1 --button=$"Add selected app's icon":2 --window-icon=/usr/share/pixmaps/icewm_peditor.png --title=$"Personal Menu Ultra Fast Manager"  --height=500 --width=1000 --center  --separator=" " --list  --column=  < ~/.apps.txt)
 desktop_file=$(echo $DADOS|awk 'NF>1{print $NF}')
#get the excutable field:
EXEC=$(grep Exec= "$desktop_file" | cut -d '=' -f2)
##get the name field:
 NAME=${DADOS%--*}
 
#try to find the app's icon:
 desktop_file=$(echo $DADOS|awk 'NF>1{print $NF}')
 ICON00=$(cat $desktop_file | grep "Icon="| cut -d '=' -f2 | head -n 1)

# By default set the icon as the gears icon, then look if the icon exist in several paths...
 DEFAULT_ICON="/usr/share/icons/papirus-antix/24x24/apps/yast-runlevel.png"
 ICONE=$DEFAULT_ICON

# if a icon with a full path exists on the .desktop, use that icon
if [[ -f "$ICON00" ]]; then  ICONE="$ICON00"
 else

#...Also check if the icon's name exists in several possible default paths, if a existing icon is found, use that instead!
#We can add as many paths as we want for the system to look for icons, also, we can look for icons with extensions other than .png (ex: svg), adding new "extension" and path's, and repeating the if-fi cicle
  if [[ -f /usr/share/pixmaps/${ICON00}.png ]]; then  ICONE="/usr/share/pixmaps/${ICON00}.png"
   echo /usr/share/pixmaps/${ICON00}.png exists
   else
    echo /usr/share/pixmaps/${ICON00}.png does not exist
   
  fi
 
  if [[ -f /usr/share/icons/hicolor/24x24/apps/${ICON00}.png ]]; then  ICONE="/usr/share/icons/papirus-antix/24x24/apps/${ICON00}.png"
  echo /usr/share/icons/papirus-antix/24x24/apps/${ICON00}.png exists
  else
   echo /usr/share/icons/papirus-antix/24x24/apps/${ICON00}.png does not exist
  fi

  if [[ -f /usr/share/icons/papirus-antix/24x24/places/${ICON00}.png ]]; then  ICONE="/usr/share/icons/papirus-antix/24x24/places/${ICON00}.png"
  echo /usr/share/icons/papirus-antix/24x24/places/${ICON00}.png exists
  else
  echo /usr/share/icons/papirus-antix/24x24/places/${ICON00}.png does not exist
  fi

  if [[ -f /usr/share/icons/papirus-antix/24x24/apps/${ICON00}.png ]]; then  ICONE="/usr/share/icons/papirus-antix/24x24/apps/${ICON00}.png"
  echo /usr/share/icons/papirus-antix/24x24/apps/${ICON00}.png exists
  else
  echo /usr/share/icons/papirus-antix/24x24/apps/${ICON00}.png does not exist
  fi
  
  #Check, for when there's an error, findind files (yes, that happened with Onlyoffice's icon, for some reason, it had a false negative)
  if [[ -f $ICONE ]]; then  echo ICON EXISTS
	    else
		echo ICON DOES NOT EXIST...........setting the default one
		ICONE="/usr/share/icons/papirus-antix/24x24/apps/yast-runlevel.png"
  fi

echo Result of normal search for ICON was: $ICONE
fi

## if no icon was found after searching the main default icon folders, perform active search for icons and use search result only if an icon was found- it takes about 1 second, but almost always finds a icon!
  generic_icon="/usr/share/icons/papirus-antix/24x24/apps/yast-runlevel.png"
  echo
  echo current icon is $ICONE
  echo generic icon is $DEFAULT_ICON
  if [ "$ICONE" == "$DEFAULT_ICON" ]; then
   echo it seems that no icon for this program was found on the default folders, I ll try searching for it...
   search=$(find /usr/share/icons/ -name ${ICON00}.*| head -n 1)
    if [[ -f $search ]]; then  ICONE="${search}"
   echo  Result: icon will be $ICONE
    fi
  fi

    ###grasping at straws now...
    if  [ "$ICONE" == "$DEFAULT_ICON" ]; then
      echo last search for $ICON00
        search_menu=$(find /usr/local/share/icons/ -name ${ICON00}.*| head -n 1)
       echo resulted in $search_menu
         if [[ -f $search_menu ]]; then  ICONE="${search}"
         fi
    fi
    ###
    #Avoid empty icon!!! (usefull in case something went wrong, while searching for the right icon...
    if  [ "$ICONE" == "" ]; then ICONE="/usr/share/icons/papirus-antix/24x24/apps/yast-runlevel.png"
    fi

# exit if no application selected- avoids creating empty icon on toolbar:
if [ -z "$EXEC" ]; then exit
fi


#create backup file before changes
cp ~/.icewm/toolbar ~/.icewm/toolbar.bak

#in case EXEC field has more than one line, use only the first
readarray -t lines < <(echo "$EXEC")
EXECperc="${lines[0]}"

###This was used to debug the result, during testing
#yad --center --text="FINAL NAME IS $ICONE for application $NAME with the EXEC $EXECperc"

#add line to toolbar - the | cut -f1 -d"%"   part removes any %x option from the exec command.
echo "prog "\"${NAME}"\" "${ICONE}" "${EXECperc}""| cut -f1 -d"%"  >> ~/.icewm/personal

#In case the personal list of icons is displayed in the first level of the menu, show the menu for one moment, so the user can see the change.
#xdotool key Super_L && sleep 1.5 && xdotool key Super_L && sleep 0.3 && echo

done ###close infite loop
		###END of Function to add a new icon
}

export -f help delete_icon advanced restore_icon add_icon move_icon

DADOS=$(yad --length=200 --width=475 --center --title=$"Personal Menu Ultra Fast Manager" \
--window-icon=/usr/share/pixmaps/icewm_peditor.png \
--form  \
--button=" x ":1 \
--field=$"HELP!help:FBTN" "bash -c help" \
--field=$"ADVANCED!help-hint:FBTN" "bash -c advanced" \
--field=$"ADD ICON!add:FBTN" "bash -c add_icon" \
--field=$"REMOVE ICON!remove:FBTN" "bash -c delete_icon" \
--field=$"UNDO LAST STEP!undo:FBTN" "bash -c restore_icon" \
--wrap )
# removed this from the line before "Undo", because it was buggy, and hard to use (users do not see here the icons are being moved, right?)
#--field=$"MOVE ICON!gtk-go-back-rtl:FBTN" "bash -c move_icon" \

### wait for a button to be pressed then perform the selected function
foo=$?

[[ $foo -eq 1 ]] && exit 0
