Копирование файлов с временной панели с сохранение структуры папок

Здесь обсуждается всё, что касается макросов.
buniak_a_h
Posts: 610
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 60 times
Been thanked: 15 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Tue 24 Apr, 2018 20:12

Предлагаю небольшой макрос, копирующий файлы с временной панели, открытой на активной панели (извините за тавтологию) в директорий, открытый на неактивной панели. Макрос "рассовывает" копируемые файлы по подкаталогам в соответствии с их расположением в исходной структуре (относительно "корневой" папки). Особенно полезна для копирования результатов поиска файлов, помещённых на временную панель.
  1. --[[ Тест
  2. Macro{
  3. --  id="";
  4.   area="Shell";
  5.   key="AltCtrlF2";
  6. --  description="";
  7. --  filemask="";
  8.   flags="";
  9. --  priority=50;
  10. --  sortpriority=50;
  11. --  condition=function(key) return true end;
  12. action=function()
  13.  far.Show(Panel.FExist(0, APanel.Current))
  14. end;
  15. }
  16. --]]
  17.  
  18. --[[
  19. CopyFiles.TempPanel.lua, Версия 4
  20. Макрос, реализующий копирование файлов из временной панели в папку, открытую
  21. на неактивной панели, с сохранением структуры каталогов.
  22. 1. Макрос повешен на AltCtrlF5
  23. 2. Макрос не обрабатывает каталоги (только файлы)
  24. 3. Макрос не запрашивает путь к приёмному каталогу. Строго в каталог неактивной панели.
  25. 4. При наличии в приемном каталоге файла запрашивает, что делать. Варианты:
  26.    - переписать \  как для одного файла,
  27.    - пропустить /  так и для всех оставшихся
  28.    - обновить - переписать только если исходный файл новее приёмного.
  29.                 Действует на все оставшиеся
  30.    - прекратить копирование.
  31. 5. Визуализации процесса не предусмотрено. Желающие могут сделать сами...
  32. Версия 4:
  33. 5.a. Предусмотен вывод копируемого файла, обновление содержимого приёмной (пассивной) панели и
  34.      возможность прерывания копирования оставшихся (не скопированных) файлов. Увы, прерывание
  35.      копирования текущего файла не предусмотрено .
  36. Версия 5:
  37. 6. Путь к "корню" запоминается при начале поиска из диалога поиска файла (AltF7).
  38. 7. Если после копирования остались не скопированные файлы, то предлагается "докопировать" их обычным копирование
  39.    в папку, открытую на пассивной панели без сохранения структуры каталогов.
  40. --
  41. © Буняк А.Х.
  42. --]]
  43. local ReWriteMode=0
  44. Macro {
  45.     area = "Shell";
  46.     key = 'AltCtrlF5';
  47.     description = 'Копирование файла из временной панели с учётом вложенных каталогов';
  48.     flags = ""; -- EnableOutput не помогает
  49.     condition=function()
  50.      --local PanGuid=win.Uuid(_G.panel.GetPanelInfo(0).OwnerGuid):upper()
  51.      return band(panel.GetPanelInfo(nil, 1).Flags, far.Flags.PFLAGS_REALNAMES) == far.Flags.PFLAGS_REALNAMES
  52.             --or
  53.             --PanGuid=='B77C964B-E31E-4D4C-8FE5-D6B0C6853E7C' or -- TempPanel
  54.             --PanGuid=='8E11EA75-0303-4374-AC60-D1E38F865449' or -- LF Search: temporary panel
  55.             --PanGuid=='F250C12A-78E2-4ABC-A784-3FDD3156E415' or -- RESearch
  56.             --PanGuid=='E2500D1C-D1D2-4C4C-91C0-6864F2AAF5E8'    -- LF TmpPanel
  57.     end;
  58.     action = function()
  59.      -- Получение имени "корневого" каталога (того, что на ..)
  60.      ReWriteMode = 0
  61.      local function _RootDir()
  62.       local ItemInfo=panel.GetPanelInfo(0)
  63.       local iItem, iTop=ItemInfo.CurrentItem, ItemInfo.TopPanelItem
  64.       Panel.SetPosIdx(0, 1)
  65.       local sRes=APanel.Path0
  66.       panel.RedrawPanel(nil, 1, {CurrentItem=iItem; TopPanelItem=iTop})
  67.       return sRes
  68.      end
  69.      -- Копирование одного файла
  70.      local function _CopyF(Src, Dst, Root)
  71.       -- Заменяю корневой каталог на приемный в исходном файле
  72.       local bRes=false
  73.       if Src:sub(1, Root:len()):upper() == Root:upper() then
  74.        local _Dst = Dst .. Src:sub(Root:len()+1)
  75.        local _DstPath = mf.fsplit(_Dst, 3)
  76.        if mf.fexist(_Dst) then
  77.         if ReWriteMode < 3 then
  78.          ReWriteMode = far.Message( _Dst..'\nФайл Существует. Что делаем?',
  79.                                     'Копирование файлов со структурой каталогов',
  80.                                     'Переписать;Пропустить;Переписать все;Пропустить все;Обновить все;Отменить' )
  81.          if ReWriteMode == 6 then ReWriteMode = -1 end
  82.         end
  83.         if ReWriteMode == 1 or ReWriteMode == 3 or
  84.            (ReWriteMode == 5 and win.GetFileInfo(Src).LastWriteTime > win.GetFileInfo(_Dst).LastWriteTime) then
  85.          win.DeleteFile(_Dst)
  86.         end
  87.        elseif not mf.fexist(_DstPath) then
  88.         if not win.CreateDir(_DstPath) then return end
  89.        end
  90.        if not mf.fexist(_Dst) and mf.fexist(_DstPath) then
  91.         far.Message('Копируется '..Src..'\nв '.._DstPath, '', '')
  92.         bRes = win.CopyFile(Src, _Dst)
  93.         far.AdvControl("ACTL_REDRAWALL")
  94.         --panel.RedrawPanel(nil, 0)
  95.         panel.UpdatePanel(nil, 0, true)
  96.        end
  97.       end -- if Src:sub(1, Root:len()):upper() == Root:upper()
  98.       return bRes
  99.      end -- _CopyF
  100.      local RootDir=_RootDir()
  101.      local aItems={}
  102.      if APanel.Selected then
  103.       -- Цикл по отмеченным
  104.       for i=1,APanel.SelCount do
  105.        table.insert(aItems, panel.GetSelectedPanelItem(nil, 1, i))
  106.       end
  107.       -- Список отмеченных элементов, которые надо будет потом погасить одной командой,
  108.       -- чтобы была возможность восстановить отметку по CtrlM
  109.       local aDone={}
  110.       local anDone, i0={}, 2 -- Для обхода ошибки ФАРа в Panel.Select (временно)
  111.       for _, Item in ipairs(aItems) do
  112.        --[[*D*]]local sBreak=mf.waitkey(1,0); if sBreak=='Esc' and far.Message('Прервать?','Копирование файлов с временной панели', ';YesNo','w') == 1 then break end
  113.        --if (mf.waitkey(1,0) == 'Esc') then break end;
  114.        if not Item.FileAttributes:match('d') and
  115.           mf.fexist(Item.FileName) -- При режиме :any на временной панели могут быть не только реальные файлы
  116.        then
  117.         if _CopyF(Item.FileName, PPanel.Path, RootDir) then
  118.          table.insert(aDone, Item.FileName)
  119.          -- Т.к. Panel.FExist не работает, ищу итем перебором.
  120.          -- Т.к. обработка итемов происходит в порядке их повления на панели, можно искать
  121.          -- не каждый раз от начала, а со следующего за предыдущим.
  122.          for i=i0,APanel.ItemCount do
  123.           if panel.GetPanelItem(nil, 1, i).FileName == Item.FileName then
  124.            table.insert(anDone, i)
  125.            i0 = i + 1
  126.            break
  127.           end
  128.          end
  129.          --table.insert(anDone, Panel.FExist(0, Item.FileName)) - Panel.FExist не работает на плагиновой панели...
  130.         end
  131.         if ReWriteMode == -1 then break end -- Был отказ (снятие)
  132.        end
  133.       end
  134.       -- Снятие отметок с файлов, которые были скопированы
  135.       if #aDone > 0 then
  136.        --Panel.Select( 0, 0, 2,  table.concat(aDone, '\n'))
  137.        panel.SetSelection(nil, 1, anDone, false)
  138.        Panel.SetPosIdx(0, APanel.CurPos)
  139.       end
  140.      else
  141.       local Item = panel.GetCurrentPanelItem(nil, 1)
  142.       if not Item.FileAttributes:match('d') then
  143.        _CopyF(Item.FileName, PPanel.Path, RootDir)
  144.       end
  145.      end
  146.     end;
  147. }

CopyFiles.TempPanel.lua.7z
CopyFiles.TempPanel.lua, версия 4
(2.77 KiB) Downloaded 48 times
Опубликовал версию 5 (с которой работаю уже пару месяцев). Только во вложении, т.к. используется пара моих модулей.
CopyFiles.TempPanel.v5.lua.7z
CopyFiles.TempPanel.lua, версия 5
(13.03 KiB) Downloaded 14 times
Last edited by buniak_a_h on Fri 30 Nov, 2018 11:09, edited 1 time in total.

Shtirla
Posts: 92
Joined: Wed 04 Mar, 2009 20:09
Has thanked: 5 times
Been thanked: 1 time

Копирование файлов с временной панели с сохранение структуры папок

Post by Shtirla » Fri 30 Nov, 2018 11:00

Latest post of the previous page:

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

buniak_a_h
Posts: 610
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 60 times
Been thanked: 15 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Fri 30 Nov, 2018 11:18

Shtirla wrote:
Fri 30 Nov, 2018 11:00
Ну как вариант, перед копированием можно проходить все файлы с путями, и искать общий знаменатель в начале строки
Я писал, чем это меня не устраивает. Конкретно меня в конкретно моих задачах.

Shtirla
Posts: 92
Joined: Wed 04 Mar, 2009 20:09
Has thanked: 5 times
Been thanked: 1 time

Копирование файлов с временной панели с сохранение структуры папок

Post by Shtirla » Fri 30 Nov, 2018 11:22

ну тогда не пойму чем вариант с заменой по первому\ не устраивает, он как раз таки полную структуру сохраняет

buniak_a_h
Posts: 610
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 60 times
Been thanked: 15 times
Contact:

Копирование файлов с временной панели с сохранение структуры папок

Post by buniak_a_h » Fri 30 Nov, 2018 14:02

Shtirla wrote:
Fri 30 Nov, 2018 11:22
ну тогда не пойму чем вариант с заменой по первому\ не устраивает, он как раз таки полную структуру сохраняет
Извините, невнимателен.
По первому - другая крайность. Например, все проекты находятся в подпапках D:\SUBSTR\F\Projects\Projecn#. Это - у меня. У юзера нет D:\SUBSTR\F\Projects\, а вместо этого есть C:\Program Files\ Я передаю файлы, относящиеся к одному проекту (Project#\) (не все - выборочно).
Я не критикую Ваш вариант: такой макрос у меня тоже есть (точнее, был). И именно убирал общее начало. Мне как раз удобнее стало копировать пути, начиная с папки, которая была текущей во время начала поиска. Да, узко специализированный получился скрипт. Но часто требуемый. В моих условиях, во всяком случае...

Post Reply

Return to “Обсуждение макросов”