int FileList::FileNameToPluginItem(const string& Name,PluginPanelItem *pi) { string strTempDir = Name; if (!CutToSlash(strTempDir,true)) return FALSE; FarChDir(strTempDir); ClearStruct(*pi); FAR_FIND_DATA_EX fdata; if (apiGetFindDataEx(Name, fdata)) { FindDataExToPluginPanelItem(&fdata, pi); return TRUE; } return FALSE; }
bool Plugin::LoadData() { if (WorkFlags.Check(PIWF_DONTLOADAGAIN)) return false; if (WorkFlags.Check(PIWF_DATALOADED)) return true; if (m_Instance) return true; if (!m_Instance) { string strCurPlugDiskPath; wchar_t Drive[]={0,L' ',L':',0}; //ставим 0, как признак того, что вертать обратно ненадо! const auto strCurPath = os::GetCurrentDirectory(); if (ParsePath(m_strModuleName) == PATH_DRIVELETTER) // если указан локальный путь, то... { Drive[0] = L'='; Drive[1] = m_strModuleName.front(); os::env::get_variable(Drive, strCurPlugDiskPath); } PrepareModulePath(m_strModuleName); m_Instance = m_model->Create(m_strModuleName); FarChDir(strCurPath); if (Drive[0]) // вернем ее (переменную окружения) обратно os::env::set_variable(Drive, strCurPlugDiskPath); } if (!m_Instance) { //чтоб не пытаться загрузить опять а то ошибка будет постоянно показываться. WorkFlags.Set(PIWF_DONTLOADAGAIN); if (!Global->Opt->LoadPlug.SilentLoadPlugin) //убрать в PluginSet { Message(MSG_WARNING|MSG_ERRORTYPE|MSG_NOPLUGINS, MSG(MError), make_vector<string>(MSG(MPlgLoadPluginError), m_strModuleName), make_vector<string>(MSG(MOk)), L"ErrLoadPlugin"); } return false; } WorkFlags.Clear(PIWF_CACHED); if(bPendingRemove) { bPendingRemove = false; m_model->GetOwner()->UndoRemove(this); } InitExports(); GlobalInfo Info={sizeof(Info)}; if(GetGlobalInfo(&Info) && Info.StructSize && Info.Title && *Info.Title && Info.Description && *Info.Description && Info.Author && *Info.Author) { MinFarVersion = Info.MinFarVersion; PluginVersion = Info.Version; VersionString = VersionToString(PluginVersion); strTitle = Info.Title; strDescription = Info.Description; strAuthor = Info.Author; bool ok=true; if(m_Guid != FarGuid && m_Guid != Info.Guid) { ok = m_model->GetOwner()->UpdateId(this, Info.Guid); } else { SetGuid(Info.Guid); } if (ok) { WorkFlags.Set(PIWF_DATALOADED); return true; } } Unload(); //чтоб не пытаться загрузить опять а то ошибка будет постоянно показываться. WorkFlags.Set(PIWF_DONTLOADAGAIN); return false; }
static BOOL PrepareModulePath(const string& ModuleName) { string strModulePath = ModuleName; CutToSlash(strModulePath); //?? return FarChDir(strModulePath); }
int FileList::PopPlugin(int EnableRestoreViewMode) { OpenPanelInfo Info={}; if (PluginsList.Empty()) { PanelMode=NORMAL_PANEL; return FALSE; } // указатель на плагин, с которого уходим PluginsListItem *PStack=*PluginsList.Last(); // закрываем текущий плагин. PluginsList.Delete(PluginsList.Last()); --PluginPanelsCount; CtrlObject->Plugins->ClosePanel(hPlugin); if (!PluginsList.Empty()) { hPlugin=(*PluginsList.Last())->hPlugin; strOriginalCurDir=PStack->strPrevOriginalCurDir; if (EnableRestoreViewMode) { SetViewMode(PStack->PrevViewMode); SortMode=PStack->PrevSortMode; NumericSort=PStack->PrevNumericSort; CaseSensitiveSort=PStack->PrevCaseSensitiveSort; SortOrder=PStack->PrevSortOrder; DirectoriesFirst=PStack->PrevDirectoriesFirst; } if (PStack->Modified) { PluginPanelItem PanelItem={}; string strSaveDir; apiGetCurrentDirectory(strSaveDir); if (FileNameToPluginItem(PStack->strHostFile,&PanelItem)) { CtrlObject->Plugins->PutFiles(hPlugin,&PanelItem,1,FALSE,0); } else { PanelItem.FileName = xf_wcsdup(PointToName(PStack->strHostFile)); CtrlObject->Plugins->DeleteFiles(hPlugin,&PanelItem,1,0); xf_free(PanelItem.FileName); } FarChDir(strSaveDir); } CtrlObject->Plugins->GetOpenPanelInfo(hPlugin,&Info); if (!(Info.Flags & OPIF_REALNAMES)) { DeleteFileWithFolder(PStack->strHostFile); // удаление файла от предыдущего плагина } } else { PanelMode=NORMAL_PANEL; hPlugin = nullptr; if (EnableRestoreViewMode) { SetViewMode(PStack->PrevViewMode); SortMode=PStack->PrevSortMode; NumericSort=PStack->PrevNumericSort; CaseSensitiveSort=PStack->PrevCaseSensitiveSort; SortOrder=PStack->PrevSortOrder; DirectoriesFirst=PStack->PrevDirectoriesFirst; } } delete PStack; if (EnableRestoreViewMode) CtrlObject->Cp()->RedrawKeyBar(); return TRUE; }
void FileList::PluginToPluginFiles(int Move) { _ALGO(CleverSysLog clv(L"FileList::PluginToPluginFiles()")); PluginPanelItem *ItemList; int ItemNumber; Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this); string strTempDir; if (AnotherPanel->GetMode()!=PLUGIN_PANEL) return; FileList *AnotherFilePanel=(FileList *)AnotherPanel; if (!FarMkTempEx(strTempDir)) return; SaveSelection(); apiCreateDirectory(strTempDir,nullptr); CreatePluginItemList(ItemList,ItemNumber); if (ItemList && ItemNumber>0) { const wchar_t *lpwszTempDir=strTempDir; int PutCode=CtrlObject->Plugins->GetFiles(hPlugin,ItemList,ItemNumber,FALSE,&lpwszTempDir,OPM_SILENT); strTempDir=lpwszTempDir; if (PutCode==1 || PutCode==2) { string strSaveDir; apiGetCurrentDirectory(strSaveDir); FarChDir(strTempDir); PutCode=CtrlObject->Plugins->PutFiles(AnotherFilePanel->hPlugin,ItemList,ItemNumber,FALSE,0); if (PutCode==1 || PutCode==2) { if (!ReturnCurrentFile) ClearSelection(); AnotherPanel->SetPluginModified(); PutDizToPlugin(AnotherFilePanel,ItemList,ItemNumber,FALSE,FALSE,&Diz,&AnotherFilePanel->Diz); if (Move) if (CtrlObject->Plugins->DeleteFiles(hPlugin,ItemList,ItemNumber,OPM_SILENT)) { SetPluginModified(); PutDizToPlugin(this,ItemList,ItemNumber,TRUE,FALSE,nullptr,&Diz); } } else if (!ReturnCurrentFile) PluginClearSelection(ItemList,ItemNumber); FarChDir(strSaveDir); } DeleteDirTree(strTempDir); DeletePluginItemList(ItemList,ItemNumber); Update(UPDATE_KEEP_SELECTION); Redraw(); if (PanelMode==PLUGIN_PANEL) AnotherPanel->Update(UPDATE_KEEP_SELECTION|UPDATE_SECONDARY); else AnotherPanel->Update(UPDATE_KEEP_SELECTION); AnotherPanel->Redraw(); } }
void FileList::PutDizToPlugin(FileList *DestPanel,PluginPanelItem *ItemList, int ItemNumber,int Delete,int Move,DizList *SrcDiz, DizList *DestDiz) { _ALGO(CleverSysLog clv(L"FileList::PutDizToPlugin()")); OpenPanelInfo Info; CtrlObject->Plugins->GetOpenPanelInfo(DestPanel->hPlugin,&Info); if (DestPanel->strPluginDizName.IsEmpty() && Info.DescrFilesNumber>0) DestPanel->strPluginDizName = Info.DescrFiles[0]; if (((Opt.Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED && IsDizDisplayed()) || Opt.Diz.UpdateMode==DIZ_UPDATE_ALWAYS) && !DestPanel->strPluginDizName.IsEmpty() && (!Info.HostFile || !*Info.HostFile || DestPanel->GetModalMode() || apiGetFileAttributes(Info.HostFile)!=INVALID_FILE_ATTRIBUTES)) { CtrlObject->Cp()->LeftPanel->ReadDiz(); CtrlObject->Cp()->RightPanel->ReadDiz(); if (DestPanel->GetModalMode()) DestPanel->ReadDiz(); int DizPresent=FALSE; for (int I=0; I<ItemNumber; I++) if (ItemList[I].Flags & PPIF_PROCESSDESCR) { string strName = ItemList[I].FileName; string strShortName = ItemList[I].AlternateFileName; int Code; if (Delete) Code=DestDiz->DeleteDiz(strName,strShortName); else { Code=SrcDiz->CopyDiz(strName,strShortName,strName,strShortName,DestDiz); if (Code && Move) SrcDiz->DeleteDiz(strName,strShortName); } if (Code) DizPresent=TRUE; } if (DizPresent) { string strTempDir; if (FarMkTempEx(strTempDir) && apiCreateDirectory(strTempDir,nullptr)) { string strSaveDir; apiGetCurrentDirectory(strSaveDir); string strDizName=strTempDir+L"\\"+DestPanel->strPluginDizName; DestDiz->Flush(L"", &strDizName); if (Move) SrcDiz->Flush(L""); PluginPanelItem PanelItem; if (FileNameToPluginItem(strDizName,&PanelItem)) CtrlObject->Plugins->PutFiles(DestPanel->hPlugin,&PanelItem,1,FALSE,OPM_SILENT|OPM_DESCR); else if (Delete) { PluginPanelItem pi={}; pi.FileName = xf_wcsdup(DestPanel->strPluginDizName); CtrlObject->Plugins->DeleteFiles(DestPanel->hPlugin,&pi,1,OPM_SILENT); xf_free(pi.FileName); } FarChDir(strSaveDir); DeleteFileWithFolder(strDizName); } } } }
static int MainProcess( const wchar_t *lpwszEditName, const wchar_t *lpwszViewName, const wchar_t *lpwszDestName1, const wchar_t *lpwszDestName2, int StartLine, int StartChar ) { { ChangePriority ChPriority(ChangePriority::NORMAL); ControlObject CtrlObj; WORD InitAttributes=0; Console.GetTextAttributes(InitAttributes); SetRealColor(COL_COMMANDLINEUSERSCREEN); if (*lpwszEditName || *lpwszViewName) { Opt.OnlyEditorViewerUsed=1; Panel *DummyPanel=new Panel; _tran(SysLog(L"create dummy panels")); CtrlObj.CreateFilePanels(); CtrlObj.Cp()->LeftPanel=CtrlObj.Cp()->RightPanel=CtrlObj.Cp()->ActivePanel=DummyPanel; CtrlObj.Plugins.LoadPlugins(); CtrlObj.Macro.LoadMacros(TRUE,FALSE); if (*lpwszEditName) { FileEditor *ShellEditor=new FileEditor(lpwszEditName,CP_AUTODETECT,FFILEEDIT_CANNEWFILE|FFILEEDIT_ENABLEF6,StartLine,StartChar); _tran(SysLog(L"make shelleditor %p",ShellEditor)); if (!ShellEditor->GetExitCode()) // ???????????? { FrameManager->ExitMainLoop(0); } } // TODO: Этот else убрать только после разборок с возможностью задавать несколько /e и /v в ком.строке else if (*lpwszViewName) { FileViewer *ShellViewer=new FileViewer(lpwszViewName,FALSE); if (!ShellViewer->GetExitCode()) { FrameManager->ExitMainLoop(0); } _tran(SysLog(L"make shellviewer, %p",ShellViewer)); } FrameManager->EnterMainLoop(); CtrlObj.Cp()->LeftPanel=CtrlObj.Cp()->RightPanel=CtrlObj.Cp()->ActivePanel=nullptr; delete DummyPanel; _tran(SysLog(L"editor/viewer closed, delete dummy panels")); } else { Opt.OnlyEditorViewerUsed=0; Opt.SetupArgv=0; FARString strPath; // воспользуемся тем, что ControlObject::Init() создает панели // юзая Opt.* if (*lpwszDestName1) // актиная панель { Opt.SetupArgv++; strPath = lpwszDestName1; CutToNameUNC(strPath); DeleteEndSlash(strPath); //BUGBUG!! если конечный слешь не убрать - получаем забавный эффект - отсутствует ".." // if ((strPath.At(1)==L':' && !strPath.At(2)) || (HasPathPrefix(strPath) && strPath.At(5)==L':' && !strPath.At(6))) // AddEndSlash(strPath); // Та панель, которая имеет фокус - активна (начнем по традиции с Левой Панели ;-) if (Opt.LeftPanel.Focus) { Opt.LeftPanel.Type=FILE_PANEL; // сменим моду панели Opt.LeftPanel.Visible=TRUE; // и включим ее Opt.strLeftFolder = strPath; } else { Opt.RightPanel.Type=FILE_PANEL; Opt.RightPanel.Visible=TRUE; Opt.strRightFolder = strPath; } if (*lpwszDestName2) // пассивная панель { Opt.SetupArgv++; strPath = lpwszDestName2; CutToNameUNC(strPath); DeleteEndSlash(strPath); //BUGBUG!! если конечный слешь не убрать - получаем забавный эффект - отсутствует ".." // if ((strPath.At(1)==L':' && !strPath.At(2)) || (HasPathPrefix(strPath) && strPath.At(5)==L':' && !strPath.At(6))) // AddEndSlash(strPath); // а здесь с точнотью наоборот - обрабатываем пассивную панель if (Opt.LeftPanel.Focus) { Opt.RightPanel.Type=FILE_PANEL; // сменим моду панели Opt.RightPanel.Visible=TRUE; // и включим ее Opt.strRightFolder = strPath; } else { Opt.LeftPanel.Type=FILE_PANEL; Opt.LeftPanel.Visible=TRUE; Opt.strLeftFolder = strPath; } } } // теперь все готово - создаем панели! CtrlObj.Init(); // а теперь "провалимся" в каталог или хост-файл (если получится ;-) if (*lpwszDestName1) // актиная панель { FARString strCurDir; Panel *ActivePanel=CtrlObject->Cp()->ActivePanel; Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(ActivePanel); if (*lpwszDestName2) // пассивная панель { AnotherPanel->GetCurDir(strCurDir); FarChDir(strCurDir); if (IsPluginPrefixPath(lpwszDestName2)) { AnotherPanel->SetFocus(); CtrlObject->CmdLine->ExecString(lpwszDestName2,0); ActivePanel->SetFocus(); } else { strPath = PointToNameUNC(lpwszDestName2); if (!strPath.IsEmpty()) { if (AnotherPanel->GoToFile(strPath)) AnotherPanel->ProcessKey(KEY_CTRLPGDN); } } } ActivePanel->GetCurDir(strCurDir); FarChDir(strCurDir); if (IsPluginPrefixPath(lpwszDestName1)) { CtrlObject->CmdLine->ExecString(lpwszDestName1,0); } else { strPath = PointToNameUNC(lpwszDestName1); if (!strPath.IsEmpty()) { if (ActivePanel->GoToFile(strPath)) ActivePanel->ProcessKey(KEY_CTRLPGDN); } } // !!! ВНИМАНИЕ !!! // Сначала редравим пассивную панель, а потом активную! AnotherPanel->Redraw(); ActivePanel->Redraw(); } FrameManager->EnterMainLoop(); } // очистим за собой! SetScreen(0,0,ScrX,ScrY,L' ',COL_COMMANDLINEUSERSCREEN); Console.SetTextAttributes(InitAttributes); ScrBuf.ResetShadow(); ScrBuf.Flush(); MoveRealCursor(0,0); } CloseConsole(); return 0; }
static int MainProcess( const string& EditName, const string& ViewName, const string& DestName1, const string& DestName2, int StartLine, int StartChar ) { SCOPED_ACTION(ChangePriority)(THREAD_PRIORITY_NORMAL); FarColor InitAttributes={}; console.GetTextAttributes(InitAttributes); SetRealColor(colors::PaletteColorToFarColor(COL_COMMANDLINEUSERSCREEN)); string ename(EditName),vname(ViewName), apanel(DestName1),ppanel(DestName2); if (ConfigProvider().ShowProblems()) { ename.clear(); vname.clear(); StartLine = StartChar = -1; apanel = Global->Opt->ProfilePath; ppanel = Global->Opt->LocalProfilePath; } if (!ename.empty() || !vname.empty()) { Global->OnlyEditorViewerUsed = true; _tran(SysLog(L"create dummy panels")); Global->CtrlObject->CreateDummyFilePanels(); Global->WindowManager->PluginCommit(); Global->CtrlObject->Plugins->LoadPlugins(); Global->CtrlObject->Macro.LoadMacros(true, true); if (!ename.empty()) { const auto ShellEditor = FileEditor::create(ename, CP_DEFAULT, FFILEEDIT_CANNEWFILE | FFILEEDIT_ENABLEF6, StartLine, StartChar); _tran(SysLog(L"make shelleditor %p",ShellEditor)); if (!ShellEditor->GetExitCode()) // ???????????? { Global->WindowManager->ExitMainLoop(0); } } // TODO: Этот else убрать только после разборок с возможностью задавать несколько /e и /v в ком.строке else if (!vname.empty()) { const auto ShellViewer = FileViewer::create(vname, true); if (!ShellViewer->GetExitCode()) { Global->WindowManager->ExitMainLoop(0); } _tran(SysLog(L"make shellviewer, %p",ShellViewer)); } Global->WindowManager->EnterMainLoop(); } else { int DirCount=0; // воспользуемся тем, что ControlObject::Init() создает панели // юзая Global->Opt->* const auto& SetupPanel = [&](bool active) { ++DirCount; string strPath = active? apanel : ppanel; if (os::fs::is_file(strPath)) { CutToParent(strPath); } bool Root = false; const auto Type = ParsePath(strPath, nullptr, &Root); if(Root && (Type == root_type::drive_letter || Type == root_type::unc_drive_letter || Type == root_type::volume)) { AddEndSlash(strPath); } auto& CurrentPanelOptions = (Global->Opt->LeftFocus == active)? Global->Opt->LeftPanel : Global->Opt->RightPanel; CurrentPanelOptions.m_Type = static_cast<int>(panel_type::FILE_PANEL); // сменим моду панели CurrentPanelOptions.Visible = true; // и включим ее CurrentPanelOptions.Folder = strPath; }; if (!apanel.empty()) { SetupPanel(true); if (!ppanel.empty()) { SetupPanel(false); } } // теперь все готово - создаем панели! Global->CtrlObject->Init(DirCount); // а теперь "провалимся" в каталог или хост-файл (если получится ;-) if (!apanel.empty()) // активная панель { const auto ActivePanel = Global->CtrlObject->Cp()->ActivePanel(); const auto AnotherPanel = Global->CtrlObject->Cp()->PassivePanel(); if (!ppanel.empty()) // пассивная панель { FarChDir(AnotherPanel->GetCurDir()); if (IsPluginPrefixPath(ppanel)) { AnotherPanel->Parent()->SetActivePanel(AnotherPanel); execute_info Info; Info.Command = ppanel; Global->CtrlObject->CmdLine()->ExecString(Info); ActivePanel->Parent()->SetActivePanel(ActivePanel); } else { const auto strPath = PointToName(ppanel); if (!strPath.empty()) { if (AnotherPanel->GoToFile(strPath)) AnotherPanel->ProcessKey(Manager::Key(KEY_CTRLPGDN)); } } } FarChDir(ActivePanel->GetCurDir()); if (IsPluginPrefixPath(apanel)) { execute_info Info; Info.Command = apanel; Global->CtrlObject->CmdLine()->ExecString(Info); } else { const auto strPath = PointToName(apanel); if (!strPath.empty()) { if (ActivePanel->GoToFile(strPath)) ActivePanel->ProcessKey(Manager::Key(KEY_CTRLPGDN)); } } // !!! ВНИМАНИЕ !!! // Сначала редравим пассивную панель, а потом активную! AnotherPanel->Redraw(); ActivePanel->Redraw(); } Global->WindowManager->EnterMainLoop(); } TreeList::FlushCache(); // очистим за собой! SetScreen(0,0,ScrX,ScrY,L' ',colors::PaletteColorToFarColor(COL_COMMANDLINEUSERSCREEN)); console.SetTextAttributes(InitAttributes); Global->ScrBuf->ResetLockCount(); Global->ScrBuf->Flush(); return 0; }
void FileList::ReadFileNames(int KeepSelection, int IgnoreVisible, int DrawMessage) { TPreRedrawFuncGuard preRedrawFuncGuard(PR_ReadFileNamesMsg); TaskBar TB(false); strOriginalCurDir=strCurDir; if (!IsVisible() && !IgnoreVisible) { UpdateRequired=TRUE; UpdateRequiredMode=KeepSelection; return; } UpdateRequired=FALSE; AccessTimeUpdateRequired=FALSE; DizRead=FALSE; FAR_FIND_DATA_EX fdata; FileListItem *CurPtr=0,**OldData=0; string strCurName, strNextCurName; int OldFileCount=0; StopFSWatcher(); if (this!=CtrlObject->Cp()->LeftPanel && this!=CtrlObject->Cp()->RightPanel) return; string strSaveDir; apiGetCurrentDirectory(strSaveDir); { string strOldCurDir = strCurDir; if (!SetCurPath()) { FlushInputBuffer(); // Очистим буффер ввода, т.к. мы уже можем быть в другом месте... if (!StrCmp(strCurDir, strOldCurDir)) //?? i?? { GetPathRoot(strOldCurDir,strOldCurDir); if (!apiIsDiskInDrive(strOldCurDir)) IfGoHome(strOldCurDir.At(0)); /* При смене каталога путь не изменился */ } return; } } SortGroupsRead=FALSE; if (GetFocus()) CtrlObject->CmdLine->SetCurDir(strCurDir); LastCurFile=-1; Panel *AnotherPanel=CtrlObject->Cp()->GetAnotherPanel(this); AnotherPanel->QViewDelTempName(); size_t PrevSelFileCount=SelFileCount; SelFileCount=0; SelFileSize=0; TotalFileCount=0; TotalFileSize=0; CacheSelIndex=-1; CacheSelClearIndex=-1; if (Opt.ShowPanelFree) { unsigned __int64 TotalSize,TotalFree; if (!apiGetDiskSize(strCurDir,&TotalSize,&TotalFree,&FreeDiskSize)) FreeDiskSize=0; } if (FileCount>0) { strCurName = ListData[CurFile]->strName; if (ListData[CurFile]->Selected) { for (int i=CurFile+1; i < FileCount; i++) { CurPtr = ListData[i]; if (!CurPtr->Selected) { strNextCurName = CurPtr->strName; break; } } } } if (KeepSelection || PrevSelFileCount>0) { OldData=ListData; OldFileCount=FileCount; } else DeleteListData(ListData,FileCount); ListData=nullptr; int ReadOwners=IsColumnDisplayed(OWNER_COLUMN); int ReadNumLinks=IsColumnDisplayed(NUMLINK_COLUMN); int ReadNumStreams=IsColumnDisplayed(NUMSTREAMS_COLUMN); int ReadStreamsSize=IsColumnDisplayed(STREAMSSIZE_COLUMN); string strComputerName; if (ReadOwners) { CurPath2ComputerName(strCurDir, strComputerName); // сбросим кэш SID`ов SIDCacheFlush(); } SetLastError(ERROR_SUCCESS); int AllocatedCount=0; FileListItem *NewPtr; // сформируем заголовок вне цикла wchar_t Title[2048]; int TitleLength=Min((int)X2-X1-1,(int)(ARRAYSIZE(Title))-1); //wmemset(Title,0x0CD,TitleLength); //BUGBUG //Title[TitleLength]=0; MakeSeparator(TitleLength, Title, 9, nullptr); BOOL IsShowTitle=FALSE; BOOL NeedHighlight=Opt.Highlight && PanelMode != PLUGIN_PANEL; if (!Filter) Filter=new FileFilter(this,FFT_PANEL); //Рефреш текущему времени для фильтра перед началом операции Filter->UpdateCurrentTime(); CtrlObject->HiFiles->UpdateCurrentTime(); bool bCurDirRoot = false; ParsePath(strCurDir, nullptr, &bCurDirRoot); PATH_TYPE Type = ParsePath(strCurDir, nullptr, &bCurDirRoot); bool NetRoot = bCurDirRoot && (Type == PATH_REMOTE || Type == PATH_REMOTEUNC); FileCount = 0; string strFind = strCurDir; AddEndSlash(strFind); strFind+=L'*'; ::FindFile Find(strFind, true); DWORD FindErrorCode = ERROR_SUCCESS; bool UseFilter=Filter->IsEnabledOnPanel(); bool ReadCustomData=IsColumnDisplayed(CUSTOM_COLUMN0)!=0; DWORD StartTime = GetTickCount(); while (Find.Get(fdata)) { FindErrorCode = GetLastError(); if ((Opt.ShowHidden || !(fdata.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) && (!UseFilter || Filter->FileInFilter(fdata, nullptr, &fdata.strFileName))) { if (FileCount>=AllocatedCount) { AllocatedCount+=4096; FileListItem **pTemp; if (!(pTemp=(FileListItem **)xf_realloc(ListData,AllocatedCount*sizeof(*ListData)))) break; ListData=pTemp; } ListData[FileCount] = new FileListItem; ListData[FileCount]->Clear(); NewPtr=ListData[FileCount]; NewPtr->FileAttr = fdata.dwFileAttributes; NewPtr->CreationTime = fdata.ftCreationTime; NewPtr->AccessTime = fdata.ftLastAccessTime; NewPtr->WriteTime = fdata.ftLastWriteTime; NewPtr->ChangeTime = fdata.ftChangeTime; NewPtr->FileSize = fdata.nFileSize; NewPtr->AllocationSize = fdata.nAllocationSize; NewPtr->strName = fdata.strFileName; NewPtr->strShortName = fdata.strAlternateFileName; NewPtr->Position=FileCount++; NewPtr->NumberOfLinks=1; if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { NewPtr->ReparseTag=fdata.dwReserved0; //MSDN } if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { TotalFileSize += NewPtr->FileSize; if (ReadNumLinks) NewPtr->NumberOfLinks=GetNumberOfLinks(fdata.strFileName); } else { NewPtr->AllocationSize = 0; } NewPtr->SortGroup=DEFAULT_SORT_GROUP; if (ReadOwners) { string strOwner; GetFileOwner(strComputerName, NewPtr->strName,strOwner); NewPtr->strOwner = strOwner; } NewPtr->NumberOfStreams=NewPtr->FileAttr&FILE_ATTRIBUTE_DIRECTORY?0:1; NewPtr->StreamsSize=NewPtr->FileSize; if (ReadNumStreams||ReadStreamsSize) { EnumStreams(TestParentFolderName(fdata.strFileName)?strCurDir:fdata.strFileName,NewPtr->StreamsSize,NewPtr->NumberOfStreams); } if (ReadCustomData) CtrlObject->Plugins->GetCustomData(NewPtr); if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) TotalFileCount++; //memcpy(ListData+FileCount,&NewPtr,sizeof(NewPtr)); // FileCount++; DWORD CurTime = GetTickCount(); if (CurTime - StartTime > RedrawTimeout) { StartTime = CurTime; if (IsVisible()) { if (!IsShowTitle) { if (!DrawMessage) { Text(X1+1,Y1,ColorIndexToColor(COL_PANELBOX),Title); IsShowTitle=TRUE; SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE); } } LangString strReadMsg(MReadingFiles); strReadMsg << FileCount; if (DrawMessage) { ReadFileNamesMsg(strReadMsg); } else { TruncStr(strReadMsg,TitleLength-2); int MsgLength=(int)strReadMsg.GetLength(); GotoXY(X1+1+(TitleLength-MsgLength-1)/2,Y1); FS<<L" "<<strReadMsg<<L" "; } } if (CheckForEsc()) { break; } } } } if (!(FindErrorCode==ERROR_SUCCESS || FindErrorCode==ERROR_NO_MORE_FILES || FindErrorCode==ERROR_FILE_NOT_FOUND)) Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError),MSG(MReadFolderError),MSG(MOk)); if ((Opt.ShowDotsInRoot || !bCurDirRoot) || (NetRoot && CtrlObject->Plugins->FindPlugin(Opt.KnownIDs.Network))) // NetWork Plugin { if (FileCount>=AllocatedCount) { FileListItem **pTemp; if ((pTemp=(FileListItem **)xf_realloc(ListData,(FileCount+1)*sizeof(*ListData)))) ListData=pTemp; } if (ListData) { ListData[FileCount] = new FileListItem; string TwoDotsOwner; if (ReadOwners) { GetFileOwner(strComputerName,strCurDir,TwoDotsOwner); } FILETIME TwoDotsTimes[4]={}; if(apiGetFindDataEx(strCurDir,fdata)) { TwoDotsTimes[0]=fdata.ftCreationTime; TwoDotsTimes[1]=fdata.ftLastAccessTime; TwoDotsTimes[2]=fdata.ftLastWriteTime; TwoDotsTimes[3]=fdata.ftChangeTime; } AddParentPoint(ListData[FileCount],FileCount,TwoDotsTimes,TwoDotsOwner); FileCount++; } } if (IsColumnDisplayed(DIZ_COLUMN)) ReadDiz(); if (NeedHighlight) { CtrlObject->HiFiles->GetHiColor(ListData, FileCount); } if (AnotherPanel->GetMode()==PLUGIN_PANEL) { HANDLE hAnotherPlugin=AnotherPanel->GetPluginHandle(); PluginPanelItem *PanelData=nullptr; string strPath; size_t PanelCount=0; strPath = strCurDir; AddEndSlash(strPath); if (CtrlObject->Plugins->GetVirtualFindData(hAnotherPlugin,&PanelData,&PanelCount,strPath)) { FileListItem **pTemp; if ((pTemp=(FileListItem **)xf_realloc(ListData,(FileCount+PanelCount)*sizeof(*ListData)))) { ListData=pTemp; for (size_t i=0; i < PanelCount; i++) { CurPtr = ListData[FileCount+i]; PluginPanelItem &pfdata=PanelData[i]; PluginToFileListItem(&PanelData[i],CurPtr); CurPtr->Position=FileCount; TotalFileSize += pfdata.FileSize; CurPtr->PrevSelected=CurPtr->Selected=0; CurPtr->ShowFolderSize=0; CurPtr->SortGroup=CtrlObject->HiFiles->GetGroup(CurPtr); if (!TestParentFolderName(pfdata.FileName) && !(CurPtr->FileAttr & FILE_ATTRIBUTE_DIRECTORY)) TotalFileCount++; } // цветовую боевую раскраску в самом конце, за один раз CtrlObject->HiFiles->GetHiColor(&ListData[FileCount],PanelCount); FileCount+=static_cast<int>(PanelCount); } CtrlObject->Plugins->FreeVirtualFindData(hAnotherPlugin,PanelData,PanelCount); } } InitFSWatcher(false); CorrectPosition(); if (KeepSelection || PrevSelFileCount>0) { MoveSelection(ListData,FileCount,OldData,OldFileCount); DeleteListData(OldData,OldFileCount); } if (SortGroups) ReadSortGroups(false); if (!KeepSelection && PrevSelFileCount>0) { SaveSelection(); ClearSelection(); } SortFileList(FALSE); if (CurFile>=FileCount || StrCmpI(ListData[CurFile]->strName,strCurName)) if (!GoToFile(strCurName) && !strNextCurName.IsEmpty()) GoToFile(strNextCurName); /* $ 13.02.2002 DJ SetTitle() - только если мы текущий фрейм! */ if (CtrlObject->Cp() == FrameManager->GetCurrentFrame()) SetTitle(); FarChDir(strSaveDir); //??? }
void ShellDelete(Panel *SrcPanel,int Wipe) { ChangePriority ChPriority(Opt.DelThreadPriority); TPreRedrawFuncGuard preRedrawFuncGuard(PR_ShellDeleteMsg); FAR_FIND_DATA_EX FindData; string strDeleteFilesMsg; string strSelName; string strSelShortName; string strDizName; string strFullName; DWORD FileAttr; int SelCount,UpdateDiz; int DizPresent; int Ret; BOOL NeedUpdate=TRUE, NeedSetUpADir=FALSE; int Opt_DeleteToRecycleBin=Opt.DeleteToRecycleBin; /*& 31.05.2001 OT Запретить перерисовку текущего фрейма*/ Frame *FrameFromLaunched=FrameManager->GetCurrentFrame(); FrameFromLaunched->Lock(); DeleteAllFolders=!Opt.Confirm.DeleteFolder; UpdateDiz=(Opt.Diz.UpdateMode==DIZ_UPDATE_ALWAYS || (SrcPanel->IsDizDisplayed() && Opt.Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED)); if (!(SelCount=SrcPanel->GetSelCount())) goto done; // Удаление в корзину только для FIXED-дисков { string strRoot; // char FSysNameSrc[NM]; SrcPanel->GetSelName(nullptr,FileAttr); SrcPanel->GetSelName(&strSelName,FileAttr); ConvertNameToFull(strSelName, strRoot); GetPathRoot(strRoot,strRoot); //_SVS(SysLog(L"Del: SelName='%s' Root='%s'",SelName,Root)); if (Opt.DeleteToRecycleBin && FAR_GetDriveType(strRoot) != DRIVE_FIXED) Opt.DeleteToRecycleBin=0; } if (SelCount==1) { SrcPanel->GetSelName(nullptr,FileAttr); SrcPanel->GetSelName(&strSelName,FileAttr); if (TestParentFolderName(strSelName) || strSelName.IsEmpty()) { NeedUpdate=FALSE; goto done; } strDeleteFilesMsg = strSelName; } else { // в зависимости от числа ставим нужное окончание const wchar_t *Ends; wchar_t StrItems[16]; _itow(SelCount,StrItems,10); Ends=MSG(MAskDeleteItemsA); int LenItems=StrLength(StrItems); if (LenItems > 0) { if ((LenItems >= 2 && StrItems[LenItems-2] == L'1') || StrItems[LenItems-1] >= L'5' || StrItems[LenItems-1] == L'0') Ends=MSG(MAskDeleteItemsS); else if (StrItems[LenItems-1] == L'1') Ends=MSG(MAskDeleteItems0); } strDeleteFilesMsg.Format(MSG(MAskDeleteItems),SelCount,Ends); } Ret=1; // Обработка "удаления" линков if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT) && SelCount==1) { string strJuncName; ConvertNameToFull(strSelName,strJuncName); if (GetReparsePointInfo(strJuncName, strJuncName)) // ? SelName ? { NormalizeSymlinkName(strJuncName); //SetMessageHelp(L"DeleteLink"); string strAskDeleteLink=MSG(MAskDeleteLink); DWORD dwAttr=apiGetFileAttributes(strJuncName); if (dwAttr!=INVALID_FILE_ATTRIBUTES) { strAskDeleteLink+=L" "; strAskDeleteLink+=dwAttr&FILE_ATTRIBUTE_DIRECTORY?MSG(MAskDeleteLinkFolder):MSG(MAskDeleteLinkFile); } Ret=Message(0,3,MSG(MDeleteLinkTitle), strDeleteFilesMsg, strAskDeleteLink, strJuncName, MSG(MDeleteLinkDelete),MSG(MDeleteLinkUnlink),MSG(MCancel)); if (Ret == 1) { ConvertNameToFull(strSelName, strJuncName); if (Opt.Confirm.Delete) { ; // ;-% } if ((NeedSetUpADir=CheckUpdateAnotherPanel(SrcPanel,strSelName)) != -1) //JuncName? { DeleteReparsePoint(strJuncName); ShellUpdatePanels(SrcPanel,NeedSetUpADir); } goto done; } if (Ret ) goto done; } } if (Ret && (Opt.Confirm.Delete || SelCount>1 || (FileAttr & FILE_ATTRIBUTE_DIRECTORY))) { const wchar_t *DelMsg; const wchar_t *TitleMsg=MSG(Wipe?MDeleteWipeTitle:MDeleteTitle); /* $ 05.01.2001 IS ! Косметика в сообщениях - разные сообщения в зависимости от того, какие и сколько элементов выделено. */ BOOL folder=(FileAttr & FILE_ATTRIBUTE_DIRECTORY); if (SelCount==1) { if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) DelMsg=MSG(folder?MAskWipeFolder:MAskWipeFile); else { if (Opt.DeleteToRecycleBin && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) DelMsg=MSG(folder?MAskDeleteRecycleFolder:MAskDeleteRecycleFile); else DelMsg=MSG(folder?MAskDeleteFolder:MAskDeleteFile); } } else { if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) { DelMsg=MSG(MAskWipe); TitleMsg=MSG(MDeleteWipeTitle); } else if (Opt.DeleteToRecycleBin && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) DelMsg=MSG(MAskDeleteRecycle); else DelMsg=MSG(MAskDelete); } SetMessageHelp(L"DeleteFile"); if (Message(0,2,TitleMsg,DelMsg,strDeleteFilesMsg,MSG(Wipe?MDeleteWipe:Opt.DeleteToRecycleBin?MDeleteRecycle:MDelete),MSG(MCancel))) { NeedUpdate=FALSE; goto done; } } if (Opt.Confirm.Delete && SelCount>1) { //SaveScreen SaveScr; SetCursorType(FALSE,0); SetMessageHelp(L"DeleteFile"); if (Message(MSG_WARNING,2,MSG(Wipe?MWipeFilesTitle:MDeleteFilesTitle),MSG(Wipe?MAskWipe:MAskDelete), strDeleteFilesMsg,MSG(MDeleteFileAll),MSG(MDeleteFileCancel))) { NeedUpdate=FALSE; goto done; } } if (UpdateDiz) SrcPanel->ReadDiz(); SrcPanel->GetDizName(strDizName); DizPresent=(!strDizName.IsEmpty() && apiGetFileAttributes(strDizName)!=INVALID_FILE_ATTRIBUTES); DeleteTitle = new ConsoleTitle(MSG(MDeletingTitle)); if ((NeedSetUpADir=CheckUpdateAnotherPanel(SrcPanel,strSelName)) == -1) goto done; if (SrcPanel->GetType()==TREE_PANEL) FarChDir(L"\\"); { TaskBar TB; wakeful W; bool Cancel=false; //SaveScreen SaveScr; SetCursorType(FALSE,0); ReadOnlyDeleteMode=-1; SkipMode=-1; SkipWipeMode=-1; SkipFoldersMode=-1; ULONG ItemsCount=0; ProcessedItems=0; if (Opt.DelOpt.DelShowTotal) { SrcPanel->GetSelName(nullptr,FileAttr); DWORD StartTime=GetTickCount(); bool FirstTime=true; while (SrcPanel->GetSelName(&strSelName,FileAttr,&strSelShortName) && !Cancel) { if (!(FileAttr&FILE_ATTRIBUTE_REPARSE_POINT)) { if (FileAttr&FILE_ATTRIBUTE_DIRECTORY) { DWORD CurTime=GetTickCount(); if (CurTime-StartTime>RedrawTimeout || FirstTime) { StartTime=CurTime; FirstTime=false; if (CheckForEscSilent() && ConfirmAbortOp()) { Cancel=true; break; } ShellDeleteMsg(strSelName,Wipe,-1); } ULONG CurrentFileCount,CurrentDirCount,ClusterSize; UINT64 FileSize,CompressedFileSize,RealSize; if (GetDirInfo(nullptr,strSelName,CurrentDirCount,CurrentFileCount,FileSize,CompressedFileSize,RealSize,ClusterSize,-1,nullptr,0)>0) { ItemsCount+=CurrentFileCount+CurrentDirCount+1; } else { Cancel=true; } } else { ItemsCount++; } } } } SrcPanel->GetSelName(nullptr,FileAttr); DWORD StartTime=GetTickCount(); bool FirstTime=true; while (SrcPanel->GetSelName(&strSelName,FileAttr,&strSelShortName) && !Cancel) { int Length=(int)strSelName.GetLength(); if (!Length || (strSelName.At(0)==L'\\' && Length<2) || (strSelName.At(1)==L':' && Length<4)) continue; DWORD CurTime=GetTickCount(); if (CurTime-StartTime>RedrawTimeout || FirstTime) { StartTime=CurTime; FirstTime=false; if (CheckForEscSilent() && ConfirmAbortOp()) { Cancel=true; break; } ShellDeleteMsg(strSelName,Wipe,Opt.DelOpt.DelShowTotal?(ItemsCount?(ProcessedItems*100/ItemsCount):0):-1); } if (FileAttr & FILE_ATTRIBUTE_DIRECTORY) { if (!DeleteAllFolders) { ConvertNameToFull(strSelName, strFullName); if (TestFolder(strFullName) == TSTFLD_NOTEMPTY) { int MsgCode=0; // для symlink`а не нужно подтверждение if (!(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) MsgCode=Message(MSG_WARNING,4,MSG(Wipe?MWipeFolderTitle:MDeleteFolderTitle), MSG(Wipe?MWipeFolderConfirm:MDeleteFolderConfirm),strFullName, MSG(Wipe?MDeleteFileWipe:MDeleteFileDelete),MSG(MDeleteFileAll), MSG(MDeleteFileSkip),MSG(MDeleteFileCancel)); if (MsgCode<0 || MsgCode==3) { NeedSetUpADir=FALSE; break; } if (MsgCode==1) DeleteAllFolders=1; if (MsgCode==2) continue; } } bool DirSymLink=(FileAttr&FILE_ATTRIBUTE_DIRECTORY && FileAttr&FILE_ATTRIBUTE_REPARSE_POINT); if (!DirSymLink && (!Opt.DeleteToRecycleBin || Wipe)) { string strFullName; ScanTree ScTree(TRUE,TRUE,FALSE); string strSelFullName; if (IsAbsolutePath(strSelName)) { strSelFullName=strSelName; } else { SrcPanel->GetCurDir(strSelFullName); AddEndSlash(strSelFullName); strSelFullName+=strSelName; } ScTree.SetFindPath(strSelFullName,L"*", 0); DWORD StartTime=GetTickCount(); while (ScTree.GetNextName(&FindData,strFullName)) { DWORD CurTime=GetTickCount(); if (CurTime-StartTime>RedrawTimeout) { StartTime=CurTime; if (CheckForEscSilent()) { int AbortOp = ConfirmAbortOp(); if (AbortOp) { Cancel=true; break; } } ShellDeleteMsg(strFullName,Wipe,Opt.DelOpt.DelShowTotal?(ItemsCount?(ProcessedItems*100/ItemsCount):0):-1); } if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL); int MsgCode=ERemoveDirectory(strFullName,Wipe); if (MsgCode==DELETE_CANCEL) { Cancel=true; break; } else if (MsgCode==DELETE_SKIP) { ScTree.SkipDir(); continue; } TreeList::DelTreeName(strFullName); if (UpdateDiz) SrcPanel->DeleteDiz(strFullName,strSelShortName); continue; } if (!DeleteAllFolders && !ScTree.IsDirSearchDone() && TestFolder(strFullName) == TSTFLD_NOTEMPTY) { int MsgCode=Message(MSG_WARNING,4,MSG(Wipe?MWipeFolderTitle:MDeleteFolderTitle), MSG(Wipe?MWipeFolderConfirm:MDeleteFolderConfirm),strFullName, MSG(Wipe?MDeleteFileWipe:MDeleteFileDelete),MSG(MDeleteFileAll), MSG(MDeleteFileSkip),MSG(MDeleteFileCancel)); if (MsgCode<0 || MsgCode==3) { Cancel=true; break; } if (MsgCode==1) DeleteAllFolders=1; if (MsgCode==2) { ScTree.SkipDir(); continue; } } if (ScTree.IsDirSearchDone()) { if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) apiSetFileAttributes(strFullName,FILE_ATTRIBUTE_NORMAL); int MsgCode=ERemoveDirectory(strFullName,Wipe); if (MsgCode==DELETE_CANCEL) { Cancel=true;; break; } else if (MsgCode==DELETE_SKIP) { //ScTree.SkipDir(); continue; } TreeList::DelTreeName(strFullName); } } else { int AskCode=AskDeleteReadOnly(strFullName,FindData.dwFileAttributes,Wipe); if (AskCode==DELETE_CANCEL) { Cancel=true; break; } if (AskCode==DELETE_YES) if (ShellRemoveFile(strFullName,Wipe)==DELETE_CANCEL) { Cancel=true; break; } } } } if (!Cancel) { if (FileAttr & FILE_ATTRIBUTE_READONLY) apiSetFileAttributes(strSelName,FILE_ATTRIBUTE_NORMAL); int DeleteCode; // нефига здесь выделываться, а надо учесть, что удаление // симлинка в корзину чревато потерей оригинала. if (DirSymLink || !Opt.DeleteToRecycleBin || Wipe) { DeleteCode=ERemoveDirectory(strSelName,Wipe); if (DeleteCode==DELETE_CANCEL) break; else if (DeleteCode==DELETE_SUCCESS) { TreeList::DelTreeName(strSelName); if (UpdateDiz) SrcPanel->DeleteDiz(strSelName,strSelShortName); } } else { DeleteCode=RemoveToRecycleBin(strSelName); if (!DeleteCode) Message(MSG_WARNING|MSG_ERRORTYPE,1,MSG(MError), MSG(MCannotDeleteFolder),strSelName,MSG(MOk)); else { TreeList::DelTreeName(strSelName); if (UpdateDiz) SrcPanel->DeleteDiz(strSelName,strSelShortName); } } } } else { int AskCode=AskDeleteReadOnly(strSelName,FileAttr,Wipe); if (AskCode==DELETE_CANCEL) break; if (AskCode==DELETE_YES) { int DeleteCode=ShellRemoveFile(strSelName,Wipe); if (DeleteCode==DELETE_SUCCESS && UpdateDiz) { SrcPanel->DeleteDiz(strSelName,strSelShortName); } if (DeleteCode==DELETE_CANCEL) break; } } } } if (UpdateDiz) if (DizPresent==(!strDizName.IsEmpty() && apiGetFileAttributes(strDizName)!=INVALID_FILE_ATTRIBUTES)) SrcPanel->FlushDiz(); delete DeleteTitle; done: Opt.DeleteToRecycleBin=Opt_DeleteToRecycleBin; // Разрешить перерисовку фрейма FrameFromLaunched->Unlock(); if (NeedUpdate) { ShellUpdatePanels(SrcPanel,NeedSetUpADir); } }
/* $ 14.01.2002 IS ! Убрал установку переменных окружения, потому что она производится в FarChDir, которая теперь используется у нас для установления текущего каталога. */ bool Panel::SetCurPath() { if (GetMode() == panel_mode::PLUGIN_PANEL) return true; const auto AnotherPanel = Parent()->GetAnotherPanel(this); if (AnotherPanel->GetMode() != panel_mode::PLUGIN_PANEL) { if (AnotherPanel->m_CurDir.size() > 1 && AnotherPanel->m_CurDir[1]==L':' && (m_CurDir.empty() || upper(AnotherPanel->m_CurDir[0])!=upper(m_CurDir[0]))) { // сначала установим переменные окружения для пассивной панели // (без реальной смены пути, чтобы лишний раз пассивный каталог // не перечитывать) FarChDir(AnotherPanel->m_CurDir, false); } } if (!FarChDir(m_CurDir)) { while (!FarChDir(m_CurDir)) { const auto strRoot = GetPathRoot(m_CurDir); if (FAR_GetDriveType(strRoot) != DRIVE_REMOVABLE || os::fs::IsDiskInDrive(strRoot)) { if (!os::fs::is_directory(m_CurDir)) { if (CheckShortcutFolder(m_CurDir, true, true) && FarChDir(m_CurDir)) { SetCurDir(m_CurDir,true); return true; } } else break; } if (Global->WindowManager->ManagerStarted()) // сначала проверим - а запущен ли менеджер { SetCurDir(Global->g_strFarPath,true); // если запущен - выставим путь который мы точно знаем что существует ChangeDisk(shared_from_this()); // и вызовем меню выбора дисков } else // оппа... { string strTemp(m_CurDir); CutToParent(m_CurDir); // подымаемся вверх, для очередной порции ChDir if (strTemp.size()==m_CurDir.size()) // здесь проблема - видимо диск недоступен { SetCurDir(Global->g_strFarPath,true); // тогда просто сваливаем в каталог, откуда стартанул FAR. break; } else { if (FarChDir(m_CurDir)) { SetCurDir(m_CurDir,true); break; } } } } return false; } return true; }