View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001903 | Wishes | Macro | public | 2011-10-12 11:21 | 2014-10-02 15:55 |
Reporter | Maximus | Assigned To | vskirdin | ||
Priority | normal | Severity | feature | Reproducibility | have not tried |
Status | closed | Resolution | fixed | ||
Product Version | 3.0 | ||||
Fixed in Version | 3.0 | ||||
Summary | 0001903: Plugin.Menu(guid,menuGuid) | ||||
Description | Собстно, надоело макросить вызов плагинов через F11. предлагаемая функция - аналогична обычному вызову пункта меню плагина, но в обход открытия всего списка и позиционирования куда надо или выбора хоткея в отличие от callplugin - выполнение макроса не останавливается, как и при F11 позвать плагин откуда он не ожидает - не получится, проверки области такие же как при населении списка F11 | ||||
Tags | No tags attached. | ||||
Build | 0 | ||||
|
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*) |
|
А ведь грядёт и ProcessMacroFuncW. Не будет ли Plugin.Menu избыточным? |
|
что есть первый параметр, что есть второй? примеры в студию |
|
не будет. каким макаром ты позовешь плаг, который НЕ экспортирует эту функцию, а расчитан только на вызов из меню? guid и menuGuid - очевидно гуиды в строковом виде из F11 F3 первый - гуид плагина второй - гуид пункта меню плагина |
|
пример - вызвать colorer outliner: plugin.Menu("D2F36B62-A470-418D-83A3-ED7A3710E5B5","45453CAC-499D-4B37-82B8-0A77F7BD087C") 5 |
|
Не нравится мне это название "Plugin.Menu" - смотря на него, ожидаешь появление какого-то плагинового меню. Надо что-то другое... А что будет, если у плагина нет "стартового" меню (про второй параметр)? Плюс к этому... плагин не будет знать, что его вызвали из макроса (OpenCode). Хотя... может это и ненадо. Помыслил... тогда нужна парная функция - вызов конфигуратора конкретного плагина (по аналогии - есть PluginManager::CommandsMenu и есть PluginManager::Configure). |
|
plugin.call(), plugin.configure()? если плагин не отдает пункт menuGuid в F11 - вызываться он не должен (поправлю) |
|
ок |
|
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", то есть ошибку, хотя все успешно отработало |
|
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]]) |
|
подумалось... может 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 зерно в отдельную функцию и... |
|
багу поправил. > по поводу пятого - чтобы плагин понимал, что ему подсунули: число, строку или макропоследовательность (которую плагин подсунет фару). ничего не понял. какая макропоследовательность? новая предлагаемая фича? число или строка - макродвижок вроде и без дополнительных параметров может понять если убирать callplugin - мне видится как-то так: plugin.call(type,guid[,item]) type - 0|1 - синхронный|ассинхронный guid - плагин item - зависит от type 0: то что в callplugin было 1: гуид пункта меню. если не указан, будет выполнен первый пункт плагина, если он всего один(!) |
|
Может не убирать callplugin, а просто переименовать покрасивше? |
|
чего? |
|
а чем не устраивает plugin.call(0,guid,значение) == callplugin(guid,значение) ? |
|
Не нравится что суть значения приципиально разная, т.е. скрещивается уж с ежом. Создаётся видимость будто пользователь может выбрать синхроность/асинхронность. Но ведь "синхронно" можно вызвать только плагины специально под это заточенные. Имхо это слишком разные вещи чтобы объединять их в 1. |
|
|
|
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 - пока только багу поправил с незагруженным плагином |
|
> Не нравится что суть значения приципиально разная, т.е. скрещивается уж с ежом. Наоборот, одинаковая. Суть одна и та же - вызвать плагин. ты же не предлагаеешь разделить edit.sel на две функции на том основании, что обычные и вертикальные блоки - суть разные вещи. > Создаётся видимость будто пользователь может выбрать синхроность/асинхронность Если юзер думать не умеет, фар ему в этом не поможет. У тебя же не создается такая видимость из-за наличия функции callplugin? imho - callplugin убить, и добавить параметр в plugin.call - самое то |
|
>Если юзер думать не умеет, фар ему в этом не поможет. Юзер не знает о "синхронности" и "асинхронности", и знать (по хорошему) не должен. И если фар будет таки принуждать его об этом задумаваться - ничего хорощего в этом нет. Может я сам чего не понимаю. Зачем вообще юзеру эта "синхронность"? |
|
Ладно, пойдем другим путем. Юзеру не нужно знать про функцию callplugin? > Зачем вообще юзеру эта "синхронность"? Вот пристал ;) Забудь про синхронность асинхронность. Один режим - аналогичен вызову плагина из F11 Второй режим - специфический, о его использовании консультируйтесь с автором плагина или читайте в документации о плагине. Вот. |
|
> И если фар будет таки принуждать его об этом задумаваться - ничего хорощего в этом нет. Использование макроязыка по определению принуждает задумываться. Не? |
|
Если планируется работа в этом направлении, то может стоит сделать так, чтобы синхронный вызов plugin.call мог возвращать любые данные, а не только признак успешности вызова?... |
|
> Юзеру не нужно знать про функцию callplugin? Лучше бы не знать. >Забудь про синхронность асинхронность. Да, так будет лучше. >Второй режим - специфический, о его использовании... Вот именно. Он специфический, и поэтому я и предложил не объединять. >Использование макроязыка по определению принуждает задумываться. Не? Но ведь не о смысле жизни. Макроязык он и для домохозяек тоже. |
|
> так, чтобы синхронный вызов plugin.call мог возвращать любые данные, а не только признак успешности вызова?... каким образом фар отличит тип результата: число от строки? и главное, нафига, если таки будет открыта ProcessMacroFunctionW? 2vskirdin: а почему, кстати, она до сих пор не открыта? |
|
как обычно - работа мешает и фактор времени :-( после отпуска постараюсь продолжить. |
|
Не, я к тому, чего там не хватает для "релиза"? |
|
>каким образом фар отличит тип результата: число от строки? Можно добавить в OpenInfo: struct FarMacroValue Result; Недавно делалось подобное - DN_GETVALUE... >и главное, нафига, если таки будет открыта ProcessMacroFunctionW? Если будет - то, может и незачем. |
|
возвращаясь к нашим баранам... 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") - аналог входа в архив |
|
или предлагаемые отдельными функциями оформить? или все-таки "все в одном" сделать... |
|
Скромное имхо: написание макроса с вызовом плагина без простого "F11 и т.д." - УЖЕ требует от писателя этого макроса продвинутости, и разветвлять вызов макросов на те которые доступны из меню, и те которые отдадут ид для калплугин не стоит, лишнее усложнение макроязыка... - я буду вызывать плагин по ГУИД плагина, который вроде как обязателен. (я бы с удовольствием вызывал плагин макроедит по плугинид, а не по менюид, потому что он недоступен из меню плагинов для диалогов, хотя там ему ни что не мешает работать!) |
|
я что-то не понял смысл этого имхо и к чему оно. Про "макроедит" вообще не в тему. Фар не должен (и не будет) предоставлять возможность вызвать плагин оттуда, откуда он не ожидает. Кроме того, полезность данного плагина в нынешних реалиях вообще под сомнением. |
|
конечный итог какой? |
|
хм, вот и мне интересно, какой? поскольку всем пофиг - доработаю патч как я его вижу, и выложу |
|
Не пофиг. >банально сложнее описать использование (например, запутаться в Edit.sel оч.просто) Золотые слова. Очень простой и эффективный критерий: если вам сложно описать, значит и пользователю сложно понять. Собственно эту мысль я и пытался донести, и именно поэтому не стоит городить монструозные функции. |
|
Как ты его видишь? 1 функция, 2 функции, ... ? |
|
склоняюсь к варианту: одна функция на одно действие т.е. plugin.call/config/cmd/... только во что переименовать callplugin? IntCall? |
|
читал, думал, склоняюсь к варианту разделения: plugin.call = F11... plugin.cfg = F9->Параметры плагинов... plugin.cmd = Префикс plugin.Exec = callplugin |
|
Следующее приближение 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 грохнуть?) |
|
|
|
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); |
|
а почему "Int"? |
|
По аналогии с asm-ом. Ну или типа "Internal". Ничего лучше пока не придумал. |
|
Может: Plugin.call -> Plugin.Open Plugin.Int -> Plugin.Call |
|
Параметры я, просто, не расписывал... в приближении Maximus они логичны... Int мне не нравится - Exec лучше :) Open - тем более, не нравится (что значит "открыть"?) Я бы Plugin.Call поменял бы на Plugin.Run - "запустить плагин и дальше разбирайтесь своими макросами с плагином"; Plugin.Int на plugin.Exec(Guid,Command) - "плагин выполни такую-то команду! и без вопрсов :), просто скажи, в возвращаемом результате, получилось или нет, и если нет, то укажи код причины". |
|
По мне, так ".Run" и ".Exec" ассоциируются с командной строкой. Так что оба - не нравятся. ".Open" тоже как-то... Что открыть? А если плагин ничего не открывает? Из редактора, например :) |
|
Мне нет разницы как будет называться 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 |
|
Ещё вроде бы решили что callplugin надо не переименовывать, а удавить "заменив на новую всем удобную функцию": * http://forum.farmanager.com/viewtopic.php?p=75799#p75799 * http://forum.farmanager.com/viewtopic.php?p=76599#p76599 |
|
На счет "bis". Патч могу хоть сейчас выкатить, но есть у меня смутное подозрение, что там что-то не того случается с макродвижком. Хотя вроде и работает... > В любом случае название не очень, потому что "префикс" как действие не имеет смысла. > Если наша цель передать плагину строку параметров, то лучше назвать это Plugin.Cmdline. Против ".cmdline" ничего не имею. Перечитывать ветку в поиске критики как-то не очень. В текущей версии "Plugin.Prefix" может быть выполнен только тогда, когда доступна командная строка. И, считаю, это правильно. Поэтому не "Exec" - плагин не должен получать управление тогда, когда этого не ожидает. > Ещё вроде бы решили что callplugin надо не переименовывать, а удавить Кто решил? Вам бы все давить. ProcessMacroFunctionW похоже еще долго не будет доступна. |
|
Не надо давить callplugin. У меня нормальная работа и механизмы тестирования своей (и неявно Фаровской) кухни все завязаны на callplugin с потрохами. |
|
NightRoman Я лично ничего не собираюсь давить, а всего лишь обращаю внимание на существование более ранних обсуждений, в которых такие намерения прозвучали от представителя команды, и тогда никто из участников не спорил (а все участники между прочим те же что и здесь). В любом случае, вначале должна появиться адекватная замена, так что бояться нечего. |
|
Maximus В таком случае зачем нам вообще ещё один отдельный запуск по префиксу, раз командная строка и так доступна? |
|
hint: командная строка может быть и не пустой |
|
Ctrl-G А если серьёзно, то опять же предлагаю более универсальный Exec. Потому что эта функция была по тем же причинам точно так же полезна для запуска всего, а не только плагинов. |
|
Я так понял, что про "Ctrl-G" ты несерьезно? "Exec" есть совершенный офтопик в данном више. Предлагаемый набор функций предназначен для руления конкретным плагином. |
|
Но есть мнение, что функция руления конкретным плагином посредством указания командной строки просто избыточна. И по функциональности перекрывается гипотетической Exec, которая тут конечно оффтопик, её обсуждаем тут: 0002021 (и на форуме: http://forum.farmanager.com/viewtopic.php?f=15&t=6153) |
|
Я бы не сказал, что она избыточна. Есть (будет) комплект функций для руления конкретным плагином. Как-то нелогично делать две "plugin.call" и plugin.config" оставляя "callplugin" и добавляя "гипотетическую" (кто ее делать-то будет?) "Exec". В общем, свое имхо по юзабилити я высказал. Лично мне была нужна только "plugin.call" |
|
> ...оставляя "callplugin" Не ясен текущий статус этой функции. Если её планируется оставить (в текущем или доработанном виде), то конечно она должна быть частью этого комплекта функций. Поднял вопрос на форуме: http://forum.farmanager.com/viewtopic.php?p=90845#p90845 |
|
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; |
|
пятая версия. Код причесан и допилен до текущего билда фара. Все вызовы новых функций перенаправлены в новую PluginManager::CallPluginItem Если плагин показывает только один пункт меню, для функций Plugin.Call и Plugin.Config можно указать только первый параметр - гуид плагина. Plugin.Int - по желанию, добавлен до кучи как алиас к callplugin. еще один довод к ее названию (если уж переименовать соберетесь) - та же длина что и callplugin, мало ли, может в каком плагине патчить бинарник надо будет... |
|
http://skirda-file.googlecode.com/files/mantis0001903.1.7z |
|
Maximus, сюда бы еще приаттачить патч для вот этого файла: https://farmanager.com/svn/trunk/enc/enc_rus3.work/meta/macro/macrocmd/prop_func/general.html с описанием 4-х новых функций |
|
Чего торопиться пока обсуждение этого хозяйства не закончено. В частности некоторые имена. |
|
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; |
|
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); |
|
так вроде правильнее |
|
Правильно я понял, что у Plugin.Call, Plugin.Config и Plugin.Prefix предполагается только 2 параметра? Так же - mmode(3) здесь тоже будет учитывается или нет? Я вот про это: int CallPluginRules=1; //GetCurrentCallPluginMode(); И... на будущее :-) Давайте в массиве intMacroFunction придерживаться алфавитной сортировки... UPD: а в macroopcode.hpp - добавлять в конец секций UPD2: и, наверное, в PluginManager::CallPluginItem задействовать Ret/ |
|
Ну да, только 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? |
|
>вот только не уверен, что вообще нужно ограничивать плагины в плане макросов У меня идея обратная: по умолчанию ничего не ограничено - mmode(3,1), а если нужно дождаться завершения плагина, то используем mmode(3,0). >И чему в этом случае будет равен %r? А зачем нам вообще возвращаемое значение? При отсутствии плагина фатальная ошибка и всё на этом. |
|
тестируем (на основе PluginCall7.diff) http://skirda-file.googlecode.com/files/mantis0001903.2.7z здесь так же mmode(3,1) по умолчанию включен |
|
> по умолчанию ничего не ограничено - mmode(3,1), а если нужно дождаться завершения плагина, то используем mmode(3,0). наверное, это правильно. > При отсутствии плагина фатальная ошибка и всё на этом хорошо бы. но смысла нет. хотя... проверить, погонять надо... |
|
>хорошо бы. но смысла нет. В чём нет смысла? |
|
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) http://skirda-file.googlecode.com/files/mantis0001903.3.7z здесь так же mmode(3,1) по умолчанию включен |
|
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); |
|
Продолжение банкета. Теперь можно сразу использовать код возврата (Call/Config/Prefix). 1 - плагин/пункт найден, 0 - не найден. Новые непонятки: http://forum.farmanager.com/viewtopic.php?p=92609#p92609 |
|
Тестим http://skirda-file.googlecode.com/files/mantis0001903.4.7z 2Maximus: патч внутри архива - синхронизируйся со своими сорцами |
|
Я так понимаю, что чем дальше, тем стабильнее и... с логикой определились? Тогда предлагаю зафиксировать 9-ю версию с моими уточнениями, а дальше отлаживать as is, ибо тестовые билды как то не тестируются (судя по скачиванию)... |
|
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> |
|
Патч 9.2 меня устраивает. Хелп приложил. |
|
build 2540 |
|
1. на DMODE_NOPLUGINS проверять разве не надо? 2. что за функция такая Plugin.Int? получить целую часть плагина? не логичней ли Plugin.Call -> Plugin.Menu, Plugin.Int -> Plugin.Call? |
|
zg, на счет Plugin.Menu, который я сначала предлагал :), смотри сюда http://bugs.farmanager.com/view.php?id=1903#c7874 Plugin.Int - internal, interrupt. не только с целой частью Int ассоциируется. Если callplugin удалять не будем (а то все грозитесь), то лично мне все-равно как она будет называться. Но если callplugin таки будет грохнут в пользу нового имени - у Plugin.Int "та же длина что и callplugin, мало ли, может в каком плагине патчить бинарник надо будет". |
|
> 1. на DMODE_NOPLUGINS проверять разве не надо? Это не ко мне. В Callplugin он тоже не проверялся. |
|
апи ещё не стабилизировано, какие бинарники? |
|
DMODE_NOPLUGINS добавил. Пошел заниматься переименованием: Plugin.Call -> Plugin.Menu, Plugin.Int -> Plugin.Call |
|
build 2543 |
|
Очепятка в хелпе. А может, до кучи, и .Prefix таки переименовать? Например в .Command ps. Plugin.Exists не по алфавиту :-P |
|
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> |
|
> А может, до кучи, и .Prefix таки переименовать? Например в .Command А смысл? Тогда юзеры будут разуметь, что "Command" - для исполнения _всего_ > Plugin.Exists не по алфавиту где? в macroopcode.hpp? там как бы пофигу, пока пофигу. в macroopcode.hpp добавлять новое нужно в __конец__ "секций" "секция" для функций начинается с KEY_MACRO_F_BASE "секция" булевые переменные - с KEY_MACRO_C_BASE сделано так для того, чтобы OpCode не изменяли своих значений (для случая, если байткод будет доступен плагнам :-)) |
|
По поводу Plugin.Exists А если добавить второй параметр - menuGuid? Может понадобиться. Когда-нибудь... :-) |
|
Когда понадобится, тогда и добавим... |
|
>> А может, до кучи, и .Prefix таки переименовать? Например в .Command >А смысл? Тогда юзеры будут разуметь, что "Command" - для исполнения _всего_ С чего бы им это так разуметь?? Никто ведь не разумеет что ".Select" в "Menu.Select" позволяет отмечать файлы на панели? Приставка "Plugin." как бы намекает, не? Вообще я за Plugin.Cmdline - "передать плагину командную строку" А Plugin.Prefix как-то невнятно, типа "задать плагину какой-то префикс" |
|
>По поводу Plugin.Exists Ещё возможна ситуация когда плагин хоть существует, но его вызов из текущей макрообласти не предусмотрен. |
|
Хмм... сейчас это не реализовано. Экзист просто говорит "есть"/"нет" плагин с таким гуидом. Здесь наверное нужен параметр... что-то типа "применим этот плагин к этой области, если такой плагин есть"... |
|
Можно и без параметра, значением 0 - нет плагина 1 - есть но не применим к текущей макрообласти 2 - есть и применим или 0, -1, 1 P.S. Что насчёт предыдущего предложения? http://bugs.farmanager.com/view.php?id=1903#c8768 |
|
build 2561 Plugin.Prefix переименован в Plugin.Cmdline Под Exist заводите другой тикет |
|
В энциклопедии сосуществуют Plugin.Call и Callplugin (причём ещё с SysID). Как я понимаю Callpugin пора уже убирать. Вначале из Энциклопедии, а потом и из Фара. |
|
в Писании убрал Callplugin. |
|
Назовите, пожалуйста, Plugin.Command, а не Plugin.Cmdline, если это не принципиально по внутренним соображениям. Нет такого слова Cmdline, а Command есть, и это по разным причинам удобно. Конечно, это шашечки. |
|
В фаре такое слово есть: http://google.com/search?q=cmdline%20site:api.farmanager.com >это по разным причинам удобно ? |
|
Вызов команды плагина к сущности командная строка прямого отношения не имеет. Команду можно вызывать из командной строки. А вот теперь и не только, можно из макроса. А потом еще откуда-то. Ну вам видней. |
|
Бага? MacroLib, комплект с макросом (MacroLib.120326.7z) прилагается. В панелях нажать, например, RAltA Вызывается "callplugin", после завершения if (CtrlObject->Plugins->CallPlugin(guid,OPEN_FROMMACRO,&info,&ResultCallPlugin)) содержимое переменной MR разрушено. |
|
|
|
Возможно и баг. Может какой нибудь тест попроще придумать, нежели MacroLib? Тяжко отлаживать (много отвлечений)... |
|
Вроде бы всё реализовано, и незачем держать открытым? Связанный тикет: 0002381 |
Date Modified | Username | Field | Change |
---|---|---|---|
2011-10-12 11:21 | Maximus | New Issue | |
2011-10-12 11:21 | Maximus | File Added: PluginMenu.diff | |
2011-10-12 11:56 | JohnDoe | Note Added: 0007867 | |
2011-10-12 12:05 | vskirdin | Note Added: 0007868 | |
2011-10-12 15:23 | Maximus | Note Added: 0007871 | |
2011-10-12 17:41 | Maximus | Note Added: 0007872 | |
2011-10-13 13:59 | vskirdin | Note Added: 0007874 | |
2011-10-13 14:49 | Maximus | Note Added: 0007877 | |
2011-10-13 18:38 | vskirdin | Note Added: 0007880 | |
2011-10-14 13:21 | Maximus | Note Added: 0007881 | |
2011-10-14 13:22 | Maximus | File Added: PluginCall.diff | |
2011-10-19 11:24 | vskirdin | Note Added: 0007910 | |
2011-10-19 15:11 | Maximus | Note Added: 0007912 | |
2011-10-19 16:04 | JohnDoe | Note Added: 0007914 | |
2011-10-19 16:38 | Maximus | Note Added: 0007915 | |
2011-10-19 17:15 | vskirdin | Note Added: 0007916 | |
2011-10-19 21:25 | JohnDoe | Note Added: 0007919 | |
2011-10-19 22:25 | Maximus | File Added: PluginCall2.diff | |
2011-10-19 22:27 | Maximus | File Added: PluginCall3.diff | |
2011-10-19 22:28 | Maximus | Note Added: 0007921 | |
2011-10-20 13:44 | Maximus | Note Added: 0007930 | |
2011-10-20 15:31 | JohnDoe | Note Added: 0007934 | |
2011-10-20 19:27 | Maximus | Note Added: 0007936 | |
2011-10-20 19:28 | Maximus | Note Added: 0007937 | |
2011-10-20 22:44 | max rusov | Note Added: 0007939 | |
2011-10-21 07:12 | JohnDoe | Note Added: 0007940 | |
2011-10-21 11:52 | Maximus | Note Added: 0007943 | |
2011-10-21 12:02 | vskirdin | Note Added: 0007944 | |
2011-10-21 14:03 | Maximus | Note Added: 0007945 | |
2011-10-21 14: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 22:53 | Maximus | Note Added: 0008826 | |
2012-03-26 22:53 | Maximus | Status | feedback => assigned |
2012-03-26 22:54 | Maximus | File Added: MacroLib.120326.7z | |
2012-03-28 11:02 | vskirdin | Note Added: 0008827 | |
2013-02-03 00:33 | alexy | Severity | minor => feature |
2014-06-10 11:49 | JohnDoe | Note Added: 0012496 | |
2014-10-02 15:55 | shmuel | Build | => 0 |
2014-10-02 15:55 | shmuel | Status | assigned => closed |
2014-10-02 15:55 | shmuel | Resolution | open => fixed |
2014-10-02 15:55 | shmuel | Fixed in Version | => 3.0 |