/* Используется для запуска внешнего редактора и вьювера */ void ProcessExternal(const wchar_t *Command, const wchar_t *Name, const wchar_t *ShortName, bool AlwaysWaitFinish) { string strListName, strAnotherListName; string strShortListName, strAnotherShortListName; string strFullName, strFullShortName; string strExecStr = Command; string strFullExecStr = Command; { int PreserveLFN=SubstFileName(strExecStr,Name,ShortName,&strListName,&strAnotherListName, &strShortListName, &strAnotherShortListName); bool ListFileUsed=!strListName.IsEmpty()||!strAnotherListName.IsEmpty()||!strShortListName.IsEmpty()||!strAnotherShortListName.IsEmpty(); // Снова все "подставлено", теперь проверим условия "if exist" if (!ExtractIfExistCommand(strExecStr)) return; PreserveLongName PreserveName(ShortName,PreserveLFN); ConvertNameToFull(Name,strFullName); ConvertNameToShort(strFullName,strFullShortName); //BUGBUGBUGBUGBUGBUG !!! Same ListNames!!! SubstFileName(strFullExecStr,strFullName,strFullShortName,&strListName,&strAnotherListName, &strShortListName, &strAnotherShortListName); // Снова все "подставлено", теперь проверим условия "if exist" if (!ExtractIfExistCommand(strFullExecStr)) return; CtrlObject->ViewHistory->AddToHistory(strFullExecStr,(AlwaysWaitFinish&1)+2); if (strExecStr.At(0) != L'@') CtrlObject->CmdLine->ExecString(strExecStr,AlwaysWaitFinish, 0, 0, ListFileUsed, true); else { SaveScreen SaveScr; CtrlObject->Cp()->LeftPanel->CloseFile(); CtrlObject->Cp()->RightPanel->CloseFile(); Execute(strExecStr.CPtr()+1,AlwaysWaitFinish, 0, 0, 0, ListFileUsed); } } if (!strListName.IsEmpty()) apiDeleteFile(strListName); if (!strAnotherListName.IsEmpty()) apiDeleteFile(strAnotherListName); if (!strShortListName.IsEmpty()) apiDeleteFile(strShortListName); if (!strAnotherShortListName.IsEmpty()) apiDeleteFile(strAnotherShortListName); }
// заполнение меню 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; }
int GetDescriptionWidth(const wchar_t *Name=nullptr,const wchar_t *ShortName=nullptr) { int Width=0; RenumKeyRecord(FTS.Associations,FTS.TypeFmt,FTS.Type0); for (int NumLine=0;; NumLine++) { string strRegKey; strRegKey.Format(FTS.TypeFmt, NumLine); string strMask; if (!GetRegKey(strRegKey,FTS.Mask, strMask, L"")) break; CFileMask FMask; if (!FMask.Set(strMask, FMF_SILENT)) continue; string strDescription; GetRegKey(strRegKey,FTS.Desc,strDescription,L""); int CurWidth; if (!Name) CurWidth = HiStrlen(strDescription); else { if (!FMask.Compare(Name)) continue; string strExpandedDesc = strDescription; SubstFileName(strExpandedDesc,Name,ShortName,nullptr,nullptr,nullptr,nullptr,TRUE); CurWidth = HiStrlen(strExpandedDesc); } if (CurWidth>Width) Width=CurWidth; } if (Width>ScrX/2) Width=ScrX/2; return(Width); }
// обработка единичного меню 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; } }
/* $ 06.07.2001 + Используем CFileMask вместо GetCommaWord, этим самым добиваемся того, что можно использовать маски исключения - Убрал непонятный мне запрет на использование маски файлов типа "*.*" (был когда-то, вроде, такой баг-репорт) */ bool ProcessLocalFileTypes(const wchar_t *Name, const wchar_t *ShortName, int Mode, bool AlwaysWaitFinish) { RenumKeyRecord(FTS.Associations,FTS.TypeFmt,FTS.Type0); MenuItemEx TypesMenuItem; VMenu TypesMenu(MSG(MSelectAssocTitle),nullptr,0,ScrY-4); TypesMenu.SetHelp(FTS.Help); TypesMenu.SetFlags(VMENU_WRAPMODE); TypesMenu.SetPosition(-1,-1,0,0); int DizWidth=GetDescriptionWidth(Name, ShortName); int ActualCmdCount=0; // отображаемых ассоциаций в меню CFileMask FMask; // для работы с масками файлов string strCommand, strDescription; int CommandCount=0; for (int I=0;; I++) { strCommand.Clear(); string strRegKey, strMask; strRegKey.Format(FTS.TypeFmt,I); if (!GetRegKey(strRegKey,FTS.Mask,strMask,L"")) break; if (FMask.Set(strMask,FMF_SILENT)) { if (FMask.Compare(Name)) { LPCWSTR Type=nullptr; switch (Mode) { case FILETYPE_EXEC: Type=FTS.Execute; break; case FILETYPE_VIEW: Type=FTS.View; break; case FILETYPE_EDIT: Type=FTS.Edit; break; case FILETYPE_ALTEXEC: Type=FTS.AltExec; break; case FILETYPE_ALTVIEW: Type=FTS.AltView; break; case FILETYPE_ALTEDIT: Type=FTS.AltEdit; break; } DWORD State=GetRegKey(strRegKey,FTS.State,0xffffffff); if (State&(1<<Mode)) { string strNewCommand; GetRegKey(strRegKey,Type,strNewCommand,L""); if (!strNewCommand.IsEmpty()) { strCommand = strNewCommand; GetRegKey(strRegKey,FTS.Desc,strDescription,L""); CommandCount++; } } } if (strCommand.IsEmpty()) continue; } TypesMenuItem.Clear(); string strCommandText = strCommand; SubstFileName(strCommandText,Name,ShortName,nullptr,nullptr,nullptr,nullptr,TRUE); // все "подставлено", теперь проверим условия "if exist" if (!ExtractIfExistCommand(strCommandText)) continue; ActualCmdCount++; string strMenuText; if (DizWidth) { string strTitle; if (!strDescription.IsEmpty()) { strTitle = strDescription; SubstFileName(strTitle, Name,ShortName,nullptr,nullptr,nullptr,nullptr,TRUE); } size_t Pos=0; bool Ampersand=strTitle.Pos(Pos,L'&'); if (DizWidth+Ampersand>ScrX/2 && Ampersand && static_cast<int>(Pos)>DizWidth) Ampersand=false; strMenuText.Format(L"%-*.*s %c ",DizWidth+Ampersand,DizWidth+Ampersand,strTitle.CPtr(),BoxSymbols[BS_V1]); } TruncStr(strCommandText,ScrX-DizWidth-14); strMenuText += strCommandText; TypesMenuItem.strName = strMenuText; TypesMenuItem.SetSelect(!I); TypesMenu.SetUserData(strCommand.CPtr(),0,TypesMenu.AddItem(&TypesMenuItem)); } if (!CommandCount) return false; if (!ActualCmdCount) return true; int ExitCode=0; if (ActualCmdCount>1) { TypesMenu.Process(); ExitCode=TypesMenu.Modal::GetExitCode(); if (ExitCode<0) return true; } int Size=TypesMenu.GetUserDataSize(ExitCode); LPWSTR Command=strCommand.GetBuffer(Size/sizeof(wchar_t)); TypesMenu.GetUserData(Command,Size,ExitCode); strCommand.ReleaseBuffer(Size); string strListName, strAnotherListName; string strShortListName, strAnotherShortListName; int PreserveLFN=SubstFileName(strCommand,Name,ShortName,&strListName,&strAnotherListName, &strShortListName, &strAnotherShortListName); bool ListFileUsed=!strListName.IsEmpty()||!strAnotherListName.IsEmpty()||!strShortListName.IsEmpty()||!strAnotherShortListName.IsEmpty(); // Снова все "подставлено", теперь проверим условия "if exist" if (ExtractIfExistCommand(strCommand)) { PreserveLongName PreserveName(ShortName,PreserveLFN); RemoveExternalSpaces(strCommand); if (!strCommand.IsEmpty()) { bool isSilent=(strCommand.At(0)==L'@'); if (isSilent) { strCommand.LShift(1); } ProcessOSAliases(strCommand); if (!isSilent) { CtrlObject->CmdLine->ExecString(strCommand,AlwaysWaitFinish, false, false, ListFileUsed); if (!(Opt.ExcludeCmdHistory&EXCLUDECMDHISTORY_NOTFARASS) && !AlwaysWaitFinish) //AN CtrlObject->CmdHistory->AddToHistory(strCommand); } else { #if 1 SaveScreen SaveScr; CtrlObject->Cp()->LeftPanel->CloseFile(); CtrlObject->Cp()->RightPanel->CloseFile(); Execute(strCommand,AlwaysWaitFinish, 0, 0, 0, ListFileUsed, true); #else // здесь была бага с прорисовкой (и... вывод данных // на команду "@type !@!" пропадал с экрана) // сделаем по аналогии с CommandLine::CmdExecute() { RedrawDesktop RdrwDesktop(TRUE); Execute(strCommand,AlwaysWaitFinish, 0, 0, 0, ListFileUsed); ScrollScreen(1); // обязательно, иначе деструктор RedrawDesktop // проредравив экран забьет последнюю строку вывода. } CtrlObject->Cp()->LeftPanel->UpdateIfChanged(UIC_UPDATE_FORCE); CtrlObject->Cp()->RightPanel->UpdateIfChanged(UIC_UPDATE_FORCE); CtrlObject->Cp()->Redraw(); #endif } if (FrameManager->GetCurrentFrame()->GetType()==MODALTYPE_VIEWER) { TypesMenu.ResetCursor(); } } } if (!strListName.IsEmpty()) apiDeleteFile(strListName); if (!strAnotherListName.IsEmpty()) apiDeleteFile(strAnotherListName); if (!strShortListName.IsEmpty()) apiDeleteFile(strShortListName); if (!strAnotherShortListName.IsEmpty()) apiDeleteFile(strAnotherShortListName); return true; }
/* $ 06.07.2001 + Используем filemasks вместо GetCommaWord, этим самым добиваемся того, что можно использовать маски исключения - Убрал непонятный мне запрет на использование маски файлов типа "*.*" (был когда-то, вроде, такой баг-репорт) */ bool ProcessLocalFileTypes(const string& Name, const string& ShortName, FILETYPE_MODE Mode, bool AlwaysWaitFinish) { string strCommand, strDescription, strMask; { const auto TypesMenu = VMenu2::create(MSG(MSelectAssocTitle), nullptr, 0, ScrY - 4); TypesMenu->SetHelp(L"FileAssoc"); TypesMenu->SetMenuFlags(VMENU_WRAPMODE); TypesMenu->SetId(SelectAssocMenuId); int ActualCmdCount=0; // отображаемых ассоциаций в меню filemasks FMask; // для работы с масками файлов int CommandCount=0; DWORD Index=0; unsigned __int64 id; string FileName = PointToName(Name); while (ConfigProvider().AssocConfig()->EnumMasksForType(Mode,Index++,&id,strMask)) { strCommand.clear(); if (FMask.Set(strMask,FMF_SILENT)) { if (FMask.Compare(FileName)) { ConfigProvider().AssocConfig()->GetCommand(id,Mode,strCommand); if (!strCommand.empty()) { ConfigProvider().AssocConfig()->GetDescription(id,strDescription); CommandCount++; } } if (strCommand.empty()) continue; } string strCommandText = strCommand; SubstFileName(nullptr,strCommandText,Name, ShortName,nullptr,nullptr,nullptr,nullptr,TRUE); // все "подставлено", теперь проверим условия "if exist" if (!ExtractIfExistCommand(strCommandText)) continue; ActualCmdCount++; if (!strDescription.empty()) SubstFileName(nullptr,strDescription, Name, ShortName, nullptr, nullptr, nullptr, nullptr, TRUE); else strDescription = strCommandText; MenuItemEx TypesMenuItem(strDescription); TypesMenuItem.SetSelect(Index==1); TypesMenuItem.UserData = strCommand; TypesMenu->AddItem(TypesMenuItem); } if (!CommandCount) return false; if (!ActualCmdCount) return true; int ExitCode=0; if (ActualCmdCount>1) { ExitCode=TypesMenu->Run(); if (ExitCode<0) return true; } strCommand = *TypesMenu->GetUserDataPtr<string>(ExitCode); } string strListName, strAnotherListName, strShortListName, strAnotherShortListName; const string* ListNames[] = { &strListName, &strAnotherListName, &strShortListName, &strAnotherShortListName }; int PreserveLFN=SubstFileName(nullptr,strCommand, Name, ShortName, &strListName, &strAnotherListName, &strShortListName, &strAnotherShortListName); const auto ListFileUsed = !std::all_of(ALL_CONST_RANGE(ListNames), std::mem_fn(&string::empty)); // Снова все "подставлено", теперь проверим условия "if exist" if (ExtractIfExistCommand(strCommand)) { SCOPED_ACTION(PreserveLongName)(ShortName, PreserveLFN); RemoveExternalSpaces(strCommand); if (!strCommand.empty()) { Global->CtrlObject->CmdLine()->ExecString(strCommand,AlwaysWaitFinish, false, false, ListFileUsed, false, Mode == FILETYPE_VIEW || Mode == FILETYPE_ALTVIEW || Mode == FILETYPE_EDIT || Mode == FILETYPE_ALTEDIT); if (!(Global->Opt->ExcludeCmdHistory&EXCLUDECMDHISTORY_NOTFARASS) && !AlwaysWaitFinish) //AN { const auto curDir = Global->CtrlObject->CmdLine()->GetCurDir(); Global->CtrlObject->CmdHistory->AddToHistory(strCommand, HR_DEFAULT, nullptr, nullptr, curDir.data()); } } } std::for_each(CONST_RANGE(ListNames, i) { if (!i->empty()) os::DeleteFile(*i); });