static void PrepareOptFolder(string &strSrc, int IsLocalPath_FarPath) { if (strSrc.IsEmpty()) { strSrc = g_strFarPath; DeleteEndSlash(strSrc); } else { apiExpandEnvironmentStrings(strSrc, strSrc); } if (!StrCmp(strSrc,L"/")) { strSrc = g_strFarPath; if (IsLocalPath_FarPath) { strSrc.SetLength(2); strSrc += L"\\"; } } else { CheckShortcutFolder(&strSrc,FALSE,TRUE); } //ConvertNameToFull(strSrc,strSrc); }
void Shortcuts::EditItem(VMenu* Menu, ShortcutItem* Item, bool Root) { string strNewDir = Item->strFolder; string strNewPluginModule = Item->strPluginModule; string strNewPluginFile = Item->strPluginFile; string strNewPluginData = Item->strPluginData; DialogBuilder Builder(MFolderShortcutsTitle, HelpFolderShortcuts); Builder.AddText(MFSShortcut); Builder.AddEditField(&strNewDir, 50, L"FS_Path", DIF_EDITPATH); if (!strNewPluginModule.IsEmpty()) { Builder.AddSeparator(); Builder.AddText(MFSShortcutModule); Builder.AddEditField(&strNewPluginModule, 50, nullptr, DIF_READONLY); Builder.AddText(MFSShortcutFile); Builder.AddEditField(&strNewPluginFile, 50, nullptr, DIF_READONLY); Builder.AddText(MFSShortcutData); Builder.AddEditField(&strNewPluginData, 50, nullptr, DIF_READONLY); } Builder.AddOKCancel(); if (Builder.ShowDialog()) { Unquote(strNewDir); if (!IsLocalRootPath(strNewDir)) DeleteEndSlash(strNewDir); bool Save=true; string strTemp(strNewDir); apiExpandEnvironmentStrings(strNewDir,strTemp); if (apiGetFileAttributes(strTemp) == INVALID_FILE_ATTRIBUTES) { Save=!Message(MSG_WARNING | MSG_ERRORTYPE, 2, MSG(MError), strNewDir, MSG(MSaveThisShortcut), MSG(MYes), MSG(MNo)); } if (Save) { Item->strPluginData.Clear(); Item->strPluginFile.Clear(); Item->strPluginModule.Clear(); Item->strFolder = strNewDir; MenuItemEx* MenuItem = Menu->GetItemPtr(); MenuItem->strName = Item->strFolder; if(Root) { MakeItemName(Menu->GetSelectPos(), MenuItem); } Menu->SetPosition(-1, -1, -1, -1); Menu->SetUpdateRequired(TRUE); Menu->Show(); } } }
// заполнение меню int FillUserMenu(VMenu& FarUserMenu,DList<UserMenuItem> *Menu,int MenuPos,int *FuncPos,const string& Name,const string& ShortName) { FarUserMenu.DeleteItems(); MenuItemEx FarUserMenuItem; int NumLines=0; for (UserMenuItem *MenuItem=Menu->First(); MenuItem; MenuItem=Menu->Next(MenuItem), NumLines++) { FarUserMenuItem.Clear(); int FuncNum=0; // сепаратором является случай, когда хоткей == "--" if (!StrCmp(MenuItem->strHotKey,L"--")) { FarUserMenuItem.Flags|=LIF_SEPARATOR; FarUserMenuItem.strName=MenuItem->strLabel; if (NumLines==MenuPos) { MenuPos++; } } else { string strLabel = MenuItem->strLabel; SubstFileName(strLabel,Name,ShortName,nullptr,nullptr,nullptr,nullptr,TRUE); apiExpandEnvironmentStrings(strLabel, strLabel); string strHotKey = MenuItem->strHotKey; FuncNum = PrepareHotKey(strHotKey); int Offset = strHotKey.At(0)==L'&'?5:4; FarUserMenuItem.strName=FormatString()<<((!strHotKey.IsEmpty() && !FuncNum)?L"&":L"")<<fmt::LeftAlign()<<fmt::ExactWidth(Offset)<<strHotKey; FarUserMenuItem.strName+=strLabel; if (MenuItem->Submenu) { FarUserMenuItem.Flags|=MIF_SUBMENU; } FarUserMenuItem.SetSelect(NumLines==MenuPos); } int ItemPos=FarUserMenu.AddItem(&FarUserMenuItem); FarUserMenu.SetUserData(&MenuItem,sizeof(MenuItem),ItemPos); if (FuncNum>0) { FuncPos[FuncNum-1]=ItemPos; } } FarUserMenuItem.Clear(); FarUserMenuItem.SetSelect(NumLines==MenuPos); FarUserMenu.AddItem(&FarUserMenuItem); return NumLines; }
void farPrepareFileName(string& strFileName) { apiExpandEnvironmentStrings(strFileName, strFileName); farUnquote(strFileName); farTrim(strFileName); if ( strFileName.IsEmpty() ) strFileName = _T("."); farGetFullPathName(strFileName, strFileName); }
// обработка единичного меню int UserMenu::ProcessSingleMenu(DList<UserMenuItem> *Menu, int MenuPos, DList<UserMenuItem> *MenuRoot, const string& MenuFileName, const wchar_t *Title) { for (;;) { int NumLine=0, ExitCode, FuncPos[24]; UserMenuItem *CurrentMenuItem = nullptr; // очистка F-хоткеев for (size_t I=0 ; I < ARRAYSIZE(FuncPos) ; I++) FuncPos[I]=-1; string strName,strShortName; CtrlObject->Cp()->ActivePanel->GetCurName(strName,strShortName); /* $ 24.07.2000 VVM + При показе главного меню в заголовок добавляет тип - FAR/Registry */ string strMenuTitle; if (Title && *Title) { strMenuTitle = Title; } else { switch (MenuMode) { case MM_LOCAL: strMenuTitle = MSG(MLocalMenuTitle); break; case MM_GLOBAL: strMenuTitle = MSG(MMainMenuTitle); strMenuTitle += L" ("; strMenuTitle += MSG(MMainMenuGlobal); strMenuTitle += L")"; break; default: strMenuTitle = MSG(MMainMenuTitle); strMenuTitle += L" ("; strMenuTitle += MSG(MMainMenuUser); strMenuTitle += L")"; } } { VMenu UserMenu(strMenuTitle,nullptr,0,ScrY-4); UserMenu.SetFlags(VMENU_WRAPMODE); UserMenu.SetHelp(L"UserMenu"); UserMenu.SetPosition(-1,-1,0,0); UserMenu.SetBottomTitle(MSG(MMainMenuBottomTitle)); MenuNeedRefresh=true; while (!UserMenu.Done()) { if (MenuNeedRefresh) { UserMenu.Hide(); // спрячем // "изнасилуем" (перезаполним :-) NumLine=FillUserMenu(UserMenu,Menu,MenuPos,FuncPos,strName,strShortName); // заставим манагер менюхи корректно отрисовать ширину и // высоту, а заодно и скорректировать вертикальные позиции UserMenu.SetPosition(-1,-1,-1,-1); UserMenu.Show(); MenuNeedRefresh=false; } int Key=UserMenu.ReadInput(); MenuPos=UserMenu.GetSelectPos(); void* userdata = UserMenu.GetUserData(nullptr, 0, MenuPos); CurrentMenuItem = userdata? *static_cast<UserMenuItem**>(userdata):nullptr; if ((unsigned int)Key>=KEY_F1 && (unsigned int)Key<=KEY_F24) { int FuncItemPos; if ((FuncItemPos=FuncPos[Key-KEY_F1])!=-1) { UserMenu.Modal::SetExitCode(FuncItemPos); continue; } } else if (Key == L' ') // исключаем пробел из "хоткеев"! continue; switch (Key) { /* $ 24.08.2001 VVM + Стрелки вправо/влево открывают/закрывают подменю соответственно */ case KEY_RIGHT: case KEY_NUMPAD6: case KEY_MSWHEEL_RIGHT: if (CurrentMenuItem && CurrentMenuItem->Submenu) UserMenu.SetExitCode(MenuPos); break; case KEY_LEFT: case KEY_NUMPAD4: case KEY_MSWHEEL_LEFT: if (Title && *Title) UserMenu.SetExitCode(-1); break; case KEY_NUMDEL: case KEY_DEL: if (CurrentMenuItem) DeleteMenuRecord(Menu,CurrentMenuItem); break; case KEY_INS: case KEY_F4: case KEY_SHIFTF4: case KEY_NUMPAD0: { bool bNew = Key == KEY_INS || Key == KEY_NUMPAD0; if (!bNew && !CurrentMenuItem) break; EditMenu(Menu,CurrentMenuItem,bNew); break; } case KEY_CTRLUP: case KEY_RCTRLUP: case KEY_CTRLDOWN: case KEY_RCTRLDOWN: { int Pos=UserMenu.GetSelectPos(); if (Pos!=UserMenu.GetItemCount()-1 && CurrentMenuItem) { if (!((Key==KEY_CTRLUP || Key==KEY_RCTRLUP) && !Pos) && !((Key==KEY_CTRLDOWN || Key==KEY_RCTRLDOWN) && Pos==UserMenu.GetItemCount()-2)) { MenuModified = MenuNeedRefresh = true; if (Key==KEY_CTRLUP || Key==KEY_RCTRLUP) { Menu->MoveBefore(Menu->Prev(CurrentMenuItem),CurrentMenuItem); MenuPos--; } else { Menu->MoveAfter(Menu->Next(CurrentMenuItem),CurrentMenuItem); MenuPos++; } } } } break; case KEY_ALTF4: // редактировать все меню case KEY_RALTF4: { File MenuFile; (*FrameManager)[0]->Unlock(); { ConsoleTitle *OldTitle=new ConsoleTitle; SaveMenu(MenuFileName); FileEditor ShellEditor(MenuFileName,CP_UNICODE,FFILEEDIT_DISABLEHISTORY,-1,-1,nullptr); delete OldTitle; ShellEditor.SetDynamicallyBorn(false); FrameManager->EnterModalEV(); FrameManager->ExecuteModal(); FrameManager->ExitModalEV(); if (!ShellEditor.IsFileChanged() || (!MenuFile.Open(MenuFileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING))) { return 0; } } MenuRoot->Clear(); GetFileString GetStr(MenuFile); MenuFileToList(MenuRoot, MenuFile, GetStr); MenuFile.Close(); MenuModified=true; UserMenu.Hide(); return 0; // Закрыть меню } /* $ 28.06.2000 tran выход из пользовательского меню по ShiftF10 из любого уровня вложенности просто задаем ExitCode -1, и возвращаем FALSE - по FALSE оно и выйдет откуда угодно */ case KEY_SHIFTF10: //UserMenu.SetExitCode(-1); return EC_CLOSE_MENU; case KEY_SHIFTF2: // Показать главное меню return(EC_MAIN_MENU); case KEY_BS: // Показать меню из родительского каталога только в MM_LOCAL режиме if (MenuMode == MM_LOCAL) return EC_PARENT_MENU; default: UserMenu.ProcessInput(); if (MenuPos!=UserMenu.GetSelectPos()) { MenuPos=UserMenu.GetSelectPos(); userdata = UserMenu.GetUserData(nullptr, 0, MenuPos); CurrentMenuItem = userdata? *static_cast<UserMenuItem**>(userdata):nullptr; } if (Key == KEY_F1) MenuNeedRefresh=true; break; } // switch(Key) } // while (!UserMenu.Done()) ExitCode=UserMenu.Modal::GetExitCode(); if (ExitCode<0 || ExitCode>=NumLine || !CurrentMenuItem) return EC_CLOSE_LEVEL; // вверх на один уровень void* userdata = UserMenu.GetUserData(nullptr, 0, ExitCode); CurrentMenuItem = userdata? *static_cast<UserMenuItem**>(userdata):nullptr; if (!CurrentMenuItem) return EC_CLOSE_LEVEL; // вверх на один уровень } if (CurrentMenuItem->Submenu) { /* $ 20.08.2001 VVM + При вложенных меню показывает заголовки предыдущих */ string strSubMenuLabel = CurrentMenuItem->strLabel; SubstFileName(strSubMenuLabel,strName,strShortName,nullptr,nullptr,nullptr,nullptr,TRUE); apiExpandEnvironmentStrings(strSubMenuLabel, strSubMenuLabel); size_t pos; if (strSubMenuLabel.Pos(pos,L'&')) strSubMenuLabel.LShift(1,pos); string strSubMenuTitle; if (Title && *Title) { strSubMenuTitle = Title; strSubMenuTitle += L" -> "; strSubMenuTitle += strSubMenuLabel; } else { strSubMenuTitle = strSubMenuLabel; } /* $ 14.07.2000 VVM ! Если закрыли подменю, то остаться. Инече передать управление выше */ MenuPos = ProcessSingleMenu(CurrentMenuItem->Menu, 0, MenuRoot, MenuFileName, strSubMenuTitle); if (MenuPos!=EC_CLOSE_LEVEL) return MenuPos; MenuPos = ExitCode; continue; } /* $ 01.05.2001 IS Отключим до лучших времен */ //int LeftVisible,RightVisible,PanelsHidden=0; string strCmdLineDir; CtrlObject->CmdLine->GetCurDir(strCmdLineDir); string strOldCmdLine; CtrlObject->CmdLine->GetString(strOldCmdLine); int OldCmdLineCurPos = CtrlObject->CmdLine->GetCurPos(); int OldCmdLineLeftPos = CtrlObject->CmdLine->GetLeftPos(); intptr_t OldCmdLineSelStart, OldCmdLineSelEnd; CtrlObject->CmdLine->GetSelection(OldCmdLineSelStart,OldCmdLineSelEnd); CtrlObject->CmdLine->LockUpdatePanel(TRUE); // Цикл исполнения команд меню (CommandX) for (string *str=CurrentMenuItem->Commands.First(); str; str=CurrentMenuItem->Commands.Next(str)) { string strCommand = *str; string strListName, strAnotherListName; string strShortListName, strAnotherShortListName; if (!((!StrCmpNI(strCommand,L"REM",3) && IsSpaceOrEos(strCommand.At(3))) || !StrCmpNI(strCommand,L"::",2))) { /* Осталось корректно обработать ситуацию, например: if exist !#!\!^!.! far:edit < diff -c -p !#!\!^!.! !\!.! Т.е. сначала "вычислить" кусок "if exist !#!\!^!.!", ну а если выполнится, то делать дальше. Или еще пример, if exist ..\a.bat D:\FAR\170\DIFF.MY\mkdiff.bat !?&Номер патча?! ЭТО выполняется всегда, т.к. парсинг всей строки идет, а надо проверить фазу "if exist ..\a.bat", а уж потом делать выводы... */ //if(ExtractIfExistCommand(Command)) { /* $ 01.05.2001 IS Отключим до лучших времен */ /* if (!PanelsHidden) { LeftVisible=CtrlObject->Cp()->LeftPanel->IsVisible(); RightVisible=CtrlObject->Cp()->RightPanel->IsVisible(); CtrlObject->Cp()->LeftPanel->Hide(); CtrlObject->Cp()->RightPanel->Hide(); CtrlObject->Cp()->LeftPanel->SetUpdateMode(FALSE); CtrlObject->Cp()->RightPanel->SetUpdateMode(FALSE); PanelsHidden=TRUE; } */ //; int PreserveLFN=SubstFileName(strCommand, strName, strShortName, &strListName, &strAnotherListName, &strShortListName, &strAnotherShortListName, FALSE, strCmdLineDir); bool ListFileUsed=!strListName.IsEmpty()||!strAnotherListName.IsEmpty()||!strShortListName.IsEmpty()||!strAnotherShortListName.IsEmpty(); if (ExtractIfExistCommand(strCommand)) { PreserveLongName PreserveName(strShortName,PreserveLFN); RemoveExternalSpaces(strCommand); if (!strCommand.IsEmpty()) { bool isSilent=false; if (strCommand.At(0) == L'@') { strCommand.LShift(1); isSilent=true; } ProcessOSAliases(strCommand); // TODO: Ахтунг. В режиме isSilent имеем проблемы с командами, которые выводят что-то на экран // Здесь необходимо переделка, например, перед исполнением подсунуть временный экранный буфер, а потом его содержимое подсунуть в ScreenBuf... if (!isSilent) { CtrlObject->CmdLine->ExecString(strCommand,FALSE, 0, 0, ListFileUsed); } else { SaveScreen SaveScr; CtrlObject->Cp()->LeftPanel->CloseFile(); CtrlObject->Cp()->RightPanel->CloseFile(); Execute(strCommand,TRUE, 0, 0, 0, ListFileUsed, true); } } } } } // strCommand != "REM" if (!strListName.IsEmpty()) apiDeleteFile(strListName); if (!strAnotherListName.IsEmpty()) apiDeleteFile(strAnotherListName); if (!strShortListName.IsEmpty()) apiDeleteFile(strShortListName); if (!strAnotherShortListName.IsEmpty()) apiDeleteFile(strAnotherShortListName); } // while (1) CtrlObject->CmdLine->LockUpdatePanel(FALSE); if (!strOldCmdLine.IsEmpty()) // восстановим сохраненную командную строку { CtrlObject->CmdLine->SetString(strOldCmdLine, FrameManager->IsPanelsActive()); CtrlObject->CmdLine->SetCurPos(OldCmdLineCurPos, OldCmdLineLeftPos); CtrlObject->CmdLine->Select(OldCmdLineSelStart, OldCmdLineSelEnd); } /* $ 01.05.2001 IS Отключим до лучших времен */ /* if (PanelsHidden) { CtrlObject->Cp()->LeftPanel->SetUpdateMode(TRUE); CtrlObject->Cp()->RightPanel->SetUpdateMode(TRUE); CtrlObject->Cp()->LeftPanel->Update(UPDATE_KEEP_SELECTION); CtrlObject->Cp()->RightPanel->Update(UPDATE_KEEP_SELECTION); if (RightVisible) CtrlObject->Cp()->RightPanel->Show(); if (LeftVisible) CtrlObject->Cp()->LeftPanel->Show(); } */ /* $ 14.07.2000 VVM ! Закрыть меню */ /* $ 25.04.2001 DJ - сообщаем, что была выполнена команда (нужно перерисовать панели) */ return EC_COMMAND_SELECTED; } }
int FarAppMain(int argc, char **argv) { Opt.IsUserAdmin = (geteuid()==0); _OT(SysLog(L"[[[[[[[[New Session of FAR]]]]]]]]]")); FARString strEditName; FARString strViewName; FARString DestNames[2]; int StartLine=-1,StartChar=-1; int CntDestName=0; // количество параметров-имен каталогов /*$ 18.04.2002 SKV Попользуем floating point что бы проинициализировался vc-ный fprtl. */ #ifdef _MSC_VER float x=1.1f; wchar_t buf[15]; swprintf(buf,L"%f",x); #endif // если под дебагером, то отключаем исключения однозначно, // иначе - смотря что указал юзвер. #if defined(_DEBUGEXC) Opt.ExceptRules=-1; #else Opt.ExceptRules=-1;//IsDebuggerPresent()?0:-1; #endif // Opt.ExceptRules=-1; #ifdef __GNUC__ Opt.ExceptRules=0; #endif //_SVS(SysLog(L"Opt.ExceptRules=%d",Opt.ExceptRules)); SetRegRootKey(HKEY_CURRENT_USER); Opt.strRegRoot = L"Software/Far2"; // По умолчанию - брать плагины из основного каталога Opt.LoadPlug.MainPluginDir=TRUE; Opt.LoadPlug.PluginsPersonal=TRUE; Opt.LoadPlug.PluginsCacheOnly=FALSE; g_strFarPath = g_strFarModuleName; bool translated = TranslateFarString<TranslateInstallPath_Bin2Share>(g_strFarPath); CutToSlash(g_strFarPath, true); if (translated) { // /usr/bin/something -> /usr/share/far2l g_strFarPath+= L"/" FAR_BASENAME; } WINPORT(SetEnvironmentVariable)(L"FARHOME", g_strFarPath); AddEndSlash(g_strFarPath); // don't inherit from parent process in any case WINPORT(SetEnvironmentVariable)(L"FARUSER", nullptr); WINPORT(SetEnvironmentVariable)(L"FARADMINMODE", Opt.IsUserAdmin?L"1":nullptr); // макросы не дисаблим Opt.Macro.DisableMacro=0; for (int I=1; I<argc; I++) { std::wstring arg_w = MB2Wide(argv[I]); if ((arg_w[0]==L'/' || arg_w[0]==L'-') && arg_w[1]) { switch (Upper(arg_w[1])) { case L'A': switch (Upper(arg_w[2])) { case 0: Opt.CleanAscii=TRUE; break; case L'G': if (!arg_w[3]) Opt.NoGraphics=TRUE; break; } break; case L'E': if (iswdigit(arg_w[2])) { StartLine=_wtoi((const wchar_t *)&arg_w[2]); wchar_t *ChPtr=wcschr((wchar_t *)&arg_w[2],L':'); if (ChPtr) StartChar=_wtoi(ChPtr+1); } if (I+1<argc) { strEditName = argv[I+1]; I++; } break; case L'V': if (I+1<argc) { strViewName = argv[I+1]; I++; } break; case L'M': switch (Upper(arg_w[2])) { case 0: Opt.Macro.DisableMacro|=MDOL_ALL; break; case L'A': if (!arg_w[3]) Opt.Macro.DisableMacro|=MDOL_AUTOSTART; break; } break; case L'I': Opt.SmallIcon=TRUE; break; case L'X': Opt.ExceptRules=0; #if defined(_DEBUGEXC) if (Upper(arg_w[2])==L'D' && !arg_w[3]) Opt.ExceptRules=1; #endif break; case L'C': if (Upper(arg_w[2])==L'O' && !arg_w[3]) { Opt.LoadPlug.PluginsCacheOnly=TRUE; Opt.LoadPlug.PluginsPersonal=FALSE; } break; case L'?': case L'H': ControlObject::ShowCopyright(1); show_help(); return 0; #ifdef DIRECT_RT case L'D': if (Upper(arg_w[2])==L'O' && !arg_w[3]) DirectRT=1; break; #endif case L'W': { Opt.WindowMode=TRUE; } break; } } else // простые параметры. Их может быть max две штукА. { if (CntDestName < 2) { if (IsPluginPrefixPath((const wchar_t *)arg_w.c_str())) { DestNames[CntDestName++] = (const wchar_t *)arg_w.c_str(); } else { apiExpandEnvironmentStrings((const wchar_t *)arg_w.c_str(), DestNames[CntDestName]); Unquote(DestNames[CntDestName]); ConvertNameToFull(DestNames[CntDestName],DestNames[CntDestName]); if (apiGetFileAttributes(DestNames[CntDestName]) != INVALID_FILE_ATTRIBUTES) CntDestName++; //??? } } } } //Настройка OEM сортировки. Должна быть после CopyGlobalSettings и перед InitKeysArray! //LocalUpperInit(); //InitLCIDSort(); //Инициализация массива клавиш. Должна быть после CopyGlobalSettings! InitKeysArray(); //WaitForInputIdle(GetCurrentProcess(),0); std::set_new_handler(nullptr); if (!Opt.LoadPlug.MainPluginDir) //если есть ключ /p то он отменяет /co Opt.LoadPlug.PluginsCacheOnly=FALSE; if (Opt.LoadPlug.PluginsCacheOnly) { Opt.LoadPlug.strCustomPluginsPath.Clear(); Opt.LoadPlug.MainPluginDir=FALSE; Opt.LoadPlug.PluginsPersonal=FALSE; } InitConsole(); GetRegKey(L"Language",L"Main",Opt.strLanguage,L"English"); if (!Lang.Init(g_strFarPath,true,MNewFileName)) { ControlObject::ShowCopyright(1); LPCWSTR LngMsg; switch(Lang.GetLastError()) { case LERROR_BAD_FILE: LngMsg = L"\nError: language data is incorrect or damaged.\n\nPress any key to exit..."; break; case LERROR_FILE_NOT_FOUND: LngMsg = L"\nError: cannot find language data.\n\nPress any key to exit..."; break; default: LngMsg = L"\nError: cannot load language data.\n\nPress any key to exit..."; break; } Console.Write(LngMsg,StrLength(LngMsg)); Console.FlushInputBuffer(); WaitKey(); // А стоит ли ожидать клавишу??? Стоит return 1; } WINPORT(SetEnvironmentVariable)(L"FARLANG",Opt.strLanguage); SetHighlighting(); initMacroVarTable(1); if (Opt.ExceptRules == -1) { GetRegKey(L"System",L"ExceptRules",Opt.ExceptRules,1); } //ErrorMode=SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX|(Opt.ExceptRules?SEM_NOGPFAULTERRORBOX:0)|(GetRegKey(L"System/Exception", L"IgnoreDataAlignmentFaults", 0)?SEM_NOALIGNMENTFAULTEXCEPT:0); //SetErrorMode(ErrorMode); int Result=MainProcessSEH(strEditName,strViewName,DestNames[0],DestNames[1],StartLine,StartChar); EmptyInternalClipboard(); doneMacroVarTable(1); VTShell_Shutdown();//ensure VTShell deinitialized before statics destructors called _OT(SysLog(L"[[[[[Exit of FAR]]]]]]]]]")); return Result; }
int ReplaceVariables(string &strStr,TSubstData *PSubstData) { const int MaxSize=20; const wchar_t *Str=strStr; const wchar_t * const StartStr=Str; if (*Str==L'\"') while (*Str && *Str!=L'\"') Str++; DialogItemEx *DlgData = new DialogItemEx[MaxSize+2]; FormatString HistoryName[MaxSize]; int DlgSize=0; int StrPos[128],StrEndPos[128],StrPosSize=0; while (*Str && DlgSize<MaxSize) { if (*(Str++)!=L'!') continue; if (!*Str) break; if (*(Str++)!=L'?') continue; if (!*Str) break; // теперича все не просто // придется сразу определить наличие операторных скобок // запомнить их позицию int scr,end, beg_t,end_t,beg_s,end_s; scr = end = beg_t = end_t = beg_s = end_s = 0; int ii = IsReplaceVariable(Str-2,&scr,&end,&beg_t,&end_t,&beg_s,&end_s); if (ii == -1) { delete [] DlgData; strStr.Clear(); return 0; } StrEndPos[StrPosSize] = (int)(Str - StartStr - 2) + ii ; //+1 StrPos[StrPosSize++]=(int)(Str-StartStr-2); DlgData[DlgSize].Clear(); DlgData[DlgSize].Type=DI_TEXT; DlgData[DlgSize].X1=5; DlgData[DlgSize].Y1=DlgSize+2; DlgData[DlgSize+1].Clear(); DlgData[DlgSize+1].Type=DI_EDIT; DlgData[DlgSize+1].X1=5; DlgData[DlgSize+1].X2=70; DlgData[DlgSize+1].Y1=DlgSize+3; DlgData[DlgSize+1].Flags|=DIF_HISTORY|DIF_USELASTHISTORY; int HistoryNumber=DlgSize/2; HistoryName[HistoryNumber] << L"UserVar" << HistoryNumber; DlgData[DlgSize+1].strHistory=HistoryName[HistoryNumber]; if (!DlgSize) { DlgData[DlgSize+1].Flags|=DIF_DEFAULTBUTTON; DlgData[DlgSize+1].Flags|=DIF_FOCUS; } string strTitle; if (scr > 2) // if between !? and ? exist some strTitle.Append(Str,scr-2); size_t hist_correct = 0; if (!strTitle.IsEmpty()) { if (strTitle[0] == L'$') // begin of history name { const wchar_t *p = &strTitle[1]; const wchar_t *p1 = wcschr(p,L'$'); if (p1) { HistoryName[HistoryNumber].Copy(p,p1-p); DlgData[DlgSize+1].strHistory=HistoryName[HistoryNumber]; strTitle = ++p1; hist_correct = p1 - p + 1; } } } if ((beg_t == -1) || (end_t == -1)) { // } else if ((end_t - beg_t) > 1) //if between ( and ) exist some { string strTitle2; string strTitle3; strTitle2.Append(strTitle.CPtr()+(end_t-2)+1-hist_correct,scr-end_t-1); // !?$zz$xxxx(fffff)ddddd // ^ ^ strTitle3.Append(strTitle.CPtr()+(beg_t-2)+1-hist_correct,end_t-beg_t-1); // !?$zz$xxxx(ffffff)ddddd // ^ ^ strTitle.SetLength(beg_t-2-hist_correct); // !?$zz$xxxx(fffff)ddddd // ^ ^ string strTmp; const wchar_t *CurStr = strTitle3; while (*CurStr) { if (*CurStr == L'!') { CurStr=_SubstFileName(CurStr,PSubstData,strTmp); } else { strTmp.Append(CurStr,1); CurStr++; } } strTitle += strTmp; strTitle += strTitle2; } //do it - типа здесь все уже раскрыто и преобразовано DlgData[DlgSize].strData = strTitle; // Заполняем поле ввода заданным шаблоном - если есть string strTxt; if ((end-scr) > 1) //if between ? and ! exist some strTxt.Append((Str-2)+scr+1,(end-scr)-1); if ((beg_s == -1) || (end_s == -1)) { // } else if ((end_s - beg_s) > 1) //if between ( and ) exist some { string strTxt2; string strTxt3; strTxt2.Copy(strTxt.CPtr()+(end_s-scr),end-end_s-1); // !?$zz$xxxx(fffff)ddddd?rrrr(pppp)qqqqq! // ^ ^ strTxt3.Copy(strTxt.CPtr()+(beg_s-scr),end_s-beg_s-1); // !?$zz$xxxx(ffffff)ddddd?rrrr(pppp)qqqqq! // ^ ^ strTxt.SetLength(beg_s-scr-1); // !?$zz$xxxx(fffff)ddddd?rrrr(pppp)qqqqq! // ^ ^ string strTmp; const wchar_t *CurStr = strTxt3; while (*CurStr) { if (*CurStr == L'!') { CurStr=_SubstFileName(CurStr,PSubstData,strTmp); } else { strTmp.Append(CurStr,1); CurStr++; } } strTxt += strTmp; strTxt += strTxt2; } DlgData[DlgSize+1].strData = strTxt; apiExpandEnvironmentStrings(DlgData[DlgSize].strData,DlgData[DlgSize].strData); DlgSize+=2; } if (!DlgSize) { delete [] DlgData; return 0; } DlgData[DlgSize].Clear(); DlgData[DlgSize].Type=DI_DOUBLEBOX; DlgData[DlgSize].X1=3; DlgData[DlgSize].Y1=1; DlgData[DlgSize].X2=72; DlgData[DlgSize].Y2=DlgSize+2; DlgSize++; int ExitCode; { Dialog Dlg(DlgData,DlgSize); Dlg.SetPosition(-1,-1,76,DlgSize+3); Dlg.Process(); ExitCode=Dlg.GetExitCode(); } if (ExitCode==-1) { delete [] DlgData; strStr.Clear(); return 0; } string strTmpStr; for (Str=StartStr; *Str; Str++) { int Replace=-1; int end_pos=0; for (int I=0; I<StrPosSize; I++) { if (Str-StartStr==StrPos[I]) { Replace=I; end_pos = StrEndPos[I]; break; } } if (Replace!=-1) { strTmpStr += DlgData[Replace*2+1].strData; Str = StartStr+end_pos; } else { strTmpStr.Append(Str,1); } } strStr = strTmpStr; apiExpandEnvironmentStrings(strStr,strStr); delete [] DlgData; return 1; }
bool Shortcuts::Get(size_t Pos, string* Folder, string* PluginModule, string* PluginFile, string* PluginData) { bool Result = false; if(!Items[Pos].Empty()) { ShortcutItem* RetItem = nullptr; if(Items[Pos].Count()>1) { VMenu FolderList(MSG(MFolderShortcutsTitle),nullptr,0,ScrY-4); FolderList.SetFlags(VMENU_WRAPMODE|VMENU_AUTOHIGHLIGHT); FolderList.SetHelp(HelpFolderShortcuts); FolderList.SetPosition(-1,-1,0,0); FolderList.SetBottomTitle(MSG(MFolderShortcutBottomSub)); for(ShortcutItem* i = Items[Pos].First(); i; i = Items[Pos].Next(i)) { MenuItemEx ListItem={}; string strFolderName; if(!i->strFolder.IsEmpty()) { strFolderName = i->strFolder; } else { strFolderName = MSG(i->strPluginModule.IsEmpty()?MShortcutNone:MShortcutPlugin); } ListItem.strName = strFolderName; ListItem.UserData = (char *)(UINT_PTR)i; ListItem.UserDataSize = sizeof(UINT); FolderList.AddItem(&ListItem); } FolderList.Show(); while (!FolderList.Done()) { DWORD Key=FolderList.ReadInput(); int ItemPos = FolderList.GetSelectPos(); ShortcutItem* Item = static_cast<ShortcutItem*>(FolderList.GetUserData(nullptr, 0, ItemPos)); switch (Key) { case KEY_NUMDEL: case KEY_DEL: case KEY_NUMPAD0: case KEY_INS: { if (Key == KEY_INS || Key == KEY_NUMPAD0) { ShortcutItem* NewItem = Items[Pos].InsertBefore(Item); Panel *ActivePanel=CtrlObject->Cp()->ActivePanel; CtrlObject->CmdLine->GetCurDir(NewItem->strFolder); if (ActivePanel->GetMode() == PLUGIN_PANEL) { OpenPluginInfo Info; ActivePanel->GetOpenPluginInfo(&Info); string strTemp; PluginHandle *ph = (PluginHandle*)ActivePanel->GetPluginHandle(); NewItem->strPluginModule = ph->pPlugin->GetModuleName(); NewItem->strPluginFile = Info.HostFile; NewItem->strPluginData = Info.ShortcutData; } MenuItemEx NewMenuItem = {}; NewMenuItem.strName = NewItem->strFolder; NewMenuItem.UserData = (char *)(UINT_PTR) NewItem; NewMenuItem.UserDataSize = sizeof(UINT); FolderList.AddItem(&NewMenuItem, ItemPos); FolderList.SetSelectPos(ItemPos, 1); } else { if(!Items[Pos].Empty()) { Items[Pos].Delete(Item); FolderList.DeleteItem(FolderList.GetSelectPos()); } } FolderList.SetPosition(-1, -1, -1, -1); FolderList.SetUpdateRequired(TRUE); FolderList.Show(); } break; case KEY_F4: { EditItem(&FolderList, Item, false); } break; default: FolderList.ProcessInput(); break; } } int ExitCode = FolderList.GetExitCode(); if (ExitCode>=0) { RetItem = static_cast<ShortcutItem*>(FolderList.GetUserData(nullptr, 0, ExitCode)); } } else { RetItem = Items[Pos].First(); } if(RetItem) { if(Folder) { *Folder = RetItem->strFolder; apiExpandEnvironmentStrings(*Folder, *Folder); } if(PluginModule) { *PluginModule = RetItem->strPluginModule; } if(PluginFile) { *PluginFile = RetItem->strPluginFile; } if(PluginData) { *PluginData = RetItem->strPluginData; } Result = true; } } return Result; }
int ExecuteCommand(Archive* pArchive, void* pParam) { ExecuteStruct* pES = (ExecuteStruct*)pParam; int nResult = RESULT_ERROR; ParamStruct psParam; FarPanelInfo info; TCHAR* lpTempPath = psParam.strTempPath.GetBuffer(260); GetTempPath (260, lpTempPath); psParam.strTempPath.ReleaseBuffer(); TCHAR* lpListFileName = psParam.strListFileName.GetBuffer(260); #ifdef UNICODE FSF.MkTemp (lpListFileName, 260, _T("NALT")); #else FSF.MkTemp (lpListFileName, _T("NALT")); #endif psParam.strListFileName.ReleaseBuffer(); string strFileName = pArchive->GetFileName(); string strPath; if ( pES->lpCurrentDiskPath ) strPath = pES->lpCurrentDiskPath; else { strPath = strFileName; CutToSlash(strPath); } QuoteSpaceOnly(psParam.strTempPath); QuoteSpaceOnly(psParam.strListFileName); QuoteSpaceOnly(strFileName); psParam.strArchiveName = strFileName; psParam.strShortArchiveName = strFileName; psParam.strPassword = pES->lpPassword; psParam.strPathInArchive = pArchive->GetCurrentDirectory(); psParam.strAdditionalCommandLine = pES->lpAdditionalCommandLine; string strExecuteString; int nStartItemNumber = 0; while ( true ) { int nParseResult = ParseString( pES->items, pES->lpCommand, strExecuteString, &psParam, nStartItemNumber ); if ( (nParseResult == PE_SUCCESS) || (nParseResult == PE_MORE_FILES) ) { PROCESS_INFORMATION pInfo; STARTUPINFO sInfo; memset (&sInfo, 0, sizeof (STARTUPINFO)); sInfo.cb = sizeof (STARTUPINFO); apiExpandEnvironmentStrings(strExecuteString, strExecuteString); HANDLE hScreen = Info.SaveScreen(0, 0, -1, -1); #ifdef UNICODE Info.Control(INVALID_HANDLE_VALUE, FCTL_GETUSERSCREEN, 0, 0); #else Info.Control(INVALID_HANDLE_VALUE, FCTL_GETUSERSCREEN, 0); #endif if ( CreateProcess ( NULL, strExecuteString.GetBuffer(), NULL, NULL, TRUE, 0, NULL, strPath, &sInfo, &pInfo ) ) { WaitForSingleObject(pInfo.hProcess, INFINITE); DWORD dwExitCode; GetExitCodeProcess(pInfo.hProcess, &dwExitCode); CloseHandle (pInfo.hProcess); CloseHandle (pInfo.hThread); nResult = (dwExitCode == 0)?RESULT_SUCCESS:RESULT_ERROR; } else { string strError; strError.Format(_T("CreateProcess failed - %d\n%s"), GetLastError(), strExecuteString.GetString()); msgError(strError); } #ifdef UNICODE Info.Control(INVALID_HANDLE_VALUE, FCTL_SETUSERSCREEN, 0, 0); #else Info.Control(INVALID_HANDLE_VALUE, FCTL_SETUSERSCREEN, 0); #endif Info.RestoreScreen(NULL); Info.RestoreScreen(hScreen); } if ( nParseResult != PE_MORE_FILES ) break; } DeleteFile (psParam.strListFileName); //WARNING!!! return nResult; }