Tcl/Tk. Альтернативный файловый проводник для платформ Linux и Android

r1upbvlbm2fjavsgczqtpxj5liu.png Чем дольше я пишу различные программы на tcl/tk, тем больше восхищаюсь его возможностями и продуманностью. Но была одна вещь, которая не давала мне покою до последнего времени. При разработке GUI часто приходится пользоваться файловым проводником (tk_getSaveFile, tk_getOpenFile или tk_chooseDirectory). И если на платформах Windows или OS X, загружается нативный файловый проводник этих платформ, то на платформах Linux загружается проводник от tcl/tk (ну нет в Linux нативного проводника):
xg4nysqi9eqgyey0wmo5sltfnui.png

Что не устраивает в этом проводнике? Это отсутствие в нем элементарных операций с папками/файлами — создать, уничтожить, переименовать. Нет, не подумайте в самом tcl все эти механизмы, естественно, реализованы, их просто нет в GUI проводника. Но в Linux это не так заметно. А вот на платформе Android проводник от Tcl/Tk вызывает массу неудобств:

tt-qbjpbrdtzrzmk8we8fjae_ry.jpeg

Когда мы говорим про платформу Android, то имеем ввиду разработку приложений на Androwish.
А тут такие времена настали, самоизоляция и т.д. В итоге, родилась балалайка (так еще называют пакеты/package для tcl) tkfe (tk file explorer).
При разработке пакета tkfe учитывалось не только то, что необходимы хотя бы элементарные операции с файлами/каталогами, то и было желание иметь проводник не только в отдельном окне, но и в отдельном фрейме, который пользователь сам разместить по своему желанию в своем GUI. В проекте имеется комплексный пример по использованию пакета. Итак, скачиваем проект, заходим в папку ~//TkFileExplorer/samples и запускаем пример:

$wish tkfe_samplefull.tcl


btmmq8p2ktwttjdrecfzwj-tzf8.png

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

hva48tow74frlaomaqds8lrmtp0.png

Сам проводник имеет интерфейс на двух языках: русском и английском. Перевод осуществляется на лету при нажатии кнопки с флагом:

k_bx_sdgpxsxmgkjtl2horlihti.png

Помимо кнопки с флагом, имеется кнопка с инструментами (tools), при нажатии на которую высвечивается контекстное меню, что можно делать в текущем каталоге (создать каталог/файл) или с выделенным файлом/папкой (удалить/переименовать):

yf4mk3cbnoh2hycyif16wko7lv4.png

Любая из функций файлового проводника возвращает имя (подчеркиваю — ИМЯ) переменной (см. пример tkfe_samplefull.tcl), в которую будет записан путь к выбранному файлу или каталогу или которая будет пустая в случае отказа от выбора. После получения имени переменной остается ждать когда, будет получен какой-либо результат, например:

 . . .
#Выбор файла для чтения
#Тип размещения проводника window - отдельное окно; frame - отдельный фрейм
set typew "window"
#Фильт для файлов
 set msk "*.txt *.doc *.crt * .*"
#Каталог пользователя
set tekdir $env(HOME)
#Вызов файлового проводника
 set vrr [FE::fe_getopenfile  $typew $w $tekdir $msk]
#Ждем результата
 vwait $vrr
. . .

Если вы используете тип размещения проводника frame, то необходимо позаботиться о его размещении на вашей картинке. Размещение может быть любым способом (grid, pack или place). Предпочтительным способом является все же метод place. При нем не стоит заботиться о переформатировании картинки, так как place в отличии от grid и pack, позволяет наложить фрейм поверх имеющейся картинки:

fqyraw3k-aogscybc21eefie_we.png

Если внимательно посмотреть на картинку, то можно заметить, что правый скриншот отличается от левого появлением на нем скрытых папок (имена начинаются с точки). Для показа скрытых кнопок надо включить кнопку с иконкой в виде глаза. Папки и файлы можно также сортировать по алфавиту, а файлы по размеру:

swm0rsrobmi2_1ljvopy4e2_3ks.png

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

  proc all_disable {parent} {
    set widgets [info commands $parent*]
    foreach w $widgets {
	catch {$w configure -state disabled}
    }
  }
  proc all_enable {parent} {
    set widgets [info commands $parent*]
    foreach w $widgets {
	catch {$w configure -state normal}
    }
  }
  namespace export fe_getsavefile
  namespace export fe_getopenfile
  namespace export fe_choosedir
  namespace export all_enable
  namespace export all_disable


Однако я предпочитаю пользоваться функцикй tk busy. Это хорошо видно в примере:

8am792svnvujhw_hp4n5l8tjed4.png

Это теория. На практике пакет tkfe был использован в криптографическом АРМ на базе стандартов с открытым ключом cryptoarmpkcs. Теперь использование файлового проводника в этом приложении для платформы Linux выглядит следующим образом:

2zvkjqj-sh-2-npm6cbrmxoytia.png

А вот проводник, размещенный во фрейме:

ljifnczdknsoy9_xert0uw8vxte.png

И, конечно, очень удобно стало работать с проводником на платформе Android:

y8pzbd8dbillkofm-m09ezqwycs.png

Кто-то может спросить: А как же Windows или OS X? Да, все замечательно. Но как всегда на Windows — это проблема русификации, в нашем случае это использование кириллицы в именовании файлов и папок, а также использование обратной косой черты. Поэтому в код необходимо добавить следующие строки:

#Перекодируем путь из кодировки ОС
#Для MS Win это скорей всего cp1251
set tekdir [encoding convertfrom cp1251 $tekdir ]
#Заменяем обратную косую в пути на нормальную косую
set tekdir [string map {"\\" "/"} $tekdir]

Вот так выглядит проводник tkfe на платформе Windows:

bpomyttxkuyi-n9aqqwddftqlvk.png

Сам пакет и примеры его использования лежат здесь.

© Habrahabr.ru