View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001914 | Far Manager | Plugins API | public | 2011-10-22 20: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 20:32 | max rusov | New Issue | |
2011-10-22 20:32 | max rusov | File Added: PluginControl1.diff | |
2011-10-23 21:31 | zg | Note Added: 0007956 | |
2011-10-23 23: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 |