#!/bin/bash

###############################################################################
# MultiRename v1.12 by JakeSFR'2015,2016,2020,2022							  #
# GNU GPL v2 applies														  #
# Req.: Gtkdialog >= 0.8.3, find, sed, awk and usuals like grep, tr, etc...	  #
###############################################################################

# Note: filenames with a newline (0x0a) are not supported!

export TEXTDOMAIN=multirename
export OUTPUT_CHARSET=UTF-8

APPNAME="MultiRename-1.12"
APPICON="/usr/share/pixmaps/multirename.png"

CURDIR="$(pwd)"
[ "$*" ] && [ -d "$*" ] && CURDIR="$(readlink -f "$*")"

WORKDIR="/tmp/MultiRename.${USER}.${$}"
mkdir -p "$WORKDIR"
trap '[ -e "$WORKDIR" ] && rm -r "$WORKDIR"; exit' 0 INT HUP TERM

: > $WORKDIR/list

[ "$(which gtkdialog4 2>/dev/null)" ] && GTKDIALOG=gtkdialog4 || GTKDIALOG=gtkdialog

if $GTKDIALOG --version | grep -wq 'GTK+ 3'; then
	DIRICON='folder'
	FILEICON='text-x-preview'
	TREEICON='icon-column="0"'
	VBOX_SCROLL='scrollable="true" width="310"'
else
	DIRICON='gtk-directory'
	FILEICON='gtk-new'
	TREEICON='stock-column="0"'
	VBOX_SCROLL=''
fi

if [ ${BASH_VERSINFO[0]} -gt 4 ] || ([ ${BASH_VERSINFO[0]} -eq 4 ] && [ ${BASH_VERSINFO[1]} -ge 3 ]); then
	USE_BASH_CASE='true'
else
	USE_BASH_CASE='false'
fi

# BB find doesn't support -regextype
if LANG=C find --help 2>&1 | grep -qwi 'BusyBox'; then
	REGEXTYPE=''
else
	REGEXTYPE='-regextype egrep'
fi

# This is to replace the <tree>'s separator | with a similarily looking character
FAKE="$(echo -e '\xe2\x88\xa3')"   # Divides (U+2223)

export APPNAME APPICON CURDIR FAKE WORKDIR GTKDIALOG DIRICON FILEICON USE_BASH_CASE REGEXTYPE

# =============================================================================

func_readdir() {

	[ "$varHIDDEN" = "true" ] && F_OPTS='' || F_OPTS='-not -path *\/.*'
	[ "$varNSORT" = "true" ] && S_OPTS="-fV" || S_OPTS="-f"
	
	if [ "${varREGEX}" = "true" ]; then
		F_WILD_L='\./.*'
		F_WILD_R='.*'
	else
		F_WILD_L='*'
		F_WILD_R='*'
		# escape these to make literal matching easier
		varFILTER="${varFILTER//\\/\\\\}"	# escape backslashes
		varFILTER="${varFILTER//\*/\\*}"	# escape *
		varFILTER="${varFILTER//\?/\\?}"	# escape ?
		varFILTER="${varFILTER//\[/\\[}"	# escape [
		varFILTER="${varFILTER//\]/\\]}"	# escape ]
	fi

	if [ "${varREGEX}" = "true" ] && [ "${varSENSITIVE}" = "true" ]; then
		F_FILTER="${REGEXTYPE} -regex"
	elif [ "${varREGEX}" = "true" ] && [ "${varSENSITIVE}" = "false" ]; then
		F_FILTER="${REGEXTYPE} -iregex"
	elif [ "${varREGEX}" = "false" ] && [ "${varSENSITIVE}" = "true" ]; then
		F_FILTER='-name'
	else
		F_FILTER="-iname"
	fi	
	
	CURDIR="$(echo "${1//$FAKE/|}" | sed -e 's|/\+|/|g')"	# deduplicate /

	if [ -d "$CURDIR" ]; then
		OLDDIR="$(pwd)"
		cd -- "$CURDIR"
		{
			[ "$varSHOW" != "$(gettext "Files only")" ] &&
				find -L . -mindepth 1 -maxdepth 1 ${F_FILTER} "${F_WILD_L}${varFILTER}${F_WILD_R}" -type d $F_OPTS -printf "$DIRICON|%P\n" | sort ${S_OPTS} -k2 -t'|' 2>/dev/null;
			[ "$varSHOW" != "$(gettext "Folders only")" ] &&
				find -L . -mindepth 1 -maxdepth 1 ${F_FILTER} "${F_WILD_L}${varFILTER}${F_WILD_R}" ! -type d $F_OPTS -printf "$FILEICON|%P\n" | sort ${S_OPTS} -k2 -t'|' 2>/dev/null;
		} | sed -e "s/|/$FAKE/g" -e "s/$FAKE/|/1" -e "s/$/||/" > $WORKDIR/list

		echo "${CURDIR//$FAKE/|}" > "${WORKDIR}/curdir"
		cd -- "$OLDDIR"
	fi
}
export -f func_readdir

# Initial call
varHIDDEN="false"
varNSORT="true"
varSHOW="$(gettext 'Folders and Files')"
varSENSITIVE='false'
varREGEX='false'
func_readdir "${CURDIR}"

# -----------------------------------------------------------------------------

# $1=full name; sets NAME and EXT variables
func_split() {
	# Ignore extension if directory or if the name doesn't contain an extension
	if ([ "$varIGNORE_DIREXT" = 'true' ] && [ -d "${CURDIR}/${1}" ]) || [ "$1" = "${1%.*}" ]; then
		NAME="$1"
		EXT=""
		DOT=""
		return
	fi

	# Separate name from extension
	if [ "$USE_BASH_CASE" = 'true' ]; then
		NAME_LOW="${1,,}"
	else
		NAME_LOW="$(echo "$1" | tr [:upper:] [:lower:])"
	fi

	case "$NAME_LOW" in	# special cases
		*.7z.[0-9][0-9][0-9]|*.tar.7z|*.tar.br|*.tar.bz|*.tar.bz2|*.tar.bzip|*.tar.bzip2|*.tar.gz2|*.tar.f|*.tar.gz|*.tar.gzip|*.tar.lrz|*.tar.lz|*.tar.lz4|*.tar.lzma|*.tar.lzo|*.tar.xz|*.tar.z|*.tar.zip|*.tar.zst|*.cpio.7z|*.cpio.br|*.cpio.bz|*.cpio.bz2|*.cpio.bzip|*.cpio.bzip2|*.cpio.f|*.cpio.gz|*.cpio.lrz|*.cpio.lz|*.cpio.lz4|*.cpio.lzma|*.cpio.lzo|*.cpio.xz|*.cpio.z|*.cpio.zip|*.cpio.zst)
			NAME="${1%.*}"
			EXT="${NAME##*.}.${1##*.}"
			NAME="${NAME%.*}"
			DOT="."
			;;
		*)
			NAME="${1%.*}"
			EXT="${1##*.}"
			if [ "$NAME" = "$EXT" ] && [ -z "${1//[^.]/}" ]; then
				DOT=""
				EXT=""
			else
				DOT="."
			fi
			;;
	esac

	[ "$NAME" = "" ] && [ "$EXT" ] && { NAME="${DOT}${EXT}"; EXT=""; DOT=""; }	# hidden files
}
export -f func_split

# -----------------------------------------------------------------------------

func_escape () {
	# hmm, sed sucks at replacing some symbols, so have to escape them...
	OLD_NAME="${OLD_NAME//\\/\\\\}"	# escape backslashes
	OLD_NAME="${OLD_NAME//\$/\\\$}"	# escape $
	OLD_NAME="${OLD_NAME//&/\\&}"	# escape &
	OLD_NAME="${OLD_NAME//[/\\[}"	# escape [
	OLD_NAME="${OLD_NAME//]/\\]}"	# escape ]
	OLD_NAME="${OLD_NAME//\*/\\*}"	# escape *
	NEW_NAME="${NEW_NAME//\\/\\\\}"	# escape backslashes
	NEW_NAME="${NEW_NAME//\$/\\\$}"	# escape $
	NEW_NAME="${NEW_NAME//&/\\&}"	# escape &
	NEW_NAME="${NEW_NAME//[/\\[}"	# escape [
	NEW_NAME="${NEW_NAME//]/\\]}"	# escape ]
	NEW_NAME="${NEW_NAME//\*/\\*}"	# escape *
}
export -f func_escape

# -----------------------------------------------------------------------------

func_preview() {

	echo -n "<b>$(gettext "Processing, please wait...")</b>" > "$WORKDIR/msg"

	$GTKDIALOG -p GUI_INFO &
	GPID=$!

	case "$varMODE" in
		"$(gettext "Basename only")")			MODE=N	;;
		"$(gettext "Extension only")")			MODE=E	;;
		"$(gettext "Basename with Extension")")	MODE=NE	;;
	esac

	VAL_SEQ=${varINSERT_SEQ_START}

	CURDIR="$(cat "$WORKDIR/curdir")"	# make sure CURDIR is updated, for func_split

	while IFS='' read -r OLD_NAME; do
		NEW_NAME="${OLD_NAME//$FAKE/|}"
		func_split "$NEW_NAME"

		# -----------

		# DELETE_FIRST
		if [ "$varDELETE_FIRST" = "true" ]; then
			VAL="${varDELETE_FIRST_VALUE}"
			case "$MODE" in
				N)	[ ${VAL} -gt ${#NAME} ] && VAL=${#NAME}
					NAME="${NAME:$VAL:${#NAME}}"				
					;;
				E)	[ ${VAL} -gt ${#EXT} ] && VAL=${#EXT}
					EXT="${EXT:$VAL:${#EXT}}"
					;;
				NE)	[ ${VAL} -gt $((${#NAME}+${#DOT}+${#EXT})) ] && VAL=$((${#NAME}+${#DOT}+${#EXT}))
					[ ${VAL} -gt ${#NAME} ] && { NAME="${NAME}${DOT}${EXT}"; EXT=""; DOT=""; }
					NAME="${NAME:$VAL:${#NAME}}"
					;;
			esac
		fi

		# -----------

		# DELETE_LAST
		if [ "$varDELETE_LAST" = "true" ]; then
			VAL="${varDELETE_LAST_VALUE}"
			case "$MODE" in
				N)	[ ${VAL} -gt ${#NAME} ] && VAL=${#NAME}
					NAME="${NAME:0:${#NAME}-$VAL}"				
					;;
				E)	[ ${VAL} -gt ${#EXT} ] && VAL=${#EXT}
					EXT="${EXT:0:${#EXT}-$VAL}"
					;;
				NE)	[ ${VAL} -gt $((${#NAME}+${#DOT}+${#EXT})) ] && VAL=$((${#NAME}+${#DOT}+${#EXT}))
					if [ ${VAL} -gt ${#EXT} ]; then
						NAME="${NAME}${DOT}${EXT}"
						EXT=""; DOT=""
						NAME="${NAME:0:${#NAME}-$VAL}"
					else
						EXT="${EXT:0:${#EXT}-$VAL}"
					fi
					;;
			esac
		fi

		# -----------

		# PREPEND
		if [ "$varPREPEND" = "true" ] && [ "$varPREPEND_STRING" ]; then
			VAL="${varPREPEND_STRING////}"	# remove /
			case "$MODE" in
				N|NE)	NAME="${VAL}${NAME}"				;;
				E)	[ "$DOT" ] && EXT="${VAL}${EXT}"	;;
			esac      
		fi

		# -----------

		# APPEND
		if [ "$varAPPEND" = "true" ] && [ "$varAPPEND_STRING" ]; then
			VAL="${varAPPEND_STRING////}"	# remove /
			case "$MODE" in
				N)	NAME="${NAME}${VAL}"				;;
				E)	[ "$DOT" ] && EXT="${EXT}${VAL}"	;;
				NE)	if [ "$DOT" ]; then
						EXT="${EXT}${VAL}"
					else
						NAME="${NAME}${VAL}"
					fi
					;;
			esac
		fi

		# -----------

		# REPLACE
		if [ "$varREPLACE" = "true" ] && [ "$varREPLACE_STRING_FROM" ]; then
			VAL_FROM="${varREPLACE_STRING_FROM////}"	# remove /
			VAL_TO="${varREPLACE_STRING_TO////}"		# remove /
			
			if [ "$varFIRST_OCCUR" = "true" ]; then
				if [ "$varPATTERN_MATCH" = "true" ]; then
					case "$MODE" in
						N)	NAME="${NAME/$VAL_FROM/$VAL_TO}"	;;
						E)	EXT="${EXT/$VAL_FROM/$VAL_TO}"	;;
						NE)	NAME="${NAME}${DOT}${EXT}"
							NAME="${NAME/$VAL_FROM/$VAL_TO}"
							func_split "$NAME"
							;;
					esac
				else
					case "$MODE" in
						N)	NAME="${NAME/"$VAL_FROM"/$VAL_TO}"	;;
						E)	EXT="${EXT/"$VAL_FROM"/$VAL_TO}"	;;
						NE)	NAME="${NAME}${DOT}${EXT}"
							NAME="${NAME/"$VAL_FROM"/$VAL_TO}"
							func_split "$NAME"
							;;
					esac
				fi
			else	# all occurences
				if [ "$varPATTERN_MATCH" = "true" ]; then
					case "$MODE" in
						N)	NAME="${NAME//$VAL_FROM/$VAL_TO}"	;;
						E)	EXT="${EXT//$VAL_FROM/$VAL_TO}"	;;
						NE)	NAME="${NAME}${DOT}${EXT}"
							NAME="${NAME//$VAL_FROM/$VAL_TO}"
							func_split "$NAME"
							;;
					esac
				else
					case "$MODE" in
						N)	NAME="${NAME//"$VAL_FROM"/$VAL_TO}"	;;
						E)	EXT="${EXT//"$VAL_FROM"/$VAL_TO}"	;;
						NE)	NAME="${NAME}${DOT}${EXT}"
							NAME="${NAME//"$VAL_FROM"/$VAL_TO}"
							func_split "$NAME"
							;;
					esac				
				fi
			fi
		fi

		# -----------

		# DELETE_AT
		if [ "$varDELETE_AT" = "true" ]; then
			VAL="${varDELETE_AT_AMOUNT}"
			OFFSET="${varDELETE_AT_OFFSET}"

			case "$MODE" in
				N)	[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#NAME}+${OFFSET}+1)) # negative offset
					[ ${OFFSET} -lt 0 ] && OFFSET=0
					[ ${OFFSET} -gt ${#NAME} ] && OFFSET=${#NAME}
					NAME="${NAME:0:$OFFSET}${NAME:${OFFSET}+${VAL}}"
					;;
				E)	if [ "$DOT" ]; then
						[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#EXT}+${OFFSET}+1)) # negative offset
						[ ${OFFSET} -lt 0 ] && OFFSET=0
						[ ${OFFSET} -gt ${#EXT} ] && OFFSET=${#EXT}
						EXT="${EXT:0:$OFFSET}${EXT:${OFFSET}+${VAL}}"
					fi
					;;
				NE)	[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#NAME}+${#DOT}+${#EXT}+${OFFSET}+1)) # negative offset
					[ ${OFFSET} -lt 0 ] && OFFSET=0
					[ ${OFFSET} -gt $((${#NAME}+${#DOT}+${#EXT})) ] && OFFSET=$((${#NAME}+${#DOT}+${#EXT}))
					NAME="${NAME}${DOT}${EXT}"
					NAME="${NAME:0:$OFFSET}${NAME:${OFFSET}+${VAL}}"
					func_split "$NAME"
					;;
			esac
		fi      

		# -----------

		# INSERT
		if [ "$varINSERT" = "true" ] && [ "$varINSERT_STRING" ]; then
			VAL="${varINSERT_STRING////}"	# remove /
			OFFSET="${varINSERT_OFFSET}"

			case "$MODE" in
				N)	[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#NAME}+${OFFSET}+1)) # negative offset
					[ ${OFFSET} -lt 0 ] && OFFSET=0
					[ ${OFFSET} -gt ${#NAME} ] && OFFSET=${#NAME}
					NAME="${NAME:0:$OFFSET}${VAL}${NAME:$OFFSET:${#NAME}-$OFFSET}"
					;;
				E)	if [ "$DOT" ]; then
						[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#EXT}+${OFFSET}+1)) # negative offset
						[ ${OFFSET} -lt 0 ] && OFFSET=0
						[ ${OFFSET} -gt ${#EXT} ] && OFFSET=${#EXT}
						EXT="${EXT:0:$OFFSET}${VAL}${EXT:$OFFSET:${#EXT}-$OFFSET}"
					fi
					;;
				NE)	if [ "$DOT" ]; then
						[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#NAME}+${#DOT}+${#EXT}+${OFFSET}+1)) # negative offset
						[ ${OFFSET} -lt 0 ] && OFFSET=0
						[ ${OFFSET} -gt $((${#NAME}+${#DOT}+${#EXT})) ] && OFFSET=$((${#NAME}+${#DOT}+${#EXT}))
						if [ ${OFFSET} -le ${#NAME} ]; then
							NAME="${NAME:0:$OFFSET}${VAL}${NAME:$OFFSET:${#NAME}-$OFFSET}"
						else
							OFFSET=$((${OFFSET}-${#NAME}-${#DOT}))
							EXT="${EXT:0:$OFFSET}${VAL}${EXT:$OFFSET:${#EXT}-$OFFSET}"
						fi
					else
						[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#NAME}+${OFFSET}+1)) # negative offset
						[ ${OFFSET} -lt 0 ] && OFFSET=0
						[ ${OFFSET} -gt ${#NAME} ] && OFFSET=${#NAME}
						NAME="${NAME:0:$OFFSET}${VAL}${NAME:$OFFSET:${#NAME}-$OFFSET}"
					fi
					;;
			esac
		fi

		# -----------

		# INSERT_SEQ
		if [ "$varINSERT_SEQ" = "true" ]; then
			VAL=$(printf "%.${varINSERT_SEQ_DIGITS}d\n" ${VAL_SEQ})
			OFFSET="${varINSERT_SEQ_OFFSET}"

			case "$MODE" in
				N)	[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#NAME}+${OFFSET}+1)) # negative offset
					[ ${OFFSET} -lt 0 ] && OFFSET=0
					[ ${OFFSET} -gt ${#NAME} ] && OFFSET=${#NAME}
					NAME="${NAME:0:$OFFSET}${VAL}${NAME:$OFFSET:${#NAME}-$OFFSET}"
					;;
				E)	if [ "$DOT" ]; then
						[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#EXT}+${OFFSET}+1)) # negative offset
						[ ${OFFSET} -lt 0 ] && OFFSET=0
						[ ${OFFSET} -gt ${#EXT} ] && OFFSET=${#EXT}
						EXT="${EXT:0:$OFFSET}${VAL}${EXT:$OFFSET:${#EXT}-$OFFSET}"
					else
						((VAL_SEQ--))
					fi
					;;
				NE)	if [ "$DOT" ]; then
						[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#NAME}+${#DOT}+${#EXT}+${OFFSET}+1)) # negative offset
						[ ${OFFSET} -lt 0 ] && OFFSET=0
						[ ${OFFSET} -gt $((${#NAME}+${#DOT}+${#EXT})) ] && OFFSET=$((${#NAME}+${#DOT}+${#EXT}))
						if [ ${OFFSET} -le ${#NAME} ]; then
							NAME="${NAME:0:$OFFSET}${VAL}${NAME:$OFFSET:${#NAME}-$OFFSET}"
						else
							OFFSET=$((${OFFSET}-${#NAME}-${#DOT}))
							EXT="${EXT:0:$OFFSET}${VAL}${EXT:$OFFSET:${#EXT}-$OFFSET}"
						fi
					else
						[ ${OFFSET//-/} -ne ${OFFSET} ] && OFFSET=$((${#NAME}+${OFFSET}+1)) # negative offset
						[ ${OFFSET} -lt 0 ] && OFFSET=0
						[ ${OFFSET} -gt ${#NAME} ] && OFFSET=${#NAME}
						NAME="${NAME:0:$OFFSET}${VAL}${NAME:$OFFSET:${#NAME}-$OFFSET}"
					fi
					;;
			esac
			((VAL_SEQ++))
		fi

		# -----------

		# CASE
		if [ "$varCASE" = "true" ]; then        
			# Note: tr (or Bash < 4.3) doesn't handle changing case of diacritics (UTF8), but AWK does

			if [ "$USE_BASH_CASE" = 'true' ]; then

				if [ "$varCASE_LOWER" = "true" ]; then
					case "$MODE" in
						N)	NAME="${NAME,,}"	;;
						E)	EXT="${EXT,,}"		;;
						NE)	NAME="${NAME,,}"
							EXT="${EXT,,}"		;;
					esac
				else
					case "$MODE" in
						N)	NAME="${NAME^^}"	;;
						E)	EXT="${EXT^^}"		;;
						NE)	NAME="${NAME^^}"
							EXT="${EXT^^}"		;;
					esac
				fi

			else	# AWK

				if [ "$varCASE_LOWER" = "true" ]; then
					case "$MODE" in
						N)	NAME="$(echo "$NAME" | awk '{print tolower($0)}')"	;;
						E)	EXT="$(echo "$EXT" | awk '{print tolower($0)}')"	;;
						NE)	NAME="$(echo "$NAME" | awk '{print tolower($0)}')"
							EXT="$(echo "$EXT" | awk '{print tolower($0)}')"	;;
					esac
				else
					case "$MODE" in
						N)	NAME="$(echo "$NAME" | awk '{print toupper($0)}')"	;;
						E)	EXT="$(echo "$EXT" | awk '{print toupper($0)}')"	;;
						NE)	NAME="$(echo "$NAME" | awk '{print toupper($0)}')"
							EXT="$(echo "$EXT" | awk '{print toupper($0)}')"	;;
					esac
				fi
			fi

		fi

		# -----------

		# CAPITALIZE
		if [ "$varCAPITALIZE" = "true" ]; then
			# Note: there is an undocumented feature of Bash (still works in Bash-5.1.16)
			# https://stackoverflow.com/questions/64745435/undocumented-c-option-for-bashs-declare
			# But it's inconsistent with AWK - it decapitalizes all other letters in a word first
			
			if [ "$USE_BASH_CASE" = 'true' ]; then
				if [ "$varCAPITALIZE_FIRST" = "true" ]; then
					case "$MODE" in
						N)	NAME="${NAME^}"	;;
						E)	EXT="${EXT^}"	;;
						NE)	NAME="${NAME^}"
							EXT="${EXT^}"	;;
					esac
				else
					case "$MODE" in
						N)	NAME="$(for i in $NAME; do echo -n "${i^} "; done)"; NAME="${NAME%?}"	;;
						E)	EXT="$(for i in $EXT; do echo -n "${i^} "; done)"; EXT="${EXT%?}" 		;;
						NE)	NAME="$(for i in $NAME; do echo -n "${i^} "; done)"; NAME="${NAME%?}"
							EXT="$(for i in $EXT; do echo -n "${i^} "; done)"; EXT="${EXT%?}"	 	;;
					esac
				fi

			else	# AWK

				if [ "$varCAPITALIZE_FIRST" = "true" ]; then
					case "$MODE" in
						N)	NAME="$(echo "$NAME" | awk '{print toupper(substr($0,1,1)) substr($0,2); }')"	;;
						E)	EXT="$(echo "$EXT" | awk '{print toupper(substr($0,1,1)) substr($0,2); }')"	;;
						NE)	NAME="$(echo "$NAME" | awk '{print toupper(substr($0,1,1)) substr($0,2); }')"
							EXT="$(echo "$EXT" | awk '{print toupper(substr($0,1,1)) substr($0,2); }')"	;;
					esac
				else
					case "$MODE" in
						N)	NAME="$(echo "$NAME" | awk 'BEGIN{FS=OFS=" "} {for (i=1;i<=NF;i++) {$i=toupper(substr($i,1,1)) substr($i,2)}}1')"	;;
						E)	EXT="$(echo "$EXT" | awk 'BEGIN{FS=OFS=" "} {for (i=1;i<=NF;i++) {$i=toupper(substr($i,1,1)) substr($i,2)}}1')"		;;
						NE)	NAME="$(echo "$NAME" | awk 'BEGIN{FS=OFS=" "} {for (i=1;i<=NF;i++) {$i=toupper(substr($i,1,1)) substr($i,2)}}1')"
							EXT="$(echo "$EXT" | awk 'BEGIN{FS=OFS=" "} {for (i=1;i<=NF;i++) {$i=toupper(substr($i,1,1)) substr($i,2)}}1')"		;;
					esac
				fi
			fi

		fi

		# -----------

		OLD_NAME="${OLD_NAME//|/$FAKE}"
		NEW_NAME="${NAME//|/$FAKE}${DOT}${EXT//|/$FAKE}"
		#[ "$NEW_NAME" = "$OLD_NAME" ] && NEW_NAME=""

		oldLANG="$LANG"; LANG=C	# faster

		func_escape
		sed -i "s/\(.*|${OLD_NAME}||\).*/\1${NEW_NAME}/" "$WORKDIR/list"

		LANG="$oldLANG"

	done <<< "$varLIST"

	kill -0 $GPID 2>/dev/null && kill $GPID
}
export -f func_preview

# -----------------------------------------------------------------------------

func_commit() {
	# Check for duplicates
	: > "${WORKDIR}/list.final"
	sed -n 's#.*|\(.*||.*\)#\1#p' "${WORKDIR}/list" | while IFS='' read -r ITEM; do
		OLD_NAME="${ITEM%%|*}"
		NEW_NAME="${ITEM##*|}"
		if [ "$NEW_NAME" = "" ] || [ "$OLD_NAME" = "$NEW_NAME" ]; then
			echo "${OLD_NAME}|" >> "${WORKDIR}/list.final"
		else
			echo "${OLD_NAME}|${NEW_NAME}" >> "${WORKDIR}/list.final"
		fi
	done

	if [ "$(cat $WORKDIR/list.final | tr '|' '\n' | sort | uniq -d)" ]; then
		echo -n "<b>$(gettext "Some filenames are duplicated, can't proceed!")</b>" > "${WORKDIR}/msg"
		$GTKDIALOG -p GUI_ERROR
		return 1
	fi

	# Are you reeeaaally sure?
	echo -n "<b>$(gettext "Are you really sure you want to proceed?")</b>" > "${WORKDIR}/msg"
	eval $($GTKDIALOG -p GUI_CONFIRM)
	[ "$EXIT" != "yes" ] && return 1

	CURDIR="$(cat $WORKDIR/curdir)"

	: > "${WORKDIR}/log"

	# Rename
	echo -n "<b>$(gettext "Renaming, please wait...")</b>" > "$WORKDIR/msg"
	$GTKDIALOG -p GUI_INFO &
	GPID=$!

	grep -o ".*|[^$].*" "${WORKDIR}/list.final" | while IFS='' read -r ITEM; do
		OLD_NAME="${ITEM%%|*}"
		NEW_NAME="${ITEM##*|}"
		if [ ! -e "${CURDIR}/${NEW_NAME//$FAKE/|}" ]; then	# PRECAUTION!!!
			mv -f "${CURDIR}/${OLD_NAME//$FAKE/|}" "${CURDIR}/${NEW_NAME//$FAKE/|}" 2>>"${WORKDIR}/log"
		else
			echo "$(gettext "Multirename: can't rename") '${OLD_NAME//$FAKE/|}' -> '${NEW_NAME//$FAKE/|}' - $(gettext "the latter already exists!")" >> "${WORKDIR}/log"
		fi
	done

	kill -0 $GPID 2>/dev/null && kill $GPID

	if [ -s "${WORKDIR}/log" ]; then
		echo -ne "<b>$(gettext "There were errors and not all files have been renamed!")</b>" > "${WORKDIR}/msg"
		$GTKDIALOG -p GUI_LOG
	fi

	func_readdir "${CURDIR}"
	
}
export -f func_commit

# -----------------------------------------------------------------------------

func_manual_do () {
	OLD_NAME="${varMANUAL_OLD//|/$FAKE}"
	NEW_NAME="${varMANUAL_NEW//|/$FAKE}"
	NEW_NAME="${NEW_NAME////}"	# remove /
	[ "$NEW_NAME" = "$OLD_NAME" ] && NEW_NAME=""

	func_escape

	sed -i "s/\(.*|${OLD_NAME}||\).*/\1${NEW_NAME}/" "${WORKDIR}/list"
}
export -f func_manual_do

# -----------------------------------------------------------------------------

func_manual () {
	[ "$varLIST" ] || return 1

	ITEM_COUNT="$(echo -e "$varLIST" | wc -l)"

	if [ $ITEM_COUNT -gt 1 ]; then
		echo -ne "<b>$(gettext "Please select only one item.")</b>" > "${WORKDIR}/msg"
		$GTKDIALOG -p GUI_ERROR
		return 1
	fi

	MANUAL_OLD="${varLIST//$FAKE/|}"
	MANUAL_NEW="$(grep -F "|$(echo "${varLIST}")||" $WORKDIR/list | cut -f4- -d'|')"
	MANUAL_NEW="${MANUAL_NEW//$FAKE/|}"

	echo -n "$MANUAL_OLD" > "${WORKDIR}/manual_old"
	echo -n "$MANUAL_NEW" > "${WORKDIR}/manual_new"

	export GUI_MANUAL='
    <window title="'${APPNAME}'" window-position="2" image-name="'${APPICON}'" resizable="true" width-request="512">
	  <vbox>
		<frame '$(gettext "Rename the item manually")'>
	      <hbox>
	        <entry editable="false" has-frame="false">
	      	  <variable>varMANUAL_OLD</variable>
	      	  <input file>"'${WORKDIR}/manual_old'"</input>
	        </entry>
	        <pixmap stock-icon-size="3"><input file stock="gtk-go-forward"></input></pixmap>
	        <entry has-focus="true">
	      	  <variable>varMANUAL_NEW</variable>
	      	  <input>[ -s "'${WORKDIR}/manual_new'" ] && cat "'${WORKDIR}/manual_new'" || cat "'${WORKDIR}/manual_old'"</input>
	        </entry>
	      </hbox>
        </frame>
            
		<hbox space-fill="false" space-expand="false">
		  <button>
		    <label>"'$(gettext "Apply")'"</label>
		    <input file stock="gtk-apply"></input>
		    <action>func_manual_do</action>
		    <action>exit:exit</action>
		  </button>
		  <button>
		    <label>"'$(gettext "Cancel")'"</label>
		    <input file stock="gtk-cancel"></input>
		    <action>exit:exit</action>
		  </button>
		</hbox>
         
	  </vbox>

	  <action signal="delete-event">exit:abort</action>
	</window>'

	$GTKDIALOG -p GUI_MANUAL

}
export -f func_manual

# =============================================================================

export GUI_ABOUT='
<window title="'${APPNAME}'" window-position="1" image-name="'${APPICON}'" resizable="false" modal="true">
  <vbox>
    <vbox space-fill="true" space-expand="true">
      <pixmap><input file stock="gtk-about"></input></pixmap>
      <text use-markup="true"><label>"<span font-size='"'x-large'"'><b>'${APPNAME}'</b></span>"</label></text>
      <hseparator></hseparator>
      <text><label>Copyright © 2015,2016,2020,2022 by JakeSFR</label></text>
      <text><label>German translation by L18L</label></text>
      <text><label>GNU GPL v2 applies</label></text>
      <hseparator></hseparator>
      <hbox>
		<button>
			<input file stock="gtk-close"></input>
			<action>closewindow:GUI_ABOUT</action>
		</button>
	  </hbox>
    </vbox>
  </vbox>
  
  <variable>GUI_ABOUT</variable>
  <action signal="delete-event">exit:abort</action>
</window>'

# -----------------------------------------------------------------------------

# Unused - add too much overhead

export GUI_PROGRESS='
<window title="'${APPNAME}'" window-position="1" image-name="'${APPICON}'" resizable="false">
  <vbox>
    <hbox space-fill="true" space-expand="true">
      <pixmap><input file stock="gtk-execute"></input></pixmap>
      <text use-markup="true"><input file>'${WORKDIR}/msg'</input></text>
    </hbox>
    <progressbar>
      <variable>varPROGRESS</variable>
      <input>while [ -e '${WORKDIR}/progress' ]; do cat '${WORKDIR}/progress' 2>/dev/null; sleep .2; done</input>
      <action>exit:EXIT</action>
    </progressbar>
  </vbox>
  
  <action signal="delete-event">exit:abort</action>
</window>'

# -----------------------------------------------------------------------------

export GUI_INFO='
<window title="'${APPNAME}'" window-position="1" image-name="'${APPICON}'" resizable="false">
  <vbox>
    <hbox space-fill="true" space-expand="true">
      <pixmap><input file stock="gtk-dialog-info"></input></pixmap>
      <text use-markup="true"><input file>'${WORKDIR}/msg'</input></text>
    </hbox>
  </vbox>
  
  <action signal="delete-event">exit:abort</action>
</window>'

# -----------------------------------------------------------------------------

export GUI_ERROR='
<window title="'${APPNAME}'" window-position="1" image-name="'${APPICON}'" resizable="false">
  <vbox>
    <hbox space-fill="true" space-expand="true">
      <pixmap><input file stock="gtk-dialog-error"></input></pixmap>
      <text use-markup="true"><input file>'${WORKDIR}/msg'</input></text>
    </hbox>
    <hbox>
      <button ok></button>
    </hbox>
  </vbox>
  
  <action signal="delete-event">exit:abort</action>
</window>'

# -----------------------------------------------------------------------------

export GUI_LOG='
<window title="'${APPNAME}'" window-position="1" image-name="'${APPICON}'">
  <vbox space-fill="true" space-expand="true">

    <hbox space-fill="false" space-expand="false">
	  <text space-fill="true" space-expand="true"><label>""</label></text>
      <pixmap>
        <input file stock="gtk-dialog-error"></input>
      </pixmap>
      <text use-markup="true" space-fill="false" space-expand="false">
        <input file>'${WORKDIR}/msg'</input>
      </text>
	  <text space-fill="true" space-expand="true"><label>""</label></text>
    </hbox>

	<vbox space-fill="true" space-expand="true">
      <edit editable="false" cursor-visible="false">
	    <input file>'${WORKDIR}/log'</input>
      </edit>
	</vbox>

    <hbox space-fill="false" space-expand="false">
      <button ok></button>
    </hbox>
  </vbox>
  
  <action signal="delete-event">exit:abort</action>
</window>'

# -----------------------------------------------------------------------------

export GUI_CONFIRM='
<window title="'${APPNAME}'" window-position="1" image-name="'${APPICON}'" resizable="false">
  <vbox>
    <pixmap><input file stock="gtk-dialog-question"></input></pixmap>
    <text><label>""</label></text>
    <text wrap="false" use-markup="true"><input file>'${WORKDIR}/msg'</input></text>
    <text><label>""</label></text>
    <hbox>
      <button use-underline="true" space-fill="true" space-expand="true">
        <label>"'$(gettext "_No")'"</label>
        <input file stock="gtk-no"></input>
        <action>exit:no</action>
      </button>
      <button use-underline="true" space-fill="true" space-expand="true">
        <label>"'$(gettext "_Yes")'"</label>
        <input file stock="gtk-yes"></input>
        <action>exit:yes</action>
      </button>
    </hbox>
  </vbox>

  <action signal="delete-event">exit:abort</action>
</window>'

# -----------------------------------------------------------------------------

export GUI_MAIN='
<window title="'${APPNAME}'" image-name="'${APPICON}'">
  <vbox space-fill="true" space-expand="true">
    <hbox>
      <hbox space-fill="true" space-expand="true">
        <vbox>

          <hbox>
            <hbox space-fill="true" space-expand="true">
              <entry fs-title="'$(gettext "Select directory")'" fs-action="folder" space-fill="true" space-expand="true">
                <variable>varCURDIR</variable>
                <input file>'"${WORKDIR}/curdir"'</input>
                <action signal="activate">func_readdir "${varCURDIR}"</action>
                <action signal="activate">refresh:varLIST</action>
                <action signal="activate">refresh:varCURDIR</action>
                <action signal="activate">refresh:varSTATUS</action>
                <action signal="activate">disable:varCOMMIT</action>
              </entry>
              <button tooltip-text="'$(gettext "Select directory")'" space-fill="false" space-expand="false">
                <input file stock="gtk-directory"></input>
                <action>fileselect:varCURDIR</action>
                <action>activate:varCURDIR</action>
              </button>
            </hbox>

            <button tooltip-text="'$(gettext "Parent directory")'">
              <variable>varPARENT</variable>
              <input file stock="gtk-go-up"></input>
              <action>func_readdir "$(dirname "$(cat $WORKDIR/curdir)")"</action>
              <action>refresh:varLIST</action>
              <action>refresh:varCURDIR</action>
              <action>refresh:varSTATUS</action>
              <action>disable:varCOMMIT</action>
            </button>
        
            <button tooltip-text="'$(gettext "Home")'">
              <input file stock="gtk-home"></input>
              <action>func_readdir "$HOME"</action>
              <action>refresh:varLIST</action>
              <action>refresh:varCURDIR</action>
              <action>refresh:varSTATUS</action>
              <action>disable:varCOMMIT</action>
            </button>
            
            <button tooltip-text="'$(gettext "Re-read current directory")'">
              <input file stock="gtk-refresh"></input>
              <action>func_readdir "$(cat $WORKDIR/curdir)"</action>
              <action>refresh:varLIST</action>
              <action>refresh:varCURDIR</action>
              <action>refresh:varSTATUS</action>
              <action>disable:varCOMMIT</action>
            </button>
           
            <togglebutton use-underline="true" tooltip-text="'$(gettext "Enable natural sort of numbers within text")'">
              <default>'${varNSORT}'</default>
              <variable>varNSORT</variable>
              <label>"'$(gettext "_Numeric sort")'"</label>
              <action>func_readdir "$(cat $WORKDIR/curdir)"</action>
              <action>refresh:varLIST</action>
              <action>refresh:varSTATUS</action>
              <action>disable:varCOMMIT</action>
            </togglebutton>

          </hbox>

          <tree rules-hint="false" column-sizing="330|14" exported-column="0" block-function-signals="true" column-header-active="true|false|true" column-resizeable="true|false|true" selection-mode="3" enable-search="false|false|false">
            <variable>varLIST</variable>
            <height>500</height>
            <label>"'$(gettext "Old Name")'|''|'$(gettext "New Name")'"</label>
            <input file '${TREEICON}'>'"${WORKDIR}/list"'</input>
            <action>func_readdir "$(cat $WORKDIR/curdir)/${varLIST}"</action>
            <action>refresh:varLIST</action>
            <action>refresh:varCURDIR</action>
            <action>refresh:varSTATUS</action>
            
            <action signal="button-release-event" condition="command_is_true( [ $PTR_BTN -eq 3 ] && echo true)">func_manual</action>
            <action signal="key-release-event" condition="command_is_true( [ \"$KEY_SYM\" = \"Return\" ] && [ $(($KEY_MOD & 1)) -eq 1 ] && echo true)">func_manual</action>
            <action signal="button-release-event" condition="command_is_true( [ $PTR_BTN -eq 3 ] && echo true)">refresh:varLIST</action>
            <action signal="key-release-event" condition="command_is_true( [ \"$KEY_SYM\" = \"Return\" ] && [ $(($KEY_MOD & 1)) -eq 1 ] && echo true)">refresh:varLIST</action>
            <action signal="button-release-event" condition="command_is_true( [ $PTR_BTN -eq 3 ] && echo true)">refresh:varSTATUS</action>
            <action signal="key-release-event" condition="command_is_true( [ \"$KEY_SYM\" = \"Return\" ] && [ $(($KEY_MOD & 1)) -eq 1 ] && echo true)">refresh:varSTATUS</action>
            <action signal="button-release-event" condition="command_is_true( [ $PTR_BTN -eq 3 ] && echo true)">enable:varCOMMIT</action>
            <action signal="key-release-event" condition="command_is_true( [ \"$KEY_SYM\" = \"Return\" ] && [ $(($KEY_MOD & 1)) -eq 1 ] && echo true)">enable:varCOMMIT</action>
            
            <action condition="command_is_true( [ $(cut -f4- -d \"|\" $WORKDIR/list | grep -v \"^$\" | wc -l) -eq 0 ] && echo true)">disable:varCOMMIT</action>
            <action signal="button-release-event" condition="command_is_true( [ $(cut -f4- -d \"|\" $WORKDIR/list | grep -v \"^$\" | wc -l) -eq 0 ] && echo true)">disable:varCOMMIT</action>
            <action signal="key-release-event" condition="command_is_true( [ $(cut -f4- -d \"|\" $WORKDIR/list | grep -v \"^$\" | wc -l) -eq 0 ] && echo true)">disable:varCOMMIT</action>

            <action signal="changed">refresh:varSTATUS</action>
          </tree>
          
          <hbox>

			<text><label>'$(gettext "Show:")'</label></text>
			<comboboxtext>
				<variable>varSHOW</variable>
				<default>'${varSHOW}'</default>
				<item>'$(gettext "Folders and Files")'</item>
				<item>'$(gettext "Folders only")'</item>
				<item>'$(gettext "Files only")'</item>
				<action>func_readdir "$(cat $WORKDIR/curdir)"</action>
				<action>refresh:varLIST</action>
				<action>refresh:varCURDIR</action>
				<action>refresh:varSTATUS</action>
				<action>disable:varCOMMIT</action>
			</comboboxtext>

            <checkbox>
              <default>'${varHIDDEN}'</default>
              <variable>varHIDDEN</variable>
              <label>"'$(gettext "Hidden")'"</label>
              <action>func_readdir "$(cat $WORKDIR/curdir)"</action>
              <action>refresh:varLIST</action>
              <action>refresh:varSTATUS</action>
              <action>disable:varCOMMIT</action>
            </checkbox>

			<text><label>""</label></text>
			<vseparator></vseparator>
			<text><label>""</label></text>

			<text><label>'$(gettext "Filter:")'</label></text>
			<entry secondary-icon-stock="gtk-clear">
				<variable>varFILTER</variable>
				<action signal="secondary-icon-release">clear:varFILTER</action>
				<action signal="secondary-icon-release">refresh:varFILTER</action>
				<action>func_readdir "$(cat $WORKDIR/curdir)"</action>
				<action>refresh:varLIST</action>
				<action>refresh:varCURDIR</action>
				<action>refresh:varSTATUS</action>
				<action>disable:varCOMMIT</action>
			</entry>

			<checkbox>
				<variable>varREGEX</variable>
				<default>'${varREGEX}'</default>
				<label>'$(gettext "Regex")'</label>
				<default>false</default>
				<action>func_readdir "$(cat $WORKDIR/curdir)"</action>
				<action>refresh:varLIST</action>
				<action>refresh:varCURDIR</action>
				<action>refresh:varSTATUS</action>
				<action>disable:varCOMMIT</action>
			</checkbox>
			
			<checkbox>
				<variable>varSENSITIVE</variable>
				<default>'${varSENSITIVE}'</default>
				<label>'$(gettext "Case sensitive")'</label>
				<default>false</default>
				<action>func_readdir "$(cat $WORKDIR/curdir)"</action>
				<action>refresh:varLIST</action>
				<action>refresh:varCURDIR</action>
				<action>refresh:varSTATUS</action>
				<action>disable:varCOMMIT</action>
			</checkbox>

          </hbox>

          <hseparator></hseparator>

          <hbox space-fill="false" space-expand="false">
            <statusbar has-resize-grip="false" space-fill="true" space-expand="true">
              <variable>varSTATUS</variable>
              <input>echo -ne " '$(gettext "All items:")' $(cat $WORKDIR/list | wc -l)\t\t'$(gettext "Selected items:")' $([ "$varLIST" = "" ] && echo -n "0" || echo "$varLIST" | wc -l)\t\t'$(gettext "Renamed items:")' $(cut -f4- -d "|" $WORKDIR/list | grep -v "^$" | wc -l)"</input>
            </statusbar>
          </hbox>
              
        </vbox>
        
      </hbox>
      
      <hbox space-fill="false" space-expand="false" spacing="2">
      
        <vseparator space-fill="false" space-expand="false"></vseparator>
        <text space-fill="true" space-expand="true"><label>""</label></text>

		<vbox spacing="2">

 		  <text use-markup="true">
			<label>"<span bgcolor='"'#e8e800'"' fgcolor='"'#000000'"'>'$(gettext "Actions are performed on <u>selected</u> items.")'</span>"</label>
		  </text>
		         
		  <frame>
		   <vbox space-fill="true" space-expand="true" spacing="2" visible="false" shadow-type="0" '${VBOX_SCROLL}'>
            <hbox>
              <text><label>"'$(gettext "Mode:")'"</label></text>
              <text space-fill="true" space-expand="true"><label>""</label></text>
              <comboboxtext>
                <variable>varMODE</variable>
                <item>"'$(gettext "Basename only")'"</item>
                <item>"'$(gettext "Extension only")'"</item>
                <item>"'$(gettext "Basename with Extension")'"</item>
              </comboboxtext>
            </hbox>
          
            <hbox>
              <checkbox>
                <variable>varIGNORE_DIREXT</variable>
                <default>true</default>
                <label>'$(gettext "Ignore extensions for folders")'</label>
              </checkbox>
            </hbox>
            
            <hseparator></hseparator>

            <hbox>
              <checkbox>
                <variable>varDELETE_FIRST</variable>
                <label>"'$(gettext "Delete first")'"</label>
                <action>if true enable:varDELETE_FIRST_VALUE</action>
                <action>if false disable:varDELETE_FIRST_VALUE</action>
              </checkbox>
              <text space-fill="true" space-expand="true"><label>""</label></text>
              <spinbutton range-min="1" range-max="255" range-step="1" range-value="1" sensitive="false">
                <variable>varDELETE_FIRST_VALUE</variable>
              </spinbutton>
              <text><label>"'$(gettext "char(s)")'"</label></text>
            </hbox>
            
            <hseparator></hseparator>
            
            <hbox>
              <checkbox>
                <variable>varDELETE_LAST</variable>
                <label>"'$(gettext "Delete last")'"</label>
                <action>if true enable:varDELETE_LAST_VALUE</action>
                <action>if false disable:varDELETE_LAST_VALUE</action>
              </checkbox>
              <text space-fill="true" space-expand="true"><label>""</label></text>
              <spinbutton range-min="1" range-max="255" range-step="1" range-value="1" sensitive="false">
                <variable>varDELETE_LAST_VALUE</variable>
              </spinbutton>
              <text><label>"'$(gettext "char(s)")'"</label></text>
            </hbox>
            
            <hseparator></hseparator>
                        
            <hbox>
              <checkbox>
                <variable>varPREPEND</variable>
                <label>"'$(gettext "Prepend")'"</label>
                <action>if true enable:varPREPEND_STRING</action>
                <action>if false disable:varPREPEND_STRING</action>
              </checkbox>
              <text space-fill="true" space-expand="true"><label>""</label></text>
              <entry sensitive="false">
                <variable>varPREPEND_STRING</variable>
              </entry>
            </hbox>
            
            <hseparator></hseparator>

            <hbox>
              <checkbox>
                <variable>varAPPEND</variable>
                <label>"'$(gettext "Append")'"</label>
                <action>if true enable:varAPPEND_STRING</action>
                <action>if false disable:varAPPEND_STRING</action>
              </checkbox>
              <text space-fill="true" space-expand="true"><label>""</label></text>
              <entry sensitive="false">
                <variable>varAPPEND_STRING</variable>
              </entry>
            </hbox>
            
            <hseparator></hseparator>

            <vbox spacing="1">
              <hbox>
                <checkbox>
                  <variable>varREPLACE</variable>
                  <label>"'$(gettext "Replace")'"</label>
                  <action>if true enable:varREPLACE_STRING_FROM</action>
                  <action>if true enable:varREPLACE_STRING_TO</action>
                  <action>if true enable:varFIRST_OCCUR</action>
                  <action>if true enable:varALL_OCCUR</action>
                  <action>if true enable:varPATTERN_MATCH</action>
                  <action>if false disable:varREPLACE_STRING_FROM</action>
                  <action>if false disable:varREPLACE_STRING_TO</action>
                  <action>if false disable:varFIRST_OCCUR</action>
                  <action>if false disable:varALL_OCCUR</action>
                  <action>if false disable:varPATTERN_MATCH</action>
                </checkbox>
                <text space-fill="true" space-expand="true"><label>""</label></text>
                <entry max-length="256" space-fill="false" space-expand="false" sensitive="false">
                  <variable>varREPLACE_STRING_FROM</variable>
                </entry>
              </hbox>
              <hbox>
                <text><label>"'$(gettext "with")'  "</label></text>
                <entry max-length="256" space-fill="false" space-expand="false" sensitive="false">
                  <variable>varREPLACE_STRING_TO</variable>
                </entry>
              </hbox>
              <hbox homogeneous="true">
                <radiobutton sensitive="false">
                  <variable>varFIRST_OCCUR</variable>
				  <label>"'$(gettext "First occurence")'"</label>
                </radiobutton>
                <radiobutton sensitive="false">
                  <variable>varALL_OCCUR</variable>
				  <label>"'$(gettext "All occurences")'"</label>
                </radiobutton>
              </hbox>
              <hbox>
			    <checkbox sensitive="false">
			      <variable>varPATTERN_MATCH</variable>
			      <label>"'$(gettext "Enable pattern matching")'"</label>
			    </checkbox>
			  </hbox>
            </vbox>
            
            <hseparator></hseparator>
            
            <vbox spacing="1">
              <hbox>
                <checkbox>
                  <variable>varDELETE_AT</variable>
                  <label>"'$(gettext "Delete")'"</label>
                  <action>if true enable:varDELETE_AT_AMOUNT</action>
                  <action>if true enable:varDELETE_AT_OFFSET</action>
                  <action>if false disable:varDELETE_AT_AMOUNT</action>
                  <action>if false disable:varDELETE_AT_OFFSET</action>
                </checkbox>
                <text space-fill="true" space-expand="true"><label>""</label></text>
                <spinbutton range-min="0" range-max="255" range-step="1" range-value="1" sensitive="false">
                  <variable>varDELETE_AT_AMOUNT</variable>
                </spinbutton>
                <text><label>"'$(gettext "char(s)")'"</label></text>
              </hbox>
              <hbox>
                <text><label>"'$(gettext "at offset")'   "</label></text>
                <spinbutton range-min="-255" range-max="255" range-step="1" range-value="0" sensitive="false">
                  <variable>varDELETE_AT_OFFSET</variable>
                </spinbutton>
              </hbox>
            </vbox>
              
            <hseparator></hseparator>
                    
            <vbox spacing="1">
              <hbox>
                <checkbox>
                  <variable>varINSERT</variable>
                  <label>"'$(gettext "Insert")'"</label>
                  <action>if true enable:varINSERT_STRING</action>
                  <action>if true enable:varINSERT_OFFSET</action>
                  <action>if false disable:varINSERT_STRING</action>
                  <action>if false disable:varINSERT_OFFSET</action>
                </checkbox>
                <text space-fill="true" space-expand="true"><label>""</label></text>
                <entry max-length="256" space-fill="false" space-expand="false" sensitive="false">
                  <variable>varINSERT_STRING</variable>
                </entry>
              </hbox>
              <hbox>
                <text><label>"'$(gettext "at offset")'   "</label></text>
                <spinbutton range-min="-255" range-max="255" range-step="1" range-value="0" sensitive="false">
                  <variable>varINSERT_OFFSET</variable>
                </spinbutton>
              </hbox>
            </vbox>
            
            <hseparator></hseparator>
            
			<vbox spacing="1">
              <hbox>
                <checkbox>
                  <variable>varINSERT_SEQ</variable>
                  <label>"'$(gettext "Insert")'"</label>
                  <action>if true enable:varINSERT_SEQ_DIGITS</action>
                  <action>if true enable:varINSERT_SEQ_OFFSET</action>
                  <action>if true enable:varINSERT_SEQ_START</action>
                  <action>if false disable:varINSERT_SEQ_DIGITS</action>
                  <action>if false disable:varINSERT_SEQ_OFFSET</action>
                  <action>if false disable:varINSERT_SEQ_START</action>
                </checkbox>
                <text space-fill="true" space-expand="true"><label>""</label></text>
                <spinbutton range-min="1" range-max="16" range-step="1" range-value="1" sensitive="false">
                  <variable>varINSERT_SEQ_DIGITS</variable>
                </spinbutton>
                <text><label>"'$(gettext "\-digit sequence")'"</label></text>
              </hbox>
              <hbox>
                <text><label>"'$(gettext "starting from")'   "</label></text>
                <spinbutton range-min="0" range-max="1000000000000000" range-step="1" range-value="1" sensitive="false">
                  <variable>varINSERT_SEQ_START</variable>
                </spinbutton>    
              </hbox>
              <hbox>
                <text><label>"'$(gettext "at offset")'   "</label></text>
                <spinbutton range-min="-255" range-max="255" range-step="1" range-value="0" sensitive="false">
                  <variable>varINSERT_SEQ_OFFSET</variable>
                </spinbutton>              
              </hbox>
			</vbox>
                        
            <hseparator></hseparator>

            <hbox>
              <checkbox>
                <variable>varCASE</variable>
                <label>"'$(gettext "Case to")'"</label>
                <action>if true enable:varCASE_LOWER</action>
                <action>if true enable:varCASE_UPPER</action>
                <action>if false disable:varCASE_LOWER</action>
                <action>if false disable:varCASE_UPPER</action>
              </checkbox>
              <text space-fill="true" space-expand="true"><label>""</label></text>
              <radiobutton sensitive="false">
                <variable>varCASE_LOWER</variable>
                <label>"'$(gettext "Lower")'"</label>
              </radiobutton>
              <radiobutton sensitive="false">
                <variable>varCASE_UPPER</variable>
                <label>"'$(gettext "Upper")'"</label>
              </radiobutton>
            </hbox>

            <hseparator></hseparator>

            <hbox>
              <checkbox>
                <variable>varCAPITALIZE</variable>
                <label>"'$(gettext "Capitalize")'"</label>
                 <action>if true enable:varCAPITALIZE_FIRST</action>
                 <action>if true enable:varCAPITALIZE_ALL</action>
                 <action>if false disable:varCAPITALIZE_FIRST</action>
                 <action>if false disable:varCAPITALIZE_ALL</action>
              </checkbox>
              <text space-fill="true" space-expand="true"><label>""</label></text>
              <radiobutton sensitive="false">
                <variable>varCAPITALIZE_FIRST</variable>
                <label>"'$(gettext "First word")'"</label>
              </radiobutton>
              <radiobutton sensitive="false">
                <variable>varCAPITALIZE_ALL</variable>
                <label>"'$(gettext "All words")'"</label>
              </radiobutton>
            </hbox>
            <variable>varOPTIONS</variable>
           </vbox>

          </frame>
          
          <hbox space-fill="false" space-expand="false">
            <button use-underline="true" can-default="true" has-default="true" space-fill="true" space-expand="true" tooltip-text="'$(gettext "Preview renamed items")'">
              <label>"'$(gettext "_Preview")'"</label>
              <input file stock="gtk-find"></input>
              <action>func_preview</action>
              <action>refresh:varLIST</action>
              <action>refresh:varSTATUS</action>
              <action>disable:varCOMMIT</action>
              <action condition="command_is_true( [ $(cut -f4- -d \"|\" $WORKDIR/list | grep -v \"^$\" | wc -l) -gt 0 ] && echo true)">enable:varCOMMIT</action>
            </button>
            
            <button use-underline="true" space-fill="true" space-expand="true" sensitive="false" tooltip-text="'$(gettext "Commit all the changes")'">
              <variable>varCOMMIT</variable>
              <label>"'$(gettext "_Commit")'"</label>
              <input file stock="gtk-apply"></input>
              <action>func_commit</action>
              <action>refresh:varLIST</action>
              <action>refresh:varSTATUS</action>
              <action condition="command_is_true( [ $(cut -f4- -d \"|\" $WORKDIR/list | grep -v \"^$\" | wc -l) -eq 0 ] && echo true)">disable:varCOMMIT</action>
            </button>
            
            <vseparator></vseparator>
            
            <button tooltip-text="'$(gettext "About")'">
              <input file stock="gtk-about"></input>
              <action>launch:GUI_ABOUT</action>
            </button>
            
            <button tooltip-text="'$(gettext "Quit")'">
              <input file stock="gtk-quit"></input>
              <action>exit:exit</action>
            </button>
            
          </hbox>

        </vbox>
        
      </hbox>
        
    </hbox>

  </vbox>

  <action signal="map-event">show:varOPTIONS</action>
  <action signal="show">disable:varCURDIR</action>
  <action signal="show">enable:varCURDIR</action>
  <action signal="delete-event">exit:abort</action>
</window>'

$GTKDIALOG -p GUI_MAIN >/dev/null

# =============================================================================

exit
