ButtonBarTools

Title ButtonBarTools
File Name ButtonBarTools.txt
Description See comments
Author Vochomurka
Parameters Stat, ClipBoard, SourceBar, TargetBar, From, To
Plugins Called vec, ini, file, clip
Icon
Version 1.0
Updated on 23.06.2017
args Stat, ClipBoard, SourceBar, TargetBar, From, To
static Buf = 0

if(ClipBoard || Shift)
	Buf = 1

static BB = "Buttonbar"
static BC = "Buttoncount"

static w = vec.createfromwords("button cmd param path menu iconic")
if(not w) do
	messagebox("ok error", "Failure creating vector", "VEC plugin Error #4")
	quit
endif

if(arg(0) > 2)
	.@Batch(SourceBar, TargetBar, From, To)

static Config = pprofolder ++ "scripts\ini\ButtonBarTools.ini"

static Height = ini.get(Config, "General", "Height")
static CR = esc(?+\r+, ?+\+)
local i
flag clear 1

if(Ctrl || Stat) do
	local Rep = pprofolder ++ "ButtonBars.ini"
	local fh = file.open(Rep, "w")

	if(fh <= 0) do
		messagebox("ok error", "File not created", "FILE plugin error #1")
		quit
	endif

	file.close(fh)
	local Bars, Buttons, Counter, j, Temp

	for each line i in ini.enum_sections(Config) 
		if(i != "General") do
			.@Read(i)
		else
			.@Read()
		endif

		Counter = v.length
		Bars += Counter
		for(j = 0; j < Counter; j++)
			Temp = ini.get(v[j], BB, BC)
			ini.set(Rep, i, v[j], Temp)
			Buttons += Temp
		endfor
		ini.set(Rep, "Summary", "Bars", Bars) 
		ini.set(Rep, "Summary", "Buttons", Buttons)
	endfor

	Temp = "File " ++ Rep ++ " created" ++ CR ++ CR ++ "Bars: " ++ Bars ++ CR ++ "Buttons: " ++ Buttons
	messagebox("ok", Temp, "ButtonBarTools script")
	quit
endif

static D = cl.Create("Dirs", 1)

for each line i in ini.enum_sections(Config)
	if(i != "General") do
		D.Insert(0)
		D.AddLeft(0, cb("@Read", i))
		D.SetLabel(0, i)
	endif
endfor

D.Insert(0)
D.AddLeft(0, cb("@Read"))
D.SetLabel(0, "Main Bars")

if(D.Length > 1)
	*menu show Dirs

.@GetBars()

*menu show Bars
quit all
;;************************************************
Function Read(Sec)

local Mask = "*.bar"
local Temp, Str, List, Elem, Counter, Path
static v

if(vec.exists(v))
	v.destroy

if(not Sec) do
	local hh = win.handle("c=TTOTAL_CMD")
	Path = file.folder(win.exepath(hh))
	Temp = file.listfiles(Path ++ "\" ++ Mask)
	v = vec.createfromlines(Temp)

	if(v <= 0)
		messagebox("ok error", "Vector not created", "VEC plugin error #1")

	quit
endif

v = vec.create(1, 1)

if(v <= 0) do
	messagebox("ok error", "Vector not created", "VEC plugin error #2")
	quit
endif

Str = ini.enum_keys(Config, Sec)

for each line Temp in Str
	Elem = ini.get(Config, Sec, Temp)

	if(Sec == "Local Bars") do
		v[Counter] = Elem ++ "_local.bar"
		Counter++
	else
		List = file.listfiles(Elem ++ Mask)
		for each line Elem in List
			v[Counter] = Elem
			Counter++
		endfor
	endif

endfor

quit
;;************************************************
Function Left(i)

if(pproflag(1)) do
	static Target = v[i]
	quit
endif

flag set 1

static Source = v[i]

static Items = ini.get(Source, BB, BC)
static B = cl.Create("Bar", 1)

setstring Quote "
local i, Str, Counter, TT, Param, Work, How, Menu, IconFile, Icon, Command, Temp

if(not Buf) do
	B.Insert(0)
	B.AddLeft(0, cb("@Copy"))
	B.AddRight(0, cb("@Clip"))
	B.SetLabel(0, "OK")
	B.SetTooltip(0, "Left:   Copy Buttons/Right: Put 1 Button to Clip")
	B.SetIcon(0, env("WINDIR") ++ "\system32\comres.dll", 8)
	B.SetBackColor(0, "128 255 128")
	B.SetHeight(0, 24)

	B.Insert(0)
	B.AddLeft(0, "*bar close Bar")
	B.SetLabel(0, "Cancel")
	B.SetIcon(0, env("WINDIR") ++ "\system32\comres.dll", 10)
	B.SetBackColor(0, "255 128 128")
	B.SetHeight(0, 24)
	B.SetTooltip(0, "Close Bar")
endif

for(i = Items; i >= 1; i--)
	B.Insert(0)

	if(ini.check_exists(Source, BB, "cmd" ++ i) == 2) do
		if(Buf) do
			B.AddLeft(0, "Format Separator")
		else
			B.SetLabel(0, "Separator")
			B.SetBackColor(0, 0)
			B.SetTextColor(0, "255 255 255")
			B.SetToolTip(0, "Button #" ++ i ++ "/Left: Close")
			B.AddLeft(0, "*bar close Bar")
		endif

		continue
	endif

	Command = ini.get(Source, BB, "cmd" ++ i)
	Command = .@CheckLength(Command)

	if(Command == -2) do
		Counter = 0
		if(Buf) do
			B.AddLeft(0, "Format NewColumnLine")
		else
			B.SetLabel(0, "New Column")
			B.SetBackColor(0, 0)
			B.SetTextColor(0, "255 255 255")
			B.SetToolTip(0, "Button #" ++ i ++ "/Left: Close")
			B.AddLeft(0, "*bar close Bar")
		endif

		continue
	endif

	TT = "Button #" ++ i ++ "/Command: " ++ Command

	if(ini.check_exists(Source, BB, "param" ++ i) == 3) do
		Param = ini.get(Source, BB, "param" ++ i)
		Param = .@CheckLength(Param)
		TT ++= "/Parameters: " ++ Param
	else
		Param = ""
	endif

	if(ini.check_exists(Source, BB, "path" ++ i) == 3) do
		Work = ini.get(Source, BB, "path" ++ i)
		TT ++= "/Start path: " ++ Work
	else
		Work = ""
	endif

	if(ini.check_exists(Source, BB, "menu" ++ i) == 3) do
		Menu = ini.get(Source, BB, "menu" ++ i)
		TT ++= "/Tooltip: " ++ Menu
		Menu = replacechars(Menu, Quote, "''")
	else
		Menu = Command
	endif

	if(ini.check_exists(Source, BB, "iconic" ++ i) == 3) do
		How = ini.get(Source, BB, "iconic" ++ i)
	else
		How = ""
	endif

	B.SetToolTip(0, TT)

	if(Buf) do
		B.SetLabel(0, Menu)
		B.AddLeft(0, cb("@Buffer", i))
	else
		B.SetLabel(0, "*control button autocheckbox" ++ Quote ++ Menu ++ Quote)
	endif

	if(ini.check_exists(Source, BB, "button" ++ i) == 3) do
		Str = ini.get(Source, BB, "button" ++ i)
		if(validpath(Str)) do
			IconFile = Str
			B.SetIcon(0, IconFile)
			Icon = ""
		else
			IconFile = nextword(Str, "Icon", ",")
			B.SetIcon(0, IconFile, Icon)
		endif
	endif

	Str = "TOTALCMD#BAR#DATA" ++ CR ++ Command ++ CR ++ Param ++ CR
	Str ++= IconFile ++ Icon ++ CR ++ Menu ++ CR ++ Work ++ CR ++ How
	B.AddRight(0, Str)

	if(Buf && Counter > Height) do
		B.Insert(0)
		B.AddLeft(0, "Format NewColumnLine")
		Counter = 0
	else
		Counter++
	endif

endfor

B.SetProperties("Format=barsize position: leftcaption samesize vertical iconsize: 16 tooltips")

if(Buf) do
	*menu show Bar
	quit
endif

B.show

quit
;;************************************************
Function Clip()
local i

for(i = 0; i < B.Length; i++)
	if(B.GetCtrlValue(i)) do
		clip.set(B.GetRightCmd(i))
		B.SetCtrlValue(i, 0)
		break
	endif
endfor

quit
;;************************************************
Function Buffer(Num)
local Str = B.GetRightCmd(Num - 1)
clip.set(Str)
quit all
;;************************************************
Function Copy()
local i, Elem, i1, Counter, Temp, Str

if(D.Length > 1)
	*menu show Dirs

.@GetBars()
*menu show Bars

local Buttons = ini.get(Target, BB, BC)
local Next = Buttons

for(i = 0; i < B.Length; i++)
	if(B.GetCtrlValue(i)) do
		i1 = i + 1
		Counter++
		Next++

		for each Elem in w
			Temp = Elem ++ i1
			if(ini.check_exists(Source, BB, Temp) == 3) do
				Str = ini.get(Source, BB, Temp)
				ini.set(Target, BB, Elem ++ Next, Str)
			endif
		endfor
	endif
endfor
B.close
ini.set(Target, BB, BC, Buttons + Counter)

Str = Counter ++ " buttons are successfully copied from " ++ Source ++ " to " ++ Target
messagebox("ok", Str, "ButtonBarTools Script")

quit
;;************************************************
Function Batch(SourceBar, TargetBar, From, To)
local i, Str, Counter, Temp, Elem
local Buttons = ini.get(TargetBar, BB, BC)
local Next = Buttons

if(not validpath(TargetBar)) do
	Str = "Target bar file name " ++ TargetBar ++ " is wrong"
	messagebox ("ok", Str, "ButtonBarTools Script")
	quit
endif

if(not validpath(SourceBar)) do
	Str = "Source bar file name " ++ SourceBar ++ " is wrong"
	messagebox ("ok", Str, "ButtonBarTools Script")
	quit
endif

if(From > To) do
	Str = "Starting button number " ++ From ++ " is more than ending number " ++ To
	messagebox ("ok", Str, "ButtonBarTools Script")
	quit
endif

i = ini.get(SourceBar, BB, BC)

if(i < To) do
	Str = "Button count in " ++ SourceBar ++ " is " ++ i ++ " and is less than ending number " ++ To
	messagebox ("ok", Str, "ButtonBarTools Script")
	quit
endif

for(i = From; i <= To; i++)
	Counter++
	Next++

	for each Elem in w
		Temp = Elem ++ i
		if(ini.check_exists(SourceBar, BB, Temp) == 3) do
			Str = ini.get(SourceBar, BB, Temp)
			ini.set(TargetBar, BB, Elem ++ Next, Str)
		endif
	endfor
endfor

ini.set(TargetBar, BB, BC, Buttons + Counter)

Str = Counter ++ " buttons are successfully copied from " ++ SourceBar ++ " to " ++ TargetBar
messagebox ("ok", Str, "ButtonBarTools Script")
quit all
;;************************************************
Function GetBars()
static Bs = cl.Create("Bars", 1)
Bs.NewProperties("tooltips")

local Number = v.length

for(i = Number - 1; i >= 0; i--)
	Bs.Insert(0)
	Bs.AddLeft(0, cb("@Left", i))
	Temp = file.name(v[i])
	Bs.SetLabel(0, Temp)
	Temp = ini.get(v[i], BB, BC)
	Bs.SetTooltip(0, v[i] ++ "/" ++ Temp ++ " buttons")
endfor

for(i = 1; i <= Number/Height; i++)
	Bs.Insert(i*Height)
	Bs.AddLeft(i*Height, "Format NewColumnLine")
endfor
quit
;;************************************************
Function CheckLength(Str)
static MT = B.GetMaxtext
local Text

if(length(Str) > MT) do
	Text = "String for command #" ++ i ++ " is longer than " ++ MT
	Text ++= " characters." ++ CR ++ "String is truncated"
	messagebox("ok", Text, "ButtonBarTools Script")
	Str = remove(Str, Temp - length(Str) - 200)
endif

quit(Str)

Comments

How to transfer buttons from one button bar to another? First, we can use the clipboard: open source panel, copy one button to the clipboard, open target panel, paste button, open source panel again, etc. Second, we can copy all buttons to the clipboard and then paste them one by one using a clipboard manager, if any. Third, we can merge panels (using, for example, this script), and then delete excessive buttons. Fourth, we can open both panels in text editor and carefully change numbers...

So, existing ways are not handy. On my computer there are 2064 buttons on 137 bars in various directories, so the button transition from one panel to another is a problem. This script is used to solve it. Its early edition was called Button2Clip and allowed to copy only one button and only to the clipboard. The present edition has more functions.

First of all let's have a look at the configuration file ButtonBarTools.ini. Its path has to be pprofolder\scripts\inis\ButtonBarTools.ini, where pprofolder is the path PowerPro is installed in. ButtonBarTools.ini has one obligatory section [General] with one obligatory key Height described below.

To use local panels (or local menus; they are described here) section with obligatory name [Local Bars] must contain strings like
Any_name=path_to_local_menu\
Local menus must have names _local.bar. If local menus are not used, the [Local Bars] section must be completely deleted or commented.

Further, the configuration file can contain other sections with any names each with any numbers of keys with the same format. Unlike the [Local Bars] section, other ones have no restrictions to both button bar file names and their quantity: all *.bar files with indicated path will be considered.

The script has five modes whose execution is provided by parameters and button presses.

First (main) mode - copying buttons from one bar to another

Script has no parameters. First, the menu of bar groups appears. For the presented configuration this menu contains three groups: second is above described "Local bars", third is "Other bars", and the first one is obligatory group "Main bars" containing all *.bar files located in %COMMANDER_PATH%. If the configuration files contains only the [General] section, then the bar group menu is not shown at all, and the next bar menu is displayed at once.

After picking one of groups its contents is presented with bars of this group. Maximum number of items in the menu column is set by the above mentioned Height key in the configuration file. Detailed info about each bar is given by the tooltip. Finally, after picking one bar the third menu of buttons is shown. "Empty buttons" are replaced with pseudo-buttons "Separator", buttons with the "-2" command: with "New Column" pseudo-buttons. All pseudo-buttons have black background with white foreground. So, a regular Total Commander button bar looks some unusual way. Moreover, this menu can not fit into the screen.

If this happens and the button of interest is out of visible limits, the menu can be closed by left-clicking any of pseud-buttons. If they are not visible either, the menu can be closed by right-clicking any button with Ctrl pressed, and then by picking the "Close Bar" command. To copy several buttons the batch mode (see below) can be used instead.

If all the buttons of interest are visible, you can check boxes to the left of buttons. After checking left-click the OK button. Then the first two steps: group menu and bar menu appear in turn, but now you have to pick the bar where the buttons have to be copied to. Finally, the script informs that this operation is done successfully.

Note that buttons are copied rather than moved! First, it is safely, second, it is sometimes useful to have the same buttons on different bars.

Second mode - copying multiple button images to the clipboard

After displaying the above described button menu the OK button can be not left- but right-clicked. Then the first checked button image is put to the clipboard. That allows to position the mouse cursor over the active TC button bar, right-click and pick "Paste". After changing the active button bar this operation can be repeated with the same or another button from the button menu.

Third mode - copying single button image to the clipboard

This mode is set with the second script parameter equal to 1. Alternatively you can press Shift at starting the script.

First two steps - group menu and bar menu - are the same as above. But the button menu looks different and more close to the TC button bar: first, empty buttons and new columns are shown correctly. Second - buttons have icons, if possible. Third - all buttons are visible.

Result of left-clicking a button is the same as in the second mode: the button image is put to the clipboard. Third mode is more pictorial and comfortable, but allow to process only one button per one script execution.

Fourth mode - batch

This mode is useful in two cases: if buttons of interest are not visible in the first mode, and if the copying task is repetitive.

Script parameters from third to sixth have the following meanings:

source_panel, target_panel, starting_number, ending_number

Panels can be set both as TC parameters like %T%M and as implicit full file names. Unlike the main mode, the batch one allows to copy only sequential buttons. Example: script with parameters
.ButtonBarTools(0, 0, ?"%P%N", "c:\some\dir\any.bar", 7, 11)
copies 5 buttons with numbers 7-11 from panel under cursor to panel c:\some\dir\any.bar.

Fifth mode - statistics

First script parameter must be set to 1 (or Ctrl must be pressed at starting the script). In the PowerPro home directory the ButtonBars.ini file containing information about all button bars, is created.


Main Page Total Commander PowerPro