View Issue Details

IDProjectCategoryView StatusLast Update
0003325Far ManagerPlugins API.Panelpublic2016-10-30 17:40
Reporterdimfish Assigned Tozg  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionfixed 
Product Version3.0 
Summary0003325: Detect external file editing and post back to plugin
DescriptionСейчас при редактировании файла родным редактором FAR он закачивается обратно в плагин, если был изменен. Сделать тоже самое для внешних редакторов, например Word, notepad вызванных по Enter. То есть запомнить дату записи времнного файла и если она поменялось закачать обратно в плагин перед удалением.
TagsNo tags attached.
Build4820

Relationships

parent of 0003328 new Если файл открыт из архива (используется arclite), то после его закрытия появляется панель "Обновление архива" 
Not all the children of this issue are yet resolved or closed.

Activities

shmuel

2016-10-10 05:51

developer   bugnote:0014872

Сейчас при редактировании файла родным редактором FAR он закачивается обратно в плагин, если был изменен.

dimfish
О каком плагине речь, и как это файл в него закачивается? Мне ваша формулировка совершенно непонятна.

dimfish

2016-10-10 06:17

reporter   bugnote:0014873

Да в любом плагине - мой это FARDroid, но проще в arclite посмотреть.
Заходим в архив test.7z и 2 случая:
1. Редактируем файл test.txt по F4 (встроенный редактор), меняем, сохраняем => он обратно запаковывается в архив.
2. Редактируем файл test.txt по Enter (открывается ассоциированная Windows программа например notepad), меняем, сохраняем => и ничего не происходит, а только удаляется временный файл.

shmuel

2016-10-10 06:55

developer   bugnote:0014874

Last edited: 2016-10-10 07:19

1. Редактируем файл test.txt по F4 (встроенный редактор), меняем, сохраняем => он обратно запаковывается в архив.

dimfish
Так это делает плагин, а не Far. У плагина есть возможность отследить закрытие редактора (он получает событие EE_CLOSE), после чего плагин считывает содержимое временного файла. А вот как плагин отследит закрытие Notepad - это другой вопрос (хотя я не говорю, что это невозможно).

(Собственно я не разбирался, как это сделано в Arclite, возможно он сам по нажатию F4 запускает редактор модально, тогда и EE_CLOSE не нужен).

dimfish

2016-10-10 07:57

reporter   bugnote:0014875

Last edited: 2016-10-10 08:06

Это делает именно FAR а не плагин - я же говорил неважно какой плагин.

Вот filelist.cpp 1951:
        if (FileNameToPluginItem(strTempName, PanelItem))
        {
            int PutCode = Global->CtrlObject->Plugins->PutFiles(m_hPlugin, &PanelItem.Item, 1, false, OPM_EDIT);

Вот как выставляется UploadFile: filelist.cpp 1910:
        UploadFile=ShellEditor->IsFileChanged() || NewFile;

Хотелось бы добавить туда логику по KEY_ENTER|KEY_SHIFTENTER послу блока if (Edit):
          elseif (LocalKey==KEY_ENTER || LocalKey==KEY_SHIFTENTER)) {
               UploadFile = IsExternaFileChanged()
          }

Где IsExternaFileChanged функция проверяющая LastWriteTime файла в strTempDir.

dimfish

2016-10-10 08:15

reporter   bugnote:0014876

Last edited: 2016-10-10 08:16

Посмотрел поглубже - наверное правильней расширить функцию FileList::ProcessEnter (filelist.cpp 2545)

Добавить такую же логику как для edit (которую я привел выше) после строчки filelist.cpp 2620
 if (!Global->CtrlObject->Plugins->GetFile(m_hPlugin, &PanelItem.Item, strTempDir, strFileName, OPM_SILENT | OPM_VIEW))

А в самой строчке поменять OPM_SILENT | OPM_VIEW => OPM_EDIT

dimfish

2016-10-10 08:27

reporter   bugnote:0014877

Если надо могу написать сам код и прислать на review.

shmuel

2016-10-10 08:40

developer   bugnote:0014878

Пожалуй вы правы по поводу того, что не плагин открывает редактор, а Far.
Но насчёт того, что Far сам "закачивает" изменённые данные в плагин, не убедили. Насколько можно видеть из структуры PutFilesInfo, плагин получает только пути файлов, а их содержимое он считывает сам.

dimfish

2016-10-10 08:45

reporter   bugnote:0014879

ну вот же еще раз filelist.cpp 1953:
            int PutCode = Global->CtrlObject->Plugins->PutFiles(m_hPlugin, &PanelItem.Item, 1, false, OPM_EDIT);

shmuel

2016-10-10 08:51

developer   bugnote:0014880

И где вы увидели, что Far передаёт содержимое файлов в плагин?

dimfish

2016-10-10 09:09

reporter   bugnote:0014881

Ну OK если придираться к словам, то конечно, FAR не может сам закачать - как закачивать знает только плагин. Естественно имелся ввиду вызов функции плагина PutFiles с заполненной структурой PutFilesInfo, которая указывает на временный файл.

shmuel

2016-10-10 09:15

developer   bugnote:0014882

Зря вы считаете, что я придираюсь - и в мыслях не было. Но есть устоявшаяся терминология, по которой "закачка файла" означает передачу содержимого. Если вы изначально имели в виду имена файлов, значит я вас не понял.

dimfish

2016-10-10 09:23

reporter   bugnote:0014883

ОК Перефразируем постановку задачи:
При нажатии Enter, ShiftEnter:
0. Изменить вызов GetFile (filelist.cpp 2620) OPM_SILENT | OPM_VIEW => OPM_EDIT
1. Cразу после GetFile (filelist.cpp 2620) сохранить в переменную 'LastWriteTime'
2. Перед удалением SCOPE_EXIT (filelist.cpp 2608) сравнить 'LastWriteTime' с сохраненной переменной и вызвать PutFiles в случая различий.

zg

2016-10-10 10:18

developer   bugnote:0014885

патч можно присылать, но есть пара моментов.
1. где можно, проверять ещё и ChangeTime. возможно ещё и размер.
2. по altf4 и по f4, если запускается внешняя программа файл обратно заливается безусловно, для консистенции хорошо бы добавить и туда проверку на изменённость.

а так идея правильная.

dimfish

2016-10-10 12:13

reporter  

DetectExternalEditing.txt (3,140 bytes)   
diff -r C:\Users\dimfish\AppData\Local\Temp\rJinGa_filelist.cpp F:\Git\Far\unicode_far\filelist.cpp
1888,1895c1888,1902
< 						if ((LocalKey==KEY_ALTF4 || LocalKey==KEY_RALTF4) &&
< 						        ProcessLocalFileTypes(strFileName,strShortFileName,FILETYPE_ALTEDIT,
< 						                              PluginMode))
< 							Processed=TRUE;
< 						else if (LocalKey==KEY_F4 &&
< 						         ProcessLocalFileTypes(strFileName,strShortFileName,FILETYPE_EDIT,
< 						                               PluginMode))
< 							Processed=TRUE;
---
> 						FILETIME tmpWriteTimeBefore, tmpWriteTimeAfter, tmpChangeTimeBefore, tmpChangeTimeAfter;
> 						os::GetFileTimeSimple(strFileName, nullptr, nullptr, &tmpWriteTimeBefore, &tmpChangeTimeBefore);
> 
> 						if ((LocalKey == KEY_ALTF4 || LocalKey == KEY_RALTF4) && ProcessLocalFileTypes(strFileName, strShortFileName, FILETYPE_ALTEDIT, PluginMode))
> 						{
> 							os::GetFileTimeSimple(strFileName, nullptr, nullptr, &tmpWriteTimeAfter, &tmpChangeTimeAfter);
> 							UploadFile = tmpWriteTimeAfter != tmpWriteTimeBefore || tmpChangeTimeAfter != tmpChangeTimeBefore;
> 							Processed = TRUE;
> 						}
> 						else if (LocalKey == KEY_F4 && ProcessLocalFileTypes(strFileName, strShortFileName, FILETYPE_EDIT, PluginMode))
> 						{
> 							os::GetFileTimeSimple(strFileName, nullptr, nullptr, &tmpWriteTimeAfter, &tmpChangeTimeAfter);
> 							UploadFile = tmpWriteTimeAfter != tmpWriteTimeBefore || tmpChangeTimeAfter != tmpChangeTimeBefore;
> 							Processed = TRUE;
> 						}
1900c1907,1911
< 								ProcessExternal(Global->Opt->strExternalEditor,strFileName,strShortFileName,PluginMode);
---
> 							{
> 								ProcessExternal(Global->Opt->strExternalEditor, strFileName, strShortFileName, PluginMode);
> 								os::GetFileTimeSimple(strFileName, nullptr, nullptr, &tmpWriteTimeAfter, &tmpChangeTimeAfter);
> 								UploadFile = tmpWriteTimeAfter != tmpWriteTimeBefore || tmpChangeTimeAfter != tmpChangeTimeBefore;
> 							}
2609a2621
> 		FILETIME tmpWriteTimeBefore, tmpWriteTimeAfter, tmpChangeTimeBefore, tmpChangeTimeAfter;
2620c2632
< 			if (!Global->CtrlObject->Plugins->GetFile(m_hPlugin, &PanelItem.Item, strTempDir, strFileName, OPM_SILENT | OPM_VIEW))
---
> 			if (!Global->CtrlObject->Plugins->GetFile(m_hPlugin, &PanelItem.Item, strTempDir, strFileName, OPM_EDIT))
2623a2636
> 			os::GetFileTimeSimple(strFileName, nullptr, nullptr, &tmpWriteTimeBefore, &tmpChangeTimeBefore);
2666a2680,2696
> 		}
> 
> 		if (PluginMode && (!OpenedPlugin || OpenedPlugin == PANEL_STOP))
> 		{
> 			if (os::GetFileTimeSimple(strFileName, nullptr, nullptr, &tmpWriteTimeAfter, &tmpChangeTimeAfter))
> 			{
> 				if (tmpWriteTimeAfter != tmpWriteTimeBefore || tmpChangeTimeAfter != tmpChangeTimeBefore)
> 				{
> 					PluginPanelItemHolder PanelItem;
> 					if (FileNameToPluginItem(strFileName, PanelItem))
> 					{
> 						int PutCode = Global->CtrlObject->Plugins->PutFiles(m_hPlugin, &PanelItem.Item, 1, false, OPM_EDIT);
> 						if (PutCode == 1 || PutCode == 2)
> 							SetPluginModified();
> 					}
> 				}
> 			}
DetectExternalEditing.txt (3,140 bytes)   

dimfish

2016-10-10 12:17

reporter   bugnote:0014886

Сделал Patch 'DetectExternalEditing.txt'
- проверяется LastWriteTime и ChangeTime
- добавил проверку ещё в 3 местах для Alt+F4, F4, External
Проверил работу на arclite и fardroid

zg

2016-10-10 13:36

developer   bugnote:0014887

4818.
на будущее либо нормальный патч, сгенерированный той же черепашкой. либо хотя бы с ключом -c.

dimfish

2016-10-10 13:53

reporter   bugnote:0014888

Last edited: 2016-10-10 15:10

нормальный это какой? Я использовал normal diff, ещё в Beyond Compare есть

Context diff:
*** E:\a\a.txt 2016-10-10 16:52:17.000000000 +0300
--- E:\a\a1.txt 2016-10-10 16:52:14.000000000 +0300
***************
*** 1 ****
! 123
--- 1 ----
! 1234

или Unified diff
--- E:\a\a.txt 2016-10-10 16:52:17.000000000 +0300
+++ E:\a\a1.txt 2016-10-10 16:52:14.000000000 +0300
@@ -1 +1 @@
-123
+1234

ага в черепашке Patch имеется ввиду вариант Unified diff - ок буду в нем делать

dimfish

2016-10-11 06:30

reporter   bugnote:0014890

Проверил 4819 на плагинах arclite и fardroid - всё работатет

shmuel

2016-10-11 14:05

developer   bugnote:0014891

zg, глянь пожалуйста на 2 сообщения, начиная от этого. Их автор мне в личку также написал.

zg

2016-10-11 15:23

developer   bugnote:0014892

что касается запроса — 4820.1. что касается удаления файлов — это сомнительно.
так же в 4820 — аналогичное поведение на enter, если сработала ассоциация фара.

Issue History

Date Modified Username Field Change
2016-10-07 19:29 dimfish New Issue
2016-10-10 05:51 shmuel Note Added: 0014872
2016-10-10 06:17 dimfish Note Added: 0014873
2016-10-10 06:55 shmuel Note Added: 0014874
2016-10-10 07:19 shmuel Note Edited: 0014874
2016-10-10 07:57 dimfish Note Added: 0014875
2016-10-10 08:06 dimfish Note Edited: 0014875
2016-10-10 08:15 dimfish Note Added: 0014876
2016-10-10 08:16 dimfish Note Edited: 0014876
2016-10-10 08:27 dimfish Note Added: 0014877
2016-10-10 08:40 shmuel Note Added: 0014878
2016-10-10 08:45 dimfish Note Added: 0014879
2016-10-10 08:51 shmuel Note Added: 0014880
2016-10-10 09:09 dimfish Note Added: 0014881
2016-10-10 09:15 shmuel Note Added: 0014882
2016-10-10 09:23 dimfish Note Added: 0014883
2016-10-10 10:18 zg Note Added: 0014885
2016-10-10 12:13 dimfish File Added: DetectExternalEditing.txt
2016-10-10 12:17 dimfish Note Added: 0014886
2016-10-10 13:36 zg Note Added: 0014887
2016-10-10 13:53 dimfish Note Added: 0014888
2016-10-10 15:10 dimfish Note Edited: 0014888
2016-10-11 06:30 dimfish Note Added: 0014890
2016-10-11 08:34 zg Build => 4818
2016-10-11 08:34 zg Status new => closed
2016-10-11 08:34 zg Assigned To => zg
2016-10-11 08:34 zg Resolution open => fixed
2016-10-11 14:05 shmuel Note Added: 0014891
2016-10-11 15:23 zg Note Added: 0014892
2016-10-11 15:23 zg Status closed => feedback
2016-10-11 15:23 zg Resolution fixed => reopened
2016-10-13 19:48 2useven10 Relationship added parent of 0003328
2016-10-30 17:40 zg Build 4818 => 4820
2016-10-30 17:40 zg Status feedback => closed
2016-10-30 17:40 zg Resolution reopened => fixed