View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001914 | Far Manager | Plugins API | public | 2011-10-22 19:32 | 2012-01-29 10:00 |
| Reporter | max rusov | Assigned To | DrKnS | ||
| Priority | normal | Severity | minor | Reproducibility | have not tried |
| Status | closed | Resolution | fixed | ||
| Product Version | 3.0 | ||||
| Fixed in Version | 3.0 | ||||
| Summary | 0001914: Расширение 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++, просьба сильно не пинать если что-то сделал неоптимально. | ||||
| Tags | No tags attached. | ||||
| Build | 2415 | ||||
|
|
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,
|
|
|
правильно ли я понимаю, что эта функциональность для реализации PlugMenu, а плагины планируется вызывать через макрос с Plugin.Call? |
|
|
Да, для PlugMenu, или аналогичных плагинов. Для вызова я хотел бы еще добавить PCTL_PLUGINCALL, когда будет принят http://bugs.farmanager.com/view.php?id=1903 Там, вроде, уже есть все необходимое (CallPluginItem)... |
|
|
Ну, что, правки будем принимать? PlugMenu уже работает... |
|
|
+ if ((Info) && (Info->StructSize == sizeof(FarPlugins))) тут, наверное, >= ? + FPF_FAR2 = 0x0000000000000002ULL, зачем? |
|
|
> + 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 плагинов включат в ядро |
|
|
Up. Раз уже сборки есть - хотелось бы применить патч. |
|
|
+1 вроде понятный патч(скорее аддон)и ничему не мешает... или у Фартим по этому поводу более продвинутая стратегия? |
|
|
+1 (за плагин PlugMenu). |
|
|
+1 |
|
|
+1 |
|
|
С некоторыми уточнениями - 2415 |
|
|
Ok. Переделал PlugMenu под новое API, вроде все работает. Можно закрывать. |
| 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 |