ButtonBarTools

Название ButtonBarTools
Имя файла (*.txt) ButtonBarTools-B.txt
Описание См. комментарии
Автор Вахмурка
Параметры Статистика, Буфер, панель-источник, панель-приемник, начальный_номер, конечный_номер
Вызываемые плагины vec, ini, file, clip
Иконка
Версия 1.0
Дата обновления 22.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)

Комментарии:

Как перенести несколько кнопок с одной панели на другую? Во-первых, можно переносить по одной через буфер: открыл одну панель, скопировал первую кнопку, открыл другую, вставил, потом еще раз, и опять... Во-вторых, можно скопировать в буфер все кнопки подряд, а потом с помощью менеджера буфера обмена (если таковой есть) вставлять по одной. В-третьих, можно присоединить одну панель к другой (с помощью, например, этого скрипта), и удалить лишнее. В-четвертых, можно открыть обе панели в текстовом редакторе и, рискуя ошибиться, вручную править номера...

Иными словами, способы есть, но все они не отличаются удобством. А поскольку у меня 2064 кнопки на 137 панелях, разбросанных по дискам, то перенос кнопок с одной на другую становится настоящей проблемой. Чтобы решить ее, я и написал этот скрипт. Сначала он назывался Button2Clip и, как ясно из названия, позволял копировать кнопку только в буфер и только одну. Но аппетит приходит во время еды, и я решил усовершенствовать скрипт и расширить его возможности.

Прежде всего ознакомимся с файлом настроек ButtonBarTools.ini. Он должен иметь путь pprofolder\scripts\inis\ButtonBarTools.ini, где pprofolder – путь к исполняемому файлу PowerPro.exe. Файл ButtonBarTools.ini имеет один обязательный раздел [General] и в нем один обязательный ключ Height, смысл которого будет раскрыт позже.

При использовании локальных панелей (локальных меню; с этим понятием можно ознакомиться здесь) раздел с обязательным именем [Local Bars] должен содержать любое число ключей вида
Произвольное_имя=путь_к_меню\
причем сами файлы должны иметь фиксированное имя _local.bar (впрочем, его легко изменить в тексте скрипта). Если локальные меню не используются, раздел следует удалить или закомментировать целиком.

Кроме того, в файле конфигурации может содержаться любое количество разделов с произвольными именами и ключами по тому же формату. Однако, в отличие от ключей раздела [Local Bars], остальные не накладывают ограничений ни на имена файлов панелей, ни на их количество: будут считаны все файлы с расширением bar, находящиеся по указанному пути.

Скрипт имеет пять функций-режимов, задаваемыми параметрами и нажатиями кнопок.

Режим первый (основной) – копирование кнопок между панелями

В этом режиме скрипт параметров не имеет. При запуске сначала возникнет "меню групп" и будет предложено выбрать "группу панелей". Для данного файла настроек таких групп будет три: вторая – уже упомянутые локальные панели, третья – прочие (раздел [Other Bars] конфигурации) и обязательная первая – группа "Main Bars", содержащая панели с путем %COMMANDER_PATH%. Если в конфигурации удалены все разделы, кроме [General], меню групп не предлагается.

Далее, выдается меню самих панелей в выбранной группе. Чтобы длинный список умещался на экране, можно экспериментально подобрать упомянутый параметр Height в конфигурации – он соответствует максимальному числу пунктов в колонке. Подробная информация о панели представлена во всплывающей подсказке (tooltip). После выбора одной из панелей выдается третье меню: меню кнопок. "Пустые кнопки" заменяются псевдо-кнопками "Separator", кнопки с командой "-2" – псевдо-кнопками "New Column". Оба типа разделителей выделяются черным цветом фона и белым – надписей. За счет всего этого панель, во-первых, выглядит несколько непривычно, а во-вторых, может выходить за границы видимой области.

Если это произошло и искомая кнопка находится вне пределов видимости, то можно закрыть меню щелчком по любому из разделителей. Если же и их нет или не видно, то следует при нажатой клавише Ctrl щелкнуть правой кнопкой мыши по любому месту меню и выбрать команду "Close Bar". Далее для копирования кнопок можно использовать пакетный режим (см. ниже).

Слева от имени каждой кнопки находится чекбокс, в котором можно поставить отметку. После этого нажимаем ОК левой кнопкой мыши и вновь проходим через выбор сначала группы, затем панели – именно в нее будут скопированы все кнопки, отмеченные на предыдущем этапе. Скрипт известит пользователя, что копирование завершилось успешно.

Кнопки именно копируются, а не перемещаются! Во-первых, так безопаснее, а во-вторых, бывает полезно иметь дубликаты кнопки на разных панелях.

Режим второй – многократное копирование образа кнопки в буфер

После описанного выше появления меню кнопок можно нажать ОК не левой, а правой кнопкой мыши. Тогда в буфер будет помещен образ кнопки (первой из отмеченных). После этого можно навести курсор на свободное место панели Total Commander, нажать правую кнопку мыши и выбрать Paste. Эту операцию можно проделывать многократно, меняя панели и помещая на них разные кнопки из меню.

Режим третий – однократное копирование образа кнопки в буфер

Для входа в этот режим надо задать второй параметр скрипта равным 1 (строго говоря, равным чему угодно, кроме "" и 0). К тому же результату приведет нажатие клавиши Shift при запуске скрипта.

Начинается все так же: меню групп, меню панелей. Но вид меню кнопок будет иным. Во-первых, пустые кнопки и новые колонки выглядят как положено. Во-вторых, кнопки имеют иконки, если это возможно. В-третьих, все кнопки панели находятся в поле видимости.

Как и во втором режиме, результатом будет образ выбранной кнопки, помещенный в буфер. Третий режим несколько нагляднее и удобнее второго, но позволяет поместить в буфер всего один образ за один запуск скрипта.

Режим четвертый – пакетный

Режим может оказаться полезным в двух случаях. Либо когда нужные кнопки выходят за пределы экрана, либо когда требуется регулярно копировать определенные кнопки с панели на панель.

Параметры скрипта с третьего по шестой имеют следующий смысл:
панель-источник, панель-приемник, начальный_номер, конечный_номер
Источник и приемник удобно задавать как "%P%N", "%T%M", но можно указать имена bar-файлов в явном виде.

Что подразумевается под "номером" кнопки? (такой вопрос может возникнуть у новичков). Следует открыть панель в программе просмотра и найти первую из тех команд, которые предполагается скопировать. Это будет выглядеть примерно так:

cmd14=c:\path\myprogram.exe
param14=%P
button14=c:\path\myprogram.exe,1
menu14=Моя программа
В данном примере 14 – это и есть номер команды. Следует ориентироваться именно на ключ "cmd.." – он один является обязательным.

Нетрудно видеть, что пакетный режим, в отличие от основного, позволяет копировать только подряд идущие кнопки.

Пример: скрипт с такими параметрами
.ButtonBarTools(0, 1, ?"%P%N", "c:\some\dir\any.bar", 7, 11)
скопирует из панели под курсором в панель c:\some\dir\any.bar кнопки с номерами с 7 до 11 включительно (всего 5 штук).

Режим пятый – статистика

Определяется первым параметром, равным 1. В директории PowerPro создается файл ButtonBars.ini, содержащий сведения о всех панелях. Информация об общем количестве панелей и кнопок, кроме того, выдается в информационном окне. Также для входа в этот режим можно нажать клавишу Ctrl при запуске скрипта.


На главную Все о Total Commander PowerPro Все скрипты