| // HashGUI.cpp |
| |
| #include "StdAfx.h" |
| |
| #include "../../../Common/IntToString.h" |
| #include "../../../Common/StringConvert.h" |
| |
| #include "../../../Windows/ErrorMsg.h" |
| |
| #include "../FileManager/FormatUtils.h" |
| #include "../FileManager/LangUtils.h" |
| #include "../FileManager/ListViewDialog.h" |
| #include "../FileManager/OverwriteDialogRes.h" |
| #include "../FileManager/ProgressDialog2.h" |
| #include "../FileManager/ProgressDialog2Res.h" |
| #include "../FileManager/PropertyNameRes.h" |
| #include "../FileManager/resourceGui.h" |
| |
| #include "HashGUI.h" |
| |
| using namespace NWindows; |
| |
| |
| |
| class CHashCallbackGUI Z7_final: public CProgressThreadVirt, public IHashCallbackUI |
| { |
| UInt64 NumFiles; |
| bool _curIsFolder; |
| UString FirstFileName; |
| // UString MainPath; |
| |
| CPropNameValPairs PropNameValPairs; |
| |
| HRESULT ProcessVirt() Z7_override; |
| virtual void ProcessWasFinished_GuiVirt() Z7_override; |
| |
| public: |
| const NWildcard::CCensor *censor; |
| const CHashOptions *options; |
| |
| DECL_EXTERNAL_CODECS_LOC_VARS_DECL |
| |
| Z7_IFACE_IMP(IDirItemsCallback) |
| Z7_IFACE_IMP(IHashCallbackUI) |
| |
| /* |
| void AddErrorMessage(DWORD systemError, const wchar_t *name) |
| { |
| Sync.AddError_Code_Name(systemError, name); |
| } |
| */ |
| void AddErrorMessage(HRESULT systemError, const wchar_t *name) |
| { |
| Sync.AddError_Code_Name(systemError, name); |
| } |
| }; |
| |
| |
| void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value) |
| { |
| CProperty &pair = pairs.AddNew(); |
| AddLangString(pair.Name, resourceID); |
| char sz[32]; |
| ConvertUInt64ToString(value, sz); |
| pair.Value = sz; |
| } |
| |
| |
| void AddSizeValue(UString &s, UInt64 value) |
| { |
| { |
| wchar_t sz[32]; |
| ConvertUInt64ToString(value, sz); |
| s += MyFormatNew(IDS_FILE_SIZE, sz); |
| } |
| if (value >= (1 << 10)) |
| { |
| char c; |
| if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; } |
| else if (value >= (10 << 20)) { value >>= 20; c = 'M'; } |
| else { value >>= 10; c = 'K'; } |
| |
| s += " ("; |
| s.Add_UInt64(value); |
| s.Add_Space(); |
| s += (wchar_t)c; |
| s += "iB)"; |
| } |
| } |
| |
| void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value) |
| { |
| CProperty &pair = pairs.AddNew(); |
| LangString(resourceID, pair.Name); |
| AddSizeValue(pair.Value, value); |
| } |
| |
| |
| HRESULT CHashCallbackGUI::StartScanning() |
| { |
| CProgressSync &sync = Sync; |
| sync.Set_Status(LangString(IDS_SCANNING)); |
| return CheckBreak(); |
| } |
| |
| HRESULT CHashCallbackGUI::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir) |
| { |
| return Sync.ScanProgress(st.NumFiles, st.GetTotalBytes(), path, isDir); |
| } |
| |
| HRESULT CHashCallbackGUI::ScanError(const FString &path, DWORD systemError) |
| { |
| AddErrorMessage(HRESULT_FROM_WIN32(systemError), fs2us(path)); |
| return CheckBreak(); |
| } |
| |
| HRESULT CHashCallbackGUI::FinishScanning(const CDirItemsStat &st) |
| { |
| return ScanProgress(st, FString(), false); // isDir |
| } |
| |
| HRESULT CHashCallbackGUI::CheckBreak() |
| { |
| return Sync.CheckStop(); |
| } |
| |
| HRESULT CHashCallbackGUI::SetNumFiles(UInt64 numFiles) |
| { |
| CProgressSync &sync = Sync; |
| sync.Set_NumFilesTotal(numFiles); |
| return CheckBreak(); |
| } |
| |
| HRESULT CHashCallbackGUI::SetTotal(UInt64 size) |
| { |
| CProgressSync &sync = Sync; |
| sync.Set_NumBytesTotal(size); |
| return CheckBreak(); |
| } |
| |
| HRESULT CHashCallbackGUI::SetCompleted(const UInt64 *completed) |
| { |
| return Sync.Set_NumBytesCur(completed); |
| } |
| |
| HRESULT CHashCallbackGUI::BeforeFirstFile(const CHashBundle & /* hb */) |
| { |
| return S_OK; |
| } |
| |
| HRESULT CHashCallbackGUI::GetStream(const wchar_t *name, bool isFolder) |
| { |
| if (NumFiles == 0) |
| FirstFileName = name; |
| _curIsFolder = isFolder; |
| CProgressSync &sync = Sync; |
| sync.Set_FilePath(name, isFolder); |
| return CheckBreak(); |
| } |
| |
| HRESULT CHashCallbackGUI::OpenFileError(const FString &path, DWORD systemError) |
| { |
| // if (systemError == ERROR_SHARING_VIOLATION) |
| { |
| AddErrorMessage(HRESULT_FROM_WIN32(systemError), fs2us(path)); |
| return S_FALSE; |
| } |
| // return systemError; |
| } |
| |
| HRESULT CHashCallbackGUI::SetOperationResult(UInt64 /* fileSize */, const CHashBundle & /* hb */, bool /* showHash */) |
| { |
| CProgressSync &sync = Sync; |
| if (!_curIsFolder) |
| NumFiles++; |
| sync.Set_NumFilesCur(NumFiles); |
| return CheckBreak(); |
| } |
| |
| static const unsigned k_DigestStringSize = k_HashCalc_DigestSize_Max * 2 + k_HashCalc_ExtraSize * 2 + 16; |
| |
| static void AddHashString(CProperty &s, const CHasherState &h, unsigned digestIndex) |
| { |
| char temp[k_DigestStringSize]; |
| h.WriteToString(digestIndex, temp); |
| s.Value = temp; |
| } |
| |
| static void AddHashResString(CPropNameValPairs &s, const CHasherState &h, unsigned digestIndex, UInt32 resID) |
| { |
| CProperty &pair = s.AddNew(); |
| UString &s2 = pair.Name; |
| LangString(resID, s2); |
| UString name (h.Name); |
| s2.Replace(L"CRC", name); |
| s2.Replace(L":", L""); |
| AddHashString(pair, h, digestIndex); |
| } |
| |
| |
| void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb) |
| { |
| if (hb.NumErrors != 0) |
| AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors); |
| |
| if (hb.NumFiles == 1 && hb.NumDirs == 0 && !hb.FirstFileName.IsEmpty()) |
| { |
| CProperty &pair = s.AddNew(); |
| LangString(IDS_PROP_NAME, pair.Name); |
| pair.Value = hb.FirstFileName; |
| } |
| else |
| { |
| if (!hb.MainName.IsEmpty()) |
| { |
| CProperty &pair = s.AddNew(); |
| LangString(IDS_PROP_NAME, pair.Name); |
| pair.Value = hb.MainName; |
| } |
| if (hb.NumDirs != 0) |
| AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs); |
| AddValuePair(s, IDS_PROP_FILES, hb.NumFiles); |
| } |
| |
| AddSizeValuePair(s, IDS_PROP_SIZE, hb.FilesSize); |
| |
| if (hb.NumAltStreams != 0) |
| { |
| AddValuePair(s, IDS_PROP_NUM_ALT_STREAMS, hb.NumAltStreams); |
| AddSizeValuePair(s, IDS_PROP_ALT_STREAMS_SIZE, hb.AltStreamsSize); |
| } |
| |
| FOR_VECTOR (i, hb.Hashers) |
| { |
| const CHasherState &h = hb.Hashers[i]; |
| if (hb.NumFiles == 1 && hb.NumDirs == 0) |
| { |
| CProperty &pair = s.AddNew(); |
| pair.Name += h.Name; |
| AddHashString(pair, h, k_HashCalc_Index_DataSum); |
| } |
| else |
| { |
| AddHashResString(s, h, k_HashCalc_Index_DataSum, IDS_CHECKSUM_CRC_DATA); |
| AddHashResString(s, h, k_HashCalc_Index_NamesSum, IDS_CHECKSUM_CRC_DATA_NAMES); |
| } |
| if (hb.NumAltStreams != 0) |
| { |
| AddHashResString(s, h, k_HashCalc_Index_StreamsSum, IDS_CHECKSUM_CRC_STREAMS_NAMES); |
| } |
| } |
| } |
| |
| |
| void AddHashBundleRes(UString &s, const CHashBundle &hb) |
| { |
| CPropNameValPairs pairs; |
| AddHashBundleRes(pairs, hb); |
| |
| FOR_VECTOR (i, pairs) |
| { |
| const CProperty &pair = pairs[i]; |
| s += pair.Name; |
| s += ": "; |
| s += pair.Value; |
| s.Add_LF(); |
| } |
| |
| if (hb.NumErrors == 0 && hb.Hashers.IsEmpty()) |
| { |
| s.Add_LF(); |
| AddLangString(s, IDS_MESSAGE_NO_ERRORS); |
| s.Add_LF(); |
| } |
| } |
| |
| |
| HRESULT CHashCallbackGUI::AfterLastFile(CHashBundle &hb) |
| { |
| hb.FirstFileName = FirstFileName; |
| // MainPath |
| AddHashBundleRes(PropNameValPairs, hb); |
| |
| CProgressSync &sync = Sync; |
| sync.Set_NumFilesCur(hb.NumFiles); |
| |
| // CProgressMessageBoxPair &pair = GetMessagePair(hb.NumErrors != 0); |
| // pair.Message = s; |
| // LangString(IDS_CHECKSUM_INFORMATION, pair.Title); |
| |
| return S_OK; |
| } |
| |
| |
| HRESULT CHashCallbackGUI::ProcessVirt() |
| { |
| NumFiles = 0; |
| AString errorInfo; |
| HRESULT res = HashCalc(EXTERNAL_CODECS_LOC_VARS |
| *censor, *options, errorInfo, this); |
| return res; |
| } |
| |
| |
| HRESULT HashCalcGUI( |
| DECL_EXTERNAL_CODECS_LOC_VARS |
| const NWildcard::CCensor &censor, |
| const CHashOptions &options, |
| bool &messageWasDisplayed) |
| { |
| CHashCallbackGUI t; |
| #ifdef Z7_EXTERNAL_CODECS |
| t._externalCodecs = _externalCodecs; |
| #endif |
| t.censor = &censor; |
| t.options = &options; |
| |
| t.ShowCompressionInfo = false; |
| |
| const UString title = LangString(IDS_CHECKSUM_CALCULATING); |
| |
| t.MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE); |
| t.MainAddTitle = title; |
| t.MainAddTitle.Add_Space(); |
| |
| RINOK(t.Create(title)) |
| messageWasDisplayed = t.ThreadFinishedOK && t.MessagesDisplayed; |
| return S_OK; |
| } |
| |
| |
| void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd) |
| { |
| CListViewDialog lv; |
| |
| FOR_VECTOR (i, propPairs) |
| { |
| const CProperty &pair = propPairs[i]; |
| lv.Strings.Add(pair.Name); |
| lv.Values.Add(pair.Value); |
| } |
| |
| lv.Title = LangString(IDS_CHECKSUM_INFORMATION); |
| lv.DeleteIsAllowed = true; |
| lv.SelectFirst = false; |
| lv.NumColumns = 2; |
| |
| lv.Create(hwnd); |
| } |
| |
| |
| void ShowHashResults(const CHashBundle &hb, HWND hwnd) |
| { |
| CPropNameValPairs propPairs; |
| AddHashBundleRes(propPairs, hb); |
| ShowHashResults(propPairs, hwnd); |
| } |
| |
| void CHashCallbackGUI::ProcessWasFinished_GuiVirt() |
| { |
| if (Result != E_ABORT) |
| ShowHashResults(PropNameValPairs, *this); |
| } |