сортировка по клику на заголовок колонки

Вам не хватает чего-то в Far? Вы считаете, что вашу идею стоит услышать? Пишите сюда.
Post Reply
lvmm
Posts: 3
Joined: Thu 15 Apr, 2021 14:31

сортировка по клику на заголовок колонки

Post by lvmm »

Кмк будет удобно, если по клику на заголовок колонки в панели файлы будут сортироваться по этой колонке, а если уже по ней отсортированы - сортировка реверсировалась бы.
User avatar
citRiks
Posts: 1421
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 431 times
Been thanked: 90 times

сортировка по клику на заголовок колонки

Post by citRiks »

Тема родственная этой, как мне кажется:
ClickToTitleDir — переход к папкам по щелчку на заголовке панели
viewtopic.php?t=11797

Нa уровне самого ФАРа реализовано думаю что не будет никогда,
на уровне скрипта - думаю что можно позаимствовать все нужные идеи из ClickToTitleDir
А кто не поверит в наше миролюбие, / Тот кровью умоется. / И будет такая борьба за мир, / Что камня на камне не останется.
buniak_a_h
Posts: 2779
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 151 times
Been thanked: 399 times
Contact:

сортировка по клику на заголовок колонки

Post by buniak_a_h »

citRiks, да, первое что пришло в голову - именно это :-) Допилить ClickToTitleDir …
User avatar
HaRT
Moderator
Posts: 9752
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 127 times
Been thanked: 265 times

сортировка по клику на заголовок колонки

Post by HaRT »

buniak_a_h wrote: Tue 04 May, 2021 16:40 Допилить ClickToTitleDir
Стоит ли пихать такие разные функции в общий скрипт?! Да и название неподходящее. Вот если бы отдельный сделать… А с новым названием я бы тоже помог, как и с тонкостями логики (предвижу, что они будут).
Фар есть инструмент, а не нянька. © 2009 DrKnS
buniak_a_h
Posts: 2779
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 151 times
Been thanked: 399 times
Contact:

сортировка по клику на заголовок колонки

Post by buniak_a_h »

HaRT wrote: Tue 04 May, 2021 16:53 Стоит ли пихать такие разные функции в общий скрипт?! Да и название неподходящее. Вот если бы отдельный сделать… А с новым названием я бы тоже помог, как и с тонкостями логики (предвижу, что они будут).
Да ну нет, конечно. Я имел в виду взять за основу ClickToTitleDir и немного поменять. Возможно, логика там будет даже проще: получить ширины столбцов и координату левой границы панели - просто.
buniak_a_h
Posts: 2779
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 151 times
Been thanked: 399 times
Contact:

сортировка по клику на заголовок колонки

Post by buniak_a_h »

Всем интересующимся.
Вот такой макрос решает задачу:
  1. local F = far.Flags
  2. local ReadConsole = require"BAX.ReadConsole"
  3. local ReadConsoleLine = ReadConsole.ReadConsoleLine
  4.  
  5. Macro{
  6.   id="7AEEB668-FFE0-422E-8E2F-0A58C2708997";
  7.   area="Shell";
  8.   key="MsLClick";
  9.   description="Сортировка по клику на заголовке столбца";
  10.   condition=function(key, data)
  11.    data.Mouse = {X=Mouse.X; Y=Mouse.Y}
  12.    local lPan, rPan = APanel, PPanel
  13.    if not APanel.Left then
  14.     lPan, rPan = rPan, lPan
  15.    end
  16.    local lgr, rgr = 3, lPan.Width-1
  17.    if Mouse.X > rgr then
  18.     lgr, rgr = lPan.Width + 4, lPan.Width + rPan.Width-1
  19.    end
  20.    if Mouse.Y == 1 and
  21.       Mouse.X > lgr and
  22.       Mouse.X < rgr and
  23.       ReadConsoleLine(Mouse.X, 1, 1):match"[^%s|║│]" then
  24.     return true
  25.    end
  26.   end;
  27.   action=function(data)
  28.    local aMouse = data.Mouse
  29.    -- Определяем, тыкнули ли на активной панели
  30.    local Rect = panel.GetPanelInfo(nil, 1).PanelRect -- APanel
  31.    if not (aMouse.X > Rect.left and aMouse.X < Rect.right) then
  32.     Rect = panel.GetPanelInfo(nil, 0).PanelRect -- APanel
  33.     if aMouse.X > Rect.left and aMouse.X < Rect.right then
  34.      panel.SetActivePanel(nil, 0)
  35.     else
  36.      return false
  37.     end
  38.    end
  39.    local aColumns = loadstring('return {' .. panel.GetColumnWidths(nil, 1) .. '}')()
  40.    local iCol = 1
  41.    if #aColumns > 1 then
  42.     local l = Rect.left + 1
  43.     for i=1,#aColumns do
  44.      iCol = i
  45.      if aMouse.X > l and aMouse.X < l+aColumns[i] then break end
  46.      l = l + aColumns[i]
  47.     end
  48.    end
  49.    local sTypes = panel.GetColumnTypes(nil, 1)
  50.    local aTypes = {}
  51.    sTypes:gsub( '[^,]+', function(a) table.insert(aTypes, a:sub(1,1)) end)
  52.    local Info = panel.GetPanelInfo(nil, 1)
  53.    if aTypes[iCol] == 'N' then
  54.     -- по имени
  55.     if Info.SortMode == F.SM_NAME or Info.SortMode == F.SM_NAMEONLY then
  56.      panel.SetSortOrder(nil, 1, band(Info.Flags, F.PFLAGS_REVERSESORTORDER) == 0 )
  57.     else
  58.      panel.SetSortMode(nil, 1, F.SM_NAME)
  59.     end
  60.    elseif aTypes[iCol] == 'X' then
  61.     -- по расширению
  62.     if Info.SortMode == F.SM_EXT then
  63.      panel.SetSortOrder(nil, 1, band(Info.Flags, F.PFLAGS_REVERSESORTORDER) == 0)
  64.     else
  65.      panel.SetSortMode(nil, 1, F.SM_EXT)
  66.     end
  67.    elseif aTypes[iCol] == 'S' then
  68.     -- по размеру
  69.     if Info.SortMode == F.SM_SIZE then
  70.      panel.SetSortOrder(nil, 1, band(Info.Flags, F.PFLAGS_REVERSESORTORDER) == 0)
  71.     else
  72.      panel.SetSortMode(nil, 1, F.SM_SIZE)
  73.     end
  74.    elseif aTypes[iCol] == 'D' or aTypes[iCol] == 'T' then
  75.     -- по времени
  76.     if Info.SortMode == F.SM_CHTIME or Info.SortMode == F.SM_MTIME or Info.SortMode == F.SM_CTIME then
  77.      panel.SetSortOrder(nil, 1, band(Info.Flags, F.PFLAGS_REVERSESORTORDER) == 0)
  78.     else
  79.      panel.SetSortMode(nil, 1, F.SM_MTIME)
  80.     end
  81.    elseif aTypes[iCol] == 'L' or aTypes[iCol] == 'T' then
  82.     -- по количеству жёстких связей
  83.     if Info.SortMode == F.SM_NUMLINKS then
  84.      panel.SetSortOrder(nil, 1, band(Info.Flags, F.PFLAGS_REVERSESORTORDER) == 0)
  85.     else
  86.      panel.SetSortMode(nil, 1, F.SM_NUMLINKS)
  87.     end
  88.    else
  89.     -- не реализовано
  90.     far.Message('Не реализовано','',nil,'w')
  91.    end
  92.   end;
  93. }
Ну, правда, не все виды сортировки реализованы. К тому же некоторые виды столбцов я не стал различать (дата - время как по CtrlF5 все). Если надо - легко добавить.

Для удобства скачивания:
Тут было вложение.

P/S. Тема, посвящённая этому макросу, отделена. Сам макрос слегка изменён.
PPS. Вложение куда-то подевалось … Уже второй раз за сегодня
Last edited by buniak_a_h on Fri 07 May, 2021 06:35, edited 2 times in total.
buniak_a_h
Posts: 2779
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 151 times
Been thanked: 399 times
Contact:

сортировка по клику на заголовок колонки

Post by buniak_a_h »

Ну вот, вроде, реализована сортировка по всем "стандартным" типам колонок (кроме атрибутов). Программа даже короче стала :-)
  1. local F = far.Flags
  2. local ReadConsole = require"BAX.ReadConsole"
  3. local ReadConsoleLine = ReadConsole.ReadConsoleLine
  4.  
  5. Macro{
  6.   id="7AEEB668-FFE0-422E-8E2F-0A58C2708997";
  7.   area="Shell";
  8.   key="MsLClick";
  9.   description="Сортировка по клику на заголовке столбца";
  10.   condition=function(key, data)
  11.    data.Mouse = {X=Mouse.X; Y=Mouse.Y}
  12.    local lPan, rPan = APanel, PPanel
  13.    if not APanel.Left then
  14.     lPan, rPan = rPan, lPan
  15.    end
  16.    local lgr, rgr = 3, lPan.Width-1
  17.    if Mouse.X > rgr then
  18.     lgr, rgr = lPan.Width + 4, lPan.Width + rPan.Width-1
  19.    end
  20.    if Mouse.Y == 1 and
  21.       Mouse.X > lgr and
  22.       Mouse.X < rgr and
  23.       ReadConsoleLine(Mouse.X, 1, 1):match"[^%s|║│]" then
  24.     return true
  25.    end
  26.   end;
  27.   action=function(data)
  28.    local aMouse = data.Mouse
  29.    -- Определяем, тыкнули ли на активной панели
  30.    local Rect = panel.GetPanelInfo(nil, 1).PanelRect -- APanel
  31.    if not (aMouse.X > Rect.left and aMouse.X < Rect.right) then
  32.     Rect = panel.GetPanelInfo(nil, 0).PanelRect -- APanel
  33.     if aMouse.X > Rect.left and aMouse.X < Rect.right then
  34.      panel.SetActivePanel(nil, 0)
  35.     else
  36.      return false
  37.     end
  38.    end
  39.    local aColumns = loadstring('return {' .. panel.GetColumnWidths(nil, 1) .. '}')()
  40.    local iCol = 1
  41.    if #aColumns > 1 then
  42.     local l = Rect.left + 1
  43.     for i=1,#aColumns do
  44.      iCol = i
  45.      if aMouse.X > l and aMouse.X < l+aColumns[i] then break end
  46.      l = l + aColumns[i]
  47.     end
  48.    end
  49.    local sTypes = panel.GetColumnTypes(nil, 1)
  50.    local aTypes = {}
  51.    sTypes:gsub( '[^,]+', function(a) table.insert(aTypes, a) end)
  52.    local Info = panel.GetPanelInfo(nil, 1)
  53.    local function SetSortMode(Mode)
  54.     if type(Mode) ~= 'table' then Mode = {Mode} end
  55.     local function ASCAN(tbl, what)
  56.      for i,v in ipairs(tbl) do if v == what then return i end end
  57.     end -- ASCAN
  58.     if ASCAN(Mode, Info.SortMode) then
  59.      panel.SetSortOrder(nil, 1, band(Info.Flags, F.PFLAGS_REVERSESORTORDER) == 0 )
  60.     else
  61.      panel.SetSortMode(nil, 1, Mode[1])
  62.     end
  63.    end -- SetSortMode
  64.    local aSwitch = {
  65.     {'^N.*N$', F.SM_NAMEONLY}; -- Имя без расширения
  66.     {'^N', F.SM_NAME};         -- Имя
  67.     {'^X', F.SM_EXT};          -- Расширение
  68.     {'^S', F.SM_SIZE};         -- Размер файла
  69.     {'^P', F.SM_SIZE};         -- Выделенный размер файла
  70.     {'^G', F.SM_STREAMSSIZE};  -- Размер потоков файла
  71.     {'^[DT]$', F.SM_MTIME};    -- Дата или время последней записи в файл
  72.     {'^DM', F.SM_MTIME};       -- Дата и время последней записи в файл
  73.     {'^DC', F.SM_CTIME};       -- Дата и время создания файла
  74.     {'^DA', F.SM_ATIME};       -- Дата и время последнего доступа к файлу
  75.     {'^DE', F.SM_CHTIME};      -- Дата и время изменения файла
  76.     {'^Z', F.SM_DESCR};        -- Описание
  77.     {'^O', F.SM_OWNER};        -- Владелец
  78.     {'^LN', F.SM_NUMLINKS};    -- Колич. жёстких ссылок
  79.     {'^F', F.SM_NUMSTREAMS};   -- Количество потоков
  80.     {'^A',  nil};              -- Атрибуты - не сортируется
  81.    } -- aSwitch
  82.    for _,v in ipairs(aSwitch) do
  83.     if aTypes[iCol]:match(v[1]) then
  84.      if v[2] then
  85.       SetSortMode({v[2]})
  86.      end
  87.     end
  88.    end
  89.   end;
  90. }
buniak_a_h
Posts: 2779
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 151 times
Been thanked: 399 times
Contact:

сортировка по клику на заголовок колонки

Post by buniak_a_h »

P/S. Макрос реагирует на клик по имени колонки. Символ под курсором при клике должен быть отличен от пробела и псевдографики - символов |, и . Пи этом при клике по пассивной панели она активируется как в стандарте.
User avatar
HaRT
Moderator
Posts: 9752
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 127 times
Been thanked: 265 times

сортировка по клику на заголовок колонки

Post by HaRT »

buniak_a_h wrote: Thu 06 May, 2021 23:40 Программа даже короче стала
Но где же номер версии? Как потом разбираться, где ошибка обнаружена, где исправлена?
Фар есть инструмент, а не нянька. © 2009 DrKnS
buniak_a_h
Posts: 2779
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 151 times
Been thanked: 399 times
Contact:

сортировка по клику на заголовок колонки

Post by buniak_a_h »

Самый первый вариант я написал "на коленке" за полчаса. Второй - немного подумав. Почти сразу. Поэтому надеялся, что первый никто не успел скачать. Оказалось, успели.
На самом деле если скрипт того заслуживает, то я оформлю и в другую тему зашлю. На конференции "Обсуждение макросов". Ну просто неудобно, если скрипт в "рядовых" сообщениях (ответах). Надо в первое сообщение темы.
buniak_a_h
Posts: 2779
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 151 times
Been thanked: 399 times
Contact:

сортировка по клику на заголовок колонки

Post by buniak_a_h »

P/S. Сделал я ветку, посвящённую этому макросу.
P/S. Правда, туда, похоже, никто не ходит … :-(
Last edited by buniak_a_h on Sun 09 May, 2021 19:48, edited 1 time in total.
Post Reply

Return to “Предложения и идеи”