void FileList::ShowTotalSize(OpenPanelInfo &Info) { if (!Opt.ShowPanelTotals && PanelMode==PLUGIN_PANEL && !(Info.Flags & OPIF_REALNAMES)) return; string strFormSize, strFreeSize, strTotalStr; int Length; InsertCommas(TotalFileSize,strFormSize); if (Opt.ShowPanelFree && (PanelMode!=PLUGIN_PANEL || (Info.Flags & OPIF_REALNAMES))) InsertCommas(FreeDiskSize,strFreeSize); if (Opt.ShowPanelTotals) { if (!Opt.ShowPanelFree || strFreeSize.IsEmpty()) { strTotalStr = LangString(__FormatEndSelectedPhrase(TotalFileCount)) << strFormSize << TotalFileCount; } else { wchar_t DHLine[4]={BoxSymbols[BS_H2],BoxSymbols[BS_H2],BoxSymbols[BS_H2],0}; FormatString str; str << L" " << strFormSize << L" (" << TotalFileCount << L") " << DHLine << L" " << strFreeSize << L" "; if ((int)str.GetLength() > X2-X1-1) { InsertCommas(FreeDiskSize>>20,strFreeSize); InsertCommas(TotalFileSize>>20,strFormSize); str.Clear(); str << L" " << strFormSize << L" " << MSG(MListMb) << L" (" << TotalFileCount << L") " << DHLine << L" " << strFreeSize << L" " << MSG(MListMb) << L" "; } strTotalStr = str; } }
Shortcuts::Shortcuts() { HKEY hNewKey = OpenRegKey(FolderShortcutsKeyTest); if (hNewKey == NULL) { for(size_t i = 0; i < KeyCount; i++) { FormatString ValueName; ValueName << RecTypeName[PSCR_RT_SHORTCUT] << i; string strValue; if(!GetRegKey(OldFolderShortcutsKey, ValueName, strValue, L"")) continue; ValueName.Clear(); ShortcutItem* Item = Items[i].Push(); Item->strFolder = strValue; ValueName << RecTypeName[PSCR_RT_PLUGINMODULE] << i; GetRegKey(OldFolderShortcutsKey, ValueName, Item->strPluginModule, L""); ValueName.Clear(); ValueName << RecTypeName[PSCR_RT_PLUGINFILE] << i; GetRegKey(OldFolderShortcutsKey, ValueName, Item->strPluginFile, L""); ValueName.Clear(); ValueName << RecTypeName[PSCR_RT_PLUGINDATA] << i; GetRegKey(OldFolderShortcutsKey, ValueName, Item->strPluginData, L""); ValueName.Clear(); } return; } for(size_t i = 0; i < KeyCount; i++) { FormatString strFolderShortcuts; strFolderShortcuts << FolderShortcutsKey << i; if (!CheckRegKey(strFolderShortcuts)) continue; for(size_t j=0; ; j++) { FormatString ValueName; ValueName << RecTypeName[PSCR_RT_SHORTCUT] << j; string strValue; if(!GetRegKey(strFolderShortcuts, ValueName, strValue, L"")) break; ValueName.Clear(); ShortcutItem* Item = Items[i].Push(); Item->strFolder = strValue; ValueName << RecTypeName[PSCR_RT_PLUGINMODULE] << j; GetRegKey(strFolderShortcuts, ValueName, Item->strPluginModule, L""); ValueName.Clear(); ValueName << RecTypeName[PSCR_RT_PLUGINFILE] << j; GetRegKey(strFolderShortcuts, ValueName, Item->strPluginFile, L""); ValueName.Clear(); ValueName << RecTypeName[PSCR_RT_PLUGINDATA] << j; GetRegKey(strFolderShortcuts, ValueName, Item->strPluginData, L""); ValueName.Clear(); } } }
// Каллбак для диалога редактирования имени кодовой страницы intptr_t WINAPI EditDialogProc(HANDLE hDlg, intptr_t Msg, intptr_t Param1, void* Param2) { if (Msg==DN_CLOSE) { if (Param1==EDITCP_OK || Param1==EDITCP_RESET) { string strCodePageName; uintptr_t CodePage = GetMenuItemCodePage(); FormatString strCodePage; strCodePage<<CodePage; if (Param1==EDITCP_OK) { FarDialogItemData item = {sizeof(FarDialogItemData)}; item.PtrLength = SendDlgMessage(hDlg, DM_GETTEXT, EDITCP_EDIT, 0); item.PtrData = strCodePageName.GetBuffer(item.PtrLength+1); SendDlgMessage(hDlg, DM_GETTEXT, EDITCP_EDIT, &item); strCodePageName.ReleaseBuffer(); } // Если имя кодовой страницы пустое, то считаем, что имя не задано if (!strCodePageName.GetLength()) GeneralCfg->DeleteValue(NamesOfCodePagesKey, strCodePage); else GeneralCfg->SetValue(NamesOfCodePagesKey, strCodePage, strCodePageName); // Получаем информацию о кодовой странице CPINFOEX cpiex; if (GetCodePageInfo(CodePage, cpiex)) { // Формируем имя таблиц символов bool IsCodePageNameCustom = false; wchar_t *CodePageName = FormatCodePageName(CodePage, cpiex.CodePageName, sizeof(cpiex.CodePageName)/sizeof(wchar_t), IsCodePageNameCustom); // Формируем строку представления strCodePage.Clear(); FormatCodePageString(CodePage, CodePageName, strCodePage, IsCodePageNameCustom); // Обновляем имя кодовой страницы int Position = CodePages->GetSelectPos(); CodePages->DeleteItem(Position); MenuItemEx NewItem; NewItem.Clear(); NewItem.strName = strCodePage; NewItem.UserData = &CodePage; NewItem.UserDataSize = sizeof(CodePage); CodePages->AddItem(&NewItem, Position); CodePages->SetSelectPos(Position, 1); } } } return DefDlgProc(hDlg, Msg, Param1, Param2); }
// Каллбак для диалога редактирования имени кодовой страницы LONG_PTR WINAPI EditDialogProc(HANDLE hDlg, int Msg, int Param1, LONG_PTR Param2) { if (Msg==DN_CLOSE) { if (Param1==EDITCP_OK || Param1==EDITCP_RESET) { FARString strCodePageName; UINT CodePage = GetMenuItemCodePage(); FormatString strCodePage; strCodePage<<CodePage; if (Param1==EDITCP_OK) { wchar_t *CodePageName = strCodePageName.GetBuffer(SendDlgMessage(hDlg, DM_GETTEXTPTR, EDITCP_EDIT, 0)+1); SendDlgMessage(hDlg, DM_GETTEXTPTR, EDITCP_EDIT, (LONG_PTR)CodePageName); strCodePageName.ReleaseBuffer(); } // Если имя кодовой страницы пустое, то считаем, что имя не задано if (!strCodePageName.GetLength()) DeleteRegValue(NamesOfCodePagesKey, strCodePage); else SetRegKey(NamesOfCodePagesKey, strCodePage, strCodePageName); // Получаем информацию о кодовой странице CPINFOEX cpiex; if (GetCodePageInfo(CodePage, cpiex)) { // Формируем имя таблиц символов bool IsCodePageNameCustom = false; wchar_t *CodePageName = FormatCodePageName(CodePage, cpiex.CodePageName, sizeof(cpiex.CodePageName)/sizeof(wchar_t), IsCodePageNameCustom); // Формируем строку представления strCodePage.Clear(); FormatCodePageString(CodePage, CodePageName, strCodePage, IsCodePageNameCustom); // Обновляем имя кодовой страницы int Position = CodePages->GetSelectPos(); CodePages->DeleteItem(Position); MenuItemEx NewItem; NewItem.Clear(); NewItem.strName = strCodePage; NewItem.UserData = (char *)(UINT_PTR)CodePage; NewItem.UserDataSize = sizeof(UINT); CodePages->AddItem(&NewItem, Position); CodePages->SetSelectPos(Position, 1); } } } return DefDlgProc(hDlg, Msg, Param1, Param2); }
static LNGID __FormatEndSelectedPhrase(size_t Count) { LNGID M_Fmt=MListFileSize; if (Count != 1) { FormatString StrItems; StrItems << Count; size_t LenItems= StrItems.GetLength(); if (StrItems.At(LenItems-1) == '1' && Count != 11) M_Fmt=MListFilesSize1; else M_Fmt=MListFilesSize2; } return M_Fmt; }
Shortcuts::~Shortcuts() { for(size_t i = 0; i < KeyCount; i++) { FormatString strFolderShortcuts; strFolderShortcuts << FolderShortcutsKey << i; int index = 0; DeleteKeyTree(strFolderShortcuts); for(ShortcutItem* j = Items[i].First(); j; j = Items[i].Next(j), index++) { FormatString ValueName; ValueName << RecTypeName[PSCR_RT_SHORTCUT] << index; SetRegKey(strFolderShortcuts, ValueName, j->strFolder); ValueName.Clear(); if(!j->strPluginModule.IsEmpty()) { ValueName << RecTypeName[PSCR_RT_PLUGINMODULE] << index; SetRegKey(strFolderShortcuts, ValueName, j->strPluginModule); ValueName.Clear(); } if(!j->strPluginFile.IsEmpty()) { ValueName << RecTypeName[PSCR_RT_PLUGINFILE] << index; SetRegKey(strFolderShortcuts, ValueName, j->strPluginFile); ValueName.Clear(); } if(!j->strPluginData.IsEmpty()) { ValueName << RecTypeName[PSCR_RT_PLUGINDATA] << index; SetRegKey(strFolderShortcuts, ValueName, j->strPluginData); ValueName.Clear(); } } } }
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); }
ShellDelete::ShellDelete(Panel *SrcPanel,bool Wipe): ReadOnlyDeleteMode(-1), m_SkipMode(-1), SkipWipeMode(-1), SkipFoldersMode(-1), ProcessedItems(0) { SCOPED_ACTION(ChangePriority)(Global->Opt->DelThreadPriority); SCOPED_ACTION(TPreRedrawFuncGuard)(std::make_unique<DelPreRedrawItem>()); os::FAR_FIND_DATA FindData; string strDeleteFilesMsg; string strSelName; string strSelShortName; string strDizName; DWORD FileAttr; size_t SelCount; int UpdateDiz; int DizPresent; int Ret; BOOL NeedUpdate=TRUE, NeedSetUpADir=FALSE; bool Opt_DeleteToRecycleBin=Global->Opt->DeleteToRecycleBin; /*& 31.05.2001 OT Запретить перерисовку текущего окна*/ auto WindowFromLaunched = Global->WindowManager->GetCurrentWindow(); WindowFromLaunched->Lock(); bool DeleteAllFolders=!Global->Opt->Confirm.DeleteFolder; UpdateDiz=(Global->Opt->Diz.UpdateMode==DIZ_UPDATE_ALWAYS || (SrcPanel->IsDizDisplayed() && Global->Opt->Diz.UpdateMode==DIZ_UPDATE_IF_DISPLAYED)); SCOPE_EXIT { Global->Opt->DeleteToRecycleBin=Opt_DeleteToRecycleBin; // Разрешить перерисовку окна WindowFromLaunched->Unlock(); if (NeedUpdate) { ShellUpdatePanels(SrcPanel,NeedSetUpADir); } }; if (!(SelCount=SrcPanel->GetSelCount())) return; // Удаление в корзину только для FIXED-дисков { string strRoot; SrcPanel->GetSelName(nullptr,FileAttr); SrcPanel->GetSelName(&strSelName,FileAttr); ConvertNameToFull(strSelName, strRoot); GetPathRoot(strRoot,strRoot); if (Global->Opt->DeleteToRecycleBin && FAR_GetDriveType(strRoot) != DRIVE_FIXED) Global->Opt->DeleteToRecycleBin=0; } if (SelCount==1) { SrcPanel->GetSelName(nullptr,FileAttr); SrcPanel->GetSelName(&strSelName,FileAttr); if (TestParentFolderName(strSelName) || strSelName.empty()) { NeedUpdate=FALSE; return; } strDeleteFilesMsg = strSelName; QuoteLeadingSpace(strDeleteFilesMsg); } else { // в зависимости от числа ставим нужное окончание const wchar_t *Ends; FormatString StrItems; StrItems << SelCount; Ends=MSG(MAskDeleteItemsA); size_t LenItems = StrItems.size(); 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 = LangString(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); string strAskDeleteLink=MSG(MAskDeleteLink); os::fs::file_status Status(strJuncName); if (os::fs::exists(Status)) { strAskDeleteLink+=L" "; strAskDeleteLink += MSG(is_directory(Status)? MAskDeleteLinkFolder : MAskDeleteLinkFile); } Ret=Message(0,2,MSG(MDeleteLinkTitle), strDeleteFilesMsg.data(), strAskDeleteLink.data(), strJuncName.data(), MSG(MDeleteLinkDelete), MSG(MCancel)); if (Ret) return; } } if (Ret && Global->Opt->Confirm.Delete) { LNGID mTitle = Wipe ? MDeleteWipeTitle : MDeleteTitle; LNGID mDText; string tText; LNGID mDBttn = Wipe ? MDeleteWipe : Global->Opt->DeleteToRecycleBin ? MDeleteRecycle : MDelete; bool bHilite = Global->Opt->DelOpt.HighlightSelected; int mshow = std::min(std::max((int)Global->Opt->DelOpt.ShowSelected, 1), ScrY/2); std::vector<string> items; items.push_back(strDeleteFilesMsg); if (SelCount == 1) { bool folder = (FileAttr & FILE_ATTRIBUTE_DIRECTORY) != 0; if (Wipe && !(FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)) mDText = folder ? MAskWipeFolder : MAskWipeFile; else { if (Global->Opt->DeleteToRecycleBin) mDText = folder ? MAskDeleteRecycleFolder : MAskDeleteRecycleFile; else mDText = folder ? MAskDeleteFolder : MAskDeleteFile; } if (bHilite) { string name, sname; SrcPanel->GetCurName(name, sname); QuoteLeadingSpace(name); bHilite = strDeleteFilesMsg != name; } } else { if (Wipe) { mDText = MAskWipe; mTitle = MDeleteWipeTitle; } else mDText = Global->Opt->DeleteToRecycleBin ? MAskDeleteRecycle : MAskDelete; if (mshow > 1) { tText = MSG(mDText) + string(L" ") + strDeleteFilesMsg; items.clear(); DWORD attr; string name; SrcPanel->GetSelName(nullptr, attr); for (size_t i = 0; i < SelCount; ++i) { if (i == (size_t)mshow-1 && i+1 < SelCount) { items.push_back(L"..."); break; } SrcPanel->GetSelName(&name, attr); QuoteLeadingSpace(name); items.push_back(name); } } } intptr_t start_hilite = 0, end_hilite = 0; DialogBuilder Builder(mTitle, nullptr, [&](Dialog* Dlg, intptr_t Msg, intptr_t Param1, void* Param2) -> intptr_t { if (bHilite && Msg == DN_CTLCOLORDLGITEM && Param1 >= start_hilite && Param1 <= end_hilite) { auto Colors = static_cast<FarDialogItemColors*>(Param2); Colors->Colors[0] = Colors->Colors[1]; } return Dlg->DefProc(Msg, Param1, Param2); }); if (tText.empty()) tText = MSG(mDText); Builder.AddText(tText.data())->Flags = DIF_CENTERTEXT; if (bHilite || (mshow > 1 && SelCount > 1)) Builder.AddSeparator(); std::for_each(RANGE(items, i) { TruncStrFromCenter(i, ScrX+1-6*2); auto dx = Builder.AddText(i.data()); dx->Flags = (SelCount <= 1 || mshow <= 1 ? DIF_CENTERTEXT : 0) | DIF_SHOWAMPERSAND; size_t index = Builder.GetLastID(); end_hilite = index; if (!start_hilite) start_hilite = index; });
string & FileSizeToStr(string &strDestStr, unsigned __int64 Size, int Width, unsigned __int64 ViewFlags) { FormatString strStr; unsigned __int64 Divider; size_t IndexDiv, IndexB; // подготовительные мероприятия if (!UnitStr[0][0][0]) { PrepareUnitStr(); } bool Commas=(ViewFlags & COLUMN_COMMAS)!=0; bool FloatSize=(ViewFlags & COLUMN_FLOATSIZE)!=0; bool Economic=(ViewFlags & COLUMN_ECONOMIC)!=0; bool UseMinSizeIndex=(ViewFlags & COLUMN_MINSIZEINDEX)!=0; size_t MinSizeIndex=(ViewFlags & COLUMN_MINSIZEINDEX_MASK)+1; bool ShowBytesIndex=(ViewFlags & COLUMN_SHOWBYTESINDEX)!=0; if (ViewFlags & COLUMN_THOUSAND) { Divider=1000; IndexDiv=0; } else { Divider=1024; IndexDiv=1; } unsigned __int64 Sz = Size, Divider2 = Divider/2, Divider64 = Divider, OldSize; if (FloatSize) { unsigned __int64 Divider64F = 1, Divider64F_mul = 1000, Divider64F2 = 1, Divider64F2_mul = Divider; //выравнивание идёт по 1000 но само деление происходит на Divider //например 999 bytes покажутся как 999 а вот 1000 bytes уже покажутся как 0.97 K for (IndexB=0; IndexB<UNIT_COUNT-1; IndexB++) { if (Sz < Divider64F*Divider64F_mul) break; Divider64F = Divider64F*Divider64F_mul; Divider64F2 = Divider64F2*Divider64F2_mul; } if (!IndexB) { strStr << Sz; } else { Sz = (OldSize=Sz) / Divider64F2; OldSize = (OldSize % Divider64F2) / (Divider64F2 / Divider64F2_mul); DWORD Decimal = (DWORD)(0.5+(double)(DWORD)OldSize/(double)Divider*100.0); if (Decimal >= 100) { Decimal -= 100; Sz++; } strStr << Sz << L"." << fmt::MinWidth(2) << fmt::FillChar(L'0') << Decimal; FormatNumber(strStr,strStr,2); } if (IndexB>0 || ShowBytesIndex) { Width-=(Economic?1:2); if (Width<0) Width=0; if (Economic) strDestStr.Format(L"%*.*s%1.1s",Width,Width,strStr.CPtr(),UnitStr[IndexB][IndexDiv]); else strDestStr.Format(L"%*.*s %1.1s",Width,Width,strStr.CPtr(),UnitStr[IndexB][IndexDiv]); } else strDestStr.Format(L"%*.*s",Width,Width,strStr.CPtr()); return strDestStr; } if (Commas) InsertCommas(Sz,strStr); else strStr << Sz; if ((!UseMinSizeIndex && strStr.GetLength()<=static_cast<size_t>(Width)) || Width<5) { if (ShowBytesIndex) { Width-=(Economic?1:2); if (Width<0) Width=0; if (Economic) strDestStr.Format(L"%*.*s%1.1s",Width,Width,strStr.CPtr(),UnitStr[0][IndexDiv]); else strDestStr.Format(L"%*.*s %1.1s",Width,Width,strStr.CPtr(),UnitStr[0][IndexDiv]); } else strDestStr.Format(L"%*.*s",Width,Width,strStr.CPtr()); } else { Width-=(Economic?1:2); IndexB=0; do { //Sz=(Sz+Divider2)/Divider64; Sz = (OldSize=Sz) / Divider64; if ((OldSize % Divider64) > Divider2) ++Sz; IndexB++; if (Commas) { InsertCommas(Sz,strStr); } else { strStr.Clear(); strStr << Sz; } } while ((UseMinSizeIndex && IndexB<MinSizeIndex) || strStr.GetLength() > static_cast<size_t>(Width)); if (Economic) strDestStr.Format(L"%*.*s%1.1s",Width,Width,strStr.CPtr(),UnitStr[IndexB][IndexDiv]); else strDestStr.Format(L"%*.*s %1.1s",Width,Width,strStr.CPtr(),UnitStr[IndexB][IndexDiv]); } return strDestStr; }
void ShellDelete(Panel *SrcPanel,bool 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; size_t SelCount; int UpdateDiz; int DizPresent; int Ret; BOOL NeedUpdate=TRUE, NeedSetUpADir=FALSE; bool 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; FormatString StrItems; StrItems << SelCount; Ends=MSG(MAskDeleteItemsA); size_t LenItems = StrItems.GetLength(); if (LenItems > 0) { if ((LenItems >= 2 && StrItems.At(LenItems-2) == L'1') || StrItems.At(LenItems-1) >= L'5' || StrItems.At(LenItems-1) == L'0') Ends=MSG(MAskDeleteItemsS); else if (StrItems.At(LenItems-1) == L'1') Ends=MSG(MAskDeleteItems0); } strDeleteFilesMsg = LangString(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 (ItemsCount > 1 && (CurTime-StartTime>(DWORD)Opt.RedrawTimeout || FirstTime)) { StartTime=CurTime; FirstTime=false; if (CheckForEscSilent() && ConfirmAbortOp()) { Cancel=true; break; } ShellDeleteMsg(strSelName, DEL_SCAN, 0, 0); } DirInfoData Data = {}; if (GetDirInfo(nullptr, strSelName, Data, -1, nullptr, 0) > 0) { ItemsCount+=Data.FileCount+Data.DirCount+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(); int TotalPercent = (Opt.DelOpt.DelShowTotal && ItemsCount >1)?(ProcessedItems*100/ItemsCount):-1; if (CurTime-StartTime>(DWORD)Opt.RedrawTimeout || FirstTime) { StartTime=CurTime; FirstTime=false; if (CheckForEscSilent() && ConfirmAbortOp()) { Cancel=true; break; } ShellDeleteMsg(strSelName, Wipe?DEL_WIPE:DEL_DEL, TotalPercent, 0); } 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(); int TotalPercent = (Opt.DelOpt.DelShowTotal && ItemsCount >1)?(ProcessedItems*100/ItemsCount):-1; if (CurTime-StartTime>(DWORD)Opt.RedrawTimeout) { StartTime=CurTime; if (CheckForEscSilent()) { int AbortOp = ConfirmAbortOp(); if (AbortOp) { Cancel=true; break; } } ShellDeleteMsg(strFullName,Wipe?DEL_WIPE:DEL_DEL, TotalPercent, 0); } 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? D_WIPE : D_DEL); 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? D_WIPE : D_DEL); 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,TotalPercent)==DELETE_CANCEL) { Cancel=true; break; } } } } if (!Cancel) { if (FileAttr & FILE_ATTRIBUTE_READONLY) apiSetFileAttributes(strSelName,FILE_ATTRIBUTE_NORMAL); int DeleteCode; // нефига здесь выделываться, а надо учесть, что удаление // симлинка в корзину чревато потерей оригинала. DIRDELTYPE Type = Wipe? D_WIPE : D_DEL; if (Opt.DeleteToRecycleBin && !(DirSymLink && WinVer < _WIN32_WINNT_VISTA)) Type = D_RECYCLE; DeleteCode=ERemoveDirectory(strSelName, Type); if (DeleteCode==DELETE_CANCEL) break; else if (DeleteCode==DELETE_SUCCESS) { 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,TotalPercent); 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); } }
void QuickView::DisplayObject() { if (Flags.Check(FSCROBJ_ISREDRAWING)) return; Flags.Set(FSCROBJ_ISREDRAWING); FARString strTitle; if (!QView && !ProcessingPluginCommand) CtrlObject->Cp()->GetAnotherPanel(this)->UpdateViewPanel(); if (QView) QView->SetPosition(X1+1,Y1+1,X2-1,Y2-3); Box(X1,Y1,X2,Y2,COL_PANELBOX,DOUBLE_BOX); SetScreen(X1+1,Y1+1,X2-1,Y2-1,L' ',COL_PANELTEXT); SetColor(Focus ? COL_PANELSELECTEDTITLE:COL_PANELTITLE); GetTitle(strTitle); if (!strTitle.IsEmpty()) { GotoXY(X1+(X2-X1+1-(int)strTitle.GetLength())/2,Y1); Text(strTitle); } DrawSeparator(Y2-2); SetColor(COL_PANELTEXT); GotoXY(X1+1,Y2-1); FS<<fmt::LeftAlign()<<fmt::Width(X2-X1-1)<<fmt::Precision(X2-X1-1)<<PointToName(strCurFileName); if (!strCurFileType.IsEmpty()) { FARString strTypeText=L" "; strTypeText+=strCurFileType; strTypeText+=L" "; TruncStr(strTypeText,X2-X1-1); SetColor(COL_PANELSELECTEDINFO); GotoXY(X1+(X2-X1+1-(int)strTypeText.GetLength())/2,Y2-2); Text(strTypeText); } if (Directory) { FormatString FString; FString<<MSG(MQuickViewFolder)<<L" \""<<strCurFileName<<L"\""; SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+2); PrintText(FString); /*if ((apiGetFileAttributes(strCurFileName)&FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT) { FARString strJuncName; DWORD ReparseTag=0; if (GetReparsePointInfo(strCurFileName, strJuncName,&ReparseTag)) { int ID_Msg=MQuickViewJunction; if (ReparseTag==IO_REPARSE_TAG_MOUNT_POINT) { if (IsLocalVolumeRootPath(strJuncName)) { ID_Msg=MQuickViewVolMount; } } else if (ReparseTag==IO_REPARSE_TAG_SYMLINK) { ID_Msg=MQuickViewSymlink; } //"\??\D:\Junc\Src\" NormalizeSymlinkName(strJuncName); TruncPathStr(strJuncName,X2-X1-1-StrLength(MSG(ID_Msg))); FString.Clear(); FString<<MSG(ID_Msg)<<L" \""<<strJuncName<<L"\""; SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+3); PrintText(FString); } }*/ if (Directory==1 || Directory==4) { GotoXY(X1+2,Y1+4); PrintText(MSG(MQuickViewContains)); GotoXY(X1+2,Y1+6); PrintText(MSG(MQuickViewFolders)); SetColor(COL_PANELINFOTEXT); FString.Clear(); FString<<DirCount; PrintText(FString); SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+7); PrintText(MSG(MQuickViewFiles)); SetColor(COL_PANELINFOTEXT); FString.Clear(); FString<<FileCount; PrintText(FString); SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+8); PrintText(MSG(MQuickViewBytes)); SetColor(COL_PANELINFOTEXT); FARString strSize; InsertCommas(FileSize,strSize); PrintText(strSize); SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+9); PrintText(MSG(MQuickViewCompressed)); SetColor(COL_PANELINFOTEXT); InsertCommas(CompressedFileSize,strSize); PrintText(strSize); SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+10); PrintText(MSG(MQuickViewRatio)); SetColor(COL_PANELINFOTEXT); FString.Clear(); FString<<ToPercent64(CompressedFileSize,FileSize)<<L"%"; PrintText(FString); if (Directory!=4 && RealFileSize>=CompressedFileSize) { SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+12); PrintText(MSG(MQuickViewCluster)); SetColor(COL_PANELINFOTEXT); FARString strSize; InsertCommas(ClusterSize,strSize); PrintText(strSize); SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+13); PrintText(MSG(MQuickViewRealSize)); SetColor(COL_PANELINFOTEXT); InsertCommas(RealFileSize,strSize); PrintText(strSize); SetColor(COL_PANELTEXT); GotoXY(X1+2,Y1+14); PrintText(MSG(MQuickViewSlack)); SetColor(COL_PANELINFOTEXT); InsertCommas(RealFileSize-CompressedFileSize,strSize); uint64_t Size1=RealFileSize-CompressedFileSize; uint64_t Size2=RealFileSize; while ((Size2 >> 32) ) { Size1=Size1>>1; Size2=Size2>>1; } FString.Clear(); FString<<strSize<<L" ("<<ToPercent((DWORD)Size1, (DWORD)Size2)<<L"%)"; PrintText(FString); } }