View Issue Details

IDProjectCategoryView StatusLast Update
0001914Far ManagerPlugins APIpublic2012-01-29 10:00
Reportermax rusov Assigned ToDrKnS  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Product Version3.0 
Fixed in Version3.0 
Summary0001914: Расширение PluginsControl - получение информации о плагинах
DescriptionПредлагаю добавить в PluginControl следующие команды:

1. PCTL_GETPLUGINS - Получение общей информации о плагинах. Пока - только количество. Param2 - указывает на FarPlugins.

2. PCTL_GETPLUGININFO - Получение информации о плагине по номеру. Param1 - номер плагина, Param2 - указывает на структуру FarGetPluginInfo. Под структуру требуется аллоцировать память, требуемый объем можно узнать вызывая PCTL_GETPLUGININFO c Param2 = null. Можно предварительно выделить буфер некоторого размера и вызвать команду указав размер буфера. Если его достаточно, то команда отработает, если нет - вернет требуемый размер. Вообщем - все как в FCTL_GETPANELITEM

3. PCTL_FINDPLUGIN - Получить индекс плагина по GUID или ModuleName. Param1 - FAR_PLUGIN_FIND_MODE, Param2 - ссылка на то по чему ищем.

Diff прилагается.

PS1.

Не до конца уверен что удачно описал структуру FarGetPluginInfo:

struct FarGetPluginInfo
{
    size_t Size;
    const wchar_t *ModuleName;
    FAR_PLUGIN_FLAGS Flags;
    struct GlobalInfo Info1;
    struct PluginInfo Info2;
};

Если есть предложения лучше - выслушаю.

PS2.

Давно не писал на C++, просьба сильно не пинать если что-то сделал неоптимально.
TagsNo tags attached.
Build2415

Activities

max rusov

2011-10-22 19:32

reporter  

PluginControl1.diff (7,890 bytes)   
Index: plugin.hpp
===================================================================
--- plugin.hpp	(revision 6817)
+++ plugin.hpp	(working copy)
@@ -1817,6 +1817,9 @@
 	PCTL_LOADPLUGIN         = 0,
 	PCTL_UNLOADPLUGIN       = 1,
 	PCTL_FORCEDLOADPLUGIN   = 2,
+	PCTL_GETPLUGINS         = 3,
+	PCTL_GETPLUGININFO      = 4,
+	PCTL_FINDPLUGIN         = 5
 };
 
 enum FAR_PLUGIN_LOAD_TYPE
@@ -1824,6 +1827,26 @@
 	PLT_PATH = 0,
 };
 
+enum FAR_PLUGIN_FIND_MODE
+{
+	PFM_GUID = 0,
+	PFM_MODULENAME = 1
+};
+
+typedef unsigned __int64 FAR_PLUGIN_FLAGS;
+static const FAR_PLUGIN_FLAGS
+	FPF_NONE           = 0,
+	FPF_FAR1           = 0x0000000000000001ULL,
+	FPF_FAR2           = 0x0000000000000002ULL,
+	FPF_LOADED         = 0x0000000000000004ULL;
+
+// PCTL_GETPLUGINS
+struct FarPlugins
+{
+	size_t StructSize;
+	int PluginsCount;
+};
+
 enum FAR_FILE_FILTER_CONTROL_COMMANDS
 {
 	FFCTL_CREATEFILEFILTER          = 0,
@@ -2310,7 +2333,17 @@
 };
 
 
+// PCTL_GETPLUGININFO
+struct FarGetPluginInfo
+{
+	size_t Size;
+	const wchar_t *ModuleName;
+	FAR_PLUGIN_FLAGS Flags;
+	struct GlobalInfo Info1;
+	struct PluginInfo Info2;
+};
 
+
 struct InfoPanelLine
 {
 	const wchar_t *Text;
Index: plugins.hpp
===================================================================
--- plugins.hpp	(revision 6817)
+++ plugins.hpp	(working copy)
@@ -228,6 +228,9 @@
 		bool SetHotKeyDialog(Plugin *pPlugin, const GUID& Guid, PluginsHotkeysConfig::HotKeyTypeEnum HotKeyType, const wchar_t *DlgPluginTitle);
 		void ShowPluginInfo(Plugin *pPlugin, const GUID& Guid);
 
+		// ������ ��������� � ������� ����� API ������������� ������������� (PCTL_GETPLUGININFO)
+		int GetPluginInfo(Plugin *pPlugin, FarGetPluginInfo *pInfo);
+
 		// $ .09.2000 SVS - ����� CallPlugin - ����� ������ �� ID � �������� OpenFrom = OPEN_*
 		int CallPlugin(const GUID& SysID,int OpenFrom, void *Data, int *Ret=nullptr);
 		Plugin *FindPlugin(const GUID& SysID);
Index: plugapi.cpp
===================================================================
--- plugapi.cpp	(revision 6817)
+++ plugapi.cpp	(working copy)
@@ -2403,6 +2403,49 @@
 
 			break;
 		}
+
+		case PCTL_GETPLUGINS:
+		{
+			FarPlugins* Info = (FarPlugins*)Param2;
+			if ((Info) && (Info->StructSize == sizeof(FarPlugins)))
+			{
+				Info->PluginsCount = CtrlObject->Plugins.GetPluginsCount();
+				return true;
+			}
+			break;
+		}
+
+		case PCTL_GETPLUGININFO:
+		{
+			FarGetPluginInfo* Info = (FarGetPluginInfo*)Param2;
+			/* ���� Info = null - ����� ������ ����������� ����� */
+			if ((!Info) || (Info->Size >= sizeof(FarGetPluginInfo)))
+			{
+				Plugin* Plug = CtrlObject->Plugins.GetPlugin(Param1);
+				if (Plug)
+					{ return CtrlObject->Plugins.GetPluginInfo(Plug, Info); }
+			}
+			break;
+		}
+
+		case PCTL_FINDPLUGIN:
+		{
+			for (int i = 0; i < CtrlObject->Plugins.GetPluginsCount(); i++)
+			{
+				Plugin* Plug = CtrlObject->Plugins.GetPlugin(i);
+				if (Param1 == PFM_GUID)
+				{
+					if (Plug->GetGUID() == *(GUID*)Param2)
+						{ return i; }
+				}
+				else if (Param1 == PFM_MODULENAME)
+				{
+					if (StrCmpI(Plug->GetModuleName(), (wchar_t*)Param2) == 0)
+						{ return i; }
+				}
+			}
+			return -1;
+		}
 	}
 
 	return 0;
Index: plugins.cpp
===================================================================
--- plugins.cpp	(revision 6817)
+++ plugins.cpp	(working copy)
@@ -1903,6 +1903,164 @@
 	Builder.ShowDialog();
 }
 
+
+char* BufReserve(char*& Buf, int Count, int& Rest, int& Size)
+{
+	char* Res = nullptr;
+
+	if (Buf)
+	{
+		if (Rest >= Count)
+		{
+			Res = Buf;
+			Buf += Count;
+			Rest -= Count;
+		}
+		else
+		{
+			Buf += Rest;
+			Rest = 0;
+		}
+	}
+
+	Size += Count;
+	return Res;
+}
+
+
+wchar_t* StrToBuf(const string& Str, char*& Buf, int& Rest, int& Size)
+{
+	int Count = (Str.GetLength() + 1) * sizeof(wchar_t);
+	wchar_t* Res = (wchar_t*)BufReserve(Buf, Count, Rest, Size);
+
+	if (Res)
+		{ wcscpy(Res, Str);	}
+
+	return Res;
+}
+
+
+void ItemsToBuf(PluginMenuItem& Menu, TArray<string> &NamesArray, TArray<string> &GuidsArray, char*& Buf, int& Rest, int& Size)
+{
+  	Menu.Count = NamesArray.getSize();
+	Menu.Strings = nullptr;
+	Menu.Guids = nullptr;
+
+	if (Menu.Count)
+	{
+		wchar_t** Items = (wchar_t**)BufReserve(Buf, Menu.Count * sizeof(wchar_t*), Rest, Size);
+		GUID* Guids = (GUID*)BufReserve(Buf, Menu.Count * sizeof(GUID), Rest, Size);
+  		Menu.Strings = Items;
+		Menu.Guids = Guids;
+
+		for (int i = 0; i < Menu.Count; i++)
+		{
+  			wchar_t* pStr = StrToBuf(*NamesArray.getItem(i), Buf, Rest, Size);
+			if (Items) 
+				Items[i] = pStr;
+
+			GUID Guid;
+  			if (StrToGuid(*GuidsArray.getItem(i), Guid))
+				Guids[i] = Guid;
+		}
+	}
+}
+
+
+int PluginManager::GetPluginInfo(Plugin *pPlugin, FarGetPluginInfo *pInfo)
+{
+	string Prefix;
+	PLUGIN_FLAGS Flags = 0;
+	TArray<string> MenuNames, MenuGuids, DiskNames, DiskGuids, ConfNames, ConfGuids;
+
+	if (pPlugin->CheckWorkFlags(PIWF_CACHED))
+	{
+		int i;
+		string Name, Guid;
+		unsigned __int64 id = PlCacheCfg->GetCacheID(pPlugin->GetCacheName());
+
+		Flags = PlCacheCfg->GetFlags(id);
+  		Prefix = PlCacheCfg->GetCommandPrefix(id);
+
+		i = 0;
+		while (PlCacheCfg->GetPluginsMenuItem(id, i++, Name, Guid))
+			{ MenuNames.addItem(Name); MenuGuids.addItem(Guid); }
+
+		i = 0;
+		while (PlCacheCfg->GetDiskMenuItem(id, i++, Name, Guid))
+			{ DiskNames.addItem(Name); DiskGuids.addItem(Guid); }
+
+		i = 0;
+		while (PlCacheCfg->GetPluginsConfigMenuItem(id, i++, Name, Guid))
+			{ ConfNames.addItem(Name); ConfGuids.addItem(Guid); }
+	}
+	else
+	{
+		PluginInfo Info = {sizeof(Info)};
+		if (pPlugin->GetPluginInfo(&Info))
+		{
+			Flags = Info.Flags;
+			Prefix = Info.CommandPrefix;
+
+			for (int i = 0; i < Info.PluginMenu.Count; i++)
+				{ MenuNames.addItem(Info.PluginMenu.Strings[i]); MenuGuids.addItem(GuidToStr(Info.PluginMenu.Guids[i])); }
+
+			for (int i = 0; i < Info.DiskMenu.Count; i++)
+				{ DiskNames.addItem(Info.DiskMenu.Strings[i]); DiskGuids.addItem(GuidToStr(Info.DiskMenu.Guids[i])); }
+
+			for (int i = 0; i < Info.PluginConfig.Count; i++)
+				{ ConfNames.addItem(Info.PluginConfig.Strings[i]); ConfGuids.addItem(GuidToStr(Info.PluginConfig.Guids[i])); }
+		}
+	}
+
+	//------------------------------------
+
+	FarGetPluginInfo Temp;
+	char* Buf = nullptr;
+	int Rest = 0;
+
+	if (pInfo)
+	{
+		Rest = pInfo->Size - sizeof(FarGetPluginInfo);
+		Buf = (char*)pInfo + sizeof(FarGetPluginInfo);
+	}
+	else
+	{
+		pInfo = &Temp;
+	}
+
+	int Size = sizeof(FarGetPluginInfo);
+
+	pInfo->ModuleName = StrToBuf(pPlugin->GetModuleName(), Buf, Rest, Size);
+
+	pInfo->Flags = 0;
+#ifndef NO_WRAPPER
+	if (pPlugin->IsOemPlugin())
+		pInfo->Flags |= FPF_FAR1;
+#endif // NO_WRAPPER
+	if (pPlugin->m_hModule)
+		pInfo->Flags |= FPF_LOADED;
+
+	pInfo->Info1.StructSize = sizeof(GlobalInfo);
+	pInfo->Info1.Guid = pPlugin->GetGUID();
+	pInfo->Info1.Version = pPlugin->GetVersion();
+	pInfo->Info1.Title = StrToBuf(pPlugin->strTitle, Buf, Rest, Size);
+	pInfo->Info1.Description = StrToBuf(pPlugin->strDescription, Buf, Rest, Size);
+	pInfo->Info1.Author = StrToBuf(pPlugin->strAuthor, Buf, Rest, Size);
+
+	pInfo->Info2.StructSize = sizeof(PluginInfo);
+	pInfo->Info2.Flags = Flags;
+	pInfo->Info2.CommandPrefix = StrToBuf(Prefix, Buf, Rest, Size);
+
+	ItemsToBuf(pInfo->Info2.DiskMenu, DiskNames, DiskGuids, Buf, Rest, Size);
+	ItemsToBuf(pInfo->Info2.PluginMenu, MenuNames, MenuGuids, Buf, Rest, Size);
+	ItemsToBuf(pInfo->Info2.PluginConfig, ConfNames, ConfGuids, Buf, Rest, Size);
+
+	return Size;
+}
+
+
+
 bool PluginManager::GetDiskMenuItem(
      Plugin *pPlugin,
      int PluginItem,
PluginControl1.diff (7,890 bytes)   

zg

2011-10-23 20:31

developer   bugnote:0007956

правильно ли я понимаю, что эта функциональность для реализации PlugMenu, а плагины планируется вызывать через макрос с Plugin.Call?

max rusov

2011-10-23 22:38

reporter   bugnote:0007957

Да, для PlugMenu, или аналогичных плагинов. Для вызова я хотел бы еще добавить PCTL_PLUGINCALL, когда будет принят http://bugs.farmanager.com/view.php?id=1903 Там, вроде, уже есть все необходимое (CallPluginItem)...

max rusov

2011-10-30 19:05

reporter   bugnote:0007964

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

DrKnS

2011-10-31 07:42

administrator   bugnote:0007965

+ if ((Info) && (Info->StructSize == sizeof(FarPlugins)))

тут, наверное, >= ?


+ FPF_FAR2 = 0x0000000000000002ULL,

зачем?

max rusov

2011-10-31 08:13

reporter   bugnote:0007966

Last edited: 2011-10-31 08:13

> + if ((Info) && (Info->StructSize == sizeof(FarPlugins)))
> тут, наверное, >= ?

Вообще-то нет. Как я понимаю смысл StructSize, в будущих версиях API могут добавляться новые поля, про которые старые плагины не знают. Поэтому FAR будет контролировать StructSize, чтобы не затереть старым плагинам стек. Поэтому тут в будущем может быть что-то типа:

(Info->StructSize == sizeofFarPluginsVer1)||(Info->StructSize == sizeofFarPluginsVer2)||(Info->StructSize == sizeof(FarPlugins))

> + FPF_FAR2 = 0x0000000000000002ULL,
> зачем?

На всякий случай. Вдруг Wrapper для Far2 плагинов включат в ядро

max rusov

2011-12-22 09:37

reporter   bugnote:0008184

Up. Раз уже сборки есть - хотелось бы применить патч.

SUSim

2012-01-07 13:09

reporter   bugnote:0008320

+1 вроде понятный патч(скорее аддон)и ничему не мешает... или у Фартим по этому поводу более продвинутая стратегия?

fibre

2012-01-07 22:15

reporter   bugnote:0008324

+1
(за плагин PlugMenu).

Denis

2012-01-08 10:05

reporter   bugnote:0008325

+1

daf

2012-01-10 11:32

reporter   bugnote:0008339

+1

DrKnS

2012-01-26 17:17

administrator   bugnote:0008483

С некоторыми уточнениями - 2415

max rusov

2012-01-28 23:02

reporter   bugnote:0008500

Ok. Переделал PlugMenu под новое API, вроде все работает. Можно закрывать.

Issue History

Date Modified Username Field Change
2011-10-22 19:32 max rusov New Issue
2011-10-22 19:32 max rusov File Added: PluginControl1.diff
2011-10-23 20:31 zg Note Added: 0007956
2011-10-23 22:38 max rusov Note Added: 0007957
2011-10-30 19:05 max rusov Note Added: 0007964
2011-10-31 07:42 DrKnS Note Added: 0007965
2011-10-31 08:13 max rusov Note Added: 0007966
2011-10-31 08:13 max rusov Note Edited: 0007966
2011-12-22 09:37 max rusov Note Added: 0008184
2012-01-07 13:09 SUSim Note Added: 0008320
2012-01-07 22:15 fibre Note Added: 0008324
2012-01-08 10:05 Denis Note Added: 0008325
2012-01-10 11:32 daf Note Added: 0008339
2012-01-26 17:17 DrKnS Note Added: 0008483
2012-01-26 17:17 DrKnS Assigned To => DrKnS
2012-01-26 17:17 DrKnS Status new => feedback
2012-01-28 23:02 max rusov Note Added: 0008500
2012-01-28 23:02 max rusov Status feedback => assigned
2012-01-29 10:00 DrKnS Build => 2415
2012-01-29 10:00 DrKnS Status assigned => closed
2012-01-29 10:00 DrKnS Resolution open => fixed
2012-01-29 10:00 DrKnS Fixed in Version => 3.0