|
Название | ButtonBarTools |
Имя файла (*.txt) | ButtonBarTools.txt |
Описание | См. комментарии |
Автор | Вахмурка |
Параметры |
[Режим] [[панель-источник], [панель-приемник], [начальный_номер], [конечный_номер]]
(см. комментарии) |
Вызываемые плагины | vec, ini, file, clip, win, miscplugin, unicode |
Иконка | |
Версия | 2.3 |
Дата обновления | 28.06.2022 |
args Param static Mode = Param if(arg(0) > 1) do .@Batch(arg(1), arg(2), arg(3), arg(4)) quit all endif static BB = "Buttonbar" static BC = "Buttoncount" static hh = win.handle("c=TTOTAL_CMD") static Path = file.folder(win.exepath(hh)) static ButtonCount = 0 static G = "General" static Config = pprofolder ++ "scripts\ini\ButtonBarTools.ini" static Height = ini.get(Config, G, "Height") - 2 local MainBar, Cur static E = cl.Create("Bars", 1) local Sex = ini.enum_sections(Config) static FSS = "Format StartSubmenu" static FES = "Format EndSubmenu" static FNCL = "Format NewColumnLine" static Mask = "*.bar" static CR = esc(?+\r+, ?+\+) static CR2 = esc(?+\r\r+, ?+\+) static Tab = esc(?+\t+, ?+\+) static BBTS = "ButtonBarTools Script" static FCV = "Failure creating vector" static Target = Path ++ "\BBT" ++ ifelse(ini.get(Config, G, "SameNameResult"), "", date ++ time) ++ ".bar" static TTS = ini.get(Config, G, "Separator") E.SetTooltipSeparator(TTS) static w = vec.createfromwords("button cmd param path menu iconic") if(not w) do messagebox("ok error", FCV, "VEC plugin Error #4") quit endif static KeyWords = w.length static S = vec.create(6) if(not S) do messagebox("ok error", FCV, "VEC plugin Error #2") quit endif S[1] = 0 S[3] = 0 S[5] = 0 E.Insert(0) E.AddLeft(0, FSS) E.SetLabel(0, "Main Bars") .@Read() Cur = E.length E.Insert(Cur) E.AddLeft(Cur, FES) for each line MainBar in Sex if(MainBar != G) do Cur = E.length E.Insert(Cur) E.AddLeft(Cur, FSS) E.SetLabel(Cur, MainBar) .@Read(MainBar) Cur = E.length E.Insert(Cur) E.AddLeft(Cur, FES) endif endfor E.SetProperties("Format=samesize vertical iconsize: 16 tooltips") if(Mode == "s" || Shift) do static Ba = "Bars" static Bu = "Buttons" Cur = S[1] + S[3] + S[5] MainBar = S[0] + S[2] + S[4] Sex = "Main:" ++ CR ++ Ba ++ Tab ++ S[0] ++ CR ++ Bu ++ Tab ++ S[1] ++ CR2 Sex ++= "Local:" ++ CR ++ Ba ++ Tab ++ S[2] ++ CR ++ Bu ++ Tab ++ S[3] ++ CR2 Sex ++= "Other:" ++ CR ++ Ba ++ Tab ++ S[4] ++ CR ++ Bu ++ Tab ++ S[5] ++ CR2 Sex ++= "Total:" ++ CR ++ Ba ++ Tab ++ MainBar ++ CR ++ Bu ++ Tab ++ Cur messagebox("ok information", Sex, BBTS) else E.ShowMenu("centerscreen") endif if(!ini.get(Config, G, "KeepResult") || Alt) file.delete(Target) if(Mode == "b") do Cur = E.GetLastMenuSel() if(Cur) quit(E.GetId(Cur)) endif quit all ;;************************************************ Function Read(Sec) local Str, List, Elem, Counter, j, Cur, Pan, Temp ;;, Item static i = "information" static B1 = " bars" static B2 = " buttons" static T = "timeout=5" static FolderIcon = env("WINDIR") ++ "\system32\shell32.dll" switch (Sec) case "Local Bars" Str = ini.enum_keys(Config, Sec) Pan = line(Str, 0) miscplugin.BalloonTip(1, i, "Local: " ++ Pan ++ B1, T) S[2] = Pan for each line Temp in Str Elem = ini.get(Config, Sec, Temp) j = Elem ++ "_local.bar" Cur = E.length with E.Insert(Cur) .SetLabel(j) .SetIcon(FolderIcon, 4) .SetTooltip(ini.get(j, BB, BC) ++ B2) .SetId(j) endwith if(Mode != "b") do E.AddLeft(Cur, FSS) S[3] += .@Bur(j) Cur = E.length E.Insert(Cur) E.AddLeft(Cur, FES) endif if(Counter > Height) do E.Insert(Cur + 1) E.AddLeft(Cur + 1, FNCL) Counter = 0 else Counter++ endif endfor break case "Other Bars" Str = ini.enum_keys(Config, Sec) for each line Pan in Str Elem = ini.get(Config, Sec, Pan) List = file.listfiles(Elem ++ Mask) S[4] += line(List, 0) miscplugin.BalloonTip(1, i, "Other: " ++ S[4] ++ B1, T) for each line j in List Cur = E.length with E.Insert(Cur) .SetLabel(j) .SetIcon(FolderIcon, 4) .SetTooltip(ini.get(j, BB, BC) ++ B2) .SetId(j) endwith if(Mode != "b") do E.AddLeft(Cur, FSS) S[5] += .@Bur(j) Cur = E.length E.Insert(Cur) E.AddLeft(Cur, FES) endif if(Counter > Height) do E.Insert(Cur + 1) E.AddLeft(Cur + 1, FNCL) Counter = 0 else Counter++ endif endfor endfor break case else Temp = file.listfiles(Path ++ "\*.bar") Pan = line(Temp, 0) S[0] = Pan miscplugin.BalloonTip(1, i, " Main: " ++ Pan ++ B1, T) for each line j in Temp Elem = file.name(j) Cur = E.length with E.Insert(Cur) .SetLabel(Elem) .SetIcon(FolderIcon, 4) .SetTooltip(j ++ TTS ++ ini.get(j, BB, BC) ++ B2) .SetId(j) endwith if(Mode != "b") do E.AddLeft(Cur, FSS) S[1] += .@Bur(j) Cur = E.length E.Insert(Cur) E.AddLeft(Cur, FES) endif if(Counter > Height) do E.Insert(Cur + 1) E.AddLeft(Cur + 1, FNCL) Counter = 0 else Counter++ endif endfor ;; quit endswitch quit ;;************************************************ Function Bur(Name) local Name local Buttons = ini.get(Name, BB, BC) local BarNum = E.length - 1 local j, Temp, Cur, TT, Counter, Item, cmds, TTL for(j = 1; j <= Buttons; j++) Temp = w[1] ++ j if(ini.check_exists(Name, BB, Temp) == 2) do Cur = E.length E.Insert(Cur) E.AddLeft(Cur, "Format Separator") continue endif if(ini.get(Name, BB, Temp) == -2) do Cur = E.length E.Insert(Cur) E.AddLeft(Cur, FNCL) continue endif Cur = E.length Item = E.Insert(Cur) cmds++ with Item if(ini.check_exists(Name, BB, w[4] ++ j) == 3) .SetLabel(ini.get(Name, BB, w[4] ++ j)) if(ini.check_exists(Name, BB, w[0] ++ j) == 3) .SetIcon(ini.get(Name, BB, w[0] ++ j)) TT = "Command: " ++ ini.get(Name, BB, Temp) if(ini.check_exists(Name, BB, w[2] ++ j) == 3) TT ++= TTS ++ "Parameters: " ++ ini.get(Name, BB, w[2] ++ j) if(ini.check_exists(Name, BB, w[3] ++ j) == 3) TT ++= TTS ++ "Path: " ++ ini.get(Name, BB, w[3] ++ j) Temp = E.GetMaxtext TTL = length(TT) if(TTL > Temp) TT = remove(TT, Temp - TTL - 20) ++ "/...truncated" .SetTooltip(TT) .AddLeft(cb("@Mark", Cur, BarNum, j)) .AddRight(cb("@BInsert", BarNum, j)) endwith if(Counter > Height) do E.Insert(Cur + 1) E.AddLeft(Cur + 1, FNCL) Counter = 0 else Counter++ endif endfor quit(cmds) ;;************************************************ Function Mark(Num, BarNum, Button) local k, Key, Value local Source = E.GetId(BarNum) static ButtonColor = ini.get(Config, G, "MarkButton") static BurColor = ini.get(Config, G, "MarkBar") E.SetBackColor(Num, ButtonColor) E.SetBackColor(BarNum, BurColor) ButtonCount++ ini.error_dialog_off() for(k = 0; k < KeyWords; k++) Temp = w[k] Key = Temp ++ Button if(ini.check_exists(Source, BB, Key) == 3) do Value = ini.get(Source, BB, Key) ini.set(Target, BB, Temp ++ ButtonCount, Value) ini.set(Target, BB, BC, ButtonCount) endif endfor E.ShowMenu("centerscreen") quit ;;************************************************ Function BInsert(BarNum, Button) local Source = E.GetId(BarNum) if(Ctrl || Mode == "c") do .@Buffer(Source, Button) quit all endif local Keys = ini.get(Source, BB, BC) local k, m, Temp, Value, Key, Shift for(k = Keys; k > Button; k--) Shift = k + ButtonCount for(m = 0; m < KeyWords; m++) Temp = w[m] Key = Temp ++ k if(ini.check_exists(Source, BB, Key) == 3) do Value = ini.get(Source, BB, Key) Temp = w[m] ++ Shift ini.set(Source, BB, Temp, Value) ini.delete_key(Source, BB, Key) endif endfor endfor for(k = 1; k <= ButtonCount; k++) Shift = k + Button for(m = 0; m < KeyWords; m++) Temp = w[m] Key = Temp ++ k if(ini.check_exists(Target, BB, Key) == 3) do Value = ini.get(Target, BB, Key) Temp = w[m] ++ Shift ini.set(Source, BB, Temp, Value) endif endfor endfor messagebox("ok information", ButtonCount ++ " buttons copied to " ++ Source, BBTS) ini.set(Source, BB, BC, Keys + ButtonCount) quit ;;************************************************ Function Batch(SourceBar, TargetBar, From, To) local j, 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, BBTS) quit endif if(not validpath(SourceBar)) do Str = "Source bar file name " ++ SourceBar ++ " is wrong" messagebox ("ok", Str, BBTS) quit endif if(From > To) do Str = "Starting button number " ++ From ++ " is more than ending number " ++ To messagebox ("ok", Str, BBTS) quit endif Temp = ini.get(SourceBar, BB, BC) if(Temp < To) do Str = "Button count in " ++ SourceBar ++ " is " ++ Temp ++ " and is less than ending number " ++ To messagebox ("ok", Str, BBTS) quit endif if(!From && !To) do From = 1 To = Temp endif for(j = From; j <= To; j++) Counter++ Next++ for each Elem in w Temp = Elem ++ j 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, BBTS) quit ;;************************************************ Function Buffer(Source, Button) local k, Value, Key local x = vec.create(KeyWords) local Temp = "TOTALCMD#BAR#DATA" ++ CR if(not x) do messagebox("ok error", FCV, "VEC plugin Error #3") quit all endif for(k = 0; k < KeyWords; k++) Value = w[k] Key = Value ++ Button x[k] = ifelse(ini.check_exists(Source, BB, Key) == 3, ini.get(Source, BB, Key), "") endfor Temp ++= x[1] ++ CR ++ x[2] ++ CR ++ x[0] ++ CR ++ x[4] ++ CR ++ x[3] ++ CR ++ x[5] unicode.clip_set(Temp) quit all
Скрипт для различных видов работ с панелями кнопок существует в четырех видах.
Button2Clip. Как ясно из названия, он позволяет копировать кнопку только в буфер и только одну;
Версия 1.0, она же B-версия. Для представления панели кнопок (button bar) Total Commander используются как меню, так и панель (bar) PowerPro. По сравнению с последней версия 1.0 чем-то выигрывала в интерфейсе, но была несколько своеобразна и непривычна в представлении и использовании;
Версия 2.0, она же М-версия. Теперь для представления панели кнопок используется только меню, что автору кажется более правильным.
В файле настроек ButtonBarTools.ini, в разделе [General] есть ключ Separator. Для данной версии символ, являющийся значением ключа, будет использован для замены косой черты "/" во всплывающих подсказках (tooltips). Например, если задано
Separator=\
то подсказка "Первый/Второй/Третий" будет выглядеть так же.
Если же задать
Separator=/
то есть не производить замену, то подсказка будет выглядеть так:
Первый
Второй
Третий
Наконец, версия 2.1, она же S-версия, то есть текущая. Имеет смысл только для версии PowerPro не ниже чем 5.3.35s, причем важна именно буква "s". Внимание: функция pproversion возвратит только цифры! Узнать текущую версию полностью можно, просмотрев свойства файла powerpro.exe.
История появления версии 2.1 такова. В кнопках Total Commander часто содержится символ "/", особенно в поле Parameters, как часть ключей программ. В то же время символ "/" является разделителем всплывающих подсказок PowerPro. Этот конфликт легко разрешить в GUI-интерфейсе настроек меню и панелей PowerPro, задав любой другой символ в качестве разделителя. Но если меню/панель формируется в скрипте, управлять символом-разделителем нельзя. Поэтому автор этих строк предложил автору PowerPro, Bruce Switzer'у, ввести функции SetTooltipSeparator и GetTooltipSeparator, что автор и сделал в версии 5.3.35s.
Соответственно, в версии 2.1 скрипта ключ Separator приобрел несколько иной смысл. Следует задать значение ключа равным тому символу, которого нет в строке всплывающей подсказки – и тогда переносы строк будут появляться там, где им и положено. В примере выше, если изначально эта строка имела вид "Первый`Второй`Третий", и мы хотим расположить каждое слово на отдельной строке, то следует задать
Separator=`
как это и сделано по умолчанию.
Кроме смысла ключа Separator и представления подсказок, нет никакой разницы между версиями 2.0 и 2.1.
Итак, как перенести несколько кнопок с одной панели на другую? Во-первых, можно переносить по одной через буфер: открыл одну панель, скопировал первую кнопку, открыл другую, вставил, потом еще раз, и опять… Во-вторых, можно скопировать в буфер все кнопки подряд, а потом с помощью менеджера буфера обмена (если таковой есть) вставлять по одной. В-третьих, можно присоединить одну панель к другой (с помощью, например, этого скрипта), и удалить лишнее. В-четвертых, можно открыть обе панели в текстовом редакторе и, рискуя ошибиться, вручную править номера…
Иными словами, способы есть, но все они не отличаются удобством. А поскольку у меня 2064 кнопки на 137 панелях, разбросанных по дискам, то перенос кнопок с одной на другую становится настоящей проблемой. Чтобы решить ее, я и написал этот скрипт.
Прежде всего ознакомимся с файлом настроек ButtonBarTools.ini. Он должен иметь путь pprofolder\scripts\ini\ButtonBarTools.ini, где pprofolder – путь к исполняемому файлу PowerPro.exe. Файл имеет один обязательный раздел [General] и в нем ряд обязательных ключей, смысл которых будет раскрыт позже.
Например, чтобы длинный список умещался на экране, можно экспериментально подобрать значение ключа Height – он соответствует максимальному числу пунктов в колонке.
При использовании локальных панелей (локальных меню; с этим понятием можно ознакомиться здесь) раздел с обязательным именем "Local Bars" должен содержать любое число ключей вида
Произвольное_имя=путь_к_меню\
причем сами файлы должны иметь фиксированное имя _local.bar (впрочем, его легко изменить в тексте скрипта). Если локальные меню не используются, раздел следует удалить или закомментировать целиком.
Кроме того, в файле конфигурации может содержаться любое количество разделов с произвольными именами и ключами по тому же формату. Однако, в отличие от ключей раздела "Local Bars", остальные не накладывают ограничений ни на имена файлов панелей, ни на их количество: будут считаны все файлы с расширением bar, находящиеся по указанному пути. В данном файле конфигурации это раздел "Other Bars" с двумя ключами.
Скрипт имеет шесть функций-режимов, задаваемыми параметрами или нажатиями клавиш. Иногда при запуске возникает многоуровневое меню. На первом уровне будет как минимум один пункт "Main Bars", а для данного файла конфигурации – еще и пункты "Local Bars" и "Other Bars".
Второй уровень содержит панели, третий – кнопки. Информация о кнопке содержится во всплывающей подсказке, о которой была речь выше. Кнопки имеют иконки, если это возможно. В пункте меню "Main Bars" содержатся панели с путем %COMMANDER_PATH%.
В этом режиме скрипт параметров не имеет. Найдя кнопку, которую нужно скопировать на другую панель, нажимаем ее левой кнопкой мыши. Сама кнопка помечается одним цветом, а панель, где кнопка находится – другим. Два этих цвета задаются ключами MarkButton и MarkBar, соответственно. Если цвета по умолчанию пользователя не устраивают, их можно поменять. Как задать цвет фона, описано в документации к PowerPro. Поиск можно проводить по ключевому слову SetTextColor.
Итак, процедуру выбора разных кнопок на разных панелях можно повторять многократно. Убедившись, что все кнопки, предназначенные к копированию, отмечены, выбираем на любой панели кнопку, после которой их предполагается вставить, и нажимаем правую кнопку мыши. Скрипт выдаст сообщение об общем числе успешно скопированных кнопок и панели-приемнике.
Кнопки именно копируются, а не перемещаются! Во-первых, так безопаснее, а во-вторых, бывает полезно иметь дубликаты кнопки на разных панелях.
Одновременно с выбором кнопок они копируются во вновь созданную панель. Ее путь определяется переменной %COMMANDER_PATH%, а имя зависит от ключа SameNameResult конфигурации: если значение ключа равно 1, то панель имеет фиксированное имя BBT.bar, иначе - уникальное имя, в которое входят текущие дата и время.
Ключ KeepResult, равный 1, оставит полученную панель после окончания работы скрипта. Иначе она будет стерта.
Имеет смысл оставлять панель, если ее предполагается переименовать и использовать как новую, содержащую ранее созданные кнопки.
Удалить панель, безотносительно к значению ключа KeepResult, можно, удерживая клавишу Alt во время окончания работы скрипта.
Это можно сделать тремя способами. Во-первых, запустить скрипт с параметром "с". Во-вторых, запустить скрипт без параметров, как в первом режиме, но нажать Ctrl в момент левого щелчка по кнопке. В-третьих, в первом режиме нажать нужную кнопку, как и ранее, правой кнопкой мыши, но сделать это тогда, когда ни одной кнопки не выделено и цветом не отмечено.
В любом случае в буфере обмена окажется образ нажатой кнопки. Следует навести курсор мыши на свободное место панели, нажать правую кнопку мыши и выбрать "Paste...".
Скрипт запускается с параметром "s" (от "summary" или "statistics"). Или без параметров, но с нажатой клавишей Shift. Диалоговое окно будет содержать самую общую информацию о панелях всех трех типов.
Параметры скрипта имеют следующий смысл:
панель-источник, панель-приемник, начальный_номер, конечный_номер
Источник и приемник удобно задавать как "%P%N", "%T%M", но можно указать имена bar-файлов в явном виде.
Что подразумевается под "номером" кнопки? (такой вопрос может возникнуть у новичков). Следует открыть панель в программе просмотра и найти первую из тех команд, которые предполагается скопировать. Это будет выглядеть примерно так:
cmd14=c:\path\myprogram.exe
param14=%P
button14=c:\path\myprogram.exe,1
menu14=Моя программа
В данном примере 14 – это и есть номер команды. Следует ориентироваться именно на ключ "cmd.." – он один является обязательным.
Нетрудно видеть, что пакетный режим, в отличие от основного, позволяет копировать только подряд идущие кнопки.
Пример: скрипт с такими параметрами
.ButtonBarTools(?"%P%N", "c:\some\dir\any.bar", 7, 11)
скопирует из панели под курсором в панель c:\some\dir\any.bar кнопки с номерами с 7 до 11 включительно (всего 5 штук).
Ранее для этих целей использовался скрипт MergeBars. Пятый режим можно считать частным случаем четвертого. Если в примере выше параметров у скрипта не 4, а 2, то есть
.ButtonBarTools(?"%P%N", "c:\some\dir\any.bar")
то будут скопированы все кнопки панели под курсором в панель any.bar.
Скрипт с параметром "b" вызывается из других скриптов. У меню всего два уровня, то есть уровень панели становится нижним. После выбора панели и нажатия пользователем левой кнопки мыши на одной из панелей скрипт возвращает полный путь панели
На главную | Все о Total Commander | PowerPro | PowerPro & Total Commander |