View Issue Details

IDProjectCategoryView StatusLast Update
0001903WishesMacropublic2014-10-02 14:55
ReporterMaximus Assigned Tovskirdin  
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status closedResolutionfixed 
Product Version3.0 
Fixed in Version3.0 
Summary0001903: Plugin.Menu(guid,menuGuid)
DescriptionСобстно, надоело макросить вызов плагинов через F11.
предлагаемая функция - аналогична обычному вызову пункта меню плагина, но в обход открытия всего списка и позиционирования куда надо или выбора хоткея
в отличие от callplugin - выполнение макроса не останавливается, как и при F11
позвать плагин откуда он не ожидает - не получится, проверки области такие же как при населении списка F11
TagsNo tags attached.
Build0

Activities

Maximus

2011-10-12 10:21

reporter  

PluginMenu.diff (6,328 bytes)   
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 6753)
+++ plugins.hpp	(working copy)
@@ -230,6 +230,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginMenu(const GUID& Guid, const GUID& ItemGuid);
 		Plugin *FindPlugin(const GUID& SysID);
 		INT_PTR PluginGuidToPluginNumber(const GUID& PluginId);
 
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 6753)
+++ plugins.cpp	(working copy)
@@ -2268,6 +2268,94 @@
 	return FALSE;
 }
 
+int PluginManager::CallPluginMenu(const GUID& Guid, const GUID& ItemGuid)
+{
+	if (!ProcessException)
+	{
+		Plugin *pPlugin = FindPlugin(Guid);
+		if (pPlugin && pPlugin->HasOpenPanel())
+		{
+			int curType = FrameManager->GetCurrentFrame()->GetType();
+			bool Editor = curType==MODALTYPE_EDITOR;
+			bool Viewer = curType==MODALTYPE_VIEWER;
+			bool Dialog = curType==MODALTYPE_DIALOG;
+
+			bool bCached = pPlugin->CheckWorkFlags(PIWF_CACHED)?true:false;
+			UINT64 IFlags;
+			unsigned __int64 id = 0;
+
+			if (bCached)
+			{
+				id = PlCacheCfg->GetCacheID(pPlugin->GetCacheName());
+				IFlags = PlCacheCfg->GetFlags(id);
+			}
+			else
+			{
+				PluginInfo Info = {sizeof(Info)};
+				if (!pPlugin->GetPluginInfo(&Info))
+					return FALSE;
+				else
+					IFlags = Info.Flags;
+			}
+
+			if ((Editor && !(IFlags & PF_EDITOR)) ||
+					(Viewer && !(IFlags & PF_VIEWER)) ||
+					(Dialog && !(IFlags & PF_DIALOG)) ||
+					(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+				return FALSE;
+
+			Panel *ActivePanel=CtrlObject->Cp()->ActivePanel;
+			int OpenCode=OPEN_PLUGINSMENU;
+			INT_PTR Item=0;
+			OpenDlgPluginData pd;
+
+			if (Editor)
+			{
+				OpenCode=OPEN_EDITOR;
+			}
+			else if (Viewer)
+			{
+				OpenCode=OPEN_VIEWER;
+			}
+			else if (Dialog)
+			{
+				OpenCode=OPEN_DIALOG;
+				pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+				Item=(INT_PTR)&pd;
+			}
+
+			HANDLE hPlugin=Open(pPlugin,OpenCode,ItemGuid,Item);
+
+			if (hPlugin!=INVALID_HANDLE_VALUE && !Editor && !Viewer && !Dialog)
+			{
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+
+			// CtrlObject->Macro.SetMode(PrevMacroMode); -- ���� ���������/�������������� �����������?
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 6753)
+++ macroopcode.hpp	(working copy)
@@ -224,6 +224,7 @@
 	MCODE_F_FMATCH,                   // N=FMatch(S,Mask)
 	MCODE_F_PLUGIN_LOAD,              // N=Plugin.Load(DllPath[,ForceLoad])
 	MCODE_F_PLUGIN_UNLOAD,            // N=Plugin.UnLoad(DllPath)
+	MCODE_F_PLUGIN_MENU,              // N=Plugin.Menu(Guid,MenuGuid)
 	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
 	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
 
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 6753)
+++ macro.cpp	(working copy)
@@ -360,6 +360,7 @@
 static bool xlatFunc(const TMacroFunction*);
 static bool pluginloadFunc(const TMacroFunction*);
 static bool pluginunloadFunc(const TMacroFunction*);
+static bool pluginmenuFunc(const TMacroFunction*);
 
 static bool __CheckCondForSkip(DWORD Op);
 
@@ -435,6 +436,7 @@
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,        3, 0},
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,      2, 1},
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,    1, 0},
+	{L"PLUGIN.MENU",      nullptr, L"N=Plugin.Menu(Guid,MenuGuid)",                              pluginmenuFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_MENU,      2, 0},
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,            1, 0},
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,           5, 5},
 	{L"REPLACE",          nullptr, L"S=Replace(Str,Find,Replace[,Cnt[,Mode]])",                  replaceFunc,        nullptr, 0, 0,                                      MCODE_F_REPLACE,          5, 2},
@@ -4376,7 +4378,30 @@
 	return Ret.i()!=0;
 }
 
+// N=Plugin.Menu(Guid,MenuGuid)
+static bool pluginmenuFunc(const TMacroFunction*)
+{
+	__int64 Ret=0;
+	TVar MenuGuid; VMStack.Pop(MenuGuid);
+	TVar Guid; VMStack.Pop(Guid);
+	GUID guid, menuGuid;
 
+	if (StrToGuid(Guid.s(),guid) && StrToGuid(MenuGuid.s(),menuGuid) && CtrlObject->Plugins.FindPlugin(guid))
+	{
+		//if( Opt.Macro.CallPluginRules )
+		//	CtrlObject->Macro.PushState(true);
+
+		Ret=(__int64)CtrlObject->Plugins.CallPluginMenu(guid,menuGuid);
+
+		//if( Opt.Macro.CallPluginRules )
+		//	CtrlObject->Macro.PopState();
+	}
+
+	VMStack.Push(Ret);
+	return Ret?true:false;
+}
+
+
 // V=callplugin(SysID[,param])
 #if 0
 static bool callpluginFunc(const TMacroFunction*)
PluginMenu.diff (6,328 bytes)   

JohnDoe

2011-10-12 10:56

updater   bugnote:0007867

А ведь грядёт и ProcessMacroFuncW.
Не будет ли Plugin.Menu избыточным?

vskirdin

2011-10-12 11:05

administrator   bugnote:0007868

что есть первый параметр, что есть второй?
примеры в студию

Maximus

2011-10-12 14:23

reporter   bugnote:0007871

не будет.
каким макаром ты позовешь плаг, который НЕ экспортирует эту функцию, а расчитан только на вызов из меню?

guid и menuGuid - очевидно гуиды в строковом виде из F11 F3
первый - гуид плагина
второй - гуид пункта меню плагина

Maximus

2011-10-12 16:41

reporter   bugnote:0007872

пример - вызвать colorer outliner:

plugin.Menu("D2F36B62-A470-418D-83A3-ED7A3710E5B5","45453CAC-499D-4B37-82B8-0A77F7BD087C") 5

vskirdin

2011-10-13 12:59

administrator   bugnote:0007874

Не нравится мне это название "Plugin.Menu" - смотря на него, ожидаешь появление какого-то плагинового меню.
Надо что-то другое...

А что будет, если у плагина нет "стартового" меню (про второй параметр)?

Плюс к этому... плагин не будет знать, что его вызвали из макроса (OpenCode). Хотя... может это и ненадо.

Помыслил... тогда нужна парная функция - вызов конфигуратора конкретного плагина (по аналогии - есть PluginManager::CommandsMenu и есть PluginManager::Configure).

Maximus

2011-10-13 13:49

reporter   bugnote:0007877

plugin.call(), plugin.configure()?

если плагин не отдает пункт menuGuid в F11 - вызываться он не должен (поправлю)

vskirdin

2011-10-13 17:38

administrator   bugnote:0007880

ок

Maximus

2011-10-14 12:21

reporter   bugnote:0007881

plugin.call(guid,menuGuid)
  может быть вызвана только из тех макрообластей, которые "умеет" плагин
  ускоренный аналог выбора пункта меню из F11
  гуиды берем из F11 F3
    guid - поле 'Plugin GUID'
    menuGuid - поле 'Plugin item GUID'
  плагин и пункт с такими гуидами должны существовать, иначе функция вернет ошибку
Пример - в редакторе вызвать 'Colorer outliner'
  plugin.Call("D2F36B62-A470-418D-83A3-ED7A3710E5B5","45453CAC-499D-4B37-82B8-0A77F7BD087C") 5

plugin.config(guid[,menuGuid])
  может быть вызвана только из панелей
  ускоренный аналог выбора пункта меню из AltShiftF9
  гуиды берем из «Plugins configuration» F3
    guid - поле 'Plugin GUID'
    menuGuid - поле 'Plugin item GUID', поле необязательное, если не указано
               то функция ConfigureW плагина будет вызвана с GUID_NULL, иначе
               проверяется наличие пункта с таким гуидом.

Странность 1. Функции как бы асинхронные, т.к. при открытии диалога/меню плагином продолжается выполнение макроса (чего и хотелось, аналог F11 Enter)
пример - позвать настройку "Far Commands" и включить "Same folders"
plugin.Config("3A2AF458-43E2-4715-AFEA-93D33D56C0C2") Tab Add Enter
финт типа
%i=plugin.Config(...); $if (%i==...
не прокатит, т.к. макрос продолжает выполняться после появляения диалога.
Смысл тогда возвращать из функции вообще что-либо? Наверное отсутствует?

Странность 2. (наверное вытекает из 1)
выполненное в панелях
macro:post %i=eval("plugin.Config(\"3A2AF458-43E2-4715-AFEA-93D33D56C0C2\") Esc"); MsgBox("eval","eval="+%i)
покажет "eval=1", то есть ошибку, хотя все успешно отработало

Maximus

2011-10-14 12:22

reporter  

PluginCall.diff (7,555 bytes)   
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 6767)
+++ macro.cpp	(working copy)
@@ -360,6 +360,8 @@
 static bool xlatFunc(const TMacroFunction*);
 static bool pluginloadFunc(const TMacroFunction*);
 static bool pluginunloadFunc(const TMacroFunction*);
+static bool plugincallFunc(const TMacroFunction*);
+static bool pluginconfigFunc(const TMacroFunction*);
 
 static bool __CheckCondForSkip(DWORD Op);
 
@@ -435,6 +437,8 @@
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,        3, 0},
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,      2, 1},
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,    1, 0},
+	{L"PLUGIN.CALL",      nullptr, L"N=Plugin.Call(Guid,MenuGuid)",                              plugincallFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_CALL,      2, 0},
+	{L"PLUGIN.CONFIG",    nullptr, L"N=Plugin.Config(Guid[,MenuGuid])",                          pluginconfigFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_CONFIG,    2, 1},
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,            1, 0},
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,           5, 5},
 	{L"REPLACE",          nullptr, L"S=Replace(Str,Find,Replace[,Cnt[,Mode]])",                  replaceFunc,        nullptr, 0, 0,                                      MCODE_F_REPLACE,          5, 2},
@@ -4376,7 +4380,68 @@
 	return Ret.i()!=0;
 }
 
+// N=Plugin.Call(Guid,MenuGuid)
+static bool plugincallFunc(const TMacroFunction*)
+{
+	__int64 Ret=0;
+	TVar MenuGuid; VMStack.Pop(MenuGuid);
+	TVar Guid; VMStack.Pop(Guid);
+	GUID guid, menuGuid;
 
+	if (StrToGuid(Guid.s(),guid) && StrToGuid(MenuGuid.s(),menuGuid) && CtrlObject->Plugins.FindPlugin(guid))
+	{
+		Ret=(__int64)CtrlObject->Plugins.CallPluginItem(guid,menuGuid);
+	}
+
+	VMStack.Push(Ret);
+	return true; //Ret?true:false;
+}
+
+// N=Plugin.Config(Guid[,MenuGuid])
+static bool pluginconfigFunc(const TMacroFunction*)
+{
+	__int64 Ret=0;
+	TVar MenuGuid; VMStack.Pop(MenuGuid);
+	TVar Guid; VMStack.Pop(Guid);
+	GUID guid, menuGuid;
+	int curType = FrameManager->GetCurrentFrame()->GetType();
+
+	if (curType==MODALTYPE_PANELS && StrToGuid(Guid.s(),guid))
+	{
+		Plugin* pPlugin = CtrlObject->Plugins.FindPlugin(guid);
+		if (pPlugin && pPlugin->HasConfigure())
+		{
+			if (MenuGuid.isUnknown() || !StrToGuid(MenuGuid.s(),menuGuid))
+			{
+				menuGuid = FarGuid;
+				Ret=1;
+			}
+			else
+			{
+				PluginInfo Info = {sizeof(Info)};
+				if (pPlugin->GetPluginInfo(&Info))
+				{
+					for (int i = 0; i < Info.PluginConfig.Count; i++)
+					{
+						if (memcmp(&menuGuid,&(Info.PluginConfig.Guids[i]),sizeof(GUID)) == 0)
+						{
+							Ret=1;
+							break;
+						}
+					}
+				}
+			}
+		
+			if (Ret)
+				CtrlObject->Plugins.ConfigureCurrent(pPlugin,menuGuid);
+		}
+	}
+
+	VMStack.Push(Ret);
+	return true;
+}
+
+
 // V=callplugin(SysID[,param])
 #if 0
 static bool callpluginFunc(const TMacroFunction*)
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 6767)
+++ plugins.cpp	(working copy)
@@ -2243,6 +2243,95 @@
 	return FALSE;
 }
 
+int PluginManager::CallPluginItem(const GUID& Guid, const GUID& ItemGuid)
+{
+	if (!ProcessException)
+	{
+		Plugin *pPlugin = FindPlugin(Guid);
+		if (pPlugin && pPlugin->HasOpenPanel())
+		{
+			int curType = FrameManager->GetCurrentFrame()->GetType();
+			bool Editor = curType==MODALTYPE_EDITOR;
+			bool Viewer = curType==MODALTYPE_VIEWER;
+			bool Dialog = curType==MODALTYPE_DIALOG;
+
+			UINT64 IFlags;
+			PluginInfo Info = {sizeof(Info)};
+			if (!pPlugin->GetPluginInfo(&Info))
+				return FALSE;
+			else
+				IFlags = Info.Flags;
+
+			if ((Editor && !(IFlags & PF_EDITOR)) ||
+					(Viewer && !(IFlags & PF_VIEWER)) ||
+					(Dialog && !(IFlags & PF_DIALOG)) ||
+					(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+				return FALSE;
+
+			bool ItemFound = false;
+			for (int i = 0; i < Info.PluginMenu.Count; i++)
+			{
+				if (memcmp(&ItemGuid,&(Info.PluginMenu.Guids[i]),sizeof(GUID)) == 0)
+				{
+					ItemFound = true;
+					break;
+				}
+			}
+			if (!ItemFound)
+				return FALSE;
+				
+			Panel *ActivePanel=CtrlObject->Cp()->ActivePanel;
+			int OpenCode=OPEN_PLUGINSMENU;
+			INT_PTR Item=0;
+			OpenDlgPluginData pd;
+
+			if (Editor)
+			{
+				OpenCode=OPEN_EDITOR;
+			}
+			else if (Viewer)
+			{
+				OpenCode=OPEN_VIEWER;
+			}
+			else if (Dialog)
+			{
+				OpenCode=OPEN_DIALOG;
+				pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+				Item=(INT_PTR)&pd;
+			}
+
+			HANDLE hPlugin=Open(pPlugin,OpenCode,ItemGuid,Item);
+
+			if (hPlugin!=INVALID_HANDLE_VALUE && !Editor && !Viewer && !Dialog)
+			{
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+
+			// CtrlObject->Macro.SetMode(PrevMacroMode); -- ���� ���������/�������������� �����������?
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 6767)
+++ plugins.hpp	(working copy)
@@ -230,6 +230,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginItem(const GUID& Guid, const GUID& ItemGuid);
 		Plugin *FindPlugin(const GUID& SysID);
 		INT_PTR PluginGuidToPluginNumber(const GUID& PluginId);
 
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 6767)
+++ macroopcode.hpp	(working copy)
@@ -224,6 +224,8 @@
 	MCODE_F_FMATCH,                   // N=FMatch(S,Mask)
 	MCODE_F_PLUGIN_LOAD,              // N=Plugin.Load(DllPath[,ForceLoad])
 	MCODE_F_PLUGIN_UNLOAD,            // N=Plugin.UnLoad(DllPath)
+	MCODE_F_PLUGIN_CALL,              // N=Plugin.Call(Guid,MenuGuid)
+	MCODE_F_PLUGIN_CONFIG,            // N=Plugin.Config(Guid[,MenuGuid])
 	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
 	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
 
PluginCall.diff (7,555 bytes)   

vskirdin

2011-10-19 10:24

administrator   bugnote:0007910

подумалось...
может callplugin удалить, а у plugin.call сделать первым параметром 0|1 - синхронный|ассинхронный
и четвертым, необязательным - значение (возможно пятым - тип значения).
по поводу пятого - чтобы плагин понимал, что ему подсунули: число, строку или макропоследовательность (которую плагин подсунет фару).

НО! В Коде бага

1. Стартуем ФАР
2. исполняем
macro:post F4 plugin.Call("C941E865-9C29-485C-99B3-0C710940F2D8","ACEF1ACF-2B06-46BD-BBF0-7A841F4CF22C") ShiftRight

получаем выделенный символ вместо нарисованной горизонталной строки.

Теперь F11 и вызываем дравлайн, потом Esc
теперь повторяем п.2

вот теперь "угу", линия нарисована

Это вот к чему:
1. твой патч не учитывает, что плагин не разу не загружался (т.е. он еще не в кеше)
2. неплохо бы вместо дубляжа кода выделить из PluginManager::CallPluginItem и PluginManager::CommandsMenu зерно в отдельную функцию и...

Maximus

2011-10-19 14:11

reporter   bugnote:0007912

багу поправил.

> по поводу пятого - чтобы плагин понимал, что ему подсунули: число, строку или макропоследовательность (которую плагин подсунет фару).
ничего не понял.
какая макропоследовательность? новая предлагаемая фича?
число или строка - макродвижок вроде и без дополнительных параметров может понять

если убирать callplugin - мне видится как-то так:
plugin.call(type,guid[,item])
type - 0|1 - синхронный|ассинхронный
guid - плагин
item - зависит от type
  0: то что в callplugin было
  1: гуид пункта меню. если не указан, будет выполнен первый пункт плагина, если он всего один(!)

JohnDoe

2011-10-19 15:04

updater   bugnote:0007914

Может не убирать callplugin, а просто переименовать покрасивше?

Maximus

2011-10-19 15:38

reporter   bugnote:0007915

чего?

vskirdin

2011-10-19 16:15

administrator   bugnote:0007916

а чем не устраивает plugin.call(0,guid,значение) == callplugin(guid,значение) ?

JohnDoe

2011-10-19 20:25

updater   bugnote:0007919

Не нравится что суть значения приципиально разная, т.е. скрещивается уж с ежом.

Создаётся видимость будто пользователь может выбрать синхроность/асинхронность.
Но ведь "синхронно" можно вызвать только плагины специально под это заточенные.
Имхо это слишком разные вещи чтобы объединять их в 1.

Maximus

2011-10-19 21:25

reporter  

PluginCall2.diff (641,896 bytes)

Maximus

2011-10-19 21:27

reporter  

PluginCall3.diff (7,574 bytes)   
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 6795)
+++ plugins.hpp	(working copy)
@@ -230,6 +230,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginItem(const GUID& Guid, const GUID& ItemGuid);
 		Plugin *FindPlugin(const GUID& SysID);
 		INT_PTR PluginGuidToPluginNumber(const GUID& PluginId);
 
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 6795)
+++ macroopcode.hpp	(working copy)
@@ -224,6 +224,8 @@
 	MCODE_F_FMATCH,                   // N=FMatch(S,Mask)
 	MCODE_F_PLUGIN_LOAD,              // N=Plugin.Load(DllPath[,ForceLoad])
 	MCODE_F_PLUGIN_UNLOAD,            // N=Plugin.UnLoad(DllPath)
+	MCODE_F_PLUGIN_CALL,              // N=Plugin.Call(Guid,MenuGuid)
+	MCODE_F_PLUGIN_CONFIG,            // N=Plugin.Config(Guid[,MenuGuid])
 	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
 	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
 
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 6795)
+++ macro.cpp	(working copy)
@@ -360,6 +360,8 @@
 static bool xlatFunc(const TMacroFunction*);
 static bool pluginloadFunc(const TMacroFunction*);
 static bool pluginunloadFunc(const TMacroFunction*);
+static bool plugincallFunc(const TMacroFunction*);
+static bool pluginconfigFunc(const TMacroFunction*);
 
 static bool __CheckCondForSkip(DWORD Op);
 
@@ -435,6 +437,8 @@
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,        3, 0},
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,      2, 1},
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,    1, 0},
+	{L"PLUGIN.CALL",      nullptr, L"N=Plugin.Call(Guid,MenuGuid)",                              plugincallFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_CALL,      2, 0},
+	{L"PLUGIN.CONFIG",    nullptr, L"N=Plugin.Config(Guid[,MenuGuid])",                          pluginconfigFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_CONFIG,    2, 1},
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,            1, 0},
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,           5, 5},
 	{L"REPLACE",          nullptr, L"S=Replace(Str,Find,Replace[,Cnt[,Mode]])",                  replaceFunc,        nullptr, 0, 0,                                      MCODE_F_REPLACE,          5, 2},
@@ -4384,7 +4388,68 @@
 	return Ret.i()!=0;
 }
 
+// N=Plugin.Call(Guid,MenuGuid)
+static bool plugincallFunc(const TMacroFunction*)
+{
+	__int64 Ret=0;
+	TVar MenuGuid; VMStack.Pop(MenuGuid);
+	TVar Guid; VMStack.Pop(Guid);
+	GUID guid, menuGuid;
 
+	if (StrToGuid(Guid.s(),guid) && StrToGuid(MenuGuid.s(),menuGuid) && CtrlObject->Plugins.FindPlugin(guid))
+	{
+		Ret=(__int64)CtrlObject->Plugins.CallPluginItem(guid,menuGuid);
+	}
+
+	VMStack.Push(Ret);
+	return true; //Ret?true:false;
+}
+
+// N=Plugin.Config(Guid[,MenuGuid])
+static bool pluginconfigFunc(const TMacroFunction*)
+{
+	__int64 Ret=0;
+	TVar MenuGuid; VMStack.Pop(MenuGuid);
+	TVar Guid; VMStack.Pop(Guid);
+	GUID guid, menuGuid;
+	int curType = FrameManager->GetCurrentFrame()->GetType();
+
+	if (curType==MODALTYPE_PANELS && StrToGuid(Guid.s(),guid))
+	{
+		Plugin* pPlugin = CtrlObject->Plugins.FindPlugin(guid);
+		if (pPlugin && pPlugin->HasConfigure())
+		{
+			if (MenuGuid.isUnknown() || !StrToGuid(MenuGuid.s(),menuGuid))
+			{
+				menuGuid = FarGuid;
+				Ret=1;
+			}
+			else
+			{
+				PluginInfo Info = {sizeof(Info)};
+				if (pPlugin->GetPluginInfo(&Info))
+				{
+					for (int i = 0; i < Info.PluginConfig.Count; i++)
+					{
+						if (memcmp(&menuGuid,&(Info.PluginConfig.Guids[i]),sizeof(GUID)) == 0)
+						{
+							Ret=1;
+							break;
+						}
+					}
+				}
+			}
+		
+			if (Ret)
+				CtrlObject->Plugins.ConfigureCurrent(pPlugin,menuGuid);
+		}
+	}
+
+	VMStack.Push(Ret);
+	return true;
+}
+
+
 // V=callplugin(SysID[,param])
 #if 0
 static bool callpluginFunc(const TMacroFunction*)
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 6795)
+++ plugins.cpp	(working copy)
@@ -2243,6 +2243,95 @@
 	return FALSE;
 }
 
+int PluginManager::CallPluginItem(const GUID& Guid, const GUID& ItemGuid)
+{
+	if (!ProcessException)
+	{
+		Plugin *pPlugin = FindPlugin(Guid);
+		if (pPlugin && pPlugin->Load() && pPlugin->HasOpenPanel())
+		{
+			int curType = FrameManager->GetCurrentFrame()->GetType();
+			bool Editor = curType==MODALTYPE_EDITOR;
+			bool Viewer = curType==MODALTYPE_VIEWER;
+			bool Dialog = curType==MODALTYPE_DIALOG;
+
+			UINT64 IFlags;
+			PluginInfo Info = {sizeof(Info)};
+			if (!pPlugin->GetPluginInfo(&Info))
+				return FALSE;
+			else
+				IFlags = Info.Flags;
+
+			if ((Editor && !(IFlags & PF_EDITOR)) ||
+					(Viewer && !(IFlags & PF_VIEWER)) ||
+					(Dialog && !(IFlags & PF_DIALOG)) ||
+					(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+				return FALSE;
+
+			bool ItemFound = false;
+			for (int i = 0; i < Info.PluginMenu.Count; i++)
+			{
+				if (memcmp(&ItemGuid,&(Info.PluginMenu.Guids[i]),sizeof(GUID)) == 0)
+				{
+					ItemFound = true;
+					break;
+				}
+			}
+			if (!ItemFound)
+				return FALSE;
+				
+			Panel *ActivePanel=CtrlObject->Cp()->ActivePanel;
+			int OpenCode=OPEN_PLUGINSMENU;
+			INT_PTR Item=0;
+			OpenDlgPluginData pd;
+
+			if (Editor)
+			{
+				OpenCode=OPEN_EDITOR;
+			}
+			else if (Viewer)
+			{
+				OpenCode=OPEN_VIEWER;
+			}
+			else if (Dialog)
+			{
+				OpenCode=OPEN_DIALOG;
+				pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+				Item=(INT_PTR)&pd;
+			}
+
+			HANDLE hPlugin=Open(pPlugin,OpenCode,ItemGuid,Item);
+
+			if (hPlugin!=INVALID_HANDLE_VALUE && !Editor && !Viewer && !Dialog)
+			{
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+
+			// CtrlObject->Macro.SetMode(PrevMacroMode); -- ���� ���������/�������������� �����������?
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
PluginCall3.diff (7,574 bytes)   

Maximus

2011-10-19 21:28

reporter   bugnote:0007921

PluginCall3.diff - пока только багу поправил с незагруженным плагином

Maximus

2011-10-20 12:44

reporter   bugnote:0007930

> Не нравится что суть значения приципиально разная, т.е. скрещивается уж с ежом.
Наоборот, одинаковая. Суть одна и та же - вызвать плагин.
ты же не предлагаеешь разделить edit.sel на две функции на том основании, что обычные и вертикальные блоки - суть разные вещи.

> Создаётся видимость будто пользователь может выбрать синхроность/асинхронность
Если юзер думать не умеет, фар ему в этом не поможет. У тебя же не создается такая видимость из-за наличия функции callplugin?

imho - callplugin убить, и добавить параметр в plugin.call - самое то

JohnDoe

2011-10-20 14:31

updater   bugnote:0007934

>Если юзер думать не умеет, фар ему в этом не поможет.
Юзер не знает о "синхронности" и "асинхронности", и знать (по хорошему) не должен.
И если фар будет таки принуждать его об этом задумаваться - ничего хорощего в этом нет.

Может я сам чего не понимаю. Зачем вообще юзеру эта "синхронность"?

Maximus

2011-10-20 18:27

reporter   bugnote:0007936

Ладно, пойдем другим путем. Юзеру не нужно знать про функцию callplugin?

> Зачем вообще юзеру эта "синхронность"?
Вот пристал ;)
Забудь про синхронность асинхронность.
Один режим - аналогичен вызову плагина из F11
Второй режим - специфический, о его использовании консультируйтесь с автором плагина или читайте в документации о плагине.
Вот.

Maximus

2011-10-20 18:28

reporter   bugnote:0007937

> И если фар будет таки принуждать его об этом задумаваться - ничего хорощего в этом нет.
Использование макроязыка по определению принуждает задумываться. Не?

max rusov

2011-10-20 21:44

reporter   bugnote:0007939

Если планируется работа в этом направлении, то может стоит сделать так, чтобы синхронный вызов plugin.call мог возвращать любые данные, а не только признак успешности вызова?...

JohnDoe

2011-10-21 06:12

updater   bugnote:0007940

> Юзеру не нужно знать про функцию callplugin?
Лучше бы не знать.

>Забудь про синхронность асинхронность.
Да, так будет лучше.

>Второй режим - специфический, о его использовании...
Вот именно. Он специфический, и поэтому я и предложил не объединять.

>Использование макроязыка по определению принуждает задумываться. Не?
Но ведь не о смысле жизни.
Макроязык он и для домохозяек тоже.

Maximus

2011-10-21 10:52

reporter   bugnote:0007943

> так, чтобы синхронный вызов plugin.call мог возвращать любые данные, а не только признак успешности вызова?...

каким образом фар отличит тип результата: число от строки?
и главное, нафига, если таки будет открыта ProcessMacroFunctionW?

2vskirdin: а почему, кстати, она до сих пор не открыта?

vskirdin

2011-10-21 11:02

administrator   bugnote:0007944

как обычно - работа мешает и фактор времени :-(
после отпуска постараюсь продолжить.

Maximus

2011-10-21 13:03

reporter   bugnote:0007945

Не, я к тому, чего там не хватает для "релиза"?

max rusov

2011-10-21 13:09

reporter   bugnote:0007946

>каким образом фар отличит тип результата: число от строки?

Можно добавить в OpenInfo:

struct FarMacroValue Result;

Недавно делалось подобное - DN_GETVALUE...

>и главное, нафига, если таки будет открыта ProcessMacroFunctionW?

Если будет - то, может и незачем.

Maximus

2011-11-28 23:52

reporter   bugnote:0008000

возвращаясь к нашим баранам...

1. если объединять функции, то все три, вместе с plugin.config
но вот сейчас мне не кажется это хорошей идеей, и дело не в различных действиях ими выполняемых (они все делают одно - передают управление плагину), а в различии параметров. банально сложнее описать использование (например, запутаться в Edit.sel оч.просто)

2. еще мысль. может быть имеет смысл дать возможность вызвать плагин с параметрами?
например:
plugin.call(0,"guid","menu guid") - аналог вызова из F11 (то что сейчас plugin.call делает)
plugin.call(1,"guid","rclk_cmd:Paste C:\") - аналог ввода в ком строке
plugin.call(2,"guid","c:\temp\1.zip") - аналог входа в архив

Maximus

2011-11-29 11:13

reporter   bugnote:0008001

или предлагаемые отдельными функциями оформить?
или все-таки "все в одном" сделать...

SUSim

2011-12-01 15:27

reporter   bugnote:0008028

Скромное имхо: написание макроса с вызовом плагина без простого "F11 и т.д." - УЖЕ требует от писателя этого макроса продвинутости, и разветвлять вызов макросов на те которые доступны из меню, и те которые отдадут ид для калплугин не стоит, лишнее усложнение макроязыка... - я буду вызывать плагин по ГУИД плагина, который вроде как обязателен.

(я бы с удовольствием вызывал плагин макроедит по плугинид, а не по менюид, потому что он недоступен из меню плагинов для диалогов, хотя там ему ни что не мешает работать!)

Maximus

2011-12-02 06:58

reporter   bugnote:0008032

я что-то не понял смысл этого имхо и к чему оно.

Про "макроедит" вообще не в тему. Фар не должен (и не будет) предоставлять возможность вызвать плагин оттуда, откуда он не ожидает. Кроме того, полезность данного плагина в нынешних реалиях вообще под сомнением.

vskirdin

2011-12-09 09:54

administrator   bugnote:0008115

конечный итог какой?

Maximus

2011-12-09 12:16

reporter   bugnote:0008125

хм, вот и мне интересно, какой?
поскольку всем пофиг - доработаю патч как я его вижу, и выложу

JohnDoe

2011-12-09 13:31

updater   bugnote:0008130

Не пофиг.
>банально сложнее описать использование (например, запутаться в Edit.sel оч.просто)
Золотые слова. Очень простой и эффективный критерий: если вам сложно описать, значит и пользователю сложно понять.
Собственно эту мысль я и пытался донести, и именно поэтому не стоит городить монструозные функции.

vskirdin

2011-12-09 13:32

administrator   bugnote:0008132

Как ты его видишь? 1 функция, 2 функции, ... ?

Maximus

2011-12-09 17:46

reporter   bugnote:0008137

склоняюсь к варианту: одна функция на одно действие
т.е. plugin.call/config/cmd/...

только во что переименовать callplugin? IntCall?

SUSim

2011-12-11 14:47

reporter   bugnote:0008138

Last edited: 2011-12-11 14:47

читал, думал, склоняюсь к варианту разделения:
plugin.call = F11...
plugin.cfg = F9->Параметры плагинов...
plugin.cmd = Префикс
plugin.Exec = callplugin

Maximus

2012-01-10 21:41

reporter   bugnote:0008357

Следующее приближение
Plugin.Call(Guid[,MenuGuid]) = F11
Plugin.Config(Guid[,MenuGuid]) = F9->Параметры плагинов...
Plugin.Prefix(Guid,Command) = ввод через префикс в комстроке
Plugin.Int(Guid,Item) = алиас callplugin

Первые три - зовут одну CtrlObject->Plugins.CallPluginItem с разными параметрами.
callplugin==Plugin.Int пока не менял, просто добавил алиас (чтобы потом callplugin грохнуть?)

Maximus

2012-01-10 21:41

reporter  

PluginCall4.inf (401 bytes)

Maximus

2012-01-10 21:42

reporter  

PluginCall4.diff (13,873 bytes)   
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 7181)
+++ macro.cpp	(working copy)
@@ -385,7 +385,6 @@
 static bool ascFunc(const TMacroFunction*);
 static bool atoiFunc(const TMacroFunction*);
 static bool beepFunc(const TMacroFunction*);
-static bool callpluginFunc(const TMacroFunction*);
 static bool chrFunc(const TMacroFunction*);
 static bool clipFunc(const TMacroFunction*);
 static bool dateFunc(const TMacroFunction*);
@@ -442,6 +441,10 @@
 static bool xlatFunc(const TMacroFunction*);
 static bool pluginloadFunc(const TMacroFunction*);
 static bool pluginunloadFunc(const TMacroFunction*);
+static bool plugincallFunc(const TMacroFunction*);
+static bool pluginconfigFunc(const TMacroFunction*);
+static bool pluginprefixFunc(const TMacroFunction*);
+static bool plugininternalFunc(const TMacroFunction*);
 
 static TMacroFunction intMacroFunction[]=
 {
@@ -462,7 +465,7 @@
 	{L"BM.BACK",          nullptr, L"N=BM.Back()",                                               usersFunc,          nullptr, 0, 0,                                      MCODE_F_BM_BACK,          0, 0},
 	{L"BM.PUSH",          nullptr, L"N=BM.Push()",                                               usersFunc,          nullptr, 0, 0,                                      MCODE_F_BM_PUSH,          0, 0},
 	{L"BM.STAT",          nullptr, L"N=BM.Stat([N])",                                            usersFunc,          nullptr, 0, 0,                                      MCODE_F_BM_STAT,          1, 1},
-	{L"CALLPLUGIN",       nullptr, L"V=CallPlugin(SysID[,param])",                               callpluginFunc,     nullptr, 0, 0,                                      MCODE_F_CALLPLUGIN,       2, 1},
+	{L"CALLPLUGIN",       nullptr, L"V=CallPlugin(SysID[,param])",                               plugininternalFunc, nullptr, 0, 0,                                      MCODE_F_CALLPLUGIN,       2, 1},
 	{L"CHECKHOTKEY",      nullptr, L"N=CheckHotkey(S[,N])",                                      usersFunc,          nullptr, 0, 0,                                      MCODE_F_MENU_CHECKHOTKEY, 2, 1},
 	{L"CHR",              nullptr, L"S=Chr(N)",                                                  chrFunc,            nullptr, 0, 0,                                      MCODE_F_CHR,              1, 0},
 	{L"CLIP",             nullptr, L"V=Clip(N[,V])",                                             clipFunc,           nullptr, 0, 0,                                      MCODE_F_CLIP,             2, 1},
@@ -516,6 +519,10 @@
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,        3, 0},
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,      2, 1},
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,    1, 0},
+	{L"PLUGIN.CALL",      nullptr, L"N=Plugin.Call(Guid[,MenuGuid])",                            plugincallFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_CALL,      2, 1},
+	{L"PLUGIN.CONFIG",    nullptr, L"N=Plugin.Config(Guid[,MenuGuid])",                          pluginconfigFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_CONFIG,    2, 1},
+	{L"PLUGIN.PREFIX",    nullptr, L"N=Plugin.Prefix(Guid,Command)",                             pluginprefixFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_PREFIX,    2, 0},
+	{L"PLUGIN.INT",       nullptr, L"N=Plugin.Int(Guid,Item)",                                   plugininternalFunc, nullptr, 0, 0,                                      MCODE_F_PLUGIN_INT,       2, 0},
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,            1, 0},
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,           5, 5},
 	{L"REPLACE",          nullptr, L"S=Replace(Str,Find,Replace[,Cnt[,Mode]])",                  replaceFunc,        nullptr, 0, 0,                                      MCODE_F_REPLACE,          5, 2},
@@ -691,10 +698,10 @@
 		}
 		if (0==MacroLIBCount)
 		{
-		xf_free(MacroLIB);
-			MacroLIB=nullptr;
+			xf_free(MacroLIB);
+				MacroLIB=nullptr;
+		}
 	}
-	}
 	else
 	{
 		MacroLIBCount=0;
@@ -4443,7 +4450,65 @@
 	return Ret.i()!=0;
 }
 
+// N=Plugin.Call(Guid[,MenuGuid])
+static bool plugincallFunc(const TMacroFunction*)
+{
+	__int64 Ret=0;
+	TVar MenuGuid; VMStack.Pop(MenuGuid);
+	TVar Guid; VMStack.Pop(Guid);
+	GUID guid, menuGuid;
+	CallPluginInfo Data={CPT_CALL};
 
+	if (StrToGuid(Guid.s(),guid) && (MenuGuid.isUnknown() || StrToGuid(MenuGuid.s(),menuGuid)))
+	{
+		if (!MenuGuid.isUnknown())
+			Data.ItemGuid=&menuGuid;
+		Ret=(__int64)CtrlObject->Plugins.CallPluginItem(guid,&Data);
+	}
+
+	VMStack.Push(Ret);
+	return true; //Ret?true:false;
+}
+
+// N=Plugin.Config(Guid[,MenuGuid])
+static bool pluginconfigFunc(const TMacroFunction*)
+{
+	__int64 Ret=0;
+	TVar MenuGuid; VMStack.Pop(MenuGuid);
+	TVar Guid; VMStack.Pop(Guid);
+	GUID guid, menuGuid;
+	CallPluginInfo Data={CPT_CONFIGURE};
+
+	if (StrToGuid(Guid.s(),guid) && (MenuGuid.isUnknown() || StrToGuid(MenuGuid.s(),menuGuid)))
+	{
+		if (!MenuGuid.isUnknown())
+			Data.ItemGuid=&menuGuid;
+		Ret=(__int64)CtrlObject->Plugins.CallPluginItem(guid,&Data);
+	}
+
+	VMStack.Push(Ret);
+	return true;
+}
+
+// N=Plugin.Prefix(Guid,Command)
+static bool pluginprefixFunc(const TMacroFunction*)
+{
+	__int64 Ret=0;
+	TVar Command; VMStack.Pop(Command);
+	TVar Guid; VMStack.Pop(Guid);
+	GUID guid;
+	CallPluginInfo Data={CPT_PREFIX};
+
+	if (StrToGuid(Guid.s(),guid) && Command.isString())
+	{
+		Data.Command=Command.s();
+		Ret=(__int64)CtrlObject->Plugins.CallPluginItem(guid,&Data);
+	}
+
+	VMStack.Push(Ret);
+	return true;
+}
+
 // V=callplugin(SysID[,param])
 #if 0
 static bool callpluginFunc(const TMacroFunction*)
@@ -4554,7 +4619,8 @@
 	return Ret?true:false;
 }
 #else
-static bool callpluginFunc(const TMacroFunction*)
+// N=Plugin.Int(Guid,Item)
+static bool plugininternalFunc(const TMacroFunction*)
 {
 	__int64 Ret=0;
 	TVar Param; VMStack.Pop(Param);
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 7181)
+++ plugins.cpp	(working copy)
@@ -775,11 +775,6 @@
 			break;
 	}
 
-	if(Data)
-	{
-		delete[] Data;
-	}
-
 	if (items.getCount() && (hResult != (HANDLE)-2))
 	{
 		bool OnlyOne = (items.getCount() == 1) && !(Name && Opt.PluginConfirm.OpenFilePlugin && Opt.PluginConfirm.StandardAssociation && Opt.PluginConfirm.EvenIfOnlyOnePlugin);
@@ -836,7 +831,13 @@
 
 		if (pResult && pResult->hPlugin == INVALID_HANDLE_VALUE)
 		{
-			HANDLE h = pResult->pPlugin->Open(OPEN_ANALYSE, FarGuid, 0);
+			AnalyseInfo Info={sizeof(Info)};
+			Info.FileName = Name? Name->CPtr() : nullptr;
+			Info.Buffer = Data;
+			Info.BufferSize = DataSize;
+			Info.OpMode = OpMode|(Type==OFP_ALTERNATIVE?OPM_PGDN:0);
+		
+			HANDLE h = pResult->pPlugin->Open(OPEN_ANALYSE, FarGuid, (INT_PTR)&Info);
 
 			if (h == (HANDLE)-2)
 			{
@@ -854,6 +855,11 @@
 		}
 	}
 
+	if(Data)
+	{
+		delete[] Data;
+	}
+	
 	for (size_t i = 0; i < items.getCount(); i++)
 	{
 		PluginHandle *handle = items.getItem(i);
@@ -2249,6 +2255,196 @@
 	return FALSE;
 }
 
+int PluginManager::CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret/*=nullptr*/)
+{
+	BOOL Result=FALSE;
+
+	if (!ProcessException)
+	{
+		Plugin *pPlugin = FindPlugin(Guid);
+		if (pPlugin && pPlugin->Load())
+		{
+			int curType = FrameManager->GetCurrentFrame()->GetType();
+			bool Editor = curType==MODALTYPE_EDITOR;
+			bool Viewer = curType==MODALTYPE_VIEWER;
+			bool Dialog = curType==MODALTYPE_DIALOG;
+
+			// ������� �� ���� ������� ���� � ������ ������� (������������� ��������)
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_CONFIGURE:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� �����?
+					//_ASSERTE(curType==MODALTYPE_PANELS);
+					return FALSE;
+				}
+				if (!pPlugin->HasConfigure())
+					return FALSE;
+				break;
+			case CPT_PREFIX:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� �����?
+					//_ASSERTE(curType==MODALTYPE_PANELS);
+					return FALSE;
+				}
+				//TODO: OpenPanel ��� OpenFilePlugin?
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				//TODO: ������ �����
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			}
+
+			UINT64 IFlags;
+			PluginInfo Info = {sizeof(Info)};
+			if (!pPlugin->GetPluginInfo(&Info))
+				return FALSE;
+			else
+				IFlags = Info.Flags;
+
+			PluginMenuItem *MenuItems=nullptr;
+			GUID ItemGuid;
+
+			// ������� �� ���� ������� ���� � ������ �������
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if ((Editor && !(IFlags & PF_EDITOR)) ||
+						(Viewer && !(IFlags & PF_VIEWER)) ||
+						(Dialog && !(IFlags & PF_DIALOG)) ||
+						(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+					return FALSE;
+				//_ASSERTE(curType==MODALTYPE_PANELS || (Editor&&curType==MODALTYPE_EDITOR) || (Viewer&&curType==MODALTYPE_VIEWER) || (Dialog&&curType==MODALTYPE_DIALOG));
+				MenuItems = &Info.PluginMenu;
+				break;
+			case CPT_CONFIGURE:
+				MenuItems = &Info.PluginConfig;
+				break;
+			case CPT_PREFIX:
+				if (!Info.CommandPrefix || !*Info.CommandPrefix)
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				break;
+			}
+
+			if (Data->CallType==CPT_CALL || Data->CallType==CPT_CONFIGURE)
+			{
+				bool ItemFound = false;
+				if (Data->ItemGuid==nullptr)
+				{
+					if (MenuItems->Count==1)
+					{
+						ItemGuid=MenuItems->Guids[0];
+						ItemFound=true;
+					}
+				}
+				else
+				{
+					for (int i = 0; i < MenuItems->Count; i++)
+					{
+						if (memcmp(Data->ItemGuid, &(MenuItems->Guids[i]), sizeof(GUID)) == 0)
+						{
+							ItemGuid=*Data->ItemGuid;
+							ItemFound=true;
+							break;
+						}
+					}
+				}
+				if (!ItemFound)
+					return FALSE;
+			}
+
+			HANDLE hPlugin=INVALID_HANDLE_VALUE;
+			Panel *ActivePanel=nullptr;
+
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					int OpenCode=OPEN_PLUGINSMENU;
+					INT_PTR Item=0;
+					OpenDlgPluginData pd;
+
+					if (Editor)
+					{
+						OpenCode=OPEN_EDITOR;
+					}
+					else if (Viewer)
+					{
+						OpenCode=OPEN_VIEWER;
+					}
+					else if (Dialog)
+					{
+						OpenCode=OPEN_DIALOG;
+						pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+						Item=(INT_PTR)&pd;
+					}
+
+					hPlugin=Open(pPlugin,OpenCode,ItemGuid,Item);
+
+					Result=TRUE;
+				}
+				break;
+
+			case CPT_CONFIGURE:
+				CtrlObject->Plugins.ConfigureCurrent(pPlugin,ItemGuid);
+				return TRUE;
+
+			case CPT_PREFIX:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					string command=Data->Command; // ����� ���� ������
+					hPlugin=Open(pPlugin,OPEN_COMMANDLINE,FarGuid,(INT_PTR)command.CPtr());
+
+					Result=TRUE;
+				}
+				break;
+			case CPT_INTERNAL:
+				//TODO: ���� CallPlugin
+				//WARNING: ����, ��� �� ���������� ��� ��������� MacroState
+				break;
+			}
+
+			if (hPlugin!=INVALID_HANDLE_VALUE && !Editor && !Viewer && !Dialog)
+			{
+				//BUGBUG: ������� ������? ����� �� ���?
+				//BUGBUG: � ProcessCommandLine ������ ����� Open, � � CPT_CALL - �����
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+		}
+	}
+
+	return FALSE;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 7181)
+++ plugins.hpp	(working copy)
@@ -131,6 +131,26 @@
 	OFP_COMMANDS,
 };
 
+enum CALLPLUGINTYPE
+{
+	CPT_CALL,
+	CPT_CONFIGURE,
+	CPT_PREFIX,
+	CPT_INTERNAL,
+};
+
+struct CallPluginInfo
+{
+	CALLPLUGINTYPE CallType;
+	int OpenFrom;
+	union
+	{
+		GUID *ItemGuid;
+		const wchar_t *Command;
+		__int64 Item;
+	};
+};
+
 struct PluginHandle
 {
 	HANDLE hPlugin;
@@ -230,6 +250,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret=nullptr);
 		Plugin *FindPlugin(const GUID& SysID);
 		INT_PTR PluginGuidToPluginNumber(const GUID& PluginId);
 		static const GUID& GetGUID(HANDLE hPlugin);
PluginCall4.diff (13,873 bytes)   

vskirdin

2012-01-11 07:00

administrator   bugnote:0008365

а почему "Int"?

Maximus

2012-01-11 07:04

reporter   bugnote:0008367

По аналогии с asm-ом. Ну или типа "Internal".
Ничего лучше пока не придумал.

max rusov

2012-01-11 07:34

reporter   bugnote:0008369

Может:
Plugin.call -> Plugin.Open
Plugin.Int -> Plugin.Call

SUSim

2012-01-11 16:38

reporter   bugnote:0008379

Last edited: 2012-01-11 16:41

Параметры я, просто, не расписывал... в приближении Maximus они логичны...
Int мне не нравится - Exec лучше :) Open - тем более, не нравится (что значит "открыть"?)

Я бы Plugin.Call поменял бы на Plugin.Run - "запустить плагин и дальше разбирайтесь своими макросами с плагином";
Plugin.Int на plugin.Exec(Guid,Command) - "плагин выполни такую-то команду! и без вопрсов :), просто скажи, в возвращаемом результате, получилось или нет, и если нет, то укажи код причины".

Maximus

2012-01-11 18:39

reporter   bugnote:0008382

По мне, так ".Run" и ".Exec" ассоциируются с командной строкой. Так что оба - не нравятся.
".Open" тоже как-то... Что открыть? А если плагин ничего не открывает? Из редактора, например :)

JohnDoe

2012-02-13 15:20

updater   bugnote:0008560

Last edited: 2012-02-13 15:40

Мне нет разницы как будет называться Call/Run/Open.

Но ряд вопросов возникает в связи с Plugin.Prefix.
Зачем? Оно только для панелей или как?
В любом случае название не очень, потому что "префикс" как действие не имеет смысла. Если наша цель передать плагину строку параметров, то лучше назвать это Plugin.Cmdline.

Но помнится такой подход подвергся критике (http://forum.farmanager.com/viewtopic.php?f=15&t=6118).

Я лично не против, но ведь нехорошо если функция будет только в bis?

P.S
И если уж реализовывать, то почему не сразу Exec? http://forum.farmanager.com/viewtopic.php?p=72945#p72945

JohnDoe

2012-02-13 15:41

updater   bugnote:0008562

Last edited: 2012-02-13 16:36

Ещё вроде бы решили что callplugin надо не переименовывать, а удавить "заменив на новую всем удобную функцию":
* http://forum.farmanager.com/viewtopic.php?p=75799#p75799
* http://forum.farmanager.com/viewtopic.php?p=76599#p76599

Maximus

2012-02-13 17:22

reporter   bugnote:0008564

На счет "bis". Патч могу хоть сейчас выкатить, но есть у меня смутное подозрение, что там что-то не того случается с макродвижком. Хотя вроде и работает...

> В любом случае название не очень, потому что "префикс" как действие не имеет смысла.
> Если наша цель передать плагину строку параметров, то лучше назвать это Plugin.Cmdline.
Против ".cmdline" ничего не имею. Перечитывать ветку в поиске критики как-то не очень. В текущей версии "Plugin.Prefix" может быть выполнен только тогда, когда доступна командная строка. И, считаю, это правильно. Поэтому не "Exec" - плагин не должен получать управление тогда, когда этого не ожидает.

> Ещё вроде бы решили что callplugin надо не переименовывать, а удавить
Кто решил? Вам бы все давить. ProcessMacroFunctionW похоже еще долго не будет доступна.

NightRoman

2012-02-13 18:21

reporter   bugnote:0008565

Не надо давить callplugin. У меня нормальная работа и механизмы тестирования своей (и неявно Фаровской) кухни все завязаны на callplugin с потрохами.

JohnDoe

2012-02-13 22:06

updater   bugnote:0008567

NightRoman
Я лично ничего не собираюсь давить, а всего лишь обращаю внимание на существование более ранних обсуждений, в которых такие намерения прозвучали от представителя команды, и тогда никто из участников не спорил (а все участники между прочим те же что и здесь).
В любом случае, вначале должна появиться адекватная замена, так что бояться нечего.

JohnDoe

2012-02-13 23:00

updater   bugnote:0008568

Maximus
В таком случае зачем нам вообще ещё один отдельный запуск по префиксу, раз командная строка и так доступна?

Maximus

2012-02-13 23:06

reporter   bugnote:0008569

hint: командная строка может быть и не пустой

JohnDoe

2012-02-14 09:43

updater   bugnote:0008570

Last edited: 2012-02-14 11:11

Ctrl-G
А если серьёзно, то опять же предлагаю более универсальный Exec.
Потому что эта функция была по тем же причинам точно так же полезна для запуска всего, а не только плагинов.

Maximus

2012-02-14 19:44

reporter   bugnote:0008571

Я так понял, что про "Ctrl-G" ты несерьезно?

"Exec" есть совершенный офтопик в данном више. Предлагаемый набор функций предназначен для руления конкретным плагином.

JohnDoe

2012-02-15 11:47

updater   bugnote:0008576

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

И по функциональности перекрывается гипотетической Exec, которая тут конечно оффтопик, её обсуждаем тут: 0002021 (и на форуме: http://forum.farmanager.com/viewtopic.php?f=15&t=6153)

Maximus

2012-02-15 12:56

reporter   bugnote:0008580

Я бы не сказал, что она избыточна. Есть (будет) комплект функций для руления конкретным плагином. Как-то нелогично делать две "plugin.call" и plugin.config" оставляя "callplugin" и добавляя "гипотетическую" (кто ее делать-то будет?) "Exec".

В общем, свое имхо по юзабилити я высказал. Лично мне была нужна только "plugin.call"

JohnDoe

2012-02-15 15:53

updater   bugnote:0008582

> ...оставляя "callplugin"
Не ясен текущий статус этой функции. Если её планируется оставить (в текущем или доработанном виде), то конечно она должна быть частью этого комплекта функций.
Поднял вопрос на форуме: http://forum.farmanager.com/viewtopic.php?p=90845#p90845

Maximus

2012-03-01 22:49

reporter  

PluginCall5.diff (11,670 bytes)   
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 7616)
+++ macroopcode.hpp	(working copy)
@@ -224,6 +224,10 @@
 	MCODE_F_FMATCH,                   // N=FMatch(S,Mask)
 	MCODE_F_PLUGIN_LOAD,              // N=Plugin.Load(DllPath[,ForceLoad])
 	MCODE_F_PLUGIN_UNLOAD,            // N=Plugin.UnLoad(DllPath)
+	MCODE_F_PLUGIN_CALL,              // N=Plugin.Call(Guid,MenuGuid)
+	MCODE_F_PLUGIN_CONFIG,            // N=Plugin.Config(Guid[,MenuGuid])
+	MCODE_F_PLUGIN_PREFIX,            // N=Plugin.Prefix(Guid,Command)
+	MCODE_F_PLUGIN_INT,               // N=Plugin.Int(Guid,Item)
 	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
 	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
 	MCODE_F_DLG_SETFOCUS,             // N=Dlg.SetFocus([ID])
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 7616)
+++ macro.cpp	(working copy)
@@ -390,6 +390,9 @@
 static bool xlatFunc(const TMacroFunction*);
 static bool pluginloadFunc(const TMacroFunction*);
 static bool pluginunloadFunc(const TMacroFunction*);
+static bool plugincallFunc(const TMacroFunction*);
+static bool pluginconfigFunc(const TMacroFunction*);
+static bool pluginprefixFunc(const TMacroFunction*);
 
 static TMacroFunction intMacroFunction[]=
 {
@@ -465,6 +468,10 @@
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,       },
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,     },
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,   },
+	{L"PLUGIN.CALL",      nullptr, L"N=Plugin.Call(Guid[,MenuGuid])",                            plugincallFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_CALL,     },
+	{L"PLUGIN.CONFIG",    nullptr, L"N=Plugin.Config(Guid[,MenuGuid])",                          pluginconfigFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_CONFIG,   },
+	{L"PLUGIN.PREFIX",    nullptr, L"N=Plugin.Prefix(Guid,Command)",                             pluginprefixFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_PREFIX,   },
+	{L"PLUGIN.INT",       nullptr, L"N=Plugin.Int(Guid,Item)",                                   usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_INT,      },
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,           },
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,          },
 	{L"REPLACE",          nullptr, L"S=Replace(Str,Find,Replace[,Cnt[,Mode]])",                  replaceFunc,        nullptr, 0, 0,                                      MCODE_F_REPLACE,         },
@@ -666,10 +673,10 @@
 		}
 		if (0==MacroLIBCount)
 		{
-		xf_free(MacroLIB);
-			MacroLIB=nullptr;
+			xf_free(MacroLIB);
+				MacroLIB=nullptr;
+		}
 	}
-	}
 	else
 	{
 		MacroLIBCount=0;
@@ -4503,7 +4510,65 @@
 	return Ret.i()!=0;
 }
 
+// N=Plugin.Call(Guid[,MenuGuid])
+static bool plugincallFunc(const TMacroFunction*)
+{
+	parseParams(2,Params);
+	TVar Ret(0ll);
+	TVar& MenuGuid = (Params[1]);
+	TVar& Guid = (Params[0]);
+	GUID guid, menuGuid;
+	CallPluginInfo Data={CPT_CALL};
 
+	if (StrToGuid(Guid.s(),guid) && (MenuGuid.isUnknown() || StrToGuid(MenuGuid.s(),menuGuid)))
+	{
+		if (!MenuGuid.isUnknown())
+			Data.ItemGuid=&menuGuid;
+		Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+	}
+
+	return Ret.i()!=0;
+}
+
+// N=Plugin.Config(Guid[,MenuGuid])
+static bool pluginconfigFunc(const TMacroFunction*)
+{
+	parseParams(2,Params);
+	TVar Ret(0ll);
+	TVar& MenuGuid = (Params[1]);
+	TVar& Guid = (Params[0]);
+	GUID guid, menuGuid;
+	CallPluginInfo Data={CPT_CONFIGURE};
+
+	if (StrToGuid(Guid.s(),guid) && (MenuGuid.isUnknown() || StrToGuid(MenuGuid.s(),menuGuid)))
+	{
+		if (!MenuGuid.isUnknown())
+			Data.ItemGuid=&menuGuid;
+		Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+	}
+
+	return Ret.i()!=0;
+}
+
+// N=Plugin.Prefix(Guid,Command)
+static bool pluginprefixFunc(const TMacroFunction*)
+{
+	parseParams(2,Params);
+	TVar Ret(0ll);
+	TVar& Command = (Params[1]);
+	TVar& Guid = (Params[0]);
+	GUID guid;
+	CallPluginInfo Data={CPT_PREFIX};
+
+	if (StrToGuid(Guid.s(),guid) && Command.isString())
+	{
+		Data.Command=Command.s();
+		Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+	}
+
+	return Ret.i()!=0;
+}
+
 static void VarToFarMacroValue(const TVar& From,FarMacroValue& To)
 {
 	To.Type=(FARMACROVARTYPE)From.type();
@@ -5699,6 +5764,8 @@
 		}
 
 		case MCODE_F_CALLPLUGIN: // V=callplugin(SysID[,param])
+		// ����� CallPlugin, �� �������
+		case MCODE_F_PLUGIN_INT: // V=Plugin.Int(SysID[,param])
 		{
 			__int64 Ret=0;
 			int count=VMStack.Pop().getInteger();
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 7616)
+++ plugins.hpp	(working copy)
@@ -129,6 +129,27 @@
 	OFP_COMMANDS,
 };
 
+// �������� ����� ����������� plugin.call � �.�.
+enum CALLPLUGINTYPE
+{
+	CPT_CALL,
+	CPT_CONFIGURE,
+	CPT_PREFIX,
+	CPT_INTERNAL,
+};
+
+struct CallPluginInfo
+{
+	CALLPLUGINTYPE CallType;
+	int OpenFrom;
+	union
+	{
+		GUID *ItemGuid;
+		const wchar_t *Command;
+		__int64 Item;
+	};
+};
+
 struct PluginHandle
 {
 	HANDLE hPlugin;
@@ -232,6 +253,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret=nullptr);
 		Plugin *FindPlugin(const GUID& SysID);
 		static const GUID& GetGUID(HANDLE hPlugin);
 
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 7616)
+++ plugins.cpp	(working copy)
@@ -2474,6 +2474,195 @@
 	return FALSE;
 }
 
+// ��������� ����������� plugin.call, plugin.cmd, plugin.config � �.�
+int PluginManager::CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret/*=nullptr*/)
+{
+	BOOL Result=FALSE;
+
+	if (!ProcessException)
+	{
+		Plugin *pPlugin = FindPlugin(Guid);
+		if (pPlugin && pPlugin->Load())
+		{
+			int curType = FrameManager->GetCurrentFrame()->GetType();
+			bool Editor = curType==MODALTYPE_EDITOR;
+			bool Viewer = curType==MODALTYPE_VIEWER;
+			bool Dialog = curType==MODALTYPE_DIALOG;
+
+			// ������� �� ���� ������� ���� � ������ ������� (������������� ��������)
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_CONFIGURE:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� curType �� �����?
+					return FALSE;
+				}
+				if (!pPlugin->HasConfigure())
+					return FALSE;
+				break;
+			case CPT_PREFIX:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� curType �� �����?
+					return FALSE;
+				}
+				//TODO: OpenPanel ��� OpenFilePlugin?
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				//TODO: ������ �����
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			}
+
+			UINT64 IFlags;
+			PluginInfo Info = {sizeof(Info)};
+			if (!pPlugin->GetPluginInfo(&Info))
+				return FALSE;
+			else
+				IFlags = Info.Flags;
+
+			PluginMenuItem *MenuItems=nullptr;
+			GUID ItemGuid;
+
+			// ������� �� ���� ������� ���� � ������ �������
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if ((Editor && !(IFlags & PF_EDITOR)) ||
+						(Viewer && !(IFlags & PF_VIEWER)) ||
+						(Dialog && !(IFlags & PF_DIALOG)) ||
+						(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+					return FALSE;
+				//_ASSERTE(curType==MODALTYPE_PANELS || (Editor&&curType==MODALTYPE_EDITOR) || (Viewer&&curType==MODALTYPE_VIEWER) || (Dialog&&curType==MODALTYPE_DIALOG));
+				MenuItems = &Info.PluginMenu;
+				break;
+			case CPT_CONFIGURE:
+				MenuItems = &Info.PluginConfig;
+				break;
+			case CPT_PREFIX:
+				if (!Info.CommandPrefix || !*Info.CommandPrefix)
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				break;
+			}
+
+			if (Data->CallType==CPT_CALL || Data->CallType==CPT_CONFIGURE)
+			{
+				bool ItemFound = false;
+				if (Data->ItemGuid==nullptr)
+				{
+					if (MenuItems->Count==1)
+					{
+						ItemGuid=MenuItems->Guids[0];
+						ItemFound=true;
+					}
+				}
+				else
+				{
+					for (size_t i = 0; i < MenuItems->Count; i++)
+					{
+						if (memcmp(Data->ItemGuid, &(MenuItems->Guids[i]), sizeof(GUID)) == 0)
+						{
+							ItemGuid=*Data->ItemGuid;
+							ItemFound=true;
+							break;
+						}
+					}
+				}
+				if (!ItemFound)
+					return FALSE;
+			}
+
+			HANDLE hPlugin=INVALID_HANDLE_VALUE;
+			Panel *ActivePanel=nullptr;
+
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					int OpenCode=OPEN_PLUGINSMENU;
+					INT_PTR Item=0;
+					OpenDlgPluginData pd;
+
+					if (Editor)
+					{
+						OpenCode=OPEN_EDITOR;
+					}
+					else if (Viewer)
+					{
+						OpenCode=OPEN_VIEWER;
+					}
+					else if (Dialog)
+					{
+						OpenCode=OPEN_DIALOG;
+						pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+						Item=(INT_PTR)&pd;
+					}
+
+					hPlugin=Open(pPlugin,OpenCode,ItemGuid,Item);
+
+					Result=TRUE;
+				}
+				break;
+
+			case CPT_CONFIGURE:
+				CtrlObject->Plugins->ConfigureCurrent(pPlugin,ItemGuid);
+				return TRUE;
+
+			case CPT_PREFIX:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					string command=Data->Command; // ����� ���� ������
+					hPlugin=Open(pPlugin,OPEN_COMMANDLINE,FarGuid,(INT_PTR)command.CPtr());
+
+					Result=TRUE;
+				}
+				break;
+			case CPT_INTERNAL:
+				//TODO: ���� CallPlugin
+				//WARNING: ����, ��� �� ���������� ��� ��������� MacroState
+				break;
+			}
+
+			if (hPlugin!=INVALID_HANDLE_VALUE && !Editor && !Viewer && !Dialog)
+			{
+				//BUGBUG: ������� ������? ����� �� ���?
+				//BUGBUG: � ProcessCommandLine ������ ����� Open, � � CPT_CALL - �����
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+		}
+	}
+
+	return FALSE;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
PluginCall5.diff (11,670 bytes)   

Maximus

2012-03-01 22:53

reporter   bugnote:0008661

пятая версия.
Код причесан и допилен до текущего билда фара.
Все вызовы новых функций перенаправлены в новую PluginManager::CallPluginItem
Если плагин показывает только один пункт меню, для функций Plugin.Call и Plugin.Config можно указать только первый параметр - гуид плагина.

Plugin.Int - по желанию, добавлен до кучи как алиас к callplugin. еще один довод к ее названию (если уж переименовать соберетесь) - та же длина что и callplugin, мало ли, может в каком плагине патчить бинарник надо будет...

vskirdin

2012-03-02 05:59

administrator   bugnote:0008668

http://skirda-file.googlecode.com/files/mantis0001903.1.7z

vskirdin

2012-03-02 09:03

administrator   bugnote:0008673

Maximus, сюда бы еще приаттачить патч для вот этого файла:
https://farmanager.com/svn/trunk/enc/enc_rus3.work/meta/macro/macrocmd/prop_func/general.html
с описанием 4-х новых функций

JohnDoe

2012-03-02 09:43

updater   bugnote:0008675

Чего торопиться пока обсуждение этого хозяйства не закончено.
В частности некоторые имена.

Maximus

2012-03-02 13:41

reporter  

PluginCall6.diff (11,648 bytes)   
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 7616)
+++ macroopcode.hpp	(working copy)
@@ -224,6 +224,10 @@
 	MCODE_F_FMATCH,                   // N=FMatch(S,Mask)
 	MCODE_F_PLUGIN_LOAD,              // N=Plugin.Load(DllPath[,ForceLoad])
 	MCODE_F_PLUGIN_UNLOAD,            // N=Plugin.UnLoad(DllPath)
+	MCODE_F_PLUGIN_CALL,              // N=Plugin.Call(Guid,MenuGuid)
+	MCODE_F_PLUGIN_CONFIG,            // N=Plugin.Config(Guid[,MenuGuid])
+	MCODE_F_PLUGIN_PREFIX,            // N=Plugin.Prefix(Guid,Command)
+	MCODE_F_PLUGIN_INT,               // N=Plugin.Int(Guid,Item)
 	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
 	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
 	MCODE_F_DLG_SETFOCUS,             // N=Dlg.SetFocus([ID])
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 7616)
+++ macro.cpp	(working copy)
@@ -390,6 +390,9 @@
 static bool xlatFunc(const TMacroFunction*);
 static bool pluginloadFunc(const TMacroFunction*);
 static bool pluginunloadFunc(const TMacroFunction*);
+static bool plugincallFunc(const TMacroFunction*);
+static bool pluginconfigFunc(const TMacroFunction*);
+static bool pluginprefixFunc(const TMacroFunction*);
 
 static TMacroFunction intMacroFunction[]=
 {
@@ -465,6 +468,10 @@
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,       },
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,     },
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,   },
+	{L"PLUGIN.CALL",      nullptr, L"N=Plugin.Call(Guid[,MenuGuid])",                            plugincallFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_CALL,     },
+	{L"PLUGIN.CONFIG",    nullptr, L"N=Plugin.Config(Guid[,MenuGuid])",                          pluginconfigFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_CONFIG,   },
+	{L"PLUGIN.PREFIX",    nullptr, L"N=Plugin.Prefix(Guid,Command)",                             pluginprefixFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_PREFIX,   },
+	{L"PLUGIN.INT",       nullptr, L"N=Plugin.Int(Guid,Item)",                                   usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_INT,      },
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,           },
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,          },
 	{L"REPLACE",          nullptr, L"S=Replace(Str,Find,Replace[,Cnt[,Mode]])",                  replaceFunc,        nullptr, 0, 0,                                      MCODE_F_REPLACE,         },
@@ -666,10 +673,10 @@
 		}
 		if (0==MacroLIBCount)
 		{
-		xf_free(MacroLIB);
-			MacroLIB=nullptr;
+			xf_free(MacroLIB);
+				MacroLIB=nullptr;
+		}
 	}
-	}
 	else
 	{
 		MacroLIBCount=0;
@@ -4503,7 +4510,65 @@
 	return Ret.i()!=0;
 }
 
+// N=Plugin.Call(Guid[,MenuGuid])
+static bool plugincallFunc(const TMacroFunction*)
+{
+	parseParams(2,Params);
+	TVar Ret(0ll);
+	TVar& MenuGuid = (Params[1]);
+	TVar& Guid = (Params[0]);
+	GUID guid, menuGuid;
+	CallPluginInfo Data={CPT_CALL};
 
+	if (StrToGuid(Guid.s(),guid) && (MenuGuid.isUnknown() || StrToGuid(MenuGuid.s(),menuGuid)))
+	{
+		if (!MenuGuid.isUnknown())
+			Data.ItemGuid=&menuGuid;
+		Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+	}
+
+	return Ret.i()!=0;
+}
+
+// N=Plugin.Config(Guid[,MenuGuid])
+static bool pluginconfigFunc(const TMacroFunction*)
+{
+	parseParams(2,Params);
+	TVar Ret(0ll);
+	TVar& MenuGuid = (Params[1]);
+	TVar& Guid = (Params[0]);
+	GUID guid, menuGuid;
+	CallPluginInfo Data={CPT_CONFIGURE};
+
+	if (StrToGuid(Guid.s(),guid) && (MenuGuid.isUnknown() || StrToGuid(MenuGuid.s(),menuGuid)))
+	{
+		if (!MenuGuid.isUnknown())
+			Data.ItemGuid=&menuGuid;
+		Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+	}
+
+	return Ret.i()!=0;
+}
+
+// N=Plugin.Prefix(Guid,Command)
+static bool pluginprefixFunc(const TMacroFunction*)
+{
+	parseParams(2,Params);
+	TVar Ret(0ll);
+	TVar& Command = (Params[1]);
+	TVar& Guid = (Params[0]);
+	GUID guid;
+	CallPluginInfo Data={CPT_PREFIX};
+
+	if (StrToGuid(Guid.s(),guid) && Command.isString())
+	{
+		Data.Command=Command.s();
+		Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+	}
+
+	return Ret.i()!=0;
+}
+
 static void VarToFarMacroValue(const TVar& From,FarMacroValue& To)
 {
 	To.Type=(FARMACROVARTYPE)From.type();
@@ -5699,6 +5764,8 @@
 		}
 
 		case MCODE_F_CALLPLUGIN: // V=callplugin(SysID[,param])
+		// ����� CallPlugin, �� �������
+		case MCODE_F_PLUGIN_INT: // V=Plugin.Int(SysID[,param])
 		{
 			__int64 Ret=0;
 			int count=VMStack.Pop().getInteger();
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 7616)
+++ plugins.hpp	(working copy)
@@ -129,6 +129,27 @@
 	OFP_COMMANDS,
 };
 
+// �������� ����� ����������� plugin.call � �.�.
+enum CALLPLUGINTYPE
+{
+	CPT_CALL,
+	CPT_CONFIGURE,
+	CPT_PREFIX,
+	CPT_INTERNAL,
+};
+
+struct CallPluginInfo
+{
+	CALLPLUGINTYPE CallType;
+	int OpenFrom;
+	union
+	{
+		GUID *ItemGuid;
+		const wchar_t *Command;
+		__int64 Item;
+	};
+};
+
 struct PluginHandle
 {
 	HANDLE hPlugin;
@@ -232,6 +253,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret=nullptr);
 		Plugin *FindPlugin(const GUID& SysID);
 		static const GUID& GetGUID(HANDLE hPlugin);
 
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 7616)
+++ plugins.cpp	(working copy)
@@ -2474,6 +2474,195 @@
 	return FALSE;
 }
 
+// ��������� ����������� plugin.call, plugin.cmd, plugin.config � �.�
+int PluginManager::CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret/*=nullptr*/)
+{
+	BOOL Result=FALSE;
+
+	if (!ProcessException)
+	{
+		Plugin *pPlugin = FindPlugin(Guid);
+		if (pPlugin && pPlugin->Load())
+		{
+			int curType = FrameManager->GetCurrentFrame()->GetType();
+			bool Editor = curType==MODALTYPE_EDITOR;
+			bool Viewer = curType==MODALTYPE_VIEWER;
+			bool Dialog = curType==MODALTYPE_DIALOG;
+
+			// ������� �� ���� ������� ���� � ������ ������� (������������� ��������)
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_CONFIGURE:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� curType �� �����?
+					return FALSE;
+				}
+				if (!pPlugin->HasConfigure())
+					return FALSE;
+				break;
+			case CPT_PREFIX:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� curType �� �����?
+					return FALSE;
+				}
+				//TODO: OpenPanel ��� OpenFilePlugin?
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				//TODO: ������ �����
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			}
+
+			UINT64 IFlags;
+			PluginInfo Info = {sizeof(Info)};
+			if (!pPlugin->GetPluginInfo(&Info))
+				return FALSE;
+			else
+				IFlags = Info.Flags;
+
+			PluginMenuItem *MenuItems=nullptr;
+			GUID ItemGuid;
+
+			// ������� �� ���� ������� ���� � ������ �������
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if ((Editor && !(IFlags & PF_EDITOR)) ||
+						(Viewer && !(IFlags & PF_VIEWER)) ||
+						(Dialog && !(IFlags & PF_DIALOG)) ||
+						(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+					return FALSE;
+				//_ASSERTE(curType==MODALTYPE_PANELS || (Editor&&curType==MODALTYPE_EDITOR) || (Viewer&&curType==MODALTYPE_VIEWER) || (Dialog&&curType==MODALTYPE_DIALOG));
+				MenuItems = &Info.PluginMenu;
+				break;
+			case CPT_CONFIGURE:
+				MenuItems = &Info.PluginConfig;
+				break;
+			case CPT_PREFIX:
+				if (!Info.CommandPrefix || !*Info.CommandPrefix)
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				break;
+			}
+
+			if (Data->CallType==CPT_CALL || Data->CallType==CPT_CONFIGURE)
+			{
+				bool ItemFound = false;
+				if (Data->ItemGuid==nullptr)
+				{
+					if (MenuItems->Count==1)
+					{
+						ItemGuid=MenuItems->Guids[0];
+						ItemFound=true;
+					}
+				}
+				else
+				{
+					for (size_t i = 0; i < MenuItems->Count; i++)
+					{
+						if (memcmp(Data->ItemGuid, &(MenuItems->Guids[i]), sizeof(GUID)) == 0)
+						{
+							ItemGuid=*Data->ItemGuid;
+							ItemFound=true;
+							break;
+						}
+					}
+				}
+				if (!ItemFound)
+					return FALSE;
+			}
+
+			HANDLE hPlugin=INVALID_HANDLE_VALUE;
+			Panel *ActivePanel=nullptr;
+
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					int OpenCode=OPEN_PLUGINSMENU;
+					INT_PTR Item=0;
+					OpenDlgPluginData pd;
+
+					if (Editor)
+					{
+						OpenCode=OPEN_EDITOR;
+					}
+					else if (Viewer)
+					{
+						OpenCode=OPEN_VIEWER;
+					}
+					else if (Dialog)
+					{
+						OpenCode=OPEN_DIALOG;
+						pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+						Item=(INT_PTR)&pd;
+					}
+
+					hPlugin=Open(pPlugin,OpenCode,ItemGuid,Item);
+
+					Result=TRUE;
+				}
+				break;
+
+			case CPT_CONFIGURE:
+				CtrlObject->Plugins->ConfigureCurrent(pPlugin,ItemGuid);
+				return TRUE;
+
+			case CPT_PREFIX:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					string command=Data->Command; // ����� ���� ������
+					hPlugin=Open(pPlugin,OPEN_COMMANDLINE,FarGuid,(INT_PTR)command.CPtr());
+
+					Result=TRUE;
+				}
+				break;
+			case CPT_INTERNAL:
+				//TODO: ���� CallPlugin
+				//WARNING: ����, ��� �� ���������� ��� ��������� MacroState
+				break;
+			}
+
+			if (hPlugin && !Editor && !Viewer && !Dialog)
+			{
+				//BUGBUG: ������� ������? ����� �� ���?
+				//BUGBUG: � ProcessCommandLine ������ ����� Open, � � CPT_CALL - �����
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+		}
+	}
+
+	return FALSE;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
PluginCall6.diff (11,648 bytes)   

Maximus

2012-03-05 20:19

reporter  

PluginCall7.diff (11,335 bytes)   
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 7650)
+++ macro.cpp	(working copy)
@@ -465,6 +465,10 @@
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,       },
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,     },
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,   },
+	{L"PLUGIN.CALL",      nullptr, L"N=Plugin.Call(Guid[,MenuGuid])",                            usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_CALL,     },
+	{L"PLUGIN.CONFIG",    nullptr, L"N=Plugin.Config(Guid[,MenuGuid])",                          usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_CONFIG,   },
+	{L"PLUGIN.PREFIX",    nullptr, L"N=Plugin.Prefix(Guid,Command)",                             usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_PREFIX,   },
+	{L"PLUGIN.INT",       nullptr, L"N=Plugin.Int(Guid,Item)",                                   usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_INT,      },
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,           },
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,          },
 	{L"REPLACE",          nullptr, L"S=Replace(Str,Find,Replace[,Cnt[,Mode]])",                  replaceFunc,        nullptr, 0, 0,                                      MCODE_F_REPLACE,         },
@@ -666,10 +670,10 @@
 		}
 		if (0==MacroLIBCount)
 		{
-		xf_free(MacroLIB);
-			MacroLIB=nullptr;
+			xf_free(MacroLIB);
+				MacroLIB=nullptr;
+		}
 	}
-	}
 	else
 	{
 		MacroLIBCount=0;
@@ -4504,6 +4508,7 @@
 }
 
 
+
 static void VarToFarMacroValue(const TVar& From,FarMacroValue& To)
 {
 	To.Type=(FARMACROVARTYPE)From.type();
@@ -5699,6 +5704,8 @@
 		}
 
 		case MCODE_F_CALLPLUGIN: // V=callplugin(SysID[,param])
+		// ����� CallPlugin, �� �������
+		case MCODE_F_PLUGIN_INT: // V=Plugin.Int(SysID[,param])
 		{
 			__int64 Ret=0;
 			int count=VMStack.Pop().getInteger();
@@ -5759,6 +5766,66 @@
 			goto begin;
 		}
 
+		case MCODE_F_PLUGIN_CALL:   // N=Plugin.Call(Guid[,MenuGuid])
+		case MCODE_F_PLUGIN_CONFIG: // N=Plugin.Config(Guid[,MenuGuid])
+		case MCODE_F_PLUGIN_PREFIX: // N=Plugin.Prefix(Guid,Command)
+		{
+			__int64 Ret=0;
+			parseParams(2,Params);
+			TVar& Arg = (Params[1]);
+			TVar& Guid = (Params[0]);
+			GUID guid, menuGuid;
+			CallPluginInfo Data={};
+			wchar_t EmptyStr[1] = {};
+
+
+			switch (Key)
+			{
+			case MCODE_F_PLUGIN_CALL:
+				Data.CallType = CPT_CALL;
+				if (StrToGuid(Arg.s(),menuGuid))
+					Data.ItemGuid=&menuGuid;
+				break;
+			case MCODE_F_PLUGIN_CONFIG:
+				Data.CallType = CPT_CONFIGURE;
+				if (StrToGuid(Arg.s(),menuGuid))
+					Data.ItemGuid=&menuGuid;
+				break;
+			case MCODE_F_PLUGIN_PREFIX:
+				Data.CallType = CPT_PREFIX;
+				if (Arg.isString())
+					Data.Command=Arg.s();
+				else
+					Data.Command=EmptyStr;
+				break;
+            }
+
+			if (StrToGuid(Guid.s(),guid) && CtrlObject->Plugins->FindPlugin(guid))
+			{
+				int CallPluginRules=1; //GetCurrentCallPluginMode();
+
+				if( CallPluginRules == 1)
+					PushState(true);
+				else
+					InternalInput++;
+
+				int ResultCallPlugin=0;
+
+				Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+
+				if( CallPluginRules == 1 )
+					PopState();
+				else
+					InternalInput--;
+			}
+
+			if (Work.Executing == MACROMODE_NOMACRO)
+				goto return_func;
+
+			VMStack.Push(Ret);
+			goto begin;
+		}
+
 		default:
 		{
 			size_t J;
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 7650)
+++ macroopcode.hpp	(working copy)
@@ -224,6 +224,10 @@
 	MCODE_F_FMATCH,                   // N=FMatch(S,Mask)
 	MCODE_F_PLUGIN_LOAD,              // N=Plugin.Load(DllPath[,ForceLoad])
 	MCODE_F_PLUGIN_UNLOAD,            // N=Plugin.UnLoad(DllPath)
+	MCODE_F_PLUGIN_CALL,              // N=Plugin.Call(Guid,MenuGuid)
+	MCODE_F_PLUGIN_CONFIG,            // N=Plugin.Config(Guid[,MenuGuid])
+	MCODE_F_PLUGIN_PREFIX,            // N=Plugin.Prefix(Guid,Command)
+	MCODE_F_PLUGIN_INT,               // N=Plugin.Int(Guid,Item)
 	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
 	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
 	MCODE_F_DLG_SETFOCUS,             // N=Dlg.SetFocus([ID])
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 7650)
+++ plugins.cpp	(working copy)
@@ -2474,6 +2474,195 @@
 	return FALSE;
 }
 
+// ��������� ����������� plugin.call, plugin.cmd, plugin.config � �.�
+int PluginManager::CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret/*=nullptr*/)
+{
+	BOOL Result=FALSE;
+
+	if (!ProcessException)
+	{
+		Plugin *pPlugin = FindPlugin(Guid);
+		if (pPlugin && pPlugin->Load())
+		{
+			int curType = FrameManager->GetCurrentFrame()->GetType();
+			bool Editor = curType==MODALTYPE_EDITOR;
+			bool Viewer = curType==MODALTYPE_VIEWER;
+			bool Dialog = curType==MODALTYPE_DIALOG;
+
+			// ������� �� ���� ������� ���� � ������ ������� (������������� ��������)
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_CONFIGURE:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� curType �� �����?
+					return FALSE;
+				}
+				if (!pPlugin->HasConfigure())
+					return FALSE;
+				break;
+			case CPT_PREFIX:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� curType �� �����?
+					return FALSE;
+				}
+				//TODO: OpenPanel ��� OpenFilePlugin?
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				//TODO: ������ �����
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			}
+
+			UINT64 IFlags;
+			PluginInfo Info = {sizeof(Info)};
+			if (!pPlugin->GetPluginInfo(&Info))
+				return FALSE;
+			else
+				IFlags = Info.Flags;
+
+			PluginMenuItem *MenuItems=nullptr;
+			GUID ItemGuid;
+
+			// ������� �� ���� ������� ���� � ������ �������
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if ((Editor && !(IFlags & PF_EDITOR)) ||
+						(Viewer && !(IFlags & PF_VIEWER)) ||
+						(Dialog && !(IFlags & PF_DIALOG)) ||
+						(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+					return FALSE;
+				//_ASSERTE(curType==MODALTYPE_PANELS || (Editor&&curType==MODALTYPE_EDITOR) || (Viewer&&curType==MODALTYPE_VIEWER) || (Dialog&&curType==MODALTYPE_DIALOG));
+				MenuItems = &Info.PluginMenu;
+				break;
+			case CPT_CONFIGURE:
+				MenuItems = &Info.PluginConfig;
+				break;
+			case CPT_PREFIX:
+				if (!Info.CommandPrefix || !*Info.CommandPrefix)
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				break;
+			}
+
+			if (Data->CallType==CPT_CALL || Data->CallType==CPT_CONFIGURE)
+			{
+				bool ItemFound = false;
+				if (Data->ItemGuid==nullptr)
+				{
+					if (MenuItems->Count==1)
+					{
+						ItemGuid=MenuItems->Guids[0];
+						ItemFound=true;
+					}
+				}
+				else
+				{
+					for (size_t i = 0; i < MenuItems->Count; i++)
+					{
+						if (memcmp(Data->ItemGuid, &(MenuItems->Guids[i]), sizeof(GUID)) == 0)
+						{
+							ItemGuid=*Data->ItemGuid;
+							ItemFound=true;
+							break;
+						}
+					}
+				}
+				if (!ItemFound)
+					return FALSE;
+			}
+
+			HANDLE hPlugin=INVALID_HANDLE_VALUE;
+			Panel *ActivePanel=nullptr;
+
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					int OpenCode=OPEN_PLUGINSMENU;
+					INT_PTR Item=0;
+					OpenDlgPluginData pd;
+
+					if (Editor)
+					{
+						OpenCode=OPEN_EDITOR;
+					}
+					else if (Viewer)
+					{
+						OpenCode=OPEN_VIEWER;
+					}
+					else if (Dialog)
+					{
+						OpenCode=OPEN_DIALOG;
+						pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+						Item=(INT_PTR)&pd;
+					}
+
+					hPlugin=Open(pPlugin,OpenCode,ItemGuid,Item);
+
+					Result=TRUE;
+				}
+				break;
+
+			case CPT_CONFIGURE:
+				CtrlObject->Plugins->ConfigureCurrent(pPlugin,ItemGuid);
+				return TRUE;
+
+			case CPT_PREFIX:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					string command=Data->Command; // ����� ���� ������
+					hPlugin=Open(pPlugin,OPEN_COMMANDLINE,FarGuid,(INT_PTR)command.CPtr());
+
+					Result=TRUE;
+				}
+				break;
+			case CPT_INTERNAL:
+				//TODO: ���� CallPlugin
+				//WARNING: ����, ��� �� ���������� ��� ��������� MacroState
+				break;
+			}
+
+			if (hPlugin!=INVALID_HANDLE_VALUE && !Editor && !Viewer && !Dialog)
+			{
+				//BUGBUG: ������� ������? ����� �� ���?
+				//BUGBUG: � ProcessCommandLine ������ ����� Open, � � CPT_CALL - �����
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+		}
+	}
+
+	return FALSE;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 7650)
+++ plugins.hpp	(working copy)
@@ -129,6 +129,27 @@
 	OFP_COMMANDS,
 };
 
+// �������� ����� ����������� plugin.call � �.�.
+enum CALLPLUGINTYPE
+{
+	CPT_CALL,
+	CPT_CONFIGURE,
+	CPT_PREFIX,
+	CPT_INTERNAL,
+};
+
+struct CallPluginInfo
+{
+	CALLPLUGINTYPE CallType;
+	int OpenFrom;
+	union
+	{
+		GUID *ItemGuid;
+		const wchar_t *Command;
+		__int64 Item;
+	};
+};
+
 struct PluginHandle
 {
 	HANDLE hPlugin;
@@ -232,6 +253,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret=nullptr);
 		Plugin *FindPlugin(const GUID& SysID);
 		static const GUID& GetGUID(HANDLE hPlugin);
 
PluginCall7.diff (11,335 bytes)   

Maximus

2012-03-05 20:20

reporter   bugnote:0008706

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

vskirdin

2012-03-06 06:23

administrator   bugnote:0008709

Last edited: 2012-03-06 06:29

Правильно я понял, что у Plugin.Call, Plugin.Config и Plugin.Prefix предполагается только 2 параметра?

Так же - mmode(3) здесь тоже будет учитывается или нет?
Я вот про это:
int CallPluginRules=1; //GetCurrentCallPluginMode();

И... на будущее :-)
Давайте в массиве intMacroFunction придерживаться алфавитной сортировки...
UPD: а в macroopcode.hpp - добавлять в конец секций


UPD2: и, наверное, в PluginManager::CallPluginItem задействовать Ret/

Maximus

2012-03-06 07:41

reporter   bugnote:0008710

Ну да, только 2. Ведь параметров при вызове пункта меню/настройки конфигурации вообще нет (кроме индекса), а для префикса - только сам префикс.

mmode(3)... я кусок оставил пока, вот только не уверен, что вообще нужно ограничивать плагины в плане макросов (это ведь получается, если "CallPluginRules!=1"?). Идея такая - они ведь не ограничиваются при вызове по хоткею через F11, тут должно быть также.

На счет Ret - я вообще не понимаю... Смысла в данном случае у него imho вообще нет.
Если в макросе написать что-то вроде
%r=Plugin.Call("bla-bla-bla") MsgBox("bla-bla-bla" + %r)
то по идее получится, что
1. при вызове Plugin.Call будет вход в OpenW
2. если плагин "отдаст" управление фару (например диалог/меню покажет), то
3. фар продолжит выполнение макроса. И чему в этом случае будет равен %r?

JohnDoe

2012-03-06 09:12

updater   bugnote:0008711

>вот только не уверен, что вообще нужно ограничивать плагины в плане макросов
У меня идея обратная: по умолчанию ничего не ограничено - mmode(3,1), а если нужно дождаться завершения плагина, то используем mmode(3,0).

>И чему в этом случае будет равен %r?
А зачем нам вообще возвращаемое значение?
При отсутствии плагина фатальная ошибка и всё на этом.

vskirdin

2012-03-06 10:02

administrator   bugnote:0008712

тестируем (на основе PluginCall7.diff)
http://skirda-file.googlecode.com/files/mantis0001903.2.7z
здесь так же mmode(3,1) по умолчанию включен

Maximus

2012-03-06 11:35

reporter   bugnote:0008713

> по умолчанию ничего не ограничено - mmode(3,1), а если нужно дождаться завершения плагина, то используем mmode(3,0).
наверное, это правильно.

> При отсутствии плагина фатальная ошибка и всё на этом
хорошо бы. но смысла нет. хотя... проверить, погонять надо...

JohnDoe

2012-03-06 11:43

updater   bugnote:0008714

>хорошо бы. но смысла нет.
В чём нет смысла?

Maximus

2012-03-07 09:56

reporter  

PluginCall8.diff (11,574 bytes)   
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 7669)
+++ macro.cpp	(working copy)
@@ -463,7 +463,11 @@
 	{L"PANEL.SETPOS",     nullptr, L"N=panel.SetPos(panelType,fileName)",                        panelsetposFunc,    nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PANEL_SETPOS,    },
 	{L"PANEL.SETPOSIDX",  nullptr, L"N=Panel.SetPosIdx(panelType,Idx[,InSelection])",            panelsetposidxFunc, nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PANEL_SETPOSIDX, },
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,       },
+	{L"PLUGIN.CALL",      nullptr, L"N=Plugin.Call(Guid[,MenuGuid])",                            usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_CALL,     },
+	{L"PLUGIN.CONFIG",    nullptr, L"N=Plugin.Config(Guid[,MenuGuid])",                          usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_CONFIG,   },
+	{L"PLUGIN.INT",       nullptr, L"N=Plugin.Int(Guid,Item)",                                   usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_INT,      },
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,     },
+	{L"PLUGIN.PREFIX",    nullptr, L"N=Plugin.Prefix(Guid,Command)",                             usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_PREFIX,   },
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,   },
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,           },
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,          },
@@ -666,10 +670,10 @@
 		}
 		if (0==MacroLIBCount)
 		{
-		xf_free(MacroLIB);
-			MacroLIB=nullptr;
+			xf_free(MacroLIB);
+				MacroLIB=nullptr;
+		}
 	}
-	}
 	else
 	{
 		MacroLIBCount=0;
@@ -4504,6 +4508,7 @@
 }
 
 
+
 static void VarToFarMacroValue(const TVar& From,FarMacroValue& To)
 {
 	To.Type=(FARMACROVARTYPE)From.type();
@@ -5699,6 +5704,8 @@
 		}
 
 		case MCODE_F_CALLPLUGIN: // V=callplugin(SysID[,param])
+		// ����� CallPlugin, �� �������
+		case MCODE_F_PLUGIN_INT: // V=Plugin.Int(SysID[,param])
 		{
 			__int64 Ret=0;
 			int count=VMStack.Pop().getInteger();
@@ -5759,6 +5766,66 @@
 			goto begin;
 		}
 
+		case MCODE_F_PLUGIN_CALL:   // N=Plugin.Call(Guid[,MenuGuid])
+		case MCODE_F_PLUGIN_CONFIG: // N=Plugin.Config(Guid[,MenuGuid])
+		case MCODE_F_PLUGIN_PREFIX: // N=Plugin.Prefix(Guid,Command)
+		{
+			__int64 Ret=0;
+			parseParams(2,Params);
+			TVar& Arg = (Params[1]);
+			TVar& Guid = (Params[0]);
+			GUID guid, menuGuid;
+			CallPluginInfo Data={};
+			wchar_t EmptyStr[1] = {};
+
+
+			switch (Key)
+			{
+			case MCODE_F_PLUGIN_CALL:
+				Data.CallType = CPT_CALL;
+				if (StrToGuid(Arg.s(),menuGuid))
+					Data.ItemGuid=&menuGuid;
+				break;
+			case MCODE_F_PLUGIN_CONFIG:
+				Data.CallType = CPT_CONFIGURE;
+				if (StrToGuid(Arg.s(),menuGuid))
+					Data.ItemGuid=&menuGuid;
+				break;
+			case MCODE_F_PLUGIN_PREFIX:
+				Data.CallType = CPT_PREFIX;
+				if (Arg.isString())
+					Data.Command=Arg.s();
+				else
+					Data.Command=EmptyStr;
+				break;
+            }
+
+			if (StrToGuid(Guid.s(),guid) && CtrlObject->Plugins->FindPlugin(guid))
+			{
+				int CallPluginRules=1; //GetCurrentCallPluginMode();
+
+				if( CallPluginRules == 1)
+					PushState(true);
+				else
+					InternalInput++;
+
+				int ResultCallPlugin=0;
+
+				Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+
+				if( CallPluginRules == 1 )
+					PopState();
+				else
+					InternalInput--;
+			}
+
+			if (Work.Executing == MACROMODE_NOMACRO)
+				goto return_func;
+
+			VMStack.Push(Ret);
+			goto begin;
+		}
+
 		default:
 		{
 			size_t J;
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 7669)
+++ macroopcode.hpp	(working copy)
@@ -222,7 +222,11 @@
 	MCODE_F_KEYBAR_SHOW,              // N=KeyBar.Show([N])
 	MCODE_F_HISTIORY_DISABLE,         // N=History.Disable([State])
 	MCODE_F_FMATCH,                   // N=FMatch(S,Mask)
+	MCODE_F_PLUGIN_CALL,              // N=Plugin.Call(Guid,MenuGuid)
+	MCODE_F_PLUGIN_CONFIG,            // N=Plugin.Config(Guid[,MenuGuid])
+	MCODE_F_PLUGIN_INT,               // N=Plugin.Int(Guid,Item)
 	MCODE_F_PLUGIN_LOAD,              // N=Plugin.Load(DllPath[,ForceLoad])
+	MCODE_F_PLUGIN_PREFIX,            // N=Plugin.Prefix(Guid,Command)
 	MCODE_F_PLUGIN_UNLOAD,            // N=Plugin.UnLoad(DllPath)
 	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
 	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 7650)
+++ plugins.cpp	(working copy)
@@ -2474,6 +2474,195 @@
 	return FALSE;
 }
 
+// ��������� ����������� plugin.call, plugin.cmd, plugin.config � �.�
+int PluginManager::CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret/*=nullptr*/)
+{
+	BOOL Result=FALSE;
+
+	if (!ProcessException)
+	{
+		Plugin *pPlugin = FindPlugin(Guid);
+		if (pPlugin && pPlugin->Load())
+		{
+			int curType = FrameManager->GetCurrentFrame()->GetType();
+			bool Editor = curType==MODALTYPE_EDITOR;
+			bool Viewer = curType==MODALTYPE_VIEWER;
+			bool Dialog = curType==MODALTYPE_DIALOG;
+
+			// ������� �� ���� ������� ���� � ������ ������� (������������� ��������)
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_CONFIGURE:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� curType �� �����?
+					return FALSE;
+				}
+				if (!pPlugin->HasConfigure())
+					return FALSE;
+				break;
+			case CPT_PREFIX:
+				if (curType!=MODALTYPE_PANELS)
+				{
+					//TODO: ����������� �� curType �� �����?
+					return FALSE;
+				}
+				//TODO: OpenPanel ��� OpenFilePlugin?
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				//TODO: ������ �����
+				if (!pPlugin->HasOpenPanel())
+					return FALSE;
+				break;
+			}
+
+			UINT64 IFlags;
+			PluginInfo Info = {sizeof(Info)};
+			if (!pPlugin->GetPluginInfo(&Info))
+				return FALSE;
+			else
+				IFlags = Info.Flags;
+
+			PluginMenuItem *MenuItems=nullptr;
+			GUID ItemGuid;
+
+			// ������� �� ���� ������� ���� � ������ �������
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				if ((Editor && !(IFlags & PF_EDITOR)) ||
+						(Viewer && !(IFlags & PF_VIEWER)) ||
+						(Dialog && !(IFlags & PF_DIALOG)) ||
+						(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+					return FALSE;
+				//_ASSERTE(curType==MODALTYPE_PANELS || (Editor&&curType==MODALTYPE_EDITOR) || (Viewer&&curType==MODALTYPE_VIEWER) || (Dialog&&curType==MODALTYPE_DIALOG));
+				MenuItems = &Info.PluginMenu;
+				break;
+			case CPT_CONFIGURE:
+				MenuItems = &Info.PluginConfig;
+				break;
+			case CPT_PREFIX:
+				if (!Info.CommandPrefix || !*Info.CommandPrefix)
+					return FALSE;
+				break;
+			case CPT_INTERNAL:
+				break;
+			}
+
+			if (Data->CallType==CPT_CALL || Data->CallType==CPT_CONFIGURE)
+			{
+				bool ItemFound = false;
+				if (Data->ItemGuid==nullptr)
+				{
+					if (MenuItems->Count==1)
+					{
+						ItemGuid=MenuItems->Guids[0];
+						ItemFound=true;
+					}
+				}
+				else
+				{
+					for (size_t i = 0; i < MenuItems->Count; i++)
+					{
+						if (memcmp(Data->ItemGuid, &(MenuItems->Guids[i]), sizeof(GUID)) == 0)
+						{
+							ItemGuid=*Data->ItemGuid;
+							ItemFound=true;
+							break;
+						}
+					}
+				}
+				if (!ItemFound)
+					return FALSE;
+			}
+
+			HANDLE hPlugin=INVALID_HANDLE_VALUE;
+			Panel *ActivePanel=nullptr;
+
+			switch (Data->CallType)
+			{
+			case CPT_CALL:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					int OpenCode=OPEN_PLUGINSMENU;
+					INT_PTR Item=0;
+					OpenDlgPluginData pd;
+
+					if (Editor)
+					{
+						OpenCode=OPEN_EDITOR;
+					}
+					else if (Viewer)
+					{
+						OpenCode=OPEN_VIEWER;
+					}
+					else if (Dialog)
+					{
+						OpenCode=OPEN_DIALOG;
+						pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+						Item=(INT_PTR)&pd;
+					}
+
+					hPlugin=Open(pPlugin,OpenCode,ItemGuid,Item);
+
+					Result=TRUE;
+				}
+				break;
+
+			case CPT_CONFIGURE:
+				CtrlObject->Plugins->ConfigureCurrent(pPlugin,ItemGuid);
+				return TRUE;
+
+			case CPT_PREFIX:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					string command=Data->Command; // ����� ���� ������
+					hPlugin=Open(pPlugin,OPEN_COMMANDLINE,FarGuid,(INT_PTR)command.CPtr());
+
+					Result=TRUE;
+				}
+				break;
+			case CPT_INTERNAL:
+				//TODO: ���� CallPlugin
+				//WARNING: ����, ��� �� ���������� ��� ��������� MacroState
+				break;
+			}
+
+			if (hPlugin && !Editor && !Viewer && !Dialog)
+			{
+				//BUGBUG: ������� ������? ����� �� ���?
+				//BUGBUG: � ProcessCommandLine ������ ����� Open, � � CPT_CALL - �����
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+		}
+	}
+
+	return FALSE;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 7650)
+++ plugins.hpp	(working copy)
@@ -129,6 +129,27 @@
 	OFP_COMMANDS,
 };
 
+// �������� ����� ����������� plugin.call � �.�.
+enum CALLPLUGINTYPE
+{
+	CPT_CALL,
+	CPT_CONFIGURE,
+	CPT_PREFIX,
+	CPT_INTERNAL,
+};
+
+struct CallPluginInfo
+{
+	CALLPLUGINTYPE CallType;
+	int OpenFrom;
+	union
+	{
+		GUID *ItemGuid;
+		const wchar_t *Command;
+		__int64 Item;
+	};
+};
+
 struct PluginHandle
 {
 	HANDLE hPlugin;
@@ -232,6 +253,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret=nullptr);
 		Plugin *FindPlugin(const GUID& SysID);
 		static const GUID& GetGUID(HANDLE hPlugin);
 
PluginCall8.diff (11,574 bytes)   

vskirdin

2012-03-07 10:57

administrator   bugnote:0008716

тестируем (на основе PluginCall8.diff)
http://skirda-file.googlecode.com/files/mantis0001903.3.7z
здесь так же mmode(3,1) по умолчанию включен

Maximus

2012-03-11 23:18

reporter  

PluginCall9.diff (12,800 bytes)   
Index: macro.cpp
===================================================================
--- macro.cpp	(revision 7682)
+++ macro.cpp	(working copy)
@@ -463,7 +463,11 @@
 	{L"PANEL.SETPOS",     nullptr, L"N=panel.SetPos(panelType,fileName)",                        panelsetposFunc,    nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PANEL_SETPOS,    },
 	{L"PANEL.SETPOSIDX",  nullptr, L"N=Panel.SetPosIdx(panelType,Idx[,InSelection])",            panelsetposidxFunc, nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PANEL_SETPOSIDX, },
 	{L"PANELITEM",        nullptr, L"V=PanelItem(Panel,Index,TypeInfo)",                         panelitemFunc,      nullptr, 0, 0,                                      MCODE_F_PANELITEM,       },
+	{L"PLUGIN.CALL",      nullptr, L"N=Plugin.Call(Guid[,MenuGuid])",                            usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_CALL,     },
+	{L"PLUGIN.CONFIG",    nullptr, L"N=Plugin.Config(Guid[,MenuGuid])",                          usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_CONFIG,   },
+	{L"PLUGIN.INT",       nullptr, L"N=Plugin.Int(Guid,Item)",                                   usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_INT,      },
 	{L"PLUGIN.LOAD",      nullptr, L"N=Plugin.Load(DllPath[,ForceLoad])",                        pluginloadFunc,     nullptr, 0, 0,                                      MCODE_F_PLUGIN_LOAD,     },
+	{L"PLUGIN.PREFIX",    nullptr, L"N=Plugin.Prefix(Guid,Command)",                             usersFunc,          nullptr, 0, 0,                                      MCODE_F_PLUGIN_PREFIX,   },
 	{L"PLUGIN.UNLOAD",    nullptr, L"N=Plugin.UnLoad(DllPath)",                                  pluginunloadFunc,   nullptr, 0, 0,                                      MCODE_F_PLUGIN_UNLOAD,   },
 	{L"PRINT",            nullptr, L"N=Print(Str)",                                              usersFunc,          nullptr, 0, 0,                                      MCODE_F_PRINT,           },
 	{L"PROMPT",           nullptr, L"S=Prompt([Title[,Prompt[,flags[,Src[,History]]]]])",        promptFunc,         nullptr, 0, IMFF_UNLOCKSCREEN|IMFF_DISABLEINTINPUT, MCODE_F_PROMPT,          },
@@ -666,10 +670,10 @@
 		}
 		if (0==MacroLIBCount)
 		{
-		xf_free(MacroLIB);
-			MacroLIB=nullptr;
+			xf_free(MacroLIB);
+				MacroLIB=nullptr;
+		}
 	}
-	}
 	else
 	{
 		MacroLIBCount=0;
@@ -4504,6 +4508,7 @@
 }
 
 
+
 static void VarToFarMacroValue(const TVar& From,FarMacroValue& To)
 {
 	To.Type=(FARMACROVARTYPE)From.type();
@@ -5699,6 +5704,8 @@
 		}
 
 		case MCODE_F_CALLPLUGIN: // V=callplugin(SysID[,param])
+		// ����� CallPlugin, �� �������
+		case MCODE_F_PLUGIN_INT: // V=Plugin.Int(SysID[,param])
 		{
 			__int64 Ret=0;
 			int count=VMStack.Pop().getInteger();
@@ -5759,6 +5766,100 @@
 			goto begin;
 		}
 
+		case MCODE_F_PLUGIN_CALL:   // N=Plugin.Call(Guid[,MenuGuid])
+		case MCODE_F_PLUGIN_CONFIG: // N=Plugin.Config(Guid[,MenuGuid])
+		case MCODE_F_PLUGIN_PREFIX: // N=Plugin.Prefix(Guid,Command)
+		{
+			__int64 Ret=0;
+			parseParams(2,Params);
+			TVar& Arg = (Params[1]);
+			TVar& Guid = (Params[0]);
+			GUID guid, menuGuid;
+			CallPluginInfo Data={CPT_CHECKONLY};
+			wchar_t EmptyStr[1]={};
+			bool ItemFailed=false;
+
+
+			switch (Key)
+			{
+			case MCODE_F_PLUGIN_CALL:
+				Data.CallFlags |= CPT_CALL;
+				if (!Arg.isUnknown())
+				{
+					if (StrToGuid(Arg.s(),menuGuid))
+						Data.ItemGuid=&menuGuid;
+					else
+						ItemFailed=true;
+				}
+				break;
+			case MCODE_F_PLUGIN_CONFIG:
+				Data.CallFlags |= CPT_CONFIGURE;
+				if (!Arg.isUnknown())
+				{
+					if (StrToGuid(Arg.s(),menuGuid))
+						Data.ItemGuid=&menuGuid;
+					else
+						ItemFailed=true;
+				}
+				break;
+			case MCODE_F_PLUGIN_PREFIX:
+				Data.CallFlags |= CPT_PREFIX;
+				if (Arg.isString())
+					Data.Command=Arg.s();
+				else
+					Data.Command=EmptyStr;
+				break;
+            }
+
+			if (!ItemFailed && StrToGuid(Guid.s(),guid) && CtrlObject->Plugins->FindPlugin(guid))
+			{
+				int CallPluginRules=1; //GetCurrentCallPluginMode();
+
+				if( CallPluginRules == 1)
+				{
+					PushState(true);
+				}
+				else
+				{
+					InternalInput++;
+				}
+
+				int ResultCallPlugin=0;
+
+				// ���� ������ �������� "��������" ����� �������� ������ �������/������
+				Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+				VMStack.Push(Ret);
+
+				if (Ret)
+				{
+					// ���� ���� ������ - �� ����� ���������
+					Data.CallFlags&=~CPT_CHECKONLY;
+					Ret=(__int64)CtrlObject->Plugins->CallPluginItem(guid,&Data);
+				}
+
+				if( CallPluginRules == 1 )
+				{
+					PopState();
+				}
+				else
+				{
+					InternalInput--;
+				}
+			}
+			else
+			{
+				VMStack.Push(Ret);
+			}
+
+			// �� �������� � KEY_F11
+			FrameManager->RefreshFrame();
+
+			if (Work.Executing == MACROMODE_NOMACRO)
+				goto return_func;
+
+			goto begin;
+		}
+
 		default:
 		{
 			size_t J;
Index: macroopcode.hpp
===================================================================
--- macroopcode.hpp	(revision 7682)
+++ macroopcode.hpp	(working copy)
@@ -222,7 +222,11 @@
 	MCODE_F_KEYBAR_SHOW,              // N=KeyBar.Show([N])
 	MCODE_F_HISTIORY_DISABLE,         // N=History.Disable([State])
 	MCODE_F_FMATCH,                   // N=FMatch(S,Mask)
+	MCODE_F_PLUGIN_CALL,              // N=Plugin.Call(Guid,MenuGuid)
+	MCODE_F_PLUGIN_CONFIG,            // N=Plugin.Config(Guid[,MenuGuid])
+	MCODE_F_PLUGIN_INT,               // N=Plugin.Int(Guid,Item)
 	MCODE_F_PLUGIN_LOAD,              // N=Plugin.Load(DllPath[,ForceLoad])
+	MCODE_F_PLUGIN_PREFIX,            // N=Plugin.Prefix(Guid,Command)
 	MCODE_F_PLUGIN_UNLOAD,            // N=Plugin.UnLoad(DllPath)
 	MCODE_F_MENU_FILTER,              // N=Menu.Filter(Action[,Mode])
 	MCODE_F_MENU_FILTERSTR,           // S=Menu.FilterStr([Action[,S]])
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 7682)
+++ plugins.cpp	(working copy)
@@ -2474,6 +2474,205 @@
 	return FALSE;
 }
 
+// ��������� ����������� plugin.call, plugin.cmd, plugin.config � �.�
+int PluginManager::CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret/*=nullptr*/)
+{
+	BOOL Result=FALSE;
+
+	if (!ProcessException)
+	{
+		int curType = FrameManager->GetCurrentFrame()->GetType();
+		bool Editor = curType==MODALTYPE_EDITOR;
+		bool Viewer = curType==MODALTYPE_VIEWER;
+		bool Dialog = curType==MODALTYPE_DIALOG;
+
+		if (Data->CallFlags & CPT_CHECKONLY)
+		{
+			Data->pPlugin = FindPlugin(Guid);
+			if (Data->pPlugin && Data->pPlugin->Load())
+			{
+				// ������� �� ���� ������� ���� � ������ ������� (������������� ��������)
+				switch ((Data->CallFlags & CPT_MASK))
+				{
+				case CPT_CALL:
+					if (!Data->pPlugin->HasOpenPanel())
+						return FALSE;
+					break;
+				case CPT_CONFIGURE:
+					if (curType!=MODALTYPE_PANELS)
+					{
+						//TODO: ����������� �� �����?
+						return FALSE;
+					}
+					if (!Data->pPlugin->HasConfigure())
+						return FALSE;
+					break;
+				case CPT_PREFIX:
+					if (curType!=MODALTYPE_PANELS)
+					{
+						//TODO: ����������� �� �����?
+						return FALSE;
+					}
+					//TODO: OpenPanel ��� OpenFilePlugin?
+					if (!Data->pPlugin->HasOpenPanel())
+						return FALSE;
+					break;
+				case CPT_INTERNAL:
+					//TODO: ������ �����
+					if (!Data->pPlugin->HasOpenPanel())
+						return FALSE;
+					break;
+				}
+
+				UINT64 IFlags;
+				PluginInfo Info = {sizeof(Info)};
+				if (!Data->pPlugin->GetPluginInfo(&Info))
+					return FALSE;
+				else
+					IFlags = Info.Flags;
+
+				PluginMenuItem *MenuItems=nullptr;
+
+				// ������� �� ���� ������� ���� � ������ �������
+				switch ((Data->CallFlags & CPT_MASK))
+				{
+				case CPT_CALL:
+					if ((Editor && !(IFlags & PF_EDITOR)) ||
+							(Viewer && !(IFlags & PF_VIEWER)) ||
+							(Dialog && !(IFlags & PF_DIALOG)) ||
+							(!Editor && !Viewer && !Dialog && (IFlags & PF_DISABLEPANELS)))
+						return FALSE;
+					MenuItems = &Info.PluginMenu;
+					break;
+				case CPT_CONFIGURE:
+					MenuItems = &Info.PluginConfig;
+					break;
+				case CPT_PREFIX:
+					if (!Info.CommandPrefix || !*Info.CommandPrefix)
+						return FALSE;
+					break;
+				case CPT_INTERNAL:
+					break;
+				}
+
+				if ((Data->CallFlags & CPT_MASK)==CPT_CALL || (Data->CallFlags & CPT_MASK)==CPT_CONFIGURE)
+				{
+					bool ItemFound = false;
+					if (Data->ItemGuid==nullptr)
+					{
+						if (MenuItems->Count==1)
+						{
+							Data->FoundGuid=MenuItems->Guids[0];
+							Data->ItemGuid=&Data->FoundGuid;
+							ItemFound=true;
+						}
+					}
+					else
+					{
+						for (size_t i = 0; i < MenuItems->Count; i++)
+						{
+							if (memcmp(Data->ItemGuid, &(MenuItems->Guids[i]), sizeof(GUID)) == 0)
+							{
+								Data->FoundGuid=*Data->ItemGuid;
+								Data->ItemGuid=&Data->FoundGuid;
+								ItemFound=true;
+								break;
+							}
+						}
+					}
+					if (!ItemFound)
+						return FALSE;
+				}
+			}
+
+			Result=TRUE;
+		}
+		else
+		{
+			if (!Data->pPlugin)
+				return FALSE;
+
+			HANDLE hPlugin=INVALID_HANDLE_VALUE;
+			Panel *ActivePanel=nullptr;
+
+			switch ((Data->CallFlags & CPT_MASK))
+			{
+			case CPT_CALL:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					int OpenCode=OPEN_PLUGINSMENU;
+					INT_PTR Item=0;
+					OpenDlgPluginData pd;
+
+					if (Editor)
+					{
+						OpenCode=OPEN_EDITOR;
+					}
+					else if (Viewer)
+					{
+						OpenCode=OPEN_VIEWER;
+					}
+					else if (Dialog)
+					{
+						OpenCode=OPEN_DIALOG;
+						pd.hDlg=(HANDLE)FrameManager->GetCurrentFrame();
+						Item=(INT_PTR)&pd;
+					}
+
+					hPlugin=Open(Data->pPlugin,OpenCode,Data->FoundGuid,Item);
+
+					Result=TRUE;
+				}
+				break;
+
+			case CPT_CONFIGURE:
+				CtrlObject->Plugins->ConfigureCurrent(Data->pPlugin,Data->FoundGuid);
+				return TRUE;
+
+			case CPT_PREFIX:
+				{
+					ActivePanel=CtrlObject->Cp()->ActivePanel;
+					string command=Data->Command; // ����� ���� ������
+					hPlugin=Open(Data->pPlugin,OPEN_COMMANDLINE,FarGuid,(INT_PTR)command.CPtr());
+
+					Result=TRUE;
+				}
+				break;
+			case CPT_INTERNAL:
+				//TODO: ���� CallPlugin
+				//WARNING: ����, ��� �� ���������� ��� ��������� MacroState
+				break;
+			}
+
+			if (hPlugin && !Editor && !Viewer && !Dialog)
+			{
+				//BUGBUG: ������� ������? ����� �� ���?
+				//BUGBUG: � ProcessCommandLine ������ ����� Open, � � CPT_CALL - �����
+				if (ActivePanel->ProcessPluginEvent(FE_CLOSE,nullptr))
+				{
+					ClosePanel(hPlugin);
+					return FALSE;
+				}
+
+				Panel *NewPanel=CtrlObject->Cp()->ChangePanel(ActivePanel,FILE_PANEL,TRUE,TRUE);
+				NewPanel->SetPluginMode(hPlugin,L"",true);
+				NewPanel->Update(0);
+				NewPanel->Show();
+			}
+
+			// restore title for old plugins only.
+			#ifndef NO_WRAPPER
+			if (Data->pPlugin->IsOemPlugin() && Editor && CurEditor)
+			{
+				CurEditor->SetPluginTitle(nullptr);
+			}
+			#endif // NO_WRAPPER
+		}
+	}
+
+	return Result;
+}
+
 Plugin *PluginManager::FindPlugin(const GUID& SysID)
 {
 	Plugin **result=nullptr;
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 7682)
+++ plugins.hpp	(working copy)
@@ -129,6 +129,30 @@
 	OFP_COMMANDS,
 };
 
+// �������� ����� ����������� plugin.call � �.�.
+typedef unsigned int CALLPLUGINFLAGS;
+static const CALLPLUGINFLAGS
+	CPT_CALL        = 0x00000001L,
+	CPT_CONFIGURE   = 0x00000002L,
+	CPT_PREFIX      = 0x00000004L,
+	CPT_INTERNAL    = 0x00000008L,
+	CPT_MASK        = 0x0000000FL,
+	CPT_CHECKONLY   = 0x10000000L;
+
+struct CallPluginInfo
+{
+	CALLPLUGINFLAGS CallFlags;
+	int OpenFrom;
+	union
+	{
+		GUID *ItemGuid;
+		const wchar_t *Command;
+	};
+	// ���������� � ������ CallPluginItem �� ��������� ����
+	Plugin *pPlugin;
+	GUID FoundGuid;
+};
+
 struct PluginHandle
 {
 	HANDLE hPlugin;
@@ -232,6 +256,7 @@
 
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
+		int CallPluginItem(const GUID& Guid, CallPluginInfo *Data, int *Ret=nullptr);
 		Plugin *FindPlugin(const GUID& SysID);
 		static const GUID& GetGUID(HANDLE hPlugin);
 
PluginCall9.diff (12,800 bytes)   

Maximus

2012-03-11 23:20

reporter   bugnote:0008736

Продолжение банкета.
Теперь можно сразу использовать код возврата (Call/Config/Prefix).
1 - плагин/пункт найден, 0 - не найден.

Новые непонятки: http://forum.farmanager.com/viewtopic.php?p=92609#p92609

vskirdin

2012-03-12 08:45

administrator   bugnote:0008744

Тестим
http://skirda-file.googlecode.com/files/mantis0001903.4.7z
2Maximus: патч внутри архива - синхронизируйся со своими сорцами

vskirdin

2012-03-12 10:33

administrator   bugnote:0008746

Я так понимаю, что чем дальше, тем стабильнее и... с логикой определились?
Тогда предлагаю зафиксировать 9-ю версию с моими уточнениями, а дальше отлаживать as is, ибо тестовые билды как то не тестируются (судя по скачиванию)...

Maximus

2012-03-12 12:25

reporter  

Html1.diff (3,496 bytes)   
Index: general.html
===================================================================
--- general.html	(revision 7683)
+++ general.html	(working copy)
@@ -1591,6 +1591,35 @@
   </tr>
 
   <tr>
+    <td>N=<dfn><a name="plugin.call">plugin.call</a></dfn>(Guid[,MenuGuid])</td>
+    <td><p>������ ����� ������� �� ��� �������� �� F11 ��� ������������ ������� ����� ������ ��� ����� ������ � ������.</p>
+       <p><var>Guid</var> � <var>MenuGuid</var> ����� ��������� � ������� "Plugin information" (F3 � ������): ��� "Plugin GUID" � "Plugin item GUID" ��������������.</p>
+       <p>��������� ����� ������ <var>Guid</var> �������. <var>MenuGuid</var> �������� ������� � ��� �����, ���� ������ ������������ ����� ������ ������ ���.</p>
+       <p>���� ������ ����������� � ������ F11 �� ������ ������������ - ����� ������ �����.</p>
+       <p>����� ��������� 1 - ������/����� ������ ��� 0 - � ����� �����.</p>
+       <p>������ ����������� - ����� FarColorer\Outliner list:</p>
+       <pre class="codesample"><code>%I = plugin.call("D2F36B62-A470-418D-83A3-ED7A3710E5B5","45453CAC-499D-4B37-82B8-0A77F7BD087C");
+$If (%I==1) 5 $End</code></pre>
+    </td>
+  </tr>
+
+  <tr>
+    <td>N=<dfn><a name="plugin.config">plugin.config</a></dfn>(Guid[,MenuGuid])</td>
+    <td><p>������ ����� ������� �� ��� "�������� ��������" ��� ������������ ������� ����� ������ ��� ����� ������ � ������. �������� ����� � �����.</p>
+       <p><var>Guid</var> � <var>MenuGuid</var> ����� ��������� � ������� "Plugin information" (F3 � ������): ��� "Plugin GUID" � "Plugin item GUID" ��������������.</p>
+       <p>��������� ����� ������ <var>Guid</var> �������. <var>MenuGuid</var> �������� ������� � ��� �����, ���� ������ ������������ ����� ������ ������ ���.</p>
+       <p>���� ������ ����������� � ������ "�������� ��������" ��� ��� ����� �� �� ������� - ����� ������ �����.</p>
+       <p>����� ��������� 1 - ������/����� ������ ��� 0 - � ����� �����.</p>
+    </td>
+  </tr>
+
+  <tr>
+    <td>N=<dfn><a name="plugin.int">plugin.int</a></dfn>(Guid[,param])</td>
+    <td><p>����� ������ <dfn><a href="#callplugin">callplugin</a></dfn>.</p>
+    </td>
+  </tr>
+
+  <tr>
     <td>N=<dfn><a name="plugin.load">plugin.load</a></dfn>(DllPath[,ForceLoad])</td>
     <td><p>�������� ������ � ������ dll-����� <var>DllPath</var>. ���� ������ <var>ForceLoad</var>, ������ �� 0, �� ������ ���������� ����� � ����.</p>
        <p>����� ��������� 1 - ������ �������� ��� 0 - � ����� �����.</p>
@@ -1598,6 +1627,15 @@
   </tr>
 
   <tr>
+    <td>N=<dfn><a name="plugin.prefix">plugin.prefix</a></dfn>(Guid,Command)</td>
+    <td><p>������ ����� ������� �� �������� �� ������� ��� ������������ ���������/����/�������������� ������ ���������� ��������� ������.</p>
+       <p><var>Guid</var> ����� ��������� � ������� "Plugin information" (F3 � ������ F11 ��� AltShiftF9): ���� "Plugin GUID".</p>
+       <p>���� ������ � ����� <var>Guid</var> �� ������������ ���� �� �������� ��� ��� ����� �� �� ������� - ����� ������ �����.</p>
+       <p>����� ��������� 1 - ������/����� ������ ��� 0 - � ����� �����.</p>
+    </td>
+  </tr>
+
+  <tr>
     <td>N=<dfn><a name="plugin.unload">plugin.unload</a></dfn>(DllPath)</td>
     <td><p>������� ������ � ������ dll-����� <var>DllPath</var>.</p>
        <p>����� ��������� 1 - ������ ������� ��� 0 - � ����� �����.</p>
Html1.diff (3,496 bytes)   

Maximus

2012-03-12 12:30

reporter   bugnote:0008747

Патч 9.2 меня устраивает. Хелп приложил.

vskirdin

2012-03-12 17:36

administrator   bugnote:0008748

build 2540

zg

2012-03-12 18:50

developer   bugnote:0008749

1. на DMODE_NOPLUGINS проверять разве не надо?
2. что за функция такая Plugin.Int? получить целую часть плагина? не логичней ли Plugin.Call -> Plugin.Menu, Plugin.Int -> Plugin.Call?

Maximus

2012-03-12 18:59

reporter   bugnote:0008750

Last edited: 2012-03-12 19:05

zg, на счет Plugin.Menu, который я сначала предлагал :), смотри сюда
http://bugs.farmanager.com/view.php?id=1903#c7874

Plugin.Int - internal, interrupt. не только с целой частью Int ассоциируется.
Если callplugin удалять не будем (а то все грозитесь), то лично мне все-равно как она будет называться. Но если callplugin таки будет грохнут в пользу нового имени - у Plugin.Int "та же длина что и callplugin, мало ли, может в каком плагине патчить бинарник надо будет".

Maximus

2012-03-12 19:05

reporter   bugnote:0008751

> 1. на DMODE_NOPLUGINS проверять разве не надо?

Это не ко мне. В Callplugin он тоже не проверялся.

zg

2012-03-12 19:06

developer   bugnote:0008752

апи ещё не стабилизировано, какие бинарники?

vskirdin

2012-03-13 06:26

administrator   bugnote:0008753

DMODE_NOPLUGINS добавил.
Пошел заниматься переименованием: Plugin.Call -> Plugin.Menu, Plugin.Int -> Plugin.Call

vskirdin

2012-03-13 07:45

administrator   bugnote:0008754

build 2543

Maximus

2012-03-13 10:23

reporter   bugnote:0008755

Очепятка в хелпе.

А может, до кучи, и .Prefix таки переименовать? Например в .Command

ps. Plugin.Exists не по алфавиту :-P

Maximus

2012-03-13 10:50

reporter  

Html2.diff (464 bytes)   
Index: general.html
===================================================================
--- general.html	(revision 7701)
+++ general.html	(working copy)
@@ -1603,7 +1603,7 @@
   </tr>
 
   <tr>
-    <td>N=<dfn><a name="plugin.int">plugin.call</a></dfn>(Guid[,param])</td>
+    <td>N=<dfn><a name="plugin.call">plugin.call</a></dfn>(Guid[,param])</td>
     <td><p>������ ������ <dfn><a href="#callplugin">callplugin</a></dfn>.</p>
     </td>
   </tr>
Html2.diff (464 bytes)   

vskirdin

2012-03-13 11:00

administrator   bugnote:0008756

> А может, до кучи, и .Prefix таки переименовать? Например в .Command
А смысл? Тогда юзеры будут разуметь, что "Command" - для исполнения _всего_

> Plugin.Exists не по алфавиту
где? в macroopcode.hpp? там как бы пофигу, пока пофигу.

в macroopcode.hpp добавлять новое нужно в __конец__ "секций"
"секция" для функций начинается с KEY_MACRO_F_BASE
"секция" булевые переменные - с KEY_MACRO_C_BASE
сделано так для того, чтобы OpCode не изменяли своих значений (для случая, если байткод будет доступен плагнам :-))

DAtaMan

2012-03-13 17:12

reporter   bugnote:0008760

По поводу Plugin.Exists
А если добавить второй параметр - menuGuid?
Может понадобиться. Когда-нибудь... :-)

vskirdin

2012-03-13 19:02

administrator   bugnote:0008763

Когда понадобится, тогда и добавим...

JohnDoe

2012-03-15 07:53

updater   bugnote:0008768

>> А может, до кучи, и .Prefix таки переименовать? Например в .Command
>А смысл? Тогда юзеры будут разуметь, что "Command" - для исполнения _всего_
С чего бы им это так разуметь??
Никто ведь не разумеет что ".Select" в "Menu.Select" позволяет отмечать файлы на панели?

Приставка "Plugin." как бы намекает, не?
Вообще я за Plugin.Cmdline - "передать плагину командную строку"

А Plugin.Prefix как-то невнятно, типа "задать плагину какой-то префикс"

JohnDoe

2012-03-15 09:49

updater   bugnote:0008769

>По поводу Plugin.Exists
Ещё возможна ситуация когда плагин хоть существует, но его вызов из текущей макрообласти не предусмотрен.

vskirdin

2012-03-15 13:40

administrator   bugnote:0008771

Хмм... сейчас это не реализовано. Экзист просто говорит "есть"/"нет" плагин с таким гуидом. Здесь наверное нужен параметр... что-то типа "применим этот плагин к этой области, если такой плагин есть"...

JohnDoe

2012-03-15 14:06

updater   bugnote:0008773

Можно и без параметра, значением
0 - нет плагина
1 - есть но не применим к текущей макрообласти
2 - есть и применим
или 0, -1, 1

P.S.
Что насчёт предыдущего предложения? http://bugs.farmanager.com/view.php?id=1903#c8768

vskirdin

2012-03-20 09:33

administrator   bugnote:0008788

Last edited: 2012-03-20 09:34

build 2561
Plugin.Prefix переименован в Plugin.Cmdline

Под Exist заводите другой тикет

JohnDoe

2012-03-20 11:50

updater   bugnote:0008791

В энциклопедии сосуществуют Plugin.Call и Callplugin (причём ещё с SysID).
Как я понимаю Callpugin пора уже убирать. Вначале из Энциклопедии, а потом и из Фара.

vskirdin

2012-03-20 12:33

administrator   bugnote:0008794

в Писании убрал Callplugin.

NightRoman

2012-03-20 14:50

reporter   bugnote:0008795

Назовите, пожалуйста, Plugin.Command, а не Plugin.Cmdline, если это не принципиально по внутренним соображениям. Нет такого слова Cmdline, а Command есть, и это по разным причинам удобно. Конечно, это шашечки.

JohnDoe

2012-03-20 15:40

updater   bugnote:0008796

В фаре такое слово есть: http://google.com/search?q=cmdline%20site:api.farmanager.com

>это по разным причинам удобно
?

NightRoman

2012-03-20 15:55

reporter   bugnote:0008797

Вызов команды плагина к сущности командная строка прямого отношения не имеет. Команду можно вызывать из командной строки. А вот теперь и не только, можно из макроса. А потом еще откуда-то. Ну вам видней.

Maximus

2012-03-26 21:53

reporter   bugnote:0008826

Бага?
MacroLib, комплект с макросом (MacroLib.120326.7z) прилагается.
В панелях нажать, например, RAltA
Вызывается "callplugin", после завершения
if (CtrlObject->Plugins->CallPlugin(guid,OPEN_FROMMACRO,&info,&ResultCallPlugin))
содержимое переменной MR разрушено.

Maximus

2012-03-26 21:54

reporter  

MacroLib.120326.7z (51,245 bytes)

vskirdin

2012-03-28 10:02

administrator   bugnote:0008827

Возможно и баг.
Может какой нибудь тест попроще придумать, нежели MacroLib? Тяжко отлаживать (много отвлечений)...

JohnDoe

2014-06-10 10:49

updater   bugnote:0012496

Вроде бы всё реализовано, и незачем держать открытым?

Связанный тикет: 0002381

Issue History

Date Modified Username Field Change
2011-10-12 10:21 Maximus New Issue
2011-10-12 10:21 Maximus File Added: PluginMenu.diff
2011-10-12 10:56 JohnDoe Note Added: 0007867
2011-10-12 11:05 vskirdin Note Added: 0007868
2011-10-12 14:23 Maximus Note Added: 0007871
2011-10-12 16:41 Maximus Note Added: 0007872
2011-10-13 12:59 vskirdin Note Added: 0007874
2011-10-13 13:49 Maximus Note Added: 0007877
2011-10-13 17:38 vskirdin Note Added: 0007880
2011-10-14 12:21 Maximus Note Added: 0007881
2011-10-14 12:22 Maximus File Added: PluginCall.diff
2011-10-19 10:24 vskirdin Note Added: 0007910
2011-10-19 14:11 Maximus Note Added: 0007912
2011-10-19 15:04 JohnDoe Note Added: 0007914
2011-10-19 15:38 Maximus Note Added: 0007915
2011-10-19 16:15 vskirdin Note Added: 0007916
2011-10-19 20:25 JohnDoe Note Added: 0007919
2011-10-19 21:25 Maximus File Added: PluginCall2.diff
2011-10-19 21:27 Maximus File Added: PluginCall3.diff
2011-10-19 21:28 Maximus Note Added: 0007921
2011-10-20 12:44 Maximus Note Added: 0007930
2011-10-20 14:31 JohnDoe Note Added: 0007934
2011-10-20 18:27 Maximus Note Added: 0007936
2011-10-20 18:28 Maximus Note Added: 0007937
2011-10-20 21:44 max rusov Note Added: 0007939
2011-10-21 06:12 JohnDoe Note Added: 0007940
2011-10-21 10:52 Maximus Note Added: 0007943
2011-10-21 11:02 vskirdin Note Added: 0007944
2011-10-21 13:03 Maximus Note Added: 0007945
2011-10-21 13:09 max rusov Note Added: 0007946
2011-11-28 23:52 Maximus Note Added: 0008000
2011-11-29 11:13 Maximus Note Added: 0008001
2011-12-01 15:27 SUSim Note Added: 0008028
2011-12-02 06:58 Maximus Note Added: 0008032
2011-12-09 09:54 vskirdin Note Added: 0008115
2011-12-09 12:16 Maximus Note Added: 0008125
2011-12-09 13:31 JohnDoe Note Added: 0008130
2011-12-09 13:32 vskirdin Note Added: 0008132
2011-12-09 17:46 Maximus Note Added: 0008137
2011-12-11 14:47 SUSim Note Added: 0008138
2011-12-11 14:47 SUSim Note Edited: 0008138
2012-01-10 21:41 Maximus Note Added: 0008357
2012-01-10 21:41 Maximus File Added: PluginCall4.inf
2012-01-10 21:42 Maximus File Added: PluginCall4.diff
2012-01-11 07:00 vskirdin Note Added: 0008365
2012-01-11 07:04 Maximus Note Added: 0008367
2012-01-11 07:34 max rusov Note Added: 0008369
2012-01-11 16:38 SUSim Note Added: 0008379
2012-01-11 16:38 SUSim Note Edited: 0008379
2012-01-11 16:41 SUSim Note Edited: 0008379
2012-01-11 18:39 Maximus Note Added: 0008382
2012-02-13 15:20 JohnDoe Note Added: 0008560
2012-02-13 15:22 JohnDoe Note Edited: 0008560
2012-02-13 15:32 JohnDoe Note Edited: 0008560
2012-02-13 15:40 JohnDoe Note Edited: 0008560
2012-02-13 15:41 JohnDoe Note Added: 0008562
2012-02-13 16:36 JohnDoe Note Edited: 0008562
2012-02-13 17:22 Maximus Note Added: 0008564
2012-02-13 18:21 NightRoman Note Added: 0008565
2012-02-13 22:06 JohnDoe Note Added: 0008567
2012-02-13 23:00 JohnDoe Note Added: 0008568
2012-02-13 23:06 Maximus Note Added: 0008569
2012-02-14 09:43 JohnDoe Note Added: 0008570
2012-02-14 11:11 JohnDoe Note Edited: 0008570
2012-02-14 19:44 Maximus Note Added: 0008571
2012-02-15 11:47 JohnDoe Note Added: 0008576
2012-02-15 12:56 Maximus Note Added: 0008580
2012-02-15 15:53 JohnDoe Note Added: 0008582
2012-03-01 22:49 Maximus File Added: PluginCall5.diff
2012-03-01 22:53 Maximus Note Added: 0008661
2012-03-02 05:59 vskirdin Note Added: 0008668
2012-03-02 09:03 vskirdin Note Added: 0008673
2012-03-02 09:43 JohnDoe Note Added: 0008675
2012-03-02 13:41 Maximus File Added: PluginCall6.diff
2012-03-05 20:19 Maximus File Added: PluginCall7.diff
2012-03-05 20:20 Maximus Note Added: 0008706
2012-03-06 06:23 vskirdin Note Added: 0008709
2012-03-06 06:26 vskirdin Note Edited: 0008709
2012-03-06 06:29 vskirdin Note Edited: 0008709
2012-03-06 07:41 Maximus Note Added: 0008710
2012-03-06 09:12 JohnDoe Note Added: 0008711
2012-03-06 10:02 vskirdin Note Added: 0008712
2012-03-06 11:35 Maximus Note Added: 0008713
2012-03-06 11:43 JohnDoe Note Added: 0008714
2012-03-07 09:56 Maximus File Added: PluginCall8.diff
2012-03-07 10:57 vskirdin Note Added: 0008716
2012-03-11 23:18 Maximus File Added: PluginCall9.diff
2012-03-11 23:20 Maximus Note Added: 0008736
2012-03-12 08:45 vskirdin Note Added: 0008744
2012-03-12 10:33 vskirdin Note Added: 0008746
2012-03-12 12:25 Maximus File Added: Html1.diff
2012-03-12 12:30 Maximus Note Added: 0008747
2012-03-12 17:36 vskirdin Note Added: 0008748
2012-03-12 17:36 vskirdin Assigned To => vskirdin
2012-03-12 17:36 vskirdin Status new => feedback
2012-03-12 18:50 zg Note Added: 0008749
2012-03-12 18:59 Maximus Note Added: 0008750
2012-03-12 18:59 Maximus Status feedback => assigned
2012-03-12 19:05 Maximus Note Added: 0008751
2012-03-12 19:05 Maximus Note Edited: 0008750
2012-03-12 19:06 zg Note Added: 0008752
2012-03-13 06:26 vskirdin Note Added: 0008753
2012-03-13 07:45 vskirdin Note Added: 0008754
2012-03-13 07:45 vskirdin Status assigned => feedback
2012-03-13 10:23 Maximus Note Added: 0008755
2012-03-13 10:23 Maximus Status feedback => assigned
2012-03-13 10:50 Maximus File Added: Html2.diff
2012-03-13 11:00 vskirdin Note Added: 0008756
2012-03-13 17:12 DAtaMan Note Added: 0008760
2012-03-13 19:02 vskirdin Note Added: 0008763
2012-03-15 07:53 JohnDoe Note Added: 0008768
2012-03-15 09:49 JohnDoe Note Added: 0008769
2012-03-15 13:40 vskirdin Note Added: 0008771
2012-03-15 14:06 JohnDoe Note Added: 0008773
2012-03-20 09:33 vskirdin Note Added: 0008788
2012-03-20 09:33 vskirdin Status assigned => feedback
2012-03-20 09:34 vskirdin Note Edited: 0008788
2012-03-20 11:50 JohnDoe Note Added: 0008791
2012-03-20 12:33 vskirdin Note Added: 0008794
2012-03-20 14:50 NightRoman Note Added: 0008795
2012-03-20 15:40 JohnDoe Note Added: 0008796
2012-03-20 15:55 NightRoman Note Added: 0008797
2012-03-26 21:53 Maximus Note Added: 0008826
2012-03-26 21:53 Maximus Status feedback => assigned
2012-03-26 21:54 Maximus File Added: MacroLib.120326.7z
2012-03-28 10:02 vskirdin Note Added: 0008827
2013-02-03 00:33 alexy Severity minor => feature
2014-06-10 10:49 JohnDoe Note Added: 0012496
2014-10-02 14:55 shmuel Build => 0
2014-10-02 14:55 shmuel Status assigned => closed
2014-10-02 14:55 shmuel Resolution open => fixed
2014-10-02 14:55 shmuel Fixed in Version => 3.0