size_t CommandLine::DrawPrompt() { const auto PromptList = GetPrompt(); const size_t MaxLength = PromptSize*ObjWidth() / 100; std::vector<size_t> Sizes; Sizes.reserve(PromptList.size()); size_t PromptLength = 0; size_t FixedLength = 0; size_t CollapsibleCount = 0; for (const auto& i: PromptList) { Sizes.emplace_back(i.Text.size()); PromptLength += i.Text.size(); if (i.Collapsible) ++CollapsibleCount; else FixedLength += i.Text.size(); } size_t CollapsibleItemLength = 0; bool TryCollapse = false; if (PromptLength > MaxLength) { if (CollapsibleCount) { if (FixedLength < MaxLength) CollapsibleItemLength = (MaxLength - FixedLength) / CollapsibleCount; TryCollapse = true; } } size_t CurLength = 0; GotoXY(m_X1, m_Y1); for (const auto& i: PromptList) { auto str = i.Text; if (TryCollapse && i.Collapsible) { TruncPathStr(str, static_cast<int>(CollapsibleItemLength)); } if (CurLength + str.size() > MaxLength) TruncPathStr(str, std::max(0, static_cast<int>(MaxLength - CurLength))); SetColor(i.Colour); Text(str); CurLength += str.size(); if (CurLength >= MaxLength) break; } return CurLength; }
string& __stdcall TruncPathStr(string &strStr, int MaxLength) { wchar_t *lpwszStr = strStr.GetBuffer(); TruncPathStr(lpwszStr, MaxLength); strStr.ReleaseBuffer(); return strStr; }
void ShellDeleteMsg(const wchar_t *Name,int Wipe,int Percent) { string strProgress; size_t Width=52; if (Percent!=-1) { size_t Length=Width-5; // -5 под проценты wchar_t *Progress=strProgress.GetBuffer(Length); if (Progress) { size_t CurPos=Min(Percent,100)*Length/100; wmemset(Progress,BoxSymbols[BS_X_DB],CurPos); wmemset(Progress+(CurPos),BoxSymbols[BS_X_B0],Length-CurPos); strProgress.ReleaseBuffer(Length); FormatString strTmp; strTmp<<L" "<<fmt::Width(3)<<Percent<<L"%"; strProgress+=strTmp; DeleteTitle->Set(L"{%d%%} %s",Percent,MSG(Wipe?MDeleteWipeTitle:MDeleteTitle)); } TBC.SetProgressValue(Percent,100); } string strOutFileName(Name); TruncPathStr(strOutFileName,static_cast<int>(Width)); CenterStr(strOutFileName,strOutFileName,static_cast<int>(Width)); Message(0,0,MSG(Wipe?MDeleteWipeTitle:MDeleteTitle),(Percent>=0||!Opt.DelOpt.DelShowTotal)?MSG(Wipe?MDeletingWiping:MDeleting):MSG(MScanningFolder),strOutFileName,strProgress.IsEmpty()?nullptr:strProgress.CPtr()); PreRedrawItem preRedrawItem=PreRedraw.Peek(); preRedrawItem.Param.Param1=static_cast<void*>(const_cast<wchar_t*>(Name)); preRedrawItem.Param.Param4=(void *)(INT_PTR)Wipe; preRedrawItem.Param.Param5=(__int64)Percent; PreRedraw.SetParam(preRedrawItem.Param); }
static void ShellDeleteMsg(const string& Name, DEL_MODE Mode, int Percent, int WipePercent, ConsoleTitle* DeleteTitle) { FormatString strProgress, strWipeProgress; size_t Width=ScrX/2; size_t Length=Width-5; // -5 под проценты if(Mode==DEL_WIPEPROCESS || Mode==DEL_WIPE) { strWipeProgress.resize(Length); size_t CurPos=std::min(WipePercent,100)*Length/100; std::fill(strWipeProgress.begin(), strWipeProgress.begin() + CurPos, BoxSymbols[BS_X_DB]); std::fill(strWipeProgress.begin() + CurPos, strWipeProgress.end(), BoxSymbols[BS_X_B0]); strWipeProgress<<L" "<<fmt::MinWidth(3)<<WipePercent<<L"%"; if(Percent==-1) { Global->TBC->SetProgressValue(WipePercent, 100); } } if (Mode!=DEL_SCAN && Percent!=-1) { strProgress.resize(Length); size_t CurPos=std::min(Percent,100)*Length/100; std::fill(strProgress.begin(), strProgress.begin() + CurPos, BoxSymbols[BS_X_DB]); std::fill(strProgress.begin() + CurPos, strProgress.end(), BoxSymbols[BS_X_B0]); strProgress<<L" "<<fmt::MinWidth(3)<<Percent<<L"%"; *DeleteTitle << L"{" << Percent << L"%} " << MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeleteWipeTitle:MDeleteTitle) << fmt::Flush(); Global->TBC->SetProgressValue(Percent,100); } string strOutFileName(Name); TruncPathStr(strOutFileName,static_cast<int>(Width)); CenterStr(strOutFileName,strOutFileName,static_cast<int>(Width)); const wchar_t* Progress1 = nullptr; const wchar_t* Progress2 = nullptr; if(!strWipeProgress.empty()) { Progress1 = strWipeProgress.data(); Progress2 = strProgress.empty()? nullptr : strProgress.data(); } else { Progress1 = strProgress.empty()? nullptr : strProgress.data(); } Message(0,0, MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeleteWipeTitle:MDeleteTitle), Mode==DEL_SCAN? MSG(MScanningFolder) : MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeletingWiping:MDeleting), strOutFileName.data(), Progress1, Progress2); if (!Global->PreRedraw->empty()) { auto item = dynamic_cast<DelPreRedrawItem*>(Global->PreRedraw->top()); item->name = Name; item->Title = DeleteTitle; item->Mode = Mode; item->Percent = Percent; item->WipePercent = WipePercent; } }
/* Проверка пути или хост-файла на существование Если идет проверка пути (IsHostFile=FALSE), то будет предпринята попытка найти ближайший путь. Результат попытки возвращается в переданном TestPath. */ bool CheckShortcutFolder(string& pTestPath,int IsHostFile, BOOL Silent) { if (!api::fs::exists(pTestPath)) { int FoundPath=0; string strTarget = pTestPath; TruncPathStr(strTarget, ScrX-16); if (IsHostFile) { SetLastError(ERROR_FILE_NOT_FOUND); Global->CatchError(); if (!Silent) Message(MSG_WARNING | MSG_ERRORTYPE, 1, MSG(MError), strTarget.data(), MSG(MOk)); } else // попытка найти! { SetLastError(ERROR_PATH_NOT_FOUND); Global->CatchError(); if (Silent || !Message(MSG_WARNING | MSG_ERRORTYPE, 2, MSG(MError), strTarget.data(), MSG(MNeedNearPath), MSG(MHYes),MSG(MHNo))) { string strTestPathTemp = pTestPath; for (;;) { if (!CutToSlash(strTestPathTemp,true)) break; if (api::fs::exists(strTestPathTemp)) { int ChkFld=TestFolder(strTestPathTemp); if (ChkFld == TSTFLD_EMPTY || ChkFld == TSTFLD_NOTEMPTY || ChkFld == TSTFLD_NOTACCESS) { if (!(pTestPath.size() > 1 && pTestPath[0] == L'\\' && pTestPath[1] == L'\\' && strTestPathTemp.size() == 1)) { pTestPath = strTestPathTemp; if (pTestPath.size() == 2) // для случая "C:", иначе попадем в текущий каталог диска C: AddEndSlash(pTestPath); FoundPath=1; } break; } } } } } if (!FoundPath) return false; } return true; }
void CommandLine::DisplayObject() { _OT(SysLog(L"[%p] CommandLine::DisplayObject()",this)); auto PromptList = GetPrompt(); size_t MaxLength = PromptSize*ObjWidth()/100; size_t CurLength = 0; GotoXY(X1,Y1); std::for_each(CONST_RANGE(PromptList, i) { SetColor(i.second); string str(i.first); if(CurLength + str.size() > MaxLength) TruncPathStr(str, std::max(0, static_cast<int>(MaxLength - CurLength))); Text(str); CurLength += str.size(); });
static void ShellDeleteMsg(const string& Name, DEL_MODE Mode, int Percent, int WipePercent, ConsoleTitle* DeleteTitle) { string strProgress, strWipeProgress; size_t Width=ScrX/2; if(Mode==DEL_WIPEPROCESS || Mode==DEL_WIPE) { strWipeProgress = make_progressbar(Width, WipePercent, true, Percent == -1); } if (Mode!=DEL_SCAN && Percent!=-1) { strProgress = make_progressbar(Width, Percent, true, true); *DeleteTitle << L"{" << Percent << L"%} " << MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeleteWipeTitle:MDeleteTitle) << fmt::Flush(); } string strOutFileName(Name); TruncPathStr(strOutFileName,static_cast<int>(Width)); CenterStr(strOutFileName,strOutFileName,static_cast<int>(Width)); const wchar_t* Progress1 = nullptr; const wchar_t* Progress2 = nullptr; if(!strWipeProgress.empty()) { Progress1 = strWipeProgress.data(); Progress2 = strProgress.empty()? nullptr : strProgress.data(); } else { Progress1 = strProgress.empty()? nullptr : strProgress.data(); } Message(0,0, MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeleteWipeTitle:MDeleteTitle), Mode==DEL_SCAN? MSG(MScanningFolder) : MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeletingWiping:MDeleting), strOutFileName.data(), Progress1, Progress2); if (!PreRedrawStack().empty()) { auto item = dynamic_cast<DelPreRedrawItem*>(PreRedrawStack().top()); item->name = Name; item->Title = DeleteTitle; item->Mode = Mode; item->Percent = Percent; item->WipePercent = WipePercent; } }
void FileViewer::ShowStatus() { string strName; string strStatus; if (!IsTitleBarVisible()) return; GetTitle(strName); int NameLength=ScrX-43; //???41 if (Opt.ViewerEditorClock && IsFullScreen()) NameLength-=6; if (NameLength<20) NameLength=20; TruncPathStr(strName, NameLength); const wchar_t *lpwszStatusFormat = L"%-*s %5u %13I64u %7.7s %-4I64d %s%3d%%"; strStatus.Format( lpwszStatusFormat, NameLength, strName.CPtr(), View.VM.CodePage, View.FileSize, MSG(MViewerStatusCol), View.LeftPos, Opt.ViewerEditorClock ? L"":L" ", (View.LastPage ? 100:ToPercent64(View.FilePos,View.FileSize)) ); SetColor(COL_VIEWERSTATUS); GotoXY(X1,Y1); FS<<fmt::LeftAlign()<<fmt::Width(View.Width+(View.ViOpt.ShowScrollbar?1:0))<<fmt::Precision(View.Width+(View.ViOpt.ShowScrollbar?1:0))<<strStatus; if (Opt.ViewerEditorClock && IsFullScreen()) ShowTime(FALSE); }
void QuickView::DisplayObject() { if (m_Flags.Check(FSCROBJ_ISREDRAWING)) return; m_Flags.Set(FSCROBJ_ISREDRAWING); if (!QView && !ProcessingPluginCommand) Parent()->GetAnotherPanel(this)->UpdateViewPanel(); if (this->Destroyed()) return; if (QView) QView->SetPosition(m_X1+1,m_Y1+1,m_X2-1,m_Y2-3); Box(m_X1,m_Y1,m_X2,m_Y2,colors::PaletteColorToFarColor(COL_PANELBOX),DOUBLE_BOX); SetScreen(m_X1+1,m_Y1+1,m_X2-1,m_Y2-1,L' ',colors::PaletteColorToFarColor(COL_PANELTEXT)); SetColor(m_Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE); string strTitle = GetTitle(); if (!strTitle.empty()) { GotoXY(m_X1+(m_X2-m_X1+1-(int)strTitle.size())/2,m_Y1); Text(strTitle); } DrawSeparator(m_Y2-2); SetColor(COL_PANELTEXT); GotoXY(m_X1+1,m_Y2-1); Global->FS << fmt::LeftAlign()<<fmt::ExactWidth(m_X2-m_X1-1)<<PointToName(strCurFileName); if (!strCurFileType.empty()) { string strTypeText=L" "; strTypeText+=strCurFileType; strTypeText+=L" "; TruncStr(strTypeText,m_X2-m_X1-1); SetColor(COL_PANELSELECTEDINFO); GotoXY(m_X1+(m_X2-m_X1+1-(int)strTypeText.size())/2,m_Y2-2); Text(strTypeText); } if (Directory) { FormatString FString; string DisplayName(strCurFileName); TruncPathStr(DisplayName,std::max(0, m_X2-m_X1-1-StrLength(MSG(MQuickViewFolder))-5)); FString<<MSG(MQuickViewFolder)<<L" \""<<DisplayName<<L"\""; SetColor(COL_PANELTEXT); GotoXY(m_X1+2,m_Y1+2); PrintText(FString); DWORD currAttr=os::GetFileAttributes(strCurFileName); // обламывается, если нет доступа if (currAttr != INVALID_FILE_ATTRIBUTES && (currAttr&FILE_ATTRIBUTE_REPARSE_POINT)) { string Tmp, Target; DWORD ReparseTag=0; const wchar_t* PtrName; if (GetReparsePointInfo(strCurFileName, Target, &ReparseTag)) { NormalizeSymlinkName(Target); switch(ReparseTag) { // 0xA0000003L = Directory Junction or Volume Mount Point case IO_REPARSE_TAG_MOUNT_POINT: { LNGID ID_Msg = MQuickViewJunction; bool Root; if(ParsePath(Target, nullptr, &Root) == PATH_VOLUMEGUID && Root) { ID_Msg=MQuickViewVolMount; } PtrName = MSG(ID_Msg); } break; // 0xA000000CL = Directory or File Symbolic Link case IO_REPARSE_TAG_SYMLINK: PtrName = MSG(MQuickViewSymlink); break; // 0x8000000AL = Distributed File System case IO_REPARSE_TAG_DFS: PtrName = MSG(MQuickViewDFS); break; // 0x80000012L = Distributed File System Replication case IO_REPARSE_TAG_DFSR: PtrName = MSG(MQuickViewDFSR); break; // 0xC0000004L = Hierarchical Storage Management case IO_REPARSE_TAG_HSM: PtrName = MSG(MQuickViewHSM); break; // 0x80000006L = Hierarchical Storage Management2 case IO_REPARSE_TAG_HSM2: PtrName = MSG(MQuickViewHSM2); break; // 0x80000007L = Single Instance Storage case IO_REPARSE_TAG_SIS: PtrName = MSG(MQuickViewSIS); break; // 0x80000008L = Windows Imaging Format case IO_REPARSE_TAG_WIM: PtrName = MSG(MQuickViewWIM); break; // 0x80000009L = Cluster Shared Volumes case IO_REPARSE_TAG_CSV: PtrName = MSG(MQuickViewCSV); break; case IO_REPARSE_TAG_DEDUP: PtrName = MSG(MQuickViewDEDUP); break; case IO_REPARSE_TAG_NFS: PtrName = MSG(MQuickViewNFS); break; case IO_REPARSE_TAG_FILE_PLACEHOLDER: PtrName = MSG(MQuickViewPlaceholder); break; // 0x????????L = anything else default: if (Global->Opt->ShowUnknownReparsePoint) { Tmp = FormatString() << L":" << fmt::Radix(16) << fmt::ExactWidth(8) << fmt::FillChar(L'0') << ReparseTag; PtrName = Tmp.data(); } else { PtrName=MSG(MQuickViewUnknownReparsePoint); } } } else { PtrName = MSG(MQuickViewUnknownReparsePoint); Target = MSG(MQuickViewNoData); } TruncPathStr(Target,std::max(0, m_X2-m_X1-1-StrLength(PtrName)-5)); FString.clear(); FString<<PtrName<<L" \""<<Target<<L"\""; SetColor(COL_PANELTEXT); GotoXY(m_X1+2,m_Y1+3); PrintText(FString); } if (Directory==1 || Directory==4) { const auto iColor = uncomplete_dirscan? COL_PANELHIGHLIGHTTEXT : COL_PANELINFOTEXT; const wchar_t *prefix = uncomplete_dirscan ? L"~" : L""; GotoXY(m_X1+2,m_Y1+4); PrintText(MSG(MQuickViewContains)); GotoXY(m_X1+2,m_Y1+6); PrintText(MSG(MQuickViewFolders)); SetColor(iColor); FString.clear(); FString<<prefix<<Data.DirCount; PrintText(FString); SetColor(COL_PANELTEXT); GotoXY(m_X1+2,m_Y1+7); PrintText(MSG(MQuickViewFiles)); SetColor(iColor); FString.clear(); FString<<prefix<<Data.FileCount; PrintText(FString); SetColor(COL_PANELTEXT); GotoXY(m_X1+2,m_Y1+8); PrintText(MSG(MQuickViewBytes)); SetColor(iColor); string strSize; InsertCommas(Data.FileSize,strSize); PrintText(prefix+strSize); SetColor(COL_PANELTEXT); GotoXY(m_X1+2,m_Y1+9); PrintText(MSG(MQuickViewAllocated)); SetColor(iColor); InsertCommas(Data.AllocationSize,strSize); FString.clear(); FString << prefix << strSize << L" (" << ToPercent(Data.AllocationSize,Data.FileSize) << L"%)"; PrintText(FString); if (Directory!=4) { SetColor(COL_PANELTEXT); GotoXY(m_X1+2,m_Y1+11); PrintText(MSG(MQuickViewCluster)); SetColor(iColor); InsertCommas(Data.ClusterSize,strSize); PrintText(prefix+strSize); SetColor(COL_PANELTEXT); GotoXY(m_X1+2,m_Y1+12); PrintText(MSG(MQuickViewSlack)); SetColor(iColor); InsertCommas(Data.FilesSlack, strSize); FString.clear(); FString << prefix << strSize << L" (" << ToPercent(Data.FilesSlack, Data.AllocationSize) << L"%)"; PrintText(FString); SetColor(COL_PANELTEXT); GotoXY(m_X1+2,m_Y1+13); PrintText(MSG(MQuickViewMFTOverhead)); SetColor(iColor); InsertCommas(Data.MFTOverhead, strSize); FString.clear(); FString<<prefix<<strSize<<L" ("<<ToPercent(Data.MFTOverhead, Data.AllocationSize)<<L"%)"; PrintText(FString); } } } else if (QView) QView->Show(); m_Flags.Clear(FSCROBJ_ISREDRAWING); }
void ShellDeleteMsg(const wchar_t *Name, DEL_MODE Mode, int Percent, int WipePercent) { FormatString strProgress, strWipeProgress; size_t Width=52; size_t Length=Width-5; // -5 под проценты if(Mode==DEL_WIPEPROCESS || Mode==DEL_WIPE) { wchar_t *WipeProgress=strWipeProgress.GetBuffer(Length); if (WipeProgress) { size_t CurPos=Min(WipePercent,100)*Length/100; wmemset(WipeProgress,BoxSymbols[BS_X_DB],CurPos); wmemset(WipeProgress+(CurPos),BoxSymbols[BS_X_B0],Length-CurPos); strWipeProgress.ReleaseBuffer(Length); strWipeProgress<<L" "<<fmt::MinWidth(3)<<WipePercent<<L"%"; } if(Percent==-1) { TBC.SetProgressValue(WipePercent, 100); } } if (Mode!=DEL_SCAN && Percent!=-1) { wchar_t *Progress=strProgress.GetBuffer(Length); if (Progress) { size_t CurPos=Min(Percent,100)*Length/100; wmemset(Progress,BoxSymbols[BS_X_DB],CurPos); wmemset(Progress+(CurPos),BoxSymbols[BS_X_B0],Length-CurPos); strProgress.ReleaseBuffer(Length); strProgress<<L" "<<fmt::MinWidth(3)<<Percent<<L"%"; *DeleteTitle << L"{" << Percent << L"%} " << MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeleteWipeTitle:MDeleteTitle) << fmt::Flush(); } TBC.SetProgressValue(Percent,100); } string strOutFileName(Name); TruncPathStr(strOutFileName,static_cast<int>(Width)); CenterStr(strOutFileName,strOutFileName,static_cast<int>(Width)); const wchar_t* Progress1 = nullptr; const wchar_t* Progress2 = nullptr; if(!strWipeProgress.IsEmpty()) { Progress1 = strWipeProgress.CPtr(); Progress2 = strProgress.IsEmpty()? nullptr : strProgress.CPtr(); } else { Progress1 = strProgress.IsEmpty()? nullptr : strProgress.CPtr(); } Message(0,0, MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeleteWipeTitle:MDeleteTitle), Mode==DEL_SCAN? MSG(MScanningFolder) : MSG((Mode==DEL_WIPE || Mode==DEL_WIPEPROCESS)?MDeletingWiping:MDeleting), strOutFileName, Progress1, Progress2); PreRedrawItem preRedrawItem=PreRedraw.Peek(); preRedrawItem.Param.Param1=static_cast<void*>(const_cast<wchar_t*>(Name)); preRedrawItem.Param.Param4=ToPtr(Mode); LARGE_INTEGER i = {(DWORD)Percent, (LONG)WipePercent}; preRedrawItem.Param.Param5=i.QuadPart; PreRedraw.SetParam(preRedrawItem.Param); }