diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/FileManager')
37 files changed, 5904 insertions, 0 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp new file mode 100644 index 00000000000..066ac219190 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp @@ -0,0 +1,1024 @@ +// BrowseDialog.cpp + +#include "StdAfx.h" + +#include "../../../Common/MyWindows.h" + +#include <commctrl.h> + +#ifndef UNDER_CE +#include "../../../Windows/CommonDialog.h" +#include "../../../Windows/Shell.h" +#endif + +#include "../../../Windows/FileName.h" +#include "../../../Windows/FileFind.h" + +#ifdef UNDER_CE +#include <commdlg.h> +#endif + +#include "BrowseDialog.h" + +#define USE_MY_BROWSE_DIALOG + +#ifdef USE_MY_BROWSE_DIALOG + +#include "../../../Common/Defs.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/Wildcard.h" + +#include "../../../Windows/FileDir.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/Edit.h" +#include "../../../Windows/Control/ListView.h" + +#include "BrowseDialogRes.h" +#include "PropertyNameRes.h" +#include "SysIconUtils.h" + +#ifndef _SFX +#include "RegistryUtils.h" +#endif + +#endif + +#include "ComboDialog.h" +#include "LangUtils.h" + +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; +using namespace NFind; + +#ifdef USE_MY_BROWSE_DIALOG + +extern bool g_LVN_ITEMACTIVATE_Support; + +static const int kParentIndex = -1; +static const UINT k_Message_RefreshPathEdit = WM_APP + 1; + +static HRESULT GetNormalizedError() +{ + DWORD errorCode = GetLastError(); + return errorCode == 0 ? E_FAIL : errorCode; +} + +extern UString HResultToMessage(HRESULT errorCode); + +static void MessageBox_Error_Global(HWND wnd, const wchar_t *message) +{ + ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR); +} + +static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *name) +{ + UString s = HResultToMessage(errorCode); + if (name) + { + s.Add_LF(); + s += name; + } + MessageBox_Error_Global(wnd, s); +} + +class CBrowseDialog: public NControl::CModalDialog +{ + NControl::CListView _list; + NControl::CEdit _pathEdit; + NControl::CComboBox _filterCombo; + + CObjectVector<CFileInfo> _files; + + CExtToIconMap _extToIconMap; + int _sortIndex; + bool _ascending; + bool _showDots; + UString _topDirPrefix; // we don't open parent of that folder + UString DirPrefix; + + virtual bool OnInit(); + virtual bool OnSize(WPARAM wParam, int xSize, int ySize); + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnNotify(UINT controlID, LPNMHDR header); + virtual bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnOK(); + + void Post_RefreshPathEdit() { PostMsg(k_Message_RefreshPathEdit); } + + bool GetParentPath(const UString &path, UString &parentPrefix, UString &name); + // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter + HRESULT Reload(const UString &pathPrefix, const UString &selectedName); + HRESULT Reload(); + + void OpenParentFolder(); + void SetPathEditText(); + void OnCreateDir(); + void OnItemEnter(); + void FinishOnOK(); + + int GetRealItemIndex(int indexInListView) const + { + LPARAM param; + if (!_list.GetItemParam(indexInListView, param)) + return (int)-1; + return (int)param; + } + +public: + bool FolderMode; + UString Title; + UString FilePath; // input/ result path + bool ShowAllFiles; + UStringVector Filters; + UString FilterDescription; + + CBrowseDialog(): FolderMode(false), _showDots(false), ShowAllFiles(true) {} + void SetFilter(const UString &s); + INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_BROWSE, parent); } + int CompareItems(LPARAM lParam1, LPARAM lParam2); +}; + +void CBrowseDialog::SetFilter(const UString &s) +{ + Filters.Clear(); + UString mask; + unsigned i; + for (i = 0; i < s.Len(); i++) + { + wchar_t c = s[i]; + if (c == ';') + { + if (!mask.IsEmpty()) + Filters.Add(mask); + mask.Empty(); + } + else + mask += c; + } + if (!mask.IsEmpty()) + Filters.Add(mask); + ShowAllFiles = Filters.IsEmpty(); + for (i = 0; i < Filters.Size(); i++) + { + const UString &f = Filters[i]; + if (f == L"*.*" || f == L"*") + { + ShowAllFiles = true; + break; + } + } +} + +bool CBrowseDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItems(*this, NULL, 0); + #endif + if (!Title.IsEmpty()) + SetText(Title); + _list.Attach(GetItem(IDL_BROWSE)); + _filterCombo.Attach(GetItem(IDC_BROWSE_FILTER)); + _pathEdit.Attach(GetItem(IDE_BROWSE_PATH)); + + if (FolderMode) + HideItem(IDC_BROWSE_FILTER); + else + EnableItem(IDC_BROWSE_FILTER, false); + + #ifndef UNDER_CE + _list.SetUnicodeFormat(); + #endif + + #ifndef _SFX + CFmSettings st; + st.Load(); + if (st.SingleClick) + _list.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT); + _showDots = st.ShowDots; + #endif + + { + UString s; + if (!FilterDescription.IsEmpty()) + s = FilterDescription; + else if (ShowAllFiles) + s = L"*.*"; + else + { + FOR_VECTOR (i, Filters) + { + if (i != 0) + s.Add_Space(); + s += Filters[i]; + } + } + _filterCombo.AddString(s); + _filterCombo.SetCurSel(0); + } + + _list.SetImageList(GetSysImageList(true), LVSIL_SMALL); + _list.SetImageList(GetSysImageList(false), LVSIL_NORMAL); + + _list.InsertColumn(0, LangString(IDS_PROP_NAME), 100); + _list.InsertColumn(1, LangString(IDS_PROP_MTIME), 100); + { + LV_COLUMNW column; + column.iSubItem = 2; + column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + column.fmt = LVCFMT_RIGHT; + column.cx = 100; + const UString s = LangString(IDS_PROP_SIZE); + column.pszText = (wchar_t *)(const wchar_t *)s; + _list.InsertColumn(2, &column); + } + + _list.InsertItem(0, L"12345678901234567" + #ifndef UNDER_CE + L"1234567890" + #endif + ); + _list.SetSubItem(0, 1, L"2009-09-09" + #ifndef UNDER_CE + L" 09:09" + #endif + ); + _list.SetSubItem(0, 2, L"9999 MB"); + for (int i = 0; i < 3; i++) + _list.SetColumnWidthAuto(i); + _list.DeleteAllItems(); + + _ascending = true; + _sortIndex = 0; + + NormalizeSize(); + + _topDirPrefix.Empty(); + { + int rootSize = GetRootPrefixSize(FilePath); + #if defined(_WIN32) && !defined(UNDER_CE) + // We can go up from root folder to drives list + if (IsDrivePath(FilePath)) + rootSize = 0; + else if (IsSuperPath(FilePath)) + { + if (IsDrivePath(FilePath.Ptr(kSuperPathPrefixSize))) + rootSize = kSuperPathPrefixSize; + } + #endif + _topDirPrefix.SetFrom(FilePath, rootSize); + } + + UString name; + if (!GetParentPath(FilePath, DirPrefix, name)) + DirPrefix = _topDirPrefix; + + for (;;) + { + UString baseFolder = DirPrefix; + if (Reload(baseFolder, name) == S_OK) + break; + name.Empty(); + if (DirPrefix.IsEmpty()) + break; + UString parent, name2; + GetParentPath(DirPrefix, parent, name2); + DirPrefix = parent; + } + + if (name.IsEmpty()) + name = FilePath; + if (FolderMode) + NormalizeDirPathPrefix(name); + _pathEdit.SetText(name); + + #ifndef UNDER_CE + /* If we clear UISF_HIDEFOCUS, the focus rectangle in ListView will be visible, + even if we use mouse for pressing the button to open this dialog. */ + PostMsg(MY__WM_UPDATEUISTATE, MAKEWPARAM(MY__UIS_CLEAR, MY__UISF_HIDEFOCUS)); + #endif + + return CModalDialog::OnInit(); +} + +bool CBrowseDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + { + RECT r; + GetClientRectOfItem(IDB_BROWSE_PARENT, r); + mx = r.left; + my = r.top; + } + InvalidateRect(NULL); + + int xLim = xSize - mx; + { + RECT r; + GetClientRectOfItem(IDT_BROWSE_FOLDER, r); + MoveItem(IDT_BROWSE_FOLDER, r.left, r.top, xLim - r.left, RECT_SIZE_Y(r)); + } + + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDOK, bx2, by); + int y = ySize - my - by; + int x = xLim - bx1; + MoveItem(IDCANCEL, x, y, bx1, by); + MoveItem(IDOK, x - mx - bx2, y, bx2, by); + + // Y_Size of ComboBox is tricky. So we use Y_Size of _pathEdit instead + + int yPathSize; + { + RECT r; + GetClientRectOfItem(IDE_BROWSE_PATH, r); + yPathSize = RECT_SIZE_Y(r); + _pathEdit.Move(r.left, y - my - yPathSize - my - yPathSize, xLim - r.left, yPathSize); + } + + { + RECT r; + GetClientRectOfItem(IDC_BROWSE_FILTER, r); + _filterCombo.Move(r.left, y - my - yPathSize, xLim - r.left, RECT_SIZE_Y(r)); + } + + { + RECT r; + GetClientRectOfItem(IDL_BROWSE, r); + _list.Move(r.left, r.top, xLim - r.left, y - my - yPathSize - my - yPathSize - my - r.top); + } + + return false; +} + +bool CBrowseDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == k_Message_RefreshPathEdit) + { + SetPathEditText(); + return true; + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + +bool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header) +{ + if (header->hwndFrom != _list) + return false; + switch (header->code) + { + case LVN_ITEMACTIVATE: + if (g_LVN_ITEMACTIVATE_Support) + OnItemEnter(); + break; + case NM_DBLCLK: + case NM_RETURN: // probabably it's unused + if (!g_LVN_ITEMACTIVATE_Support) + OnItemEnter(); + break; + case LVN_COLUMNCLICK: + { + int index = LPNMLISTVIEW(header)->iSubItem; + if (index == _sortIndex) + _ascending = !_ascending; + else + { + _ascending = (index == 0); + _sortIndex = index; + } + Reload(); + return false; + } + case LVN_KEYDOWN: + { + bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header)); + Post_RefreshPathEdit(); + return boolResult; + } + case NM_RCLICK: + case NM_CLICK: + case LVN_BEGINDRAG: + Post_RefreshPathEdit(); + break; + } + return false; +} + +bool CBrowseDialog::OnKeyDown(LPNMLVKEYDOWN keyDownInfo) +{ + bool ctrl = IsKeyDown(VK_CONTROL); + + switch (keyDownInfo->wVKey) + { + case VK_BACK: + OpenParentFolder(); + return true; + case 'R': + if (ctrl) + { + Reload(); + return true; + } + return false; + case VK_F7: + OnCreateDir(); + return true; + } + return false; +} + +bool CBrowseDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDB_BROWSE_PARENT: OpenParentFolder(); break; + case IDB_BROWSE_CREATE_DIR: OnCreateDir(); break; + default: return CModalDialog::OnButtonClicked(buttonID, buttonHWND); + } + _list.SetFocus(); + return true; +} + +void CBrowseDialog::OnOK() +{ + /* When we press "Enter" in listview, Windows sends message to first Button. + We check that message was from ListView; */ + if (GetFocus() == _list) + { + OnItemEnter(); + return; + } + FinishOnOK(); +} + + +bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, UString &name) +{ + parentPrefix.Empty(); + name.Empty(); + if (path.IsEmpty()) + return false; + if (_topDirPrefix == path) + return false; + UString s = path; + if (s.Back() == WCHAR_PATH_SEPARATOR) + s.DeleteBack(); + if (s.IsEmpty()) + return false; + if (s.Back() == WCHAR_PATH_SEPARATOR) + return false; + int pos = s.ReverseFind_PathSepar(); + parentPrefix.SetFrom(s, pos + 1); + name = s.Ptr(pos + 1); + return true; +} + +int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2) +{ + if (lParam1 == kParentIndex) return -1; + if (lParam2 == kParentIndex) return 1; + const CFileInfo &f1 = _files[(int)lParam1]; + const CFileInfo &f2 = _files[(int)lParam2]; + + bool isDir1 = f1.IsDir(); + bool isDir2 = f2.IsDir(); + if (isDir1 && !isDir2) return -1; + if (isDir2 && !isDir1) return 1; + + int res = 0; + switch (_sortIndex) + { + case 0: res = CompareFileNames(fs2us(f1.Name), fs2us(f2.Name)); break; + case 1: res = CompareFileTime(&f1.MTime, &f2.MTime); break; + case 2: res = MyCompare(f1.Size, f2.Size); break; + } + return _ascending ? res: -res; +} + +static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + return ((CBrowseDialog *)lpData)->CompareItems(lParam1, lParam2); +} + +static void ConvertSizeToString(UInt64 v, wchar_t *s) +{ + Byte c = 0; + if (v >= ((UInt64)10000 << 20)) { v >>= 30; c = 'G'; } + else if (v >= ((UInt64)10000 << 10)) { v >>= 20; c = 'M'; } + else if (v >= ((UInt64)10000 << 0)) { v >>= 10; c = 'K'; } + ConvertUInt64ToString(v, s); + if (c != 0) + { + s += MyStringLen(s); + *s++ = ' '; + *s++ = c; + *s++ = 0; + } +} + +// Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter + +HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selectedName) +{ + CObjectVector<CFileInfo> files; + + #ifndef UNDER_CE + bool isDrive = false; + if (pathPrefix.IsEmpty() || pathPrefix == kSuperPathPrefix) + { + isDrive = true; + FStringVector drives; + if (!MyGetLogicalDriveStrings(drives)) + return GetNormalizedError(); + FOR_VECTOR (i, drives) + { + FString d = drives[i]; + if (d.Len() < 3 || d.Back() != '\\') + return E_FAIL; + d.DeleteBack(); + CFileInfo &fi = files.AddNew(); + fi.SetAsDir(); + fi.Name = d; + } + } + else + #endif + { + CEnumerator enumerator(us2fs(pathPrefix + L'*')); + for (;;) + { + bool found; + CFileInfo fi; + if (!enumerator.Next(fi, found)) + return GetNormalizedError(); + if (!found) + break; + if (!fi.IsDir()) + { + if (FolderMode) + continue; + if (!ShowAllFiles) + { + unsigned i; + for (i = 0; i < Filters.Size(); i++) + if (DoesWildcardMatchName(Filters[i], fs2us(fi.Name))) + break; + if (i == Filters.Size()) + continue; + } + } + files.Add(fi); + } + } + + DirPrefix = pathPrefix; + + _files = files; + + SetItemText(IDT_BROWSE_FOLDER, DirPrefix); + + _list.SetRedraw(false); + _list.DeleteAllItems(); + + LVITEMW item; + + int index = 0; + int cursorIndex = -1; + + #ifndef _SFX + if (_showDots && _topDirPrefix != DirPrefix) + { + item.iItem = index; + const UString itemName = L".."; + if (selectedName.IsEmpty()) + cursorIndex = index; + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + int subItem = 0; + item.iSubItem = subItem++; + item.lParam = kParentIndex; + item.pszText = (wchar_t *)(const wchar_t *)itemName; + item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix); + if (item.iImage < 0) + item.iImage = 0; + _list.InsertItem(&item); + _list.SetSubItem(index, subItem++, L""); + _list.SetSubItem(index, subItem++, L""); + index++; + } + #endif + + for (unsigned i = 0; i < _files.Size(); i++, index++) + { + item.iItem = index; + const CFileInfo &fi = _files[i]; + const UString name = fs2us(fi.Name); + if (!selectedName.IsEmpty() && CompareFileNames(name, selectedName) == 0) + cursorIndex = index; + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + int subItem = 0; + item.iSubItem = subItem++; + item.lParam = i; + item.pszText = (wchar_t *)(const wchar_t *)name; + + const UString fullPath = DirPrefix + name; + #ifndef UNDER_CE + if (isDrive) + { + if (GetRealIconIndex(fi.Name + FCHAR_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, item.iImage) == 0) + item.iImage = 0; + } + else + #endif + item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath); + if (item.iImage < 0) + item.iImage = 0; + _list.InsertItem(&item); + wchar_t s[32]; + { + FILETIME ft; + s[0] = 0; + if (FileTimeToLocalFileTime(&fi.MTime, &ft)) + ConvertFileTimeToString(ft, s, + #ifndef UNDER_CE + true + #else + false + #endif + , false); + _list.SetSubItem(index, subItem++, s); + } + { + s[0] = 0; + if (!fi.IsDir()) + ConvertSizeToString(fi.Size, s); + _list.SetSubItem(index, subItem++, s); + } + } + + if (_list.GetItemCount() > 0 && cursorIndex >= 0) + _list.SetItemState_FocusedSelected(cursorIndex); + _list.SortItems(CompareItems2, (LPARAM)this); + if (_list.GetItemCount() > 0 && cursorIndex < 0) + _list.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED); + _list.EnsureVisible(_list.GetFocusedItem(), false); + _list.SetRedraw(true); + _list.InvalidateRect(NULL, true); + return S_OK; +} + +HRESULT CBrowseDialog::Reload() +{ + UString selected; + int index = _list.GetNextSelectedItem(-1); + if (index >= 0) + { + int fileIndex = GetRealItemIndex(index); + if (fileIndex != kParentIndex) + selected = fs2us(_files[fileIndex].Name); + } + UString dirPathTemp = DirPrefix; + return Reload(dirPathTemp, selected); +} + +void CBrowseDialog::OpenParentFolder() +{ + UString parent, selected; + if (GetParentPath(DirPrefix, parent, selected)) + { + Reload(parent, selected); + SetPathEditText(); + } +} + +void CBrowseDialog::SetPathEditText() +{ + int index = _list.GetNextSelectedItem(-1); + if (index < 0) + { + if (FolderMode) + _pathEdit.SetText(DirPrefix); + return; + } + int fileIndex = GetRealItemIndex(index); + if (fileIndex == kParentIndex) + { + if (FolderMode) + _pathEdit.SetText(L".." WSTRING_PATH_SEPARATOR); + return; + } + const CFileInfo &file = _files[fileIndex]; + if (file.IsDir()) + { + if (!FolderMode) + return; + _pathEdit.SetText(fs2us(file.Name) + WCHAR_PATH_SEPARATOR); + } + else + _pathEdit.SetText(fs2us(file.Name)); +} + +void CBrowseDialog::OnCreateDir() +{ + UString name; + { + UString enteredName; + Dlg_CreateFolder((HWND)*this, enteredName); + if (enteredName.IsEmpty()) + return; + if (!CorrectFsPath(DirPrefix, enteredName, name)) + { + MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, name); + return; + } + } + if (name.IsEmpty()) + return; + + FString destPath; + if (GetFullPath(us2fs(DirPrefix), us2fs(name), destPath)) + { + if (!NDir::CreateComplexDir(destPath)) + { + MessageBox_HResError((HWND)*this, GetNormalizedError(), fs2us(destPath)); + } + else + { + UString tempPath = DirPrefix; + Reload(tempPath, name); + SetPathEditText(); + } + _list.SetFocus(); + } +} + +void CBrowseDialog::OnItemEnter() +{ + int index = _list.GetNextSelectedItem(-1); + if (index < 0) + return; + int fileIndex = GetRealItemIndex(index); + if (fileIndex == kParentIndex) + OpenParentFolder(); + else + { + const CFileInfo &file = _files[fileIndex]; + if (!file.IsDir()) + { + if (!FolderMode) + FinishOnOK(); + /* + MessageBox_Error_Global(*this, FolderMode ? + L"You must select some folder": + L"You must select some file"); + */ + return; + } + UString s = DirPrefix + fs2us(file.Name) + WCHAR_PATH_SEPARATOR; + HRESULT res = Reload(s, L""); + if (res != S_OK) + MessageBox_HResError(*this, res, s); + SetPathEditText(); + } +} + +void CBrowseDialog::FinishOnOK() +{ + UString s; + _pathEdit.GetText(s); + FString destPath; + if (!GetFullPath(us2fs(DirPrefix), us2fs(s), destPath)) + { + MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, s); + return; + } + FilePath = fs2us(destPath); + if (FolderMode) + NormalizeDirPathPrefix(FilePath); + End(IDOK); +} + +#endif + +bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath) +{ + resultPath.Empty(); + + #ifndef UNDER_CE + + #ifdef USE_MY_BROWSE_DIALOG + if (!IsSuperOrDevicePath(path)) + #endif + return NShell::BrowseForFolder(owner, title, path, resultPath); + + #endif + + #ifdef USE_MY_BROWSE_DIALOG + + CBrowseDialog dialog; + dialog.FolderMode = true; + if (title) + dialog.Title = title; + if (path) + dialog.FilePath = path; + if (dialog.Create(owner) != IDOK) + return false; + resultPath = dialog.FilePath; + #endif + + return true; +} + +bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, + LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath) +{ + resultPath.Empty(); + + #ifndef UNDER_CE + + #ifdef USE_MY_BROWSE_DIALOG + if (!IsSuperOrDevicePath(path)) + #endif + { + if (MyGetOpenFileName(owner, title, NULL, path, filterDescription, filter, resultPath)) + return true; + #ifdef UNDER_CE + return false; + #else + // maybe we must use GetLastError in WinCE. + DWORD errorCode = CommDlgExtendedError(); + const wchar_t *errorMessage = NULL; + switch (errorCode) + { + case 0: return false; // cancel or close obn dialog + case FNERR_INVALIDFILENAME: errorMessage = L"Invalid File Name"; break; + default: errorMessage = L"Open Dialog Error"; + } + if (!errorMessage) + return false; + { + UString s = errorMessage; + s.Add_LF(); + s += path; + MessageBox_Error_Global(owner, s); + } + #endif + } + + #endif + + #ifdef USE_MY_BROWSE_DIALOG + CBrowseDialog dialog; + if (title) + dialog.Title = title; + if (path) + dialog.FilePath = path; + dialog.FolderMode = false; + if (filter) + dialog.SetFilter(filter); + if (filterDescription) + dialog.FilterDescription = filterDescription; + if (dialog.Create(owner) != IDOK) + return false; + resultPath = dialog.FilePath; + #endif + + return true; +} + + +#ifdef _WIN32 + +static void RemoveDotsAndSpaces(UString &path) +{ + while (!path.IsEmpty()) + { + wchar_t c = path.Back(); + if (c != ' ' && c != '.') + return; + path.DeleteBack(); + } +} + + +bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result) +{ + result.Empty(); + + UString path = path2; + path.Replace(L'/', WCHAR_PATH_SEPARATOR); + unsigned start = 0; + UString base; + + if (IsAbsolutePath(path)) + { + #if defined(_WIN32) && !defined(UNDER_CE) + if (IsSuperOrDevicePath(path)) + { + result = path; + return true; + } + #endif + int pos = GetRootPrefixSize(path); + if (pos > 0) + start = pos; + } + else + { + #if defined(_WIN32) && !defined(UNDER_CE) + if (IsSuperOrDevicePath(relBase)) + { + result = path; + return true; + } + #endif + base = relBase; + } + + /* We can't use backward, since we must change only disk paths */ + /* + for (;;) + { + if (path.Len() <= start) + break; + if (DoesFileOrDirExist(us2fs(path))) + break; + if (path.Back() == WCHAR_PATH_SEPARATOR) + { + path.DeleteBack(); + result.Insert(0, WCHAR_PATH_SEPARATOR);; + } + int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR) + 1; + UString cur = path.Ptr(pos); + RemoveDotsAndSpaces(cur); + result.Insert(0, cur); + path.DeleteFrom(pos); + } + result.Insert(0, path); + return true; + */ + + result += path.Left(start); + bool checkExist = true; + UString cur; + + for (;;) + { + if (start == path.Len()) + break; + int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start); + cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : slashPos) - start); + if (checkExist) + { + CFileInfo fi; + if (fi.Find(us2fs(base + result + cur))) + { + if (!fi.IsDir()) + { + result = path; + break; + } + } + else + checkExist = false; + } + if (!checkExist) + RemoveDotsAndSpaces(cur); + result += cur; + if (slashPos < 0) + break; + result.Add_PathSepar(); + start = slashPos + 1; + } + + return true; +} + +#else + +bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result) +{ + result = path; + return true; +} + +#endif + +bool Dlg_CreateFolder(HWND wnd, UString &destName) +{ + destName.Empty(); + CComboDialog dlg; + LangString(IDS_CREATE_FOLDER, dlg.Title); + LangString(IDS_CREATE_FOLDER_NAME, dlg.Static); + LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, dlg.Value); + if (dlg.Create(wnd) != IDOK) + return false; + destName = dlg.Value; + return true; +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h new file mode 100644 index 00000000000..957af2e2577 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialog.h @@ -0,0 +1,21 @@ +// BrowseDialog.h + +#ifndef __BROWSE_DIALOG_H +#define __BROWSE_DIALOG_H + +#include "../../../Common/MyString.h" + +bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath); +bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath); + +/* CorrectFsPath removes undesirable characters in names (dots and spaces at the end of file) + But it doesn't change "bad" name in any of the following cases: + - path is Super Path (with \\?\ prefix) + - path is relative and relBase is Super Path + - there is file or dir in filesystem with specified "bad" name */ + +bool CorrectFsPath(const UString &relBase, const UString &path, UString &result); + +bool Dlg_CreateFolder(HWND wnd, UString &destName); + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialogRes.h new file mode 100644 index 00000000000..aff84ec9aa3 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/BrowseDialogRes.h @@ -0,0 +1,9 @@ +#define IDD_BROWSE 95 + +#define IDL_BROWSE 100 +#define IDT_BROWSE_FOLDER 101 +#define IDE_BROWSE_PATH 102 +#define IDC_BROWSE_FILTER 103 + +#define IDB_BROWSE_PARENT 110 +#define IDB_BROWSE_CREATE_DIR 112 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp new file mode 100644 index 00000000000..729743e8795 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.cpp @@ -0,0 +1,64 @@ +// ComboDialog.cpp + +#include "StdAfx.h" +#include "ComboDialog.h" + +#include "../../../Windows/Control/Static.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +using namespace NWindows; + +bool CComboDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItems(*this, NULL, 0); + #endif + _comboBox.Attach(GetItem(IDC_COMBO)); + + /* + // why it doesn't work ? + DWORD style = _comboBox.GetStyle(); + if (Sorted) + style |= CBS_SORT; + else + style &= ~CBS_SORT; + _comboBox.SetStyle(style); + */ + SetText(Title); + + NControl::CStatic staticContol; + staticContol.Attach(GetItem(IDT_COMBO)); + staticContol.SetText(Static); + _comboBox.SetText(Value); + FOR_VECTOR (i, Strings) + _comboBox.AddString(Strings[i]); + NormalizeSize(); + return CModalDialog::OnInit(); +} + +bool CComboDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int mx, my; + GetMargins(8, mx, my); + int bx1, bx2, by; + GetItemSizes(IDCANCEL, bx1, by); + GetItemSizes(IDOK, bx2, by); + int y = ySize - my - by; + int x = xSize - mx - bx1; + + InvalidateRect(NULL); + + MoveItem(IDCANCEL, x, y, bx1, by); + MoveItem(IDOK, x - mx - bx2, y, bx2, by); + ChangeSubWindowSizeX(_comboBox, xSize - mx * 2); + return false; +} + +void CComboDialog::OnOK() +{ + _comboBox.GetText(Value); + CModalDialog::OnOK(); +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h new file mode 100644 index 00000000000..29b28b5b49c --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialog.h @@ -0,0 +1,28 @@ +// ComboDialog.h + +#ifndef __COMBO_DIALOG_H +#define __COMBO_DIALOG_H + +#include "../../../Windows/Control/ComboBox.h" +#include "../../../Windows/Control/Dialog.h" + +#include "ComboDialogRes.h" + +class CComboDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _comboBox; + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnSize(WPARAM wParam, int xSize, int ySize); +public: + // bool Sorted; + UString Title; + UString Static; + UString Value; + UStringVector Strings; + + // CComboDialog(): Sorted(false) {}; + INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_COMBO, parentWindow); } +}; + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialogRes.h new file mode 100644 index 00000000000..a044797e456 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ComboDialogRes.h @@ -0,0 +1,4 @@ +#define IDD_COMBO 98 + +#define IDT_COMBO 100 +#define IDC_COMBO 101 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h new file mode 100644 index 00000000000..504541bdf3c --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/DialogSize.h @@ -0,0 +1,16 @@ +// DialogSize.h + +#ifndef __DIALOG_SIZE_H +#define __DIALOG_SIZE_H + +#include "../../../Windows/Control/Dialog.h" + +#ifdef UNDER_CE +#define BIG_DIALOG_SIZE(x, y) bool isBig = NWindows::NControl::IsDialogSizeOK(x, y); +#define SIZED_DIALOG(big) (isBig ? big : big ## _2) +#else +#define BIG_DIALOG_SIZE(x, y) +#define SIZED_DIALOG(big) big +#endif + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp new file mode 100644 index 00000000000..7d61d14d9d9 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.cpp @@ -0,0 +1,1035 @@ +// ExtractCallback.cpp + +#include "StdAfx.h" + + +#include "../../../Common/ComTry.h" +#include "../../../Common/IntToString.h" +#include "../../../Common/Lang.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileDir.h" +#include "../../../Windows/FileFind.h" +#include "../../../Windows/PropVariantConv.h" + +#include "../../Common/FilePathAutoRename.h" +#include "../../Common/StreamUtils.h" +#include "../Common/ExtractingFilePath.h" + +#ifndef _SFX +#include "../Common/ZipRegistry.h" +#endif + +#include "../GUI/ExtractRes.h" +#include "resourceGui.h" + +#include "ExtractCallback.h" +#include "FormatUtils.h" +#include "LangUtils.h" +#include "OverwriteDialog.h" +#ifndef _NO_CRYPTO +#include "PasswordDialog.h" +#endif +#include "PropertyName.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +CExtractCallbackImp::~CExtractCallbackImp() {} + +void CExtractCallbackImp::Init() +{ + _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING); + _lang_Testing = LangString(IDS_PROGRESS_TESTING); + _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING); + + NumArchiveErrors = 0; + ThereAreMessageErrors = false; + #ifndef _SFX + NumFolders = NumFiles = 0; + NeedAddFile = false; + #endif +} + +void CExtractCallbackImp::AddError_Message(LPCWSTR s) +{ + ThereAreMessageErrors = true; + ProgressDialog->Sync.AddError_Message(s); +} + +#ifndef _SFX + +STDMETHODIMP CExtractCallbackImp::SetNumFiles(UInt64 + #ifndef _SFX + numFiles + #endif + ) +{ + #ifndef _SFX + ProgressDialog->Sync.Set_NumFilesTotal(numFiles); + #endif + return S_OK; +} + +#endif + +STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total) +{ + ProgressDialog->Sync.Set_NumBytesTotal(total); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *value) +{ + return ProgressDialog->Sync.Set_NumBytesCur(value); +} + +HRESULT CExtractCallbackImp::Open_CheckBreak() +{ + return ProgressDialog->Sync.CheckStop(); +} + +HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + HRESULT res = S_OK; + if (!MultiArcMode) + { + if (files) + { + _totalFilesDefined = true; + // res = ProgressDialog->Sync.Set_NumFilesTotal(*files); + } + else + _totalFilesDefined = false; + + if (bytes) + { + _totalBytesDefined = true; + ProgressDialog->Sync.Set_NumBytesTotal(*bytes); + } + else + _totalBytesDefined = false; + } + + return res; +} + +HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + if (!MultiArcMode) + { + if (files) + { + ProgressDialog->Sync.Set_NumFilesCur(*files); + } + + if (bytes) + { + } + } + + return ProgressDialog->Sync.CheckStop(); +} + +HRESULT CExtractCallbackImp::Open_Finished() +{ + return ProgressDialog->Sync.CheckStop(); +} + +#ifndef _NO_CRYPTO + +HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password) +{ + return CryptoGetTextPassword(password); +} + +/* +HRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) +{ + passwordIsDefined = PasswordIsDefined; + password = Password; + return S_OK; +} + +bool CExtractCallbackImp::Open_WasPasswordAsked() +{ + return PasswordWasAsked; +} + +void CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag() +{ + PasswordWasAsked = false; +} +*/ + +#endif + + +#ifndef _SFX +STDMETHODIMP CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + ProgressDialog->Sync.Set_Ratio(inSize, outSize); + return S_OK; +} +#endif + +/* +STDMETHODIMP CExtractCallbackImp::SetTotalFiles(UInt64 total) +{ + ProgressDialog->Sync.SetNumFilesTotal(total); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetCompletedFiles(const UInt64 *value) +{ + if (value != NULL) + ProgressDialog->Sync.SetNumFilesCur(*value); + return S_OK; +} +*/ + +STDMETHODIMP CExtractCallbackImp::AskOverwrite( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer) +{ + COverwriteDialog dialog; + + dialog.OldFileInfo.SetTime(existTime); + dialog.OldFileInfo.SetSize(existSize); + dialog.OldFileInfo.Name = existName; + + dialog.NewFileInfo.SetTime(newTime); + dialog.NewFileInfo.SetSize(newSize); + dialog.NewFileInfo.Name = newName; + + ProgressDialog->WaitCreating(); + INT_PTR writeAnswer = dialog.Create(*ProgressDialog); + + switch (writeAnswer) + { + case IDCANCEL: *answer = NOverwriteAnswer::kCancel; return E_ABORT; + case IDYES: *answer = NOverwriteAnswer::kYes; break; + case IDNO: *answer = NOverwriteAnswer::kNo; break; + case IDB_YES_TO_ALL: *answer = NOverwriteAnswer::kYesToAll; break; + case IDB_NO_TO_ALL: *answer = NOverwriteAnswer::kNoToAll; break; + case IDB_AUTO_RENAME: *answer = NOverwriteAnswer::kAutoRename; break; + default: return E_FAIL; + } + return S_OK; +} + + +STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */) +{ + _isFolder = IntToBool(isFolder); + _currentFilePath = name; + + const UString *msg = &_lang_Empty; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break; + case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break; + case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break; + // default: s = "Unknown operation"; + } + + return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder)); +} + +STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *s) +{ + AddError_Message(s); + return S_OK; +} + +HRESULT CExtractCallbackImp::MessageError(const char *message, const FString &path) +{ + ThereAreMessageErrors = true; + ProgressDialog->Sync.AddError_Message_Name(GetUnicodeString(message), fs2us(path)); + return S_OK; +} + +#ifndef _SFX + +STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *s) +{ + AddError_Message(s); + return S_OK; +} + +#endif + +void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s) +{ + s.Empty(); + + if (opRes == NArchive::NExtract::NOperationResult::kOK) + return; + + UINT messageID = 0; + UINT id = 0; + + switch (opRes) + { + case NArchive::NExtract::NOperationResult::kUnsupportedMethod: + messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD; + id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD; + break; + case NArchive::NExtract::NOperationResult::kDataError: + messageID = encrypted ? + IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED: + IDS_EXTRACT_MESSAGE_DATA_ERROR; + id = IDS_EXTRACT_MSG_DATA_ERROR; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + messageID = encrypted ? + IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED: + IDS_EXTRACT_MESSAGE_CRC_ERROR; + id = IDS_EXTRACT_MSG_CRC_ERROR; + break; + case NArchive::NExtract::NOperationResult::kUnavailable: + id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA; + break; + case NArchive::NExtract::NOperationResult::kUnexpectedEnd: + id = IDS_EXTRACT_MSG_UEXPECTED_END; + break; + case NArchive::NExtract::NOperationResult::kDataAfterEnd: + id = IDS_EXTRACT_MSG_DATA_AFTER_END; + break; + case NArchive::NExtract::NOperationResult::kIsNotArc: + id = IDS_EXTRACT_MSG_IS_NOT_ARC; + break; + case NArchive::NExtract::NOperationResult::kHeadersError: + id = IDS_EXTRACT_MSG_HEADERS_ERROR; + break; + case NArchive::NExtract::NOperationResult::kWrongPassword: + id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM; + break; + /* + default: + messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR; + break; + */ + } + + UString msg; + UString msgOld; + + #ifndef _SFX + if (id != 0) + LangString_OnlyFromLangFile(id, msg); + if (messageID != 0 && msg.IsEmpty()) + LangString_OnlyFromLangFile(messageID, msgOld); + #endif + + if (msg.IsEmpty() && !msgOld.IsEmpty()) + s = MyFormatNew(msgOld, fileName); + else + { + if (msg.IsEmpty() && id != 0) + LangString(id, msg); + if (!msg.IsEmpty()) + s += msg; + else + { + char temp[16]; + ConvertUInt32ToString(opRes, temp); + s.AddAscii("Error #"); + s.AddAscii(temp); + } + + if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword) + { + // s.AddAscii(" : "); + // AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED); + s.AddAscii(" : "); + AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); + } + s.AddAscii(" : "); + s += fileName; + } +} + +STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted) +{ + switch (opRes) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + UString s; + SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s); + Add_ArchiveName_Error(); + AddError_Message(s); + } + } + + #ifndef _SFX + if (_isFolder) + NumFolders++; + else + NumFiles++; + ProgressDialog->Sync.Set_NumFilesCur(NumFiles); + #endif + + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name) +{ + if (opRes != NArchive::NExtract::NOperationResult::kOK) + { + UString s; + SetExtractErrorMessage(opRes, encrypted, name, s); + Add_ArchiveName_Error(); + AddError_Message(s); + } + return S_OK; +} + +//////////////////////////////////////// +// IExtractCallbackUI + +HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */) +{ + #ifndef _SFX + RINOK(ProgressDialog->Sync.CheckStop()); + ProgressDialog->Sync.Set_TitleFileName(name); + #endif + _currentArchivePath = name; + return S_OK; +} + +HRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path) +{ + _currentFilePath = path; + #ifndef _SFX + ProgressDialog->Sync.Set_FilePath(path); + #endif + return S_OK; +} + +#ifndef _SFX + +HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path) +{ + #ifndef _SFX + if (NeedAddFile) + NumFiles++; + NeedAddFile = true; + ProgressDialog->Sync.Set_NumFilesCur(NumFiles); + #endif + return SetCurrentFilePath2(path); +} + +#endif + +UString HResultToMessage(HRESULT errorCode); + +static const UInt32 k_ErrorFlagsIds[] = +{ + IDS_EXTRACT_MSG_IS_NOT_ARC, + IDS_EXTRACT_MSG_HEADERS_ERROR, + IDS_EXTRACT_MSG_HEADERS_ERROR, + IDS_OPEN_MSG_UNAVAILABLE_START, + IDS_OPEN_MSG_UNCONFIRMED_START, + IDS_EXTRACT_MSG_UEXPECTED_END, + IDS_EXTRACT_MSG_DATA_AFTER_END, + IDS_EXTRACT_MSG_UNSUPPORTED_METHOD, + IDS_OPEN_MSG_UNSUPPORTED_FEATURE, + IDS_EXTRACT_MSG_DATA_ERROR, + IDS_EXTRACT_MSG_CRC_ERROR +}; + +static void AddNewLineString(UString &s, const UString &m) +{ + s += m; + s.Add_LF(); +} + +UString GetOpenArcErrorMessage(UInt32 errorFlags) +{ + UString s; + + for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsIds); i++) + { + UInt32 f = ((UInt32)1 << i); + if ((errorFlags & f) == 0) + continue; + UInt32 id = k_ErrorFlagsIds[i]; + UString m = LangString(id); + if (m.IsEmpty()) + continue; + if (f == kpv_ErrorFlags_EncryptedHeadersError) + { + m.AddAscii(" : "); + AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS); + } + if (!s.IsEmpty()) + s.Add_LF(); + s += m; + errorFlags &= ~f; + } + + if (errorFlags != 0) + { + char sz[16]; + sz[0] = '0'; + sz[1] = 'x'; + ConvertUInt32ToHex(errorFlags, sz + 2); + if (!s.IsEmpty()) + s.Add_LF(); + s.AddAscii(sz); + } + + return s; +} + +static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) +{ + UInt32 errorFlags = er.GetErrorFlags(); + UInt32 warningFlags = er.GetWarningFlags(); + + if (errorFlags != 0) + AddNewLineString(s, GetOpenArcErrorMessage(errorFlags)); + + if (!er.ErrorMessage.IsEmpty()) + AddNewLineString(s, er.ErrorMessage); + + if (warningFlags != 0) + { + s += GetNameOfProperty(kpidWarningFlags, L"Warnings"); + s.AddAscii(":"); + s.Add_LF(); + AddNewLineString(s, GetOpenArcErrorMessage(warningFlags)); + } + + if (!er.WarningMessage.IsEmpty()) + { + s += GetNameOfProperty(kpidWarning, L"Warning"); + s.AddAscii(": "); + s += er.WarningMessage; + s.Add_LF(); + } +} + +static UString GetBracedType(const wchar_t *type) +{ + UString s = L'['; + s += type; + s += L']'; + return s; +} + +void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) +{ + FOR_VECTOR (level, arcLink.Arcs) + { + const CArc &arc = arcLink.Arcs[level]; + const CArcErrorInfo &er = arc.ErrorInfo; + + if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0) + continue; + + if (s.IsEmpty()) + { + s += name; + s.Add_LF(); + } + + if (level != 0) + { + AddNewLineString(s, arc.Path); + } + + ErrorInfo_Print(s, er); + + if (er.ErrorFormatIndex >= 0) + { + AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning")); + if (arc.FormatIndex == er.ErrorFormatIndex) + { + AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET)); + } + else + { + AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex)))); + AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex)))); + } + } + } + + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK) + { + s += name; + s.Add_LF(); + if (!arcLink.Arcs.IsEmpty()) + AddNewLineString(s, arcLink.NonOpen_ArcPath); + + if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE) + { + UINT id = IDS_CANT_OPEN_ARCHIVE; + UString param; + if (arcLink.PasswordWasAsked) + id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE; + else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0) + { + id = IDS_CANT_OPEN_AS_TYPE; + param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex)); + } + UString s2 = MyFormatNew(id, param); + s2.Replace(L" ''", L""); + s2.Replace(L"''", L""); + s += s2; + } + else + s += HResultToMessage(result); + + s.Add_LF(); + ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo); + } + + if (!s.IsEmpty() && s.Back() == '\n') + s.DeleteBack(); +} + +HRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result) +{ + _currentArchivePath = name; + _needWriteArchivePath = true; + + UString s; + OpenResult_GUI(s, codecs, arcLink, name, result); + if (!s.IsEmpty()) + { + NumArchiveErrors++; + AddError_Message(s); + _needWriteArchivePath = false; + } + + return S_OK; +} + +HRESULT CExtractCallbackImp::ThereAreNoFiles() +{ + return S_OK; +} + +void CExtractCallbackImp::Add_ArchiveName_Error() +{ + if (_needWriteArchivePath) + { + if (!_currentArchivePath.IsEmpty()) + AddError_Message(_currentArchivePath); + _needWriteArchivePath = false; + } +} + +HRESULT CExtractCallbackImp::ExtractResult(HRESULT result) +{ + if (result == S_OK) + return result; + NumArchiveErrors++; + if (result == E_ABORT || result == ERROR_DISK_FULL) + return result; + + Add_ArchiveName_Error(); + if (!_currentFilePath.IsEmpty()) + MessageError(_currentFilePath); + MessageError(NError::MyFormatMessage(result)); + return S_OK; +} + +#ifndef _NO_CRYPTO + +HRESULT CExtractCallbackImp::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) +{ + PasswordWasAsked = true; + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + #ifndef _SFX + bool showPassword = NExtract::Read_ShowPassword(); + dialog.ShowPassword = showPassword; + #endif + ProgressDialog->WaitCreating(); + if (dialog.Create(*ProgressDialog) != IDOK) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + #ifndef _SFX + if (dialog.ShowPassword != showPassword) + NExtract::Save_ShowPassword(dialog.ShowPassword); + #endif + } + return StringToBstr(Password, password); +} + +#endif + +#ifndef _SFX + +STDMETHODIMP CExtractCallbackImp::AskWrite( + const wchar_t *srcPath, Int32 srcIsFolder, + const FILETIME *srcTime, const UInt64 *srcSize, + const wchar_t *destPath, + BSTR *destPathResult, + Int32 *writeAnswer) +{ + UString destPathResultTemp = destPath; + + // RINOK(StringToBstr(destPath, destPathResult)); + + *destPathResult = 0; + *writeAnswer = BoolToInt(false); + + FString destPathSys = us2fs(destPath); + bool srcIsFolderSpec = IntToBool(srcIsFolder); + CFileInfo destFileInfo; + + if (destFileInfo.Find(destPathSys)) + { + if (srcIsFolderSpec) + { + if (!destFileInfo.IsDir()) + { + RINOK(MessageError("can not replace file with folder with same name", destPathSys)); + return E_ABORT; + } + *writeAnswer = BoolToInt(false); + return S_OK; + } + + if (destFileInfo.IsDir()) + { + RINOK(MessageError("can not replace folder with file with same name", destPathSys)); + *writeAnswer = BoolToInt(false); + return S_OK; + } + + switch (OverwriteMode) + { + case NExtract::NOverwriteMode::kSkip: + return S_OK; + case NExtract::NOverwriteMode::kAsk: + { + Int32 overwriteResult; + UString destPathSpec = destPath; + int slashPos = destPathSpec.ReverseFind_PathSepar(); + destPathSpec.DeleteFrom(slashPos + 1); + destPathSpec += fs2us(destFileInfo.Name); + + RINOK(AskOverwrite( + destPathSpec, + &destFileInfo.MTime, &destFileInfo.Size, + srcPath, + srcTime, srcSize, + &overwriteResult)); + + switch (overwriteResult) + { + case NOverwriteAnswer::kCancel: return E_ABORT; + case NOverwriteAnswer::kNo: return S_OK; + case NOverwriteAnswer::kNoToAll: OverwriteMode = NExtract::NOverwriteMode::kSkip; return S_OK; + case NOverwriteAnswer::kYes: break; + case NOverwriteAnswer::kYesToAll: OverwriteMode = NExtract::NOverwriteMode::kOverwrite; break; + case NOverwriteAnswer::kAutoRename: OverwriteMode = NExtract::NOverwriteMode::kRename; break; + default: + return E_FAIL; + } + } + } + + if (OverwriteMode == NExtract::NOverwriteMode::kRename) + { + if (!AutoRenamePath(destPathSys)) + { + RINOK(MessageError("can not create name for file", destPathSys)); + return E_ABORT; + } + destPathResultTemp = fs2us(destPathSys); + } + else + if (!NDir::DeleteFileAlways(destPathSys)) + { + RINOK(MessageError("can not delete output file", destPathSys)); + return E_ABORT; + } + } + *writeAnswer = BoolToInt(true); + return StringToBstr(destPathResultTemp, destPathResult); +} + + +STDMETHODIMP CExtractCallbackImp::UseExtractToStream(Int32 *res) +{ + *res = BoolToInt(StreamMode); + return S_OK; +} + +static HRESULT GetTime(IGetProp *getProp, PROPID propID, FILETIME &ft, bool &ftDefined) +{ + ftDefined = false; + NCOM::CPropVariant prop; + RINOK(getProp->GetProp(propID, &prop)); + if (prop.vt == VT_FILETIME) + { + ft = prop.filetime; + ftDefined = (ft.dwHighDateTime != 0 || ft.dwLowDateTime != 0); + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + + +static HRESULT GetItemBoolProp(IGetProp *getProp, PROPID propID, bool &result) +{ + NCOM::CPropVariant prop; + result = false; + RINOK(getProp->GetProp(propID, &prop)); + if (prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + + +STDMETHODIMP CExtractCallbackImp::GetStream7(const wchar_t *name, + Int32 isDir, + ISequentialOutStream **outStream, Int32 askExtractMode, + IGetProp *getProp) +{ + COM_TRY_BEGIN + *outStream = 0; + _newVirtFileWasAdded = false; + _hashStreamWasUsed = false; + _needUpdateStat = false; + + if (_hashStream) + _hashStreamSpec->ReleaseStream(); + + GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream); + + if (!ProcessAltStreams && _isAltStream) + return S_OK; + + _filePath = name; + _isFolder = IntToBool(isDir); + _curSize = 0; + _curSizeDefined = false; + + UInt64 size = 0; + bool sizeDefined; + { + NCOM::CPropVariant prop; + RINOK(getProp->GetProp(kpidSize, &prop)); + sizeDefined = ConvertPropVariantToUInt64(prop, size); + } + + if (sizeDefined) + { + _curSize = size; + _curSizeDefined = true; + } + + if (askExtractMode != NArchive::NExtract::NAskMode::kExtract && + askExtractMode != NArchive::NExtract::NAskMode::kTest) + return S_OK; + + _needUpdateStat = true; + + CMyComPtr<ISequentialOutStream> outStreamLoc; + + if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract) + { + CVirtFile &file = VirtFileSystemSpec->AddNewFile(); + _newVirtFileWasAdded = true; + file.Name = name; + file.IsDir = IntToBool(isDir); + file.IsAltStream = _isAltStream; + file.Size = 0; + + RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined)); + RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined)); + RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined)); + + NCOM::CPropVariant prop; + RINOK(getProp->GetProp(kpidAttrib, &prop)); + if (prop.vt == VT_UI4) + { + file.Attrib = prop.ulVal; + file.AttribDefined = true; + } + // else if (isDir) file.Attrib = FILE_ATTRIBUTE_DIRECTORY; + + file.ExpectedSize = 0; + if (sizeDefined) + file.ExpectedSize = size; + outStreamLoc = VirtFileSystem; + } + + if (_hashStream) + { + { + _hashStreamSpec->SetStream(outStreamLoc); + outStreamLoc = _hashStream; + _hashStreamSpec->Init(true); + _hashStreamWasUsed = true; + } + } + + if (outStreamLoc) + *outStream = outStreamLoc.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode) +{ + COM_TRY_BEGIN + _needUpdateStat = ( + askExtractMode == NArchive::NExtract::NAskMode::kExtract || + askExtractMode == NArchive::NExtract::NAskMode::kTest); + + /* + _extractMode = false; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + if (_testMode) + askExtractMode = NArchive::NExtract::NAskMode::kTest; + else + _extractMode = true; + break; + }; + */ + return SetCurrentFilePath2(_filePath); + COM_TRY_END +} + +STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypted) +{ + COM_TRY_BEGIN + if (VirtFileSystem && _newVirtFileWasAdded) + { + // FIXME: probably we must request file size from VirtFileSystem + // _curSize = VirtFileSystem->GetLastFileSize() + // _curSizeDefined = true; + RINOK(VirtFileSystemSpec->CloseMemFile()); + } + if (_hashStream && _hashStreamWasUsed) + { + _hashStreamSpec->_hash->Final(_isFolder, _isAltStream, _filePath); + _curSize = _hashStreamSpec->GetSize(); + _curSizeDefined = true; + _hashStreamSpec->ReleaseStream(); + _hashStreamWasUsed = false; + } + else if (_hashCalc && _needUpdateStat) + { + _hashCalc->SetSize(_curSize); + _hashCalc->Final(_isFolder, _isAltStream, _filePath); + } + return SetOperationResult(opRes, encrypted); + COM_TRY_END +} + + +static const size_t k_SizeT_MAX = (size_t)((size_t)0 - 1); + +static const UInt32 kBlockSize = ((UInt32)1 << 31); + +STDMETHODIMP CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (size == 0) + return S_OK; + if (!_fileMode) + { + CVirtFile &file = Files.Back(); + size_t rem = file.Data.Size() - (size_t)file.Size; + bool useMem = true; + if (rem < size) + { + UInt64 b = 0; + if (file.Data.Size() == 0) + b = file.ExpectedSize; + UInt64 a = file.Size + size; + if (b < a) + b = a; + a = (UInt64)file.Data.Size() * 2; + if (b < a) + b = a; + useMem = false; + if (b <= k_SizeT_MAX && b <= MaxTotalAllocSize) + useMem = file.Data.ReAlloc_KeepData((size_t)b, (size_t)file.Size); + } + if (useMem) + { + memcpy(file.Data + file.Size, data, size); + file.Size += size; + if (processedSize) + *processedSize = (UInt32)size; + return S_OK; + } + _fileMode = true; + } + RINOK(FlushToDisk(false)); + return _outFileStream->Write(data, size, processedSize); +} + +HRESULT CVirtFileSystem::FlushToDisk(bool closeLast) +{ + if (!_outFileStream) + { + _outFileStreamSpec = new COutFileStream; + _outFileStream = _outFileStreamSpec; + } + while (_numFlushed < Files.Size()) + { + const CVirtFile &file = Files[_numFlushed]; + const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name)); + if (!_fileIsOpen) + { + if (!_outFileStreamSpec->Create(path, false)) + { + _outFileStream.Release(); + return E_FAIL; + // MessageBoxMyError(UString(L"Can't create file ") + fs2us(tempFilePath)); + } + _fileIsOpen = true; + RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size)); + } + if (_numFlushed == Files.Size() - 1 && !closeLast) + break; + if (file.CTimeDefined || + file.ATimeDefined || + file.MTimeDefined) + _outFileStreamSpec->SetTime( + file.CTimeDefined ? &file.CTime : NULL, + file.ATimeDefined ? &file.ATime : NULL, + file.MTimeDefined ? &file.MTime : NULL); + _outFileStreamSpec->Close(); + _numFlushed++; + _fileIsOpen = false; + if (file.AttribDefined) + NDir::SetFileAttrib(path, file.Attrib); + } + return S_OK; +} + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h new file mode 100644 index 00000000000..6cd8d0aa83d --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ExtractCallback.h @@ -0,0 +1,328 @@ +// ExtractCallback.h + +#ifndef __EXTRACT_CALLBACK_H +#define __EXTRACT_CALLBACK_H + +#include "../../../../C/Alloc.h" + +#include "../../../Common/MyCom.h" +#include "../../../Common/StringConvert.h" + +#ifndef _SFX +#include "../Agent/IFolderArchive.h" +#endif + +#include "../Common/ArchiveExtractCallback.h" +#include "../Common/ArchiveOpenCallback.h" + +#ifndef _NO_CRYPTO +#include "../../IPassword.h" +#endif + +#ifndef _SFX +#include "IFolder.h" +#endif + +#include "ProgressDialog2.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +#ifndef _SFX + +class CGrowBuf +{ + Byte *_items; + size_t _size; + + CLASS_NO_COPY(CGrowBuf); + +public: + bool ReAlloc_KeepData(size_t newSize, size_t keepSize) + { + void *buf = MyAlloc(newSize); + if (!buf) + return false; + if (keepSize != 0) + memcpy(buf, _items, keepSize); + MyFree(_items); + _items = (Byte *)buf; + _size = newSize; + return true; + } + + CGrowBuf(): _items(0), _size(0) {} + ~CGrowBuf() { MyFree(_items); } + + operator Byte *() { return _items; } + operator const Byte *() const { return _items; } + size_t Size() const { return _size; } +}; + +struct CVirtFile +{ + CGrowBuf Data; + + UInt64 Size; // real size + UInt64 ExpectedSize; // the size from props request. 0 if unknown + + UString Name; + + bool CTimeDefined; + bool ATimeDefined; + bool MTimeDefined; + bool AttribDefined; + + bool IsDir; + bool IsAltStream; + + DWORD Attrib; + + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; + + CVirtFile(): + CTimeDefined(false), + ATimeDefined(false), + MTimeDefined(false), + AttribDefined(false), + IsDir(false), + IsAltStream(false) {} +}; + +class CVirtFileSystem: + public ISequentialOutStream, + public CMyUnknownImp +{ + UInt64 _totalAllocSize; + + size_t _pos; + unsigned _numFlushed; + bool _fileIsOpen; + bool _fileMode; + COutFileStream *_outFileStreamSpec; + CMyComPtr<ISequentialOutStream> _outFileStream; +public: + CObjectVector<CVirtFile> Files; + UInt64 MaxTotalAllocSize; + FString DirPrefix; + + CVirtFile &AddNewFile() + { + if (!Files.IsEmpty()) + { + MaxTotalAllocSize -= Files.Back().Data.Size(); + } + return Files.AddNew(); + } + HRESULT CloseMemFile() + { + if (_fileMode) + { + return FlushToDisk(true); + } + CVirtFile &file = Files.Back(); + if (file.Data.Size() != file.Size) + { + file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size); + } + return S_OK; + } + + bool IsStreamInMem() const + { + if (_fileMode) + return false; + if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir) + return false; + return true; + } + + size_t GetMemStreamWrittenSize() const { return _pos; } + + CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {} + + void Init() + { + _totalAllocSize = 0; + _fileMode = false; + _pos = 0; + _numFlushed = 0; + _fileIsOpen = false; + } + + HRESULT CloseFile(const FString &path); + HRESULT FlushToDisk(bool closeLast); + size_t GetPos() const { return _pos; } + + MY_UNKNOWN_IMP + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); +}; + +#endif + +class CExtractCallbackImp: + public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback + public IOpenCallbackUI, + public IFolderArchiveExtractCallback2, + #ifndef _SFX + public IFolderOperationsExtractCallback, + public IFolderExtractToStreamCallback, + public ICompressProgressInfo, + #endif + #ifndef _NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public CMyUnknownImp +{ + HRESULT MessageError(const char *message, const FString &path); + void Add_ArchiveName_Error(); +public: + MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback) + MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2) + #ifndef _SFX + MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback) + MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback) + MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) + #endif + #ifndef _NO_CRYPTO + MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) + #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + INTERFACE_IProgress(;) + INTERFACE_IOpenCallbackUI(;) + INTERFACE_IFolderArchiveExtractCallback(;) + INTERFACE_IFolderArchiveExtractCallback2(;) + // STDMETHOD(SetTotalFiles)(UInt64 total); + // STDMETHOD(SetCompletedFiles)(const UInt64 *value); + + INTERFACE_IExtractCallbackUI(;) + + #ifndef _SFX + // IFolderOperationsExtractCallback + STDMETHOD(AskWrite)( + const wchar_t *srcPath, + Int32 srcIsFolder, + const FILETIME *srcTime, + const UInt64 *srcSize, + const wchar_t *destPathRequest, + BSTR *destPathResult, + Int32 *writeAnswer); + STDMETHOD(ShowMessage)(const wchar_t *message); + STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath); + STDMETHOD(SetNumFiles)(UInt64 numFiles); + INTERFACE_IFolderExtractToStreamCallback(;) + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); + #endif + + // ICryptoGetTextPassword + #ifndef _NO_CRYPTO + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + #endif + +private: + UString _currentArchivePath; + bool _needWriteArchivePath; + + UString _currentFilePath; + bool _isFolder; + + bool _isAltStream; + UInt64 _curSize; + bool _curSizeDefined; + UString _filePath; + // bool _extractMode; + // bool _testMode; + bool _newVirtFileWasAdded; + bool _needUpdateStat; + + + HRESULT SetCurrentFilePath2(const wchar_t *filePath); + void AddError_Message(LPCWSTR message); + + #ifndef _SFX + bool _hashStreamWasUsed; + COutStreamWithHash *_hashStreamSpec; + CMyComPtr<ISequentialOutStream> _hashStream; + IHashCalc *_hashCalc; // it's for stat in Test operation + #endif + +public: + + #ifndef _SFX + CVirtFileSystem *VirtFileSystemSpec; + CMyComPtr<ISequentialOutStream> VirtFileSystem; + #endif + + bool ProcessAltStreams; + + bool StreamMode; + + CProgressDialog *ProgressDialog; + #ifndef _SFX + UInt64 NumFolders; + UInt64 NumFiles; + bool NeedAddFile; + #endif + UInt32 NumArchiveErrors; + bool ThereAreMessageErrors; + NExtract::NOverwriteMode::EEnum OverwriteMode; + + #ifndef _NO_CRYPTO + bool PasswordIsDefined; + bool PasswordWasAsked; + UString Password; + #endif + + + UString _lang_Extracting; + UString _lang_Testing; + UString _lang_Skipping; + UString _lang_Empty; + + bool _totalFilesDefined; + bool _totalBytesDefined; + bool MultiArcMode; + + CExtractCallbackImp(): + #ifndef _NO_CRYPTO + PasswordIsDefined(false), + PasswordWasAsked(false), + #endif + OverwriteMode(NExtract::NOverwriteMode::kAsk), + StreamMode(false), + ProcessAltStreams(true), + + _totalFilesDefined(false), + _totalBytesDefined(false), + MultiArcMode(false) + + #ifndef _SFX + , _hashCalc(NULL) + #endif + {} + + ~CExtractCallbackImp(); + void Init(); + + #ifndef _SFX + void SetHashCalc(IHashCalc *hashCalc) { _hashCalc = hashCalc; } + + void SetHashMethods(IHashCalc *hash) + { + if (!hash) + return; + _hashStreamSpec = new COutStreamWithHash; + _hashStream = _hashStreamSpec; + _hashStreamSpec->_hash = hash; + } + #endif + + bool IsOK() const { return NumArchiveErrors == 0 && !ThereAreMessageErrors; } +}; + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.cpp new file mode 100644 index 00000000000..2143c3f1b12 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.cpp @@ -0,0 +1,28 @@ +// FormatUtils.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "FormatUtils.h" + +#include "LangUtils.h" + +UString NumberToString(UInt64 number) +{ + wchar_t numberString[32]; + ConvertUInt64ToString(number, numberString); + return numberString; +} + +UString MyFormatNew(const UString &format, const UString &argument) +{ + UString result = format; + result.Replace(L"{0}", argument); + return result; +} + +UString MyFormatNew(UINT resourceID, const UString &argument) +{ + return MyFormatNew(LangString(resourceID), argument); +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h new file mode 100644 index 00000000000..993e803390f --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/FormatUtils.h @@ -0,0 +1,14 @@ +// FormatUtils.h + +#ifndef __FORMAT_UTILS_H +#define __FORMAT_UTILS_H + +#include "../../../Common/MyTypes.h" +#include "../../../Common/MyString.h" + +UString NumberToString(UInt64 number); + +UString MyFormatNew(const UString &format, const UString &argument); +UString MyFormatNew(UINT resourceID, const UString &argument); + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h new file mode 100644 index 00000000000..d63a443c6d3 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/LangUtils.h @@ -0,0 +1,40 @@ +// LangUtils.h + +#ifndef __LANG_UTILS_H +#define __LANG_UTILS_H + +#include "../../../Windows/ResourceString.h" + +#ifdef LANG + +extern UString g_LangID; + +struct CIDLangPair +{ + UInt32 ControlID; + UInt32 LangID; +}; + +void ReloadLang(); +void LoadLangOneTime(); +FString GetLangDirPrefix(); + +void LangSetDlgItemText(HWND dialog, UInt32 controlID, UInt32 langID); +void LangSetDlgItems(HWND dialog, const UInt32 *ids, unsigned numItems); +void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems); +void LangSetWindowText(HWND window, UInt32 langID); + +UString LangString(UInt32 langID); +void AddLangString(UString &s, UInt32 langID); +void LangString(UInt32 langID, UString &dest); +void LangString_OnlyFromLangFile(UInt32 langID, UString &dest); + +#else + +inline UString LangString(UInt32 langID) { return NWindows::MyLoadString(langID); } +inline void LangString(UInt32 langID, UString &dest) { NWindows::MyLoadString(langID, dest); } +inline void AddLangString(UString &s, UInt32 langID) { s += NWindows::MyLoadString(langID); } + +#endif + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h new file mode 100644 index 00000000000..48a95359e6f --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/MyWindowsNew.h @@ -0,0 +1,76 @@ +// MyWindowsNew.h + +#ifndef __MY_WINDOWS_NEW_H +#define __MY_WINDOWS_NEW_H + +#ifdef _MSC_VER + +#include <ShObjIdl.h> + +#ifndef __ITaskbarList3_INTERFACE_DEFINED__ +#define __ITaskbarList3_INTERFACE_DEFINED__ + +typedef enum THUMBBUTTONFLAGS +{ + THBF_ENABLED = 0, + THBF_DISABLED = 0x1, + THBF_DISMISSONCLICK = 0x2, + THBF_NOBACKGROUND = 0x4, + THBF_HIDDEN = 0x8, + THBF_NONINTERACTIVE = 0x10 +} THUMBBUTTONFLAGS; + +typedef enum THUMBBUTTONMASK +{ + THB_BITMAP = 0x1, + THB_ICON = 0x2, + THB_TOOLTIP = 0x4, + THB_FLAGS = 0x8 +} THUMBBUTTONMASK; + +// #include <pshpack8.h> + +typedef struct THUMBBUTTON +{ + THUMBBUTTONMASK dwMask; + UINT iId; + UINT iBitmap; + HICON hIcon; + WCHAR szTip[260]; + THUMBBUTTONFLAGS dwFlags; +} THUMBBUTTON; + +typedef struct THUMBBUTTON *LPTHUMBBUTTON; + +typedef enum TBPFLAG +{ + TBPF_NOPROGRESS = 0, + TBPF_INDETERMINATE = 0x1, + TBPF_NORMAL = 0x2, + TBPF_ERROR = 0x4, + TBPF_PAUSED = 0x8 +} TBPFLAG; + +DEFINE_GUID(IID_ITaskbarList3, 0xEA1AFB91, 0x9E28, 0x4B86, 0x90, 0xE9, 0x9E, 0x9F, 0x8A, 0x5E, 0xEF, 0xAF); + +struct ITaskbarList3: public ITaskbarList2 +{ + STDMETHOD(SetProgressValue)(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0; + STDMETHOD(SetProgressState)(HWND hwnd, TBPFLAG tbpFlags) = 0; + STDMETHOD(RegisterTab)(HWND hwndTab, HWND hwndMDI) = 0; + STDMETHOD(UnregisterTab)(HWND hwndTab) = 0; + STDMETHOD(SetTabOrder)(HWND hwndTab, HWND hwndInsertBefore) = 0; + STDMETHOD(SetTabActive)(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0; + STDMETHOD(ThumbBarAddButtons)(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) = 0; + STDMETHOD(ThumbBarUpdateButtons)(HWND hwnd, UINT cButtons, LPTHUMBBUTTON pButton) = 0; + STDMETHOD(ThumbBarSetImageList)(HWND hwnd, HIMAGELIST himl) = 0; + STDMETHOD(SetOverlayIcon)(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0; + STDMETHOD(SetThumbnailTooltip)(HWND hwnd, LPCWSTR pszTip) = 0; + STDMETHOD(SetThumbnailClip)(HWND hwnd, RECT *prcClip) = 0; +}; + +#endif + +#endif + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp new file mode 100644 index 00000000000..c6feb9021bb --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.cpp @@ -0,0 +1,119 @@ +// OverwriteDialog.cpp + +#include "StdAfx.h" + +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/PropVariantConv.h" +#include "../../../Windows/ResourceString.h" + +#include "../../../Windows/Control/Static.h" + +#include "FormatUtils.h" +#include "LangUtils.h" +#include "OverwriteDialog.h" + +#include "PropertyNameRes.h" + +using namespace NWindows; + +#ifdef LANG +static const UInt32 kLangIDs[] = +{ + IDT_OVERWRITE_HEADER, + IDT_OVERWRITE_QUESTION_BEGIN, + IDT_OVERWRITE_QUESTION_END, + IDB_YES_TO_ALL, + IDB_NO_TO_ALL, + IDB_AUTO_RENAME +}; +#endif + +static const unsigned kCurrentFileNameSizeLimit = 82; +static const unsigned kCurrentFileNameSizeLimit2 = 30; + +void COverwriteDialog::ReduceString(UString &s) +{ + unsigned size = _isBig ? kCurrentFileNameSizeLimit : kCurrentFileNameSizeLimit2; + if (s.Len() > size) + { + s.Delete(size / 2, s.Len() - size); + s.Insert(size / 2, L" ... "); + } +} + +void COverwriteDialog::SetFileInfoControl(int textID, int iconID, + const NOverwriteDialog::CFileInfo &fileInfo) +{ + UString sizeString; + if (fileInfo.SizeIsDefined) + sizeString = MyFormatNew(IDS_FILE_SIZE, NumberToString(fileInfo.Size)); + + const UString &fileName = fileInfo.Name; + int slashPos = fileName.ReverseFind_PathSepar(); + UString s1 = fileName.Left(slashPos + 1); + UString s2 = fileName.Ptr(slashPos + 1); + + ReduceString(s1); + ReduceString(s2); + + UString s = s1; + s.Add_LF(); + s += s2; + s.Add_LF(); + s += sizeString; + s.Add_LF(); + + if (fileInfo.TimeIsDefined) + { + FILETIME localFileTime; + if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) + throw 4190402; + AddLangString(s, IDS_PROP_MTIME); + s += L": "; + wchar_t t[32]; + ConvertFileTimeToString(localFileTime, t); + s += t; + } + + NControl::CDialogChildControl control; + control.Init(*this, textID); + control.SetText(s); + + SHFILEINFO shellFileInfo; + if (::SHGetFileInfo( + GetSystemString(fileInfo.Name), FILE_ATTRIBUTE_NORMAL, &shellFileInfo, + sizeof(shellFileInfo), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES | SHGFI_LARGEICON)) + { + NControl::CStatic staticContol; + staticContol.Attach(GetItem(iconID)); + staticContol.SetIcon(shellFileInfo.hIcon); + } +} + +bool COverwriteDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(*this, IDD_OVERWRITE); + LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); + #endif + SetFileInfoControl(IDT_OVERWRITE_OLD_FILE_SIZE_TIME, IDI_OVERWRITE_OLD_FILE, OldFileInfo); + SetFileInfoControl(IDT_OVERWRITE_NEW_FILE_SIZE_TIME, IDI_OVERWRITE_NEW_FILE, NewFileInfo); + NormalizePosition(); + return CModalDialog::OnInit(); +} + +bool COverwriteDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDYES: + case IDNO: + case IDB_YES_TO_ALL: + case IDB_NO_TO_ALL: + case IDB_AUTO_RENAME: + End(buttonID); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h new file mode 100644 index 00000000000..da7fa55ff68 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.h @@ -0,0 +1,69 @@ +// OverwriteDialog.h + +#ifndef __OVERWRITE_DIALOG_H +#define __OVERWRITE_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" + +#include "DialogSize.h" +#include "OverwriteDialogRes.h" + +namespace NOverwriteDialog +{ + struct CFileInfo + { + bool SizeIsDefined; + bool TimeIsDefined; + UInt64 Size; + FILETIME Time; + UString Name; + + void SetTime(const FILETIME *t) + { + if (t == 0) + TimeIsDefined = false; + else + { + TimeIsDefined = true; + Time = *t; + } + } + void SetSize(const UInt64 *size) + { + if (size == 0) + SizeIsDefined = false; + else + { + SizeIsDefined = true; + Size = *size; + } + } + }; +} + +class COverwriteDialog: public NWindows::NControl::CModalDialog +{ + bool _isBig; + + void SetFileInfoControl(int textID, int iconID, const NOverwriteDialog::CFileInfo &fileInfo); + virtual bool OnInit(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); + void ReduceString(UString &s); + +public: + INT_PTR Create(HWND parent = 0) + { + BIG_DIALOG_SIZE(280, 200); + #ifdef UNDER_CE + _isBig = isBig; + #else + _isBig = true; + #endif + return CModalDialog::Create(SIZED_DIALOG(IDD_OVERWRITE), parent); + } + + NOverwriteDialog::CFileInfo OldFileInfo; + NOverwriteDialog::CFileInfo NewFileInfo; +}; + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.rc new file mode 100644 index 00000000000..29f99122bfd --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialog.rc @@ -0,0 +1,91 @@ +#include "OverwriteDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 280 +#define yc 200 + +#undef iconSize +#define iconSize 24 + +#undef x +#undef fx +#undef fy +#define x (m + iconSize + m) +#define fx (xc - iconSize - m) +#define fy 50 + +#define bSizeBig 104 +#undef bx1 +#define bx1 (xs - m - bSizeBig) + +IDD_OVERWRITE DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Confirm File Replace" +BEGIN + LTEXT "Destination folder already contains processed file.", IDT_OVERWRITE_HEADER, m, 7, xc, 8 + LTEXT "Would you like to replace the existing file", IDT_OVERWRITE_QUESTION_BEGIN, m, 28, xc, 8 + + ICON "", IDI_OVERWRITE_OLD_FILE, m, 44, iconSize, iconSize + LTEXT "", IDT_OVERWRITE_OLD_FILE_SIZE_TIME, x, 44, fx, fy, SS_NOPREFIX + + LTEXT "with this one?", IDT_OVERWRITE_QUESTION_END, m, 98, xc, 8 + + ICON "", IDI_OVERWRITE_NEW_FILE, m, 114, iconSize, iconSize + LTEXT "", IDT_OVERWRITE_NEW_FILE_SIZE_TIME, x, 114, fx, fy, SS_NOPREFIX + + PUSHBUTTON "&Yes", IDYES, bx3, by2, bxs, bys + PUSHBUTTON "Yes to &All", IDB_YES_TO_ALL, bx2, by2, bxs, bys + PUSHBUTTON "A&uto Rename", IDB_AUTO_RENAME, bx1, by2, bSizeBig, bys + PUSHBUTTON "&No", IDNO, bx3, by1, bxs, bys + PUSHBUTTON "No to A&ll", IDB_NO_TO_ALL, bx2, by1, bxs, bys + PUSHBUTTON "&Cancel", IDCANCEL, xs - m - bxs, by1, bxs, bys +END + + +#ifdef UNDER_CE + +#undef m +#undef xc +#undef yc + +#define m 4 +#define xc 152 +#define yc 144 + +#undef fy +#define fy 40 + +#undef bxs +#define bxs 48 + +#undef bx1 + +#define bx1 (xs - m - bxs) + +IDD_OVERWRITE_2 DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Confirm File Replace" +BEGIN + LTEXT "Would you like to replace the existing file", IDT_OVERWRITE_QUESTION_BEGIN, m, m, xc, 8 + + ICON "", IDI_OVERWRITE_OLD_FILE, m, 20, iconSize, iconSize + LTEXT "", IDT_OVERWRITE_OLD_FILE_SIZE_TIME, x, 20, fx, fy, SS_NOPREFIX + + LTEXT "with this one?", IDT_OVERWRITE_QUESTION_END, m, 60, xc, 8 + + ICON "", IDI_OVERWRITE_NEW_FILE, m, 72, iconSize, iconSize + LTEXT "", IDT_OVERWRITE_NEW_FILE_SIZE_TIME, x, 72, fx, fy, SS_NOPREFIX + + PUSHBUTTON "&Yes", IDYES, bx3, by2, bxs, bys + PUSHBUTTON "Yes to &All", IDB_YES_TO_ALL, bx2, by2, bxs, bys + PUSHBUTTON "A&uto Rename", IDB_AUTO_RENAME, bx1, by2, bxs, bys + PUSHBUTTON "&No", IDNO, bx3, by1, bxs, bys + PUSHBUTTON "No to A&ll", IDB_NO_TO_ALL, bx2, by1, bxs, bys + PUSHBUTTON "&Cancel", IDCANCEL, bx1, by1, bxs, bys +END + +#endif + + +STRINGTABLE +BEGIN + IDS_FILE_SIZE "{0} bytes" +END diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialogRes.h new file mode 100644 index 00000000000..b480ba1634c --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/OverwriteDialogRes.h @@ -0,0 +1,17 @@ +#define IDD_OVERWRITE 3500 +#define IDD_OVERWRITE_2 13500 + +#define IDT_OVERWRITE_HEADER 3501 +#define IDT_OVERWRITE_QUESTION_BEGIN 3502 +#define IDT_OVERWRITE_QUESTION_END 3503 +#define IDS_FILE_SIZE 3504 + +#define IDB_AUTO_RENAME 3505 +#define IDB_YES_TO_ALL 440 +#define IDB_NO_TO_ALL 441 + +#define IDI_OVERWRITE_OLD_FILE 100 +#define IDI_OVERWRITE_NEW_FILE 101 + +#define IDT_OVERWRITE_OLD_FILE_SIZE_TIME 102 +#define IDT_OVERWRITE_NEW_FILE_SIZE_TIME 103 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp new file mode 100644 index 00000000000..6ead39c3764 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.cpp @@ -0,0 +1,58 @@ +// PasswordDialog.cpp + +#include "StdAfx.h" + +#include "PasswordDialog.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +#ifdef LANG +static const UInt32 kLangIDs[] = +{ + IDT_PASSWORD_ENTER, + IDX_PASSWORD_SHOW +}; +#endif + +void CPasswordDialog::ReadControls() +{ + _passwordEdit.GetText(Password); + ShowPassword = IsButtonCheckedBool(IDX_PASSWORD_SHOW); +} + +void CPasswordDialog::SetTextSpec() +{ + _passwordEdit.SetPasswordChar(ShowPassword ? 0: TEXT('*')); + _passwordEdit.SetText(Password); +} + +bool CPasswordDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(*this, IDD_PASSWORD); + LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); + #endif + _passwordEdit.Attach(GetItem(IDE_PASSWORD_PASSWORD)); + CheckButton(IDX_PASSWORD_SHOW, ShowPassword); + SetTextSpec(); + return CModalDialog::OnInit(); +} + +bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + if (buttonID == IDX_PASSWORD_SHOW) + { + ReadControls(); + SetTextSpec(); + return true; + } + return CDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CPasswordDialog::OnOK() +{ + ReadControls(); + CModalDialog::OnOK(); +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h new file mode 100644 index 00000000000..339ebdaf072 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.h @@ -0,0 +1,28 @@ +// PasswordDialog.h + +#ifndef __PASSWORD_DIALOG_H +#define __PASSWORD_DIALOG_H + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/Edit.h" + +#include "PasswordDialogRes.h" + +class CPasswordDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CEdit _passwordEdit; + + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + void SetTextSpec(); + void ReadControls(); +public: + UString Password; + bool ShowPassword; + + CPasswordDialog(): ShowPassword(false) {} + INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_PASSWORD, parentWindow); } +}; + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.rc new file mode 100644 index 00000000000..90c57efa607 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialog.rc @@ -0,0 +1,14 @@ +#include "PasswordDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 140 +#define yc 72 + +IDD_PASSWORD DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Enter password" +BEGIN + LTEXT "&Enter password:", IDT_PASSWORD_ENTER, m, m, xc, 8 + EDITTEXT IDE_PASSWORD_PASSWORD, m, 20, xc, 14, ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "&Show password", IDX_PASSWORD_SHOW, MY_CHECKBOX, m, 42, xc, 10 + OK_CANCEL +END diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialogRes.h new file mode 100644 index 00000000000..1fe32e10aa5 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PasswordDialogRes.h @@ -0,0 +1,5 @@ +#define IDD_PASSWORD 3800 +#define IDT_PASSWORD_ENTER 3801 +#define IDX_PASSWORD_SHOW 3803 + +#define IDE_PASSWORD_PASSWORD 120 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp new file mode 100644 index 00000000000..65201a9ed16 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.cpp @@ -0,0 +1,196 @@ +// ProgressDialog.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "resource.h" + +#include "ProgressDialog.h" + +using namespace NWindows; + +extern HINSTANCE g_hInstance; + +static const UINT_PTR kTimerID = 3; +static const UINT kTimerElapse = 100; + +#ifdef LANG +#include "LangUtils.h" +#endif + +HRESULT CProgressSync::ProcessStopAndPause() +{ + for (;;) + { + if (GetStopped()) + return E_ABORT; + if (!GetPaused()) + break; + ::Sleep(100); + } + return S_OK; +} + +#ifndef _SFX +CProgressDialog::~CProgressDialog() +{ + AddToTitle(L""); +} +void CProgressDialog::AddToTitle(LPCWSTR s) +{ + if (MainWindow != 0) + MySetWindowText(MainWindow, UString(s) + MainTitle); +} +#endif + + +bool CProgressDialog::OnInit() +{ + _range = (UInt64)(Int64)-1; + _prevPercentValue = -1; + + _wasCreated = true; + _dialogCreatedEvent.Set(); + + #ifdef LANG + LangSetDlgItems(*this, NULL, 0); + #endif + + m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); + + if (IconID >= 0) + { + HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID)); + SetIcon(ICON_BIG, icon); + } + + _timer = SetTimer(kTimerID, kTimerElapse); + SetText(_title); + CheckNeedClose(); + return CModalDialog::OnInit(); +} + +void CProgressDialog::OnCancel() { Sync.SetStopped(true); } +void CProgressDialog::OnOK() { } + +void CProgressDialog::SetRange(UInt64 range) +{ + _range = range; + _peviousPos = (UInt64)(Int64)-1; + _converter.Init(range); + m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100% +} + +void CProgressDialog::SetPos(UInt64 pos) +{ + bool redraw = true; + if (pos < _range && pos > _peviousPos) + { + UInt64 posDelta = pos - _peviousPos; + if (posDelta < (_range >> 10)) + redraw = false; + } + if (redraw) + { + m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100% + _peviousPos = pos; + } +} + +bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + if (Sync.GetPaused()) + return true; + + CheckNeedClose(); + + UInt64 total, completed; + Sync.GetProgress(total, completed); + if (total != _range) + SetRange(total); + SetPos(completed); + + if (total == 0) + total = 1; + + int percentValue = (int)(completed * 100 / total); + if (percentValue != _prevPercentValue) + { + wchar_t s[64]; + ConvertUInt64ToString(percentValue, s); + UString title = s; + title += L"% "; + SetText(title + _title); + #ifndef _SFX + AddToTitle(title + MainAddTitle); + #endif + _prevPercentValue = percentValue; + } + return true; +} + +bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case kCloseMessage: + { + KillTimer(_timer); + _timer = 0; + if (_inCancelMessageBox) + { + _externalCloseMessageWasReceived = true; + break; + } + return OnExternalCloseMessage(); + } + /* + case WM_SETTEXT: + { + if (_timer == 0) + return true; + } + */ + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + +bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + case IDCANCEL: + { + bool paused = Sync.GetPaused(); + Sync.SetPaused(true); + _inCancelMessageBox = true; + int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNOCANCEL); + _inCancelMessageBox = false; + Sync.SetPaused(paused); + if (res == IDCANCEL || res == IDNO) + { + if (_externalCloseMessageWasReceived) + OnExternalCloseMessage(); + return true; + } + break; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CProgressDialog::CheckNeedClose() +{ + if (_needClose) + { + PostMsg(kCloseMessage); + _needClose = false; + } +} + +bool CProgressDialog::OnExternalCloseMessage() +{ + End(0); + return true; +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h new file mode 100644 index 00000000000..0f41b57aed6 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.h @@ -0,0 +1,170 @@ +// ProgressDialog.h + +#ifndef __PROGRESS_DIALOG_H +#define __PROGRESS_DIALOG_H + +#include "../../../Windows/Synchronization.h" +#include "../../../Windows/Thread.h" + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/ProgressBar.h" + +#include "ProgressDialogRes.h" + +class CProgressSync +{ + NWindows::NSynchronization::CCriticalSection _cs; + bool _stopped; + bool _paused; + UInt64 _total; + UInt64 _completed; +public: + CProgressSync(): _stopped(false), _paused(false), _total(1), _completed(0) {} + + HRESULT ProcessStopAndPause(); + bool GetStopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + return _stopped; + } + void SetStopped(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _stopped = value; + } + bool GetPaused() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + return _paused; + } + void SetPaused(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _paused = value; + } + void SetProgress(UInt64 total, UInt64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _total = total; + _completed = completed; + } + void SetPos(UInt64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _completed = completed; + } + void GetProgress(UInt64 &total, UInt64 &completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + total = _total; + completed = _completed; + } +}; + +class CU64ToI32Converter +{ + UInt64 _numShiftBits; +public: + void Init(UInt64 range) + { + // Windows CE doesn't like big number here. + for (_numShiftBits = 0; range > (1 << 15); _numShiftBits++) + range >>= 1; + } + int Count(UInt64 value) { return int(value >> _numShiftBits); } +}; + +class CProgressDialog: public NWindows::NControl::CModalDialog +{ +private: + UINT_PTR _timer; + + UString _title; + CU64ToI32Converter _converter; + UInt64 _peviousPos; + UInt64 _range; + NWindows::NControl::CProgressBar m_ProgressBar; + + int _prevPercentValue; + + bool _wasCreated; + bool _needClose; + bool _inCancelMessageBox; + bool _externalCloseMessageWasReceived; + + bool OnTimer(WPARAM timerID, LPARAM callback); + void SetRange(UInt64 range); + void SetPos(UInt64 pos); + virtual bool OnInit(); + virtual void OnCancel(); + virtual void OnOK(); + NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; + #ifndef _SFX + void AddToTitle(LPCWSTR string); + #endif + bool OnButtonClicked(int buttonID, HWND buttonHWND); + + void WaitCreating() { _dialogCreatedEvent.Lock(); } + void CheckNeedClose(); + bool OnExternalCloseMessage(); +public: + CProgressSync Sync; + int IconID; + + #ifndef _SFX + HWND MainWindow; + UString MainTitle; + UString MainAddTitle; + ~CProgressDialog(); + #endif + + CProgressDialog(): _timer(0) + #ifndef _SFX + ,MainWindow(0) + #endif + { + IconID = -1; + _wasCreated = false; + _needClose = false; + _inCancelMessageBox = false; + _externalCloseMessageWasReceived = false; + + if (_dialogCreatedEvent.Create() != S_OK) + throw 1334987; + } + + INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0) + { + _title = title; + INT_PTR res = CModalDialog::Create(IDD_PROGRESS, wndParent); + thread.Wait(); + return res; + } + + enum + { + kCloseMessage = WM_APP + 1 + }; + + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + + void ProcessWasFinished() + { + WaitCreating(); + if (_wasCreated) + PostMsg(kCloseMessage); + else + _needClose = true; + }; +}; + + +class CProgressCloser +{ + CProgressDialog *_p; +public: + CProgressCloser(CProgressDialog &p) : _p(&p) {} + ~CProgressCloser() { _p->ProcessWasFinished(); } +}; + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.rc new file mode 100644 index 00000000000..55d99233b05 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog.rc @@ -0,0 +1,12 @@ +#include "ProgressDialogRes.h" +#include "../../GuiCommon.rc" + +#define xc 172 +#define yc 44 + +IDD_PROGRESS DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE MY_FONT +CAPTION "Progress" +BEGIN + PUSHBUTTON "Cancel", IDCANCEL, bx, by, bxs, bys + CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, m, m, xc, 14 +END diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp new file mode 100644 index 00000000000..378ad9035c3 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -0,0 +1,1319 @@ +// ProgressDialog2.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" +#include "../../../Common/StringConvert.h" + +#include "../../../Windows/Control/Static.h" +#include "../../../Windows/ErrorMsg.h" + +#include "../GUI/ExtractRes.h" + +#include "LangUtils.h" + +#include "DialogSize.h" +#include "ProgressDialog2.h" +#include "ProgressDialog2Res.h" + +using namespace NWindows; + +extern HINSTANCE g_hInstance; + +static const UINT_PTR kTimerID = 3; + +static const UINT kCloseMessage = WM_APP + 1; +// we can't use WM_USER, since WM_USER can be used by standard Windows procedure for Dialog + +static const UINT kTimerElapse = + #ifdef UNDER_CE + 500 + #else + 200 + #endif + ; + +static const UINT kCreateDelay = + #ifdef UNDER_CE + 2500 + #else + 500 + #endif + ; + +static const DWORD kPauseSleepTime = 100; + +#ifdef LANG + +static const UInt32 kLangIDs[] = +{ + IDT_PROGRESS_ELAPSED, + IDT_PROGRESS_REMAINING, + IDT_PROGRESS_TOTAL, + IDT_PROGRESS_SPEED, + IDT_PROGRESS_PROCESSED, + IDT_PROGRESS_RATIO, + IDT_PROGRESS_ERRORS, + IDB_PROGRESS_BACKGROUND, + IDB_PAUSE +}; + +static const UInt32 kLangIDs_Colon[] = +{ + IDT_PROGRESS_PACKED, + IDT_PROGRESS_FILES +}; + +#endif + + +#define UNDEFINED_VAL ((UInt64)(Int64)-1) +#define INIT_AS_UNDEFINED(v) v = UNDEFINED_VAL; +#define IS_UNDEFINED_VAL(v) ((v) == UNDEFINED_VAL) +#define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL) + +CProgressSync::CProgressSync(): + _stopped(false), _paused(false), + _bytesProgressMode(true), + _totalBytes(UNDEFINED_VAL), _completedBytes(0), + _totalFiles(UNDEFINED_VAL), _curFiles(0), + _inSize(UNDEFINED_VAL), + _outSize(UNDEFINED_VAL), + _isDir(false) + {} + +#define CHECK_STOP if (_stopped) return E_ABORT; if (!_paused) return S_OK; +#define CRITICAL_LOCK NSynchronization::CCriticalSectionLock lock(_cs); + +bool CProgressSync::Get_Paused() +{ + CRITICAL_LOCK + return _paused; +} + +HRESULT CProgressSync::CheckStop() +{ + for (;;) + { + { + CRITICAL_LOCK + CHECK_STOP + } + ::Sleep(kPauseSleepTime); + } +} + +HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir) +{ + { + CRITICAL_LOCK + _totalFiles = numFiles; + _totalBytes = totalSize; + _filePath = fs2us(fileName); + _isDir = isDir; + // _completedBytes = 0; + CHECK_STOP + } + return CheckStop(); +} + +HRESULT CProgressSync::Set_NumFilesTotal(UInt64 val) +{ + { + CRITICAL_LOCK + _totalFiles = val; + CHECK_STOP + } + return CheckStop(); +} + +void CProgressSync::Set_NumBytesTotal(UInt64 val) +{ + CRITICAL_LOCK + _totalBytes = val; +} + +void CProgressSync::Set_NumFilesCur(UInt64 val) +{ + CRITICAL_LOCK + _curFiles = val; +} + +HRESULT CProgressSync::Set_NumBytesCur(const UInt64 *val) +{ + { + CRITICAL_LOCK + if (val) + _completedBytes = *val; + CHECK_STOP + } + return CheckStop(); +} + +HRESULT CProgressSync::Set_NumBytesCur(UInt64 val) +{ + { + CRITICAL_LOCK + _completedBytes = val; + CHECK_STOP + } + return CheckStop(); +} + +void CProgressSync::Set_Ratio(const UInt64 *inSize, const UInt64 *outSize) +{ + CRITICAL_LOCK + if (inSize) + _inSize = *inSize; + if (outSize) + _outSize = *outSize; +} + +void CProgressSync::Set_TitleFileName(const UString &fileName) +{ + CRITICAL_LOCK + _titleFileName = fileName; +} + +void CProgressSync::Set_Status(const UString &s) +{ + CRITICAL_LOCK + _status = s; +} + +HRESULT CProgressSync::Set_Status2(const UString &s, const wchar_t *path, bool isDir) +{ + { + CRITICAL_LOCK + _status = s; + if (path) + _filePath = path; + else + _filePath.Empty(); + _isDir = isDir; + } + return CheckStop(); +} + +void CProgressSync::Set_FilePath(const wchar_t *path, bool isDir) +{ + CRITICAL_LOCK + if (path) + _filePath = path; + else + _filePath.Empty(); + _isDir = isDir; +} + + +void CProgressSync::AddError_Message(const wchar_t *message) +{ + CRITICAL_LOCK + Messages.Add(message); +} + +void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t *name) +{ + UString s; + if (name && *name != 0) + s += name; + if (message && *message != 0 ) + { + if (!s.IsEmpty()) + s.Add_LF(); + s += message; + if (!s.IsEmpty() && s.Back() == L'\n') + s.DeleteBack(); + } + AddError_Message(s); +} + +void CProgressSync::AddError_Code_Name(DWORD systemError, const wchar_t *name) +{ + UString s = NError::MyFormatMessage(systemError); + if (systemError == 0) + s = L"Error"; + AddError_Message_Name(s, name); +} + +CProgressDialog::CProgressDialog(): _timer(0), CompressingMode(true), MainWindow(0) +{ + _isDir = false; + + _numMessages = 0; + IconID = -1; + MessagesDisplayed = false; + _wasCreated = false; + _needClose = false; + _inCancelMessageBox = false; + _externalCloseMessageWasReceived = false; + + _numPostedMessages = 0; + _numAutoSizeMessages = 0; + _errorsWereDisplayed = false; + _waitCloseByCancelButton = false; + _cancelWasPressed = false; + ShowCompressionInfo = true; + WaitMode = false; + if (_dialogCreatedEvent.Create() != S_OK) + throw 1334987; + if (_createDialogEvent.Create() != S_OK) + throw 1334987; + #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void**)&_taskbarList); + if (_taskbarList) + _taskbarList->HrInit(); + #endif +} + +#ifndef _SFX + +CProgressDialog::~CProgressDialog() +{ + #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + SetTaskbarProgressState(TBPF_NOPROGRESS); + #endif + AddToTitle(L""); +} +void CProgressDialog::AddToTitle(LPCWSTR s) +{ + if (MainWindow != 0) + { + CWindow window(MainWindow); + window.SetText((UString)s + MainTitle); + } +} + +#endif + + +void CProgressDialog::SetTaskbarProgressState() +{ + #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + if (_taskbarList && _hwndForTaskbar) + { + TBPFLAG tbpFlags; + if (Sync.Get_Paused()) + tbpFlags = TBPF_PAUSED; + else + tbpFlags = _errorsWereDisplayed ? TBPF_ERROR: TBPF_NORMAL; + SetTaskbarProgressState(tbpFlags); + } + #endif +} + +static const unsigned kTitleFileNameSizeLimit = 36; +static const unsigned kCurrentFileNameSizeLimit = 82; + +static void ReduceString(UString &s, unsigned size) +{ + if (s.Len() <= size) + return; + s.Delete(size / 2, s.Len() - size); + s.Insert(size / 2, L" ... "); +} + +void CProgressDialog::EnableErrorsControls(bool enable) +{ + ShowItem_Bool(IDT_PROGRESS_ERRORS, enable); + ShowItem_Bool(IDT_PROGRESS_ERRORS_VAL, enable); + ShowItem_Bool(IDL_PROGRESS_MESSAGES, enable); +} + +bool CProgressDialog::OnInit() +{ + _hwndForTaskbar = MainWindow; + if (!_hwndForTaskbar) + _hwndForTaskbar = GetParent(); + if (!_hwndForTaskbar) + _hwndForTaskbar = *this; + + INIT_AS_UNDEFINED(_progressBar_Range); + INIT_AS_UNDEFINED(_progressBar_Pos); + + INIT_AS_UNDEFINED(_prevPercentValue); + INIT_AS_UNDEFINED(_prevElapsedSec); + INIT_AS_UNDEFINED(_prevRemainingSec); + + INIT_AS_UNDEFINED(_prevSpeed); + _prevSpeed_MoveBits = 0; + + _prevTime = ::GetTickCount(); + _elapsedTime = 0; + + INIT_AS_UNDEFINED(_totalBytes_Prev); + INIT_AS_UNDEFINED(_processed_Prev); + INIT_AS_UNDEFINED(_packed_Prev); + INIT_AS_UNDEFINED(_ratio_Prev); + _filesStr_Prev.Empty(); + + _foreground = true; + + m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); + _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES)); + _messageList.SetUnicodeFormat(); + + _wasCreated = true; + _dialogCreatedEvent.Set(); + + #ifdef LANG + LangSetDlgItems(*this, kLangIDs, ARRAY_SIZE(kLangIDs)); + LangSetDlgItems_Colon(*this, kLangIDs_Colon, ARRAY_SIZE(kLangIDs_Colon)); + #endif + + CWindow window(GetItem(IDB_PROGRESS_BACKGROUND)); + window.GetText(_background_String); + _backgrounded_String = _background_String; + _backgrounded_String.RemoveChar(L'&'); + + window = GetItem(IDB_PAUSE); + window.GetText(_pause_String); + + LangString(IDS_PROGRESS_FOREGROUND, _foreground_String); + LangString(IDS_CONTINUE, _continue_String); + LangString(IDS_PROGRESS_PAUSED, _paused_String); + + SetText(_title); + SetPauseText(); + SetPriorityText(); + + _messageList.InsertColumn(0, L"", 30); + _messageList.InsertColumn(1, L"", 600); + + _messageList.SetColumnWidthAuto(0); + _messageList.SetColumnWidthAuto(1); + + EnableErrorsControls(false); + + GetItemSizes(IDCANCEL, _buttonSizeX, _buttonSizeY); + _numReduceSymbols = kCurrentFileNameSizeLimit; + NormalizeSize(true); + + if (!ShowCompressionInfo) + { + HideItem(IDT_PROGRESS_PACKED); + HideItem(IDT_PROGRESS_PACKED_VAL); + HideItem(IDT_PROGRESS_RATIO); + HideItem(IDT_PROGRESS_RATIO_VAL); + } + + if (IconID >= 0) + { + HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID)); + // SetIcon(ICON_SMALL, icon); + SetIcon(ICON_BIG, icon); + } + _timer = SetTimer(kTimerID, kTimerElapse); + #ifdef UNDER_CE + Foreground(); + #endif + + CheckNeedClose(); + + SetTaskbarProgressState(); + + return CModalDialog::OnInit(); +} + +static const UINT kIDs[] = +{ + IDT_PROGRESS_ELAPSED, IDT_PROGRESS_ELAPSED_VAL, + IDT_PROGRESS_REMAINING, IDT_PROGRESS_REMAINING_VAL, + IDT_PROGRESS_FILES, IDT_PROGRESS_FILES_VAL, + IDT_PROGRESS_RATIO, IDT_PROGRESS_RATIO_VAL, + IDT_PROGRESS_ERRORS, IDT_PROGRESS_ERRORS_VAL, + + IDT_PROGRESS_TOTAL, IDT_PROGRESS_TOTAL_VAL, + IDT_PROGRESS_SPEED, IDT_PROGRESS_SPEED_VAL, + IDT_PROGRESS_PROCESSED, IDT_PROGRESS_PROCESSED_VAL, + IDT_PROGRESS_PACKED, IDT_PROGRESS_PACKED_VAL +}; + +bool CProgressDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + int sY; + int sStep; + int mx, my; + { + RECT r; + GetClientRectOfItem(IDT_PROGRESS_ELAPSED, r); + mx = r.left; + my = r.top; + sY = RECT_SIZE_Y(r); + GetClientRectOfItem(IDT_PROGRESS_REMAINING, r); + sStep = r.top - my; + } + + InvalidateRect(NULL); + + int xSizeClient = xSize - mx * 2; + + { + int i; + for (i = 800; i > 40; i = i * 9 / 10) + if (Units_To_Pixels_X(i) <= xSizeClient) + break; + _numReduceSymbols = i / 4; + } + + int yPos = ySize - my - _buttonSizeY; + + ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_STATUS), xSize - mx * 2); + ChangeSubWindowSizeX(GetItem(IDT_PROGRESS_FILE_NAME), xSize - mx * 2); + ChangeSubWindowSizeX(GetItem(IDC_PROGRESS1), xSize - mx * 2); + + int bSizeX = _buttonSizeX; + int mx2 = mx; + for (;; mx2--) + { + int bSize2 = bSizeX * 3 + mx2 * 2; + if (bSize2 <= xSizeClient) + break; + if (mx2 < 5) + { + bSizeX = (xSizeClient - mx2 * 2) / 3; + break; + } + } + if (bSizeX < 2) + bSizeX = 2; + + { + RECT r; + GetClientRectOfItem(IDL_PROGRESS_MESSAGES, r); + int y = r.top; + int ySize2 = yPos - my - y; + const int kMinYSize = _buttonSizeY + _buttonSizeY * 3 / 4; + int xx = xSize - mx * 2; + if (ySize2 < kMinYSize) + { + ySize2 = kMinYSize; + if (xx > bSizeX * 2) + xx -= bSizeX; + } + + _messageList.Move(mx, y, xx, ySize2); + } + + { + int xPos = xSize - mx; + xPos -= bSizeX; + MoveItem(IDCANCEL, xPos, yPos, bSizeX, _buttonSizeY); + xPos -= (mx2 + bSizeX); + MoveItem(IDB_PAUSE, xPos, yPos, bSizeX, _buttonSizeY); + xPos -= (mx2 + bSizeX); + MoveItem(IDB_PROGRESS_BACKGROUND, xPos, yPos, bSizeX, _buttonSizeY); + } + + int valueSize; + int labelSize; + int padSize; + + labelSize = Units_To_Pixels_X(MY_PROGRESS_LABEL_UNITS_MIN); + valueSize = Units_To_Pixels_X(MY_PROGRESS_VAL_UNITS); + padSize = Units_To_Pixels_X(MY_PROGRESS_PAD_UNITS); + int requiredSize = (labelSize + valueSize) * 2 + padSize; + + int gSize; + { + if (requiredSize < xSizeClient) + { + int incr = (xSizeClient - requiredSize) / 3; + labelSize += incr; + } + else + labelSize = (xSizeClient - valueSize * 2 - padSize) / 2; + if (labelSize < 0) + labelSize = 0; + + gSize = labelSize + valueSize; + padSize = xSizeClient - gSize * 2; + } + + labelSize = gSize - valueSize; + + yPos = my; + for (int i = 0; i < ARRAY_SIZE(kIDs); i += 2) + { + int x = mx; + const int kNumColumn1Items = 5 * 2; + if (i >= kNumColumn1Items) + { + if (i == kNumColumn1Items) + yPos = my; + x = mx + gSize + padSize; + } + MoveItem(kIDs[i], x, yPos, labelSize, sY); + MoveItem(kIDs[i + 1], x + labelSize, yPos, valueSize, sY); + yPos += sStep; + } + return false; +} + +void CProgressDialog::OnCancel() { Sync.Set_Stopped(true); } +void CProgressDialog::OnOK() { } + +void CProgressDialog::SetProgressRange(UInt64 range) +{ + if (range == _progressBar_Range) + return; + _progressBar_Range = range; + INIT_AS_UNDEFINED(_progressBar_Pos); + _progressConv.Init(range); + m_ProgressBar.SetRange32(0, _progressConv.Count(range)); +} + +void CProgressDialog::SetProgressPos(UInt64 pos) +{ + if (pos >= _progressBar_Range || + pos <= _progressBar_Pos || + pos - _progressBar_Pos >= (_progressBar_Range >> 10)) + { + m_ProgressBar.SetPos(_progressConv.Count(pos)); + #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + if (_taskbarList && _hwndForTaskbar) + _taskbarList->SetProgressValue(_hwndForTaskbar, pos, _progressBar_Range); + #endif + _progressBar_Pos = pos; + } +} + +#define UINT_TO_STR_2(val) { s[0] = (wchar_t)('0' + (val) / 10); s[1] = (wchar_t)('0' + (val) % 10); s += 2; } + +void GetTimeString(UInt64 timeValue, wchar_t *s) +{ + UInt64 hours = timeValue / 3600; + UInt32 seconds = (UInt32)(timeValue - hours * 3600); + UInt32 minutes = seconds / 60; + seconds %= 60; + if (hours > 99) + { + ConvertUInt64ToString(hours, s); + for (; *s != 0; s++); + } + else + { + UInt32 hours32 = (UInt32)hours; + UINT_TO_STR_2(hours32); + } + *s++ = ':'; UINT_TO_STR_2(minutes); + *s++ = ':'; UINT_TO_STR_2(seconds); + *s = 0; +} + +static void ConvertSizeToString(UInt64 v, wchar_t *s) +{ + Byte c = 0; + if (v >= ((UInt64)100000 << 20)) { v >>= 30; c = 'G'; } + else if (v >= ((UInt64)100000 << 10)) { v >>= 20; c = 'M'; } + else if (v >= ((UInt64)100000 << 0)) { v >>= 10; c = 'K'; } + ConvertUInt64ToString(v, s); + if (c != 0) + { + s += MyStringLen(s); + *s++ = ' '; + *s++ = c; + *s++ = 0; + } +} + +void CProgressDialog::ShowSize(int id, UInt64 val, UInt64 &prev) +{ + if (val == prev) + return; + prev = val; + wchar_t s[40]; + s[0] = 0; + if (IS_DEFINED_VAL(val)) + ConvertSizeToString(val, s); + SetItemText(id, s); +} + +static void GetChangedString(const UString &newStr, UString &prevStr, bool &hasChanged) +{ + hasChanged = !(prevStr == newStr); + if (hasChanged) + prevStr = newStr; +} + +static unsigned GetPower32(UInt32 val) +{ + const unsigned kStart = 32; + UInt32 mask = ((UInt32)1 << (kStart - 1)); + for (unsigned i = kStart;; i--) + { + if (i == 0 || (val & mask) != 0) + return i; + mask >>= 1; + } +} + +static unsigned GetPower64(UInt64 val) +{ + UInt32 high = (UInt32)(val >> 32); + if (high == 0) + return GetPower32((UInt32)val); + return GetPower32(high) + 32; +} + +static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider) +{ + unsigned pow1 = GetPower64(mult1); + unsigned pow2 = GetPower64(mult2); + while (pow1 + pow2 > 64) + { + if (pow1 > pow2) { pow1--; mult1 >>= 1; } + else { pow2--; mult2 >>= 1; } + divider >>= 1; + } + UInt64 res = mult1 * mult2; + if (divider != 0) + res /= divider; + return res; +} + +void CProgressDialog::UpdateStatInfo(bool showAll) +{ + UInt64 total, completed, totalFiles, completedFiles, inSize, outSize; + bool bytesProgressMode; + + bool titleFileName_Changed; + bool curFilePath_Changed; + bool status_Changed; + unsigned numErrors; + { + NSynchronization::CCriticalSectionLock lock(Sync._cs); + total = Sync._totalBytes; + completed = Sync._completedBytes; + totalFiles = Sync._totalFiles; + completedFiles = Sync._curFiles; + inSize = Sync._inSize; + outSize = Sync._outSize; + bytesProgressMode = Sync._bytesProgressMode; + + GetChangedString(Sync._titleFileName, _titleFileName, titleFileName_Changed); + GetChangedString(Sync._filePath, _filePath, curFilePath_Changed); + GetChangedString(Sync._status, _status, status_Changed); + if (_isDir != Sync._isDir) + { + curFilePath_Changed = true; + _isDir = Sync._isDir; + } + numErrors = Sync.Messages.Size(); + } + + UInt32 curTime = ::GetTickCount(); + + const UInt64 progressTotal = bytesProgressMode ? total : totalFiles; + const UInt64 progressCompleted = bytesProgressMode ? completed : completedFiles; + { + if (IS_UNDEFINED_VAL(progressTotal)) + { + // SetPos(0); + // SetRange(progressCompleted); + } + else + { + if (_progressBar_Pos != 0 || progressCompleted != 0 || + (_progressBar_Range == 0 && progressTotal != 0)) + { + SetProgressRange(progressTotal); + SetProgressPos(progressCompleted); + } + } + } + + ShowSize(IDT_PROGRESS_TOTAL_VAL, total, _totalBytes_Prev); + + _elapsedTime += (curTime - _prevTime); + _prevTime = curTime; + UInt64 elapsedSec = _elapsedTime / 1000; + bool elapsedChanged = false; + if (elapsedSec != _prevElapsedSec) + { + _prevElapsedSec = elapsedSec; + elapsedChanged = true; + wchar_t s[40]; + GetTimeString(elapsedSec, s); + SetItemText(IDT_PROGRESS_ELAPSED_VAL, s); + } + + bool needSetTitle = false; + if (elapsedChanged || showAll) + { + if (numErrors > _numPostedMessages) + { + UpdateMessagesDialog(); + wchar_t s[32]; + ConvertUInt64ToString(numErrors, s); + SetItemText(IDT_PROGRESS_ERRORS_VAL, s); + if (!_errorsWereDisplayed) + { + _errorsWereDisplayed = true; + EnableErrorsControls(true); + SetTaskbarProgressState(); + } + } + + if (progressCompleted != 0) + { + if (IS_UNDEFINED_VAL(progressTotal)) + { + if (IS_DEFINED_VAL(_prevRemainingSec)) + { + INIT_AS_UNDEFINED(_prevRemainingSec); + SetItemText(IDT_PROGRESS_REMAINING_VAL, L""); + } + } + else + { + UInt64 remainingTime = 0; + if (progressCompleted < progressTotal) + remainingTime = MyMultAndDiv(_elapsedTime, progressTotal - progressCompleted, progressCompleted); + UInt64 remainingSec = remainingTime / 1000; + if (remainingSec != _prevRemainingSec) + { + _prevRemainingSec = remainingSec; + wchar_t s[40]; + GetTimeString(remainingSec, s); + SetItemText(IDT_PROGRESS_REMAINING_VAL, s); + } + } + { + UInt64 elapsedTime = (_elapsedTime == 0) ? 1 : _elapsedTime; + UInt64 v = (progressCompleted * 1000) / elapsedTime; + Byte c = 0; + unsigned moveBits = 0; + if (v >= ((UInt64)10000 << 10)) { moveBits = 20; c = 'M'; } + else if (v >= ((UInt64)10000 << 0)) { moveBits = 10; c = 'K'; } + v >>= moveBits; + if (moveBits != _prevSpeed_MoveBits || v != _prevSpeed) + { + _prevSpeed_MoveBits = moveBits; + _prevSpeed = v; + wchar_t s[40]; + ConvertUInt64ToString(v, s); + unsigned pos = MyStringLen(s); + s[pos++] = ' '; + if (moveBits != 0) + s[pos++] = c; + s[pos++] = 'B'; + s[pos++] = '/'; + s[pos++] = 's'; + s[pos++] = 0; + SetItemText(IDT_PROGRESS_SPEED_VAL, s); + } + } + } + + { + UInt64 percent = 0; + { + if (IS_DEFINED_VAL(progressTotal)) + { + percent = progressCompleted * 100; + if (progressTotal != 0) + percent /= progressTotal; + } + } + if (percent != _prevPercentValue) + { + _prevPercentValue = percent; + needSetTitle = true; + } + } + + { + wchar_t s[64]; + ConvertUInt64ToString(completedFiles, s); + if (IS_DEFINED_VAL(totalFiles)) + { + wcscat(s, L" / "); + ConvertUInt64ToString(totalFiles, s + wcslen(s)); + } + if (_filesStr_Prev != s) + { + _filesStr_Prev = s; + SetItemText(IDT_PROGRESS_FILES_VAL, s); + } + } + + const UInt64 packSize = CompressingMode ? outSize : inSize; + const UInt64 unpackSize = CompressingMode ? inSize : outSize; + + if (IS_UNDEFINED_VAL(unpackSize) && + IS_UNDEFINED_VAL(packSize)) + { + ShowSize(IDT_PROGRESS_PROCESSED_VAL, completed, _processed_Prev); + ShowSize(IDT_PROGRESS_PACKED_VAL, UNDEFINED_VAL, _packed_Prev); + } + else + { + ShowSize(IDT_PROGRESS_PROCESSED_VAL, unpackSize, _processed_Prev); + ShowSize(IDT_PROGRESS_PACKED_VAL, packSize, _packed_Prev); + + if (IS_DEFINED_VAL(packSize) && + IS_DEFINED_VAL(unpackSize) && + unpackSize != 0) + { + wchar_t s[32]; + UInt64 ratio = packSize * 100 / unpackSize; + if (_ratio_Prev != ratio) + { + _ratio_Prev = ratio; + ConvertUInt64ToString(ratio, s); + wcscat(s, L"%"); + SetItemText(IDT_PROGRESS_RATIO_VAL, s); + } + } + } + } + + if (needSetTitle || titleFileName_Changed) + SetTitleText(); + + if (status_Changed) + { + UString s = _status; + ReduceString(s, _numReduceSymbols); + SetItemText(IDT_PROGRESS_STATUS, _status); + } + + if (curFilePath_Changed) + { + UString s1, s2; + if (_isDir) + s1 = _filePath; + else + { + int slashPos = _filePath.ReverseFind_PathSepar(); + if (slashPos >= 0) + { + s1.SetFrom(_filePath, slashPos + 1); + s2 = _filePath.Ptr(slashPos + 1); + } + else + s2 = _filePath; + } + ReduceString(s1, _numReduceSymbols); + ReduceString(s2, _numReduceSymbols); + s1.Add_LF(); + s1 += s2; + SetItemText(IDT_PROGRESS_FILE_NAME, s1); + } +} + +bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + if (Sync.Get_Paused()) + return true; + CheckNeedClose(); + UpdateStatInfo(false); + return true; +} + +struct CWaitCursor +{ + HCURSOR _waitCursor; + HCURSOR _oldCursor; + CWaitCursor() + { + _waitCursor = LoadCursor(NULL, IDC_WAIT); + if (_waitCursor != NULL) + _oldCursor = SetCursor(_waitCursor); + } + ~CWaitCursor() + { + if (_waitCursor != NULL) + SetCursor(_oldCursor); + } +}; + +INT_PTR CProgressDialog::Create(const UString &title, NWindows::CThread &thread, HWND wndParent) +{ + INT_PTR res = 0; + try + { + if (WaitMode) + { + CWaitCursor waitCursor; + HANDLE h[] = { thread, _createDialogEvent }; + + WRes res = WaitForMultipleObjects(ARRAY_SIZE(h), h, FALSE, kCreateDelay); + if (res == WAIT_OBJECT_0 && !Sync.ThereIsMessage()) + return 0; + } + _title = title; + BIG_DIALOG_SIZE(360, 192); + res = CModalDialog::Create(SIZED_DIALOG(IDD_PROGRESS), wndParent); + } + catch(...) + { + _wasCreated = true; + _dialogCreatedEvent.Set(); + res = res; + } + thread.Wait(); + if (!MessagesDisplayed) + MessageBoxW(wndParent, L"Progress Error", L"7-Zip", MB_ICONERROR); + return res; +} + +bool CProgressDialog::OnExternalCloseMessage() +{ + // it doesn't work if there is MessageBox. + #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + SetTaskbarProgressState(TBPF_NOPROGRESS); + #endif + // AddToTitle(L"Finished "); + // SetText(L"Finished2 "); + + UpdateStatInfo(true); + + SetItemText(IDCANCEL, LangString(IDS_CLOSE)); + ::SendMessage(GetItem(IDCANCEL), BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); + HideItem(IDB_PROGRESS_BACKGROUND); + HideItem(IDB_PAUSE); + + bool thereAreMessages; + CProgressFinalMessage fm; + { + NSynchronization::CCriticalSectionLock lock(Sync._cs); + thereAreMessages = !Sync.Messages.IsEmpty(); + fm = Sync.FinalMessage; + } + if (!fm.ErrorMessage.Message.IsEmpty()) + { + MessagesDisplayed = true; + if (fm.ErrorMessage.Title.IsEmpty()) + fm.ErrorMessage.Title = L"7-Zip"; + MessageBoxW(*this, fm.ErrorMessage.Message, fm.ErrorMessage.Title, MB_ICONERROR); + } + else if (!thereAreMessages) + { + MessagesDisplayed = true; + if (!fm.OkMessage.Message.IsEmpty()) + { + if (fm.OkMessage.Title.IsEmpty()) + fm.OkMessage.Title = L"7-Zip"; + MessageBoxW(*this, fm.OkMessage.Message, fm.OkMessage.Title, MB_OK); + } + } + + if (thereAreMessages && !_cancelWasPressed) + { + _waitCloseByCancelButton = true; + UpdateMessagesDialog(); + return true; + } + + End(0); + return true; +} + +bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case kCloseMessage: + { + KillTimer(_timer); + _timer = 0; + if (_inCancelMessageBox) + { + _externalCloseMessageWasReceived = true; + break; + } + return OnExternalCloseMessage(); + } + /* + case WM_SETTEXT: + { + if (_timer == 0) + return true; + break; + } + */ + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + +void CProgressDialog::SetTitleText() +{ + UString s; + if (Sync.Get_Paused()) + { + s += _paused_String; + s.Add_Space(); + } + if (IS_DEFINED_VAL(_prevPercentValue)) + { + char temp[32]; + ConvertUInt64ToString(_prevPercentValue, temp); + s.AddAscii(temp); + s += L'%'; + } + if (!_foreground) + { + s.Add_Space(); + s += _backgrounded_String; + } + + s.Add_Space(); + #ifndef _SFX + { + unsigned len = s.Len(); + s += MainAddTitle; + AddToTitle(s); + s.DeleteFrom(len); + } + #endif + + s += _title; + if (!_titleFileName.IsEmpty()) + { + UString fileName = _titleFileName; + ReduceString(fileName, kTitleFileNameSizeLimit); + s.Add_Space(); + s += fileName; + } + SetText(s); +} + +void CProgressDialog::SetPauseText() +{ + SetItemText(IDB_PAUSE, Sync.Get_Paused() ? _continue_String : _pause_String); + SetTitleText(); +} + +void CProgressDialog::OnPauseButton() +{ + bool paused = !Sync.Get_Paused(); + Sync.Set_Paused(paused); + UInt32 curTime = ::GetTickCount(); + if (paused) + _elapsedTime += (curTime - _prevTime); + SetTaskbarProgressState(); + _prevTime = curTime; + SetPauseText(); +} + +void CProgressDialog::SetPriorityText() +{ + SetItemText(IDB_PROGRESS_BACKGROUND, _foreground ? + _background_String : + _foreground_String); + SetTitleText(); +} + +void CProgressDialog::OnPriorityButton() +{ + _foreground = !_foreground; + #ifndef UNDER_CE + SetPriorityClass(GetCurrentProcess(), _foreground ? NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS); + #endif + SetPriorityText(); +} + +void CProgressDialog::AddMessageDirect(LPCWSTR message, bool needNumber) +{ + int itemIndex = _messageList.GetItemCount(); + wchar_t sz[16]; + sz[0] = 0; + if (needNumber) + ConvertUInt32ToString(_numMessages + 1, sz); + _messageList.InsertItem(itemIndex, sz); + _messageList.SetSubItem(itemIndex, 1, message); +} + +void CProgressDialog::AddMessage(LPCWSTR message) +{ + UString s = message; + bool needNumber = true; + while (!s.IsEmpty()) + { + int pos = s.Find(L'\n'); + if (pos < 0) + break; + AddMessageDirect(s.Left(pos), needNumber); + needNumber = false; + s.DeleteFrontal(pos + 1); + } + AddMessageDirect(s, needNumber); + _numMessages++; +} + +static unsigned GetNumDigits(UInt32 val) +{ + unsigned i; + for (i = 0; val >= 10; i++) + val /= 10; + return i; +} + +void CProgressDialog::UpdateMessagesDialog() +{ + UStringVector messages; + { + NSynchronization::CCriticalSectionLock lock(Sync._cs); + unsigned num = Sync.Messages.Size(); + if (num > _numPostedMessages) + { + messages.ClearAndReserve(num - _numPostedMessages); + for (unsigned i = _numPostedMessages; i < num; i++) + messages.AddInReserved(Sync.Messages[i]); + _numPostedMessages = num; + } + } + if (!messages.IsEmpty()) + { + FOR_VECTOR (i, messages) + AddMessage(messages[i]); + if (_numAutoSizeMessages < 256 || GetNumDigits(_numPostedMessages) > GetNumDigits(_numAutoSizeMessages)) + { + _messageList.SetColumnWidthAuto(0); + _messageList.SetColumnWidthAuto(1); + _numAutoSizeMessages = _numPostedMessages; + } + } +} + + +bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch (buttonID) + { + // case IDOK: // if IDCANCEL is not DEFPUSHBUTTON + case IDCANCEL: + { + if (_waitCloseByCancelButton) + { + MessagesDisplayed = true; + End(IDCLOSE); + break; + } + + bool paused = Sync.Get_Paused(); + if (!paused) + OnPauseButton(); + _inCancelMessageBox = true; + int res = ::MessageBoxW(*this, LangString(IDS_PROGRESS_ASK_CANCEL), _title, MB_YESNOCANCEL); + _inCancelMessageBox = false; + if (!paused) + OnPauseButton(); + if (res == IDCANCEL || res == IDNO) + { + if (_externalCloseMessageWasReceived) + OnExternalCloseMessage(); + return true; + } + + _cancelWasPressed = true; + MessagesDisplayed = true; + break; + } + + case IDB_PAUSE: + OnPauseButton(); + return true; + case IDB_PROGRESS_BACKGROUND: + OnPriorityButton(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CProgressDialog::CheckNeedClose() +{ + if (_needClose) + { + PostMsg(kCloseMessage); + _needClose = false; + } +} + +void CProgressDialog::ProcessWasFinished() +{ + // Set Window title here. + if (!WaitMode) + WaitCreating(); + + if (_wasCreated) + PostMsg(kCloseMessage); + else + _needClose = true; +} + + +HRESULT CProgressThreadVirt::Create(const UString &title, HWND parentWindow) +{ + NWindows::CThread thread; + RINOK(thread.Create(MyThreadFunction, this)); + ProgressDialog.Create(title, thread, parentWindow); + return S_OK; +} + +static void AddMessageToString(UString &dest, const UString &src) +{ + if (!src.IsEmpty()) + { + if (!dest.IsEmpty()) + dest.Add_LF(); + dest += src; + } +} + +void CProgressThreadVirt::Process() +{ + CProgressCloser closer(ProgressDialog); + UString m; + try { Result = ProcessVirt(); } + catch(const wchar_t *s) { m = s; } + catch(const UString &s) { m = s; } + catch(const char *s) { m = GetUnicodeString(s); } + catch(int v) + { + wchar_t s[16]; + ConvertUInt32ToString(v, s); + m = L"Error #"; + m += s; + } + catch(...) { m = L"Error"; } + if (Result != E_ABORT) + { + if (m.IsEmpty() && Result != S_OK) + m = HResultToMessage(Result); + } + AddMessageToString(m, FinalMessage.ErrorMessage.Message); + + { + FOR_VECTOR(i, ErrorPaths) + { + if (i >= 32) + break; + AddMessageToString(m, fs2us(ErrorPaths[i])); + } + } + + CProgressSync &sync = ProgressDialog.Sync; + NSynchronization::CCriticalSectionLock lock(sync._cs); + if (m.IsEmpty()) + { + if (!FinalMessage.OkMessage.Message.IsEmpty()) + sync.FinalMessage.OkMessage = FinalMessage.OkMessage; + } + else + { + sync.FinalMessage.ErrorMessage.Message = m; + if (Result == S_OK) + Result = E_FAIL; + } +} + +UString HResultToMessage(HRESULT errorCode) +{ + if (errorCode == E_OUTOFMEMORY) + return LangString(IDS_MEM_ERROR); + else + return NError::MyFormatMessage(errorCode); +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h new file mode 100644 index 00000000000..03f836da219 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h @@ -0,0 +1,313 @@ +// ProgressDialog2.h + +#ifndef __PROGRESS_DIALOG_2_H +#define __PROGRESS_DIALOG_2_H + +#include "../../../Common/MyCom.h" + +#include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/Synchronization.h" +#include "../../../Windows/Thread.h" + +#include "../../../Windows/Control/Dialog.h" +#include "../../../Windows/Control/ListView.h" +#include "../../../Windows/Control/ProgressBar.h" + +#include "MyWindowsNew.h" + +struct CProgressMessageBoxPair +{ + UString Title; + UString Message; +}; + +struct CProgressFinalMessage +{ + CProgressMessageBoxPair ErrorMessage; + CProgressMessageBoxPair OkMessage; + + bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); } +}; + +class CProgressSync +{ + bool _stopped; + bool _paused; + +public: + bool _bytesProgressMode; + UInt64 _totalBytes; + UInt64 _completedBytes; + UInt64 _totalFiles; + UInt64 _curFiles; + UInt64 _inSize; + UInt64 _outSize; + + UString _titleFileName; + UString _status; + UString _filePath; + bool _isDir; + + UStringVector Messages; + CProgressFinalMessage FinalMessage; + + NWindows::NSynchronization::CCriticalSection _cs; + + CProgressSync(); + + bool Get_Stopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + return _stopped; + } + void Set_Stopped(bool val) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _stopped = val; + } + + bool Get_Paused(); + void Set_Paused(bool val) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _paused = val; + } + + void Set_BytesProgressMode(bool bytesProgressMode) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_cs); + _bytesProgressMode = bytesProgressMode; + } + + HRESULT CheckStop(); + HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false); + + HRESULT Set_NumFilesTotal(UInt64 val); + void Set_NumBytesTotal(UInt64 val); + void Set_NumFilesCur(UInt64 val); + HRESULT Set_NumBytesCur(const UInt64 *val); + HRESULT Set_NumBytesCur(UInt64 val); + void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize); + + void Set_TitleFileName(const UString &fileName); + void Set_Status(const UString &s); + HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false); + void Set_FilePath(const wchar_t *path, bool isDir = false); + + void AddError_Message(const wchar_t *message); + void AddError_Message_Name(const wchar_t *message, const wchar_t *name); + void AddError_Code_Name(DWORD systemError, const wchar_t *name); + + bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); } +}; + +class CProgressDialog: public NWindows::NControl::CModalDialog +{ + UString _titleFileName; + UString _filePath; + UString _status; + bool _isDir; + + UString _background_String; + UString _backgrounded_String; + UString _foreground_String; + UString _pause_String; + UString _continue_String; + UString _paused_String; + + int _buttonSizeX; + int _buttonSizeY; + + UINT_PTR _timer; + + UString _title; + + class CU64ToI32Converter + { + unsigned _numShiftBits; + UInt64 _range; + public: + CU64ToI32Converter(): _numShiftBits(0), _range(1) {} + void Init(UInt64 range) + { + _range = range; + // Windows CE doesn't like big number for ProgressBar. + for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++) + range >>= 1; + } + int Count(UInt64 val) + { + int res = (int)(val >> _numShiftBits); + if (val == _range) + res++; + return res; + } + }; + + CU64ToI32Converter _progressConv; + UInt64 _progressBar_Pos; + UInt64 _progressBar_Range; + + NWindows::NControl::CProgressBar m_ProgressBar; + NWindows::NControl::CListView _messageList; + + int _numMessages; + + #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + CMyComPtr<ITaskbarList3> _taskbarList; + #endif + HWND _hwndForTaskbar; + + UInt32 _prevTime; + UInt64 _elapsedTime; + + UInt64 _prevPercentValue; + UInt64 _prevElapsedSec; + UInt64 _prevRemainingSec; + + UInt64 _totalBytes_Prev; + UInt64 _processed_Prev; + UInt64 _packed_Prev; + UInt64 _ratio_Prev; + UString _filesStr_Prev; + + unsigned _prevSpeed_MoveBits; + UInt64 _prevSpeed; + + bool _foreground; + + unsigned _numReduceSymbols; + + bool _wasCreated; + bool _needClose; + + unsigned _numPostedMessages; + UInt32 _numAutoSizeMessages; + + bool _errorsWereDisplayed; + + bool _waitCloseByCancelButton; + bool _cancelWasPressed; + + bool _inCancelMessageBox; + bool _externalCloseMessageWasReceived; + + + #ifdef __ITaskbarList3_INTERFACE_DEFINED__ + void SetTaskbarProgressState(TBPFLAG tbpFlags) + { + if (_taskbarList && _hwndForTaskbar) + _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags); + } + #endif + void SetTaskbarProgressState(); + + void UpdateStatInfo(bool showAll); + bool OnTimer(WPARAM timerID, LPARAM callback); + void SetProgressRange(UInt64 range); + void SetProgressPos(UInt64 pos); + virtual bool OnInit(); + virtual bool OnSize(WPARAM wParam, int xSize, int ySize); + virtual void OnCancel(); + virtual void OnOK(); + NWindows::NSynchronization::CManualResetEvent _createDialogEvent; + NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; + #ifndef _SFX + void AddToTitle(LPCWSTR string); + #endif + + void SetPauseText(); + void SetPriorityText(); + void OnPauseButton(); + void OnPriorityButton(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); + bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + + void SetTitleText(); + void ShowSize(int id, UInt64 val, UInt64 &prev); + + void UpdateMessagesDialog(); + + void AddMessageDirect(LPCWSTR message, bool needNumber); + void AddMessage(LPCWSTR message); + + bool OnExternalCloseMessage(); + void EnableErrorsControls(bool enable); + + void ShowAfterMessages(HWND wndParent); + + void CheckNeedClose(); +public: + CProgressSync Sync; + bool CompressingMode; + bool WaitMode; + bool ShowCompressionInfo; + bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages. + int IconID; + + HWND MainWindow; + #ifndef _SFX + UString MainTitle; + UString MainAddTitle; + ~CProgressDialog(); + #endif + + CProgressDialog(); + void WaitCreating() + { + _createDialogEvent.Set(); + _dialogCreatedEvent.Lock(); + } + + INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0); + + void ProcessWasFinished(); +}; + + +class CProgressCloser +{ + CProgressDialog *_p; +public: + CProgressCloser(CProgressDialog &p) : _p(&p) {} + ~CProgressCloser() { _p->ProcessWasFinished(); } +}; + +class CProgressThreadVirt +{ +protected: + FStringVector ErrorPaths; + CProgressFinalMessage FinalMessage; + + // error if any of HRESULT, ErrorMessage, ErrorPath + virtual HRESULT ProcessVirt() = 0; + void Process(); +public: + HRESULT Result; + bool ThreadFinishedOK; // if there is no fatal exception + CProgressDialog ProgressDialog; + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + CProgressThreadVirt *p = (CProgressThreadVirt *)param; + try + { + p->Process(); + p->ThreadFinishedOK = true; + } + catch (...) { p->Result = E_FAIL; } + return 0; + } + + void AddErrorPath(const FString &path) { ErrorPaths.Add(path); } + + HRESULT Create(const UString &title, HWND parentWindow = 0); + CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {} + + CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; } + +}; + +UString HResultToMessage(HRESULT errorCode); + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.rc new file mode 100644 index 00000000000..4d0e0c7bfe0 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.rc @@ -0,0 +1,40 @@ +#include "ProgressDialog2Res.h" +#include "../../GuiCommon.rc" + +#undef DIALOG_ID +#define DIALOG_ID IDD_PROGRESS +#define xc 360 +#define k 11 +#define z1s 16 + +#include "ProgressDialog2a.rc" + +#ifdef UNDER_CE + +#include "../../GuiCommon.rc" + + +#undef DIALOG_ID +#undef m +#undef k +#undef z1s + +#define DIALOG_ID IDD_PROGRESS_2 +#define m 4 +#define k 8 +#define z1s 12 + +#define xc 280 + +#include "ProgressDialog2a.rc" + +#endif + +STRINGTABLE DISCARDABLE +{ + IDS_PROGRESS_PAUSED "Paused" + IDS_PROGRESS_FOREGROUND "&Foreground" + IDS_CONTINUE "&Continue" + IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?" + IDS_CLOSE "&Close" +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h new file mode 100644 index 00000000000..b45d7b49506 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2Res.h @@ -0,0 +1,48 @@ +#define IDD_PROGRESS 97 +#define IDD_PROGRESS_2 10097 + +#define IDS_CLOSE 408 +#define IDS_CONTINUE 411 + +#define IDB_PROGRESS_BACKGROUND 444 +#define IDS_PROGRESS_FOREGROUND 445 +#define IDB_PAUSE 446 +#define IDS_PROGRESS_PAUSED 447 +#define IDS_PROGRESS_ASK_CANCEL 448 + +#define IDT_PROGRESS_PACKED 1008 +#define IDT_PROGRESS_FILES 1032 + +#define IDT_PROGRESS_ELAPSED 3900 +#define IDT_PROGRESS_REMAINING 3901 +#define IDT_PROGRESS_TOTAL 3902 +#define IDT_PROGRESS_SPEED 3903 +#define IDT_PROGRESS_PROCESSED 3904 +#define IDT_PROGRESS_RATIO 3905 +#define IDT_PROGRESS_ERRORS 3906 + +#define IDC_PROGRESS1 100 +#define IDL_PROGRESS_MESSAGES 101 +#define IDT_PROGRESS_FILE_NAME 102 +#define IDT_PROGRESS_STATUS 103 + +#define IDT_PROGRESS_PACKED_VAL 110 +#define IDT_PROGRESS_FILES_VAL 111 + +#define IDT_PROGRESS_ELAPSED_VAL 120 +#define IDT_PROGRESS_REMAINING_VAL 121 +#define IDT_PROGRESS_TOTAL_VAL 122 +#define IDT_PROGRESS_SPEED_VAL 123 +#define IDT_PROGRESS_PROCESSED_VAL 124 +#define IDT_PROGRESS_RATIO_VAL 125 +#define IDT_PROGRESS_ERRORS_VAL 126 + + +#ifdef UNDER_CE +#define MY_PROGRESS_VAL_UNITS 44 +#else +#define MY_PROGRESS_VAL_UNITS 76 +#endif +#define MY_PROGRESS_LABEL_UNITS_MIN 60 +#define MY_PROGRESS_LABEL_UNITS_START 90 +#define MY_PROGRESS_PAD_UNITS 4 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc new file mode 100644 index 00000000000..e9713930be1 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialog2a.rc @@ -0,0 +1,80 @@ +#undef bxs +#define bxs 80 + +#define x0s MY_PROGRESS_LABEL_UNITS_START +#define x1s MY_PROGRESS_VAL_UNITS +#define x2s MY_PROGRESS_LABEL_UNITS_START +#define x3s MY_PROGRESS_VAL_UNITS + +#define x1 (m + x0s) +#define x3 (xs - m - x3s) +#define x2 (x3 - x2s) + +#undef y0 +#undef y1 +#undef y2 +#undef y3 +#undef y4 + +#undef z0 +#undef z1 +#undef z2 +#undef z3 + +#define y0 m +#define y1 (y0 + k) +#define y2 (y1 + k) +#define y3 (y2 + k) +#define y4 (y3 + k) + +#define z3 (y4 + k + 1) + +#define z2 (z3 + k + 1) +#define z2s 24 + +#define z1 (z2 + z2s) + +#define z0 (z1 + z1s + m) +#define z0s 48 + +#define yc (z0 + z0s + bys) + + +DIALOG_ID DIALOG 0, 0, xs, ys MY_MODAL_RESIZE_DIALOG_STYLE MY_FONT +CAPTION "Progress" +{ + DEFPUSHBUTTON "&Background", IDB_PROGRESS_BACKGROUND, bx3, by, bxs, bys + PUSHBUTTON "&Pause", IDB_PAUSE bx2, by, bxs, bys + PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys + + LTEXT "Elapsed time:", IDT_PROGRESS_ELAPSED, m, y0, x0s, 8 + LTEXT "Remaining time:", IDT_PROGRESS_REMAINING, m, y1, x0s, 8 + LTEXT "Files:", IDT_PROGRESS_FILES, m, y2, x0s, 8 + LTEXT "Compression ratio:", IDT_PROGRESS_RATIO, m, y3, x0s, 8 + LTEXT "Errors:", IDT_PROGRESS_ERRORS, m, y4, x0s, 8 + + LTEXT "Total size:", IDT_PROGRESS_TOTAL, x2, y0, x2s, 8 + LTEXT "Speed:", IDT_PROGRESS_SPEED, x2, y1, x2s, 8 + LTEXT "Processed:", IDT_PROGRESS_PROCESSED,x2, y2, x2s, 8 + LTEXT "Compressed size:" , IDT_PROGRESS_PACKED, x2, y3, x2s, 8 + + RTEXT "", IDT_PROGRESS_ELAPSED_VAL, x1, y0, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_REMAINING_VAL, x1, y1, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_FILES_VAL, x1, y2, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_RATIO_VAL, x1, y3, x1s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_ERRORS_VAL, x1, y4, x1s, MY_TEXT_NOPREFIX + + RTEXT "", IDT_PROGRESS_TOTAL_VAL, x3, y0, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_SPEED_VAL, x3, y1, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_PROCESSED_VAL, x3, y2, x3s, MY_TEXT_NOPREFIX + RTEXT "", IDT_PROGRESS_PACKED_VAL, x3, y3, x3s, MY_TEXT_NOPREFIX + + LTEXT "", IDT_PROGRESS_STATUS, m, z3, xc, MY_TEXT_NOPREFIX + CONTROL "", IDT_PROGRESS_FILE_NAME, "Static", SS_NOPREFIX | SS_LEFTNOWORDWRAP, m, z2, xc, z2s + + CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, m, z1, xc, z1s + + CONTROL "List1", IDL_PROGRESS_MESSAGES, "SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + m, z0, xc, z0s +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialogRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialogRes.h new file mode 100644 index 00000000000..cbf3beb2179 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/ProgressDialogRes.h @@ -0,0 +1,3 @@ +#define IDD_PROGRESS 97 + +#define IDC_PROGRESS1 100 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.cpp new file mode 100644 index 00000000000..838b6e3f63c --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.cpp @@ -0,0 +1,23 @@ +// PropertyName.cpp + +#include "StdAfx.h" + +#include "../../../Common/IntToString.h" + +#include "LangUtils.h" +#include "PropertyName.h" + +UString GetNameOfProperty(PROPID propID, const wchar_t *name) +{ + if (propID < 1000) + { + UString s = LangString(1000 + propID); + if (!s.IsEmpty()) + return s; + } + if (name) + return name; + wchar_t temp[16]; + ConvertUInt32ToString(propID, temp); + return temp; +} diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h new file mode 100644 index 00000000000..4f0d6dc11d9 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyName.h @@ -0,0 +1,10 @@ +// PropertyName.h + +#ifndef __PROPERTY_NAME_H +#define __PROPERTY_NAME_H + +#include "../../../Common/MyString.h" + +UString GetNameOfProperty(PROPID propID, const wchar_t *name); + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h new file mode 100644 index 00000000000..67f339028fe --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/PropertyNameRes.h @@ -0,0 +1,95 @@ + + +#define IDS_PROP_PATH 1003 +#define IDS_PROP_NAME 1004 +#define IDS_PROP_EXTENSION 1005 +#define IDS_PROP_IS_FOLDER 1006 +#define IDS_PROP_SIZE 1007 +#define IDS_PROP_PACKED_SIZE 1008 +#define IDS_PROP_ATTRIBUTES 1009 +#define IDS_PROP_CTIME 1010 +#define IDS_PROP_ATIME 1011 +#define IDS_PROP_MTIME 1012 +#define IDS_PROP_SOLID 1013 +#define IDS_PROP_C0MMENTED 1014 +#define IDS_PROP_ENCRYPTED 1015 +#define IDS_PROP_SPLIT_BEFORE 1016 +#define IDS_PROP_SPLIT_AFTER 1017 +#define IDS_PROP_DICTIONARY_SIZE 1018 +#define IDS_PROP_CRC 1019 +#define IDS_PROP_FILE_TYPE 1020 +#define IDS_PROP_ANTI 1021 +#define IDS_PROP_METHOD 1022 +#define IDS_PROP_HOST_OS 1023 +#define IDS_PROP_FILE_SYSTEM 1024 +#define IDS_PROP_USER 1025 +#define IDS_PROP_GROUP 1026 +#define IDS_PROP_BLOCK 1027 +#define IDS_PROP_COMMENT 1028 +#define IDS_PROP_POSITION 1029 +#define IDS_PROP_PREFIX 1030 +#define IDS_PROP_FOLDERS 1031 +#define IDS_PROP_FILES 1032 +#define IDS_PROP_VERSION 1033 +#define IDS_PROP_VOLUME 1034 +#define IDS_PROP_IS_VOLUME 1035 +#define IDS_PROP_OFFSET 1036 +#define IDS_PROP_LINKS 1037 +#define IDS_PROP_NUM_BLOCKS 1038 +#define IDS_PROP_NUM_VOLUMES 1039 + +#define IDS_PROP_BIT64 1041 +#define IDS_PROP_BIG_ENDIAN 1042 +#define IDS_PROP_CPU 1043 +#define IDS_PROP_PHY_SIZE 1044 +#define IDS_PROP_HEADERS_SIZE 1045 +#define IDS_PROP_CHECKSUM 1046 +#define IDS_PROP_CHARACTS 1047 +#define IDS_PROP_VA 1048 +#define IDS_PROP_ID 1049 +#define IDS_PROP_SHORT_NAME 1050 +#define IDS_PROP_CREATOR_APP 1051 +#define IDS_PROP_SECTOR_SIZE 1052 +#define IDS_PROP_POSIX_ATTRIB 1053 +#define IDS_PROP_SYM_LINK 1054 +#define IDS_PROP_ERROR 1055 +#define IDS_PROP_TOTAL_SIZE 1056 +#define IDS_PROP_FREE_SPACE 1057 +#define IDS_PROP_CLUSTER_SIZE 1058 +#define IDS_PROP_VOLUME_NAME 1059 +#define IDS_PROP_LOCAL_NAME 1060 +#define IDS_PROP_PROVIDER 1061 +#define IDS_PROP_NT_SECURITY 1062 +#define IDS_PROP_ALT_STREAM 1063 +#define IDS_PROP_AUX 1064 +#define IDS_PROP_DELETED 1065 +#define IDS_PROP_IS_TREE 1066 +#define IDS_PROP_SHA1 1067 +#define IDS_PROP_SHA256 1068 +#define IDS_PROP_ERROR_TYPE 1069 +#define IDS_PROP_NUM_ERRORS 1070 +#define IDS_PROP_ERROR_FLAGS 1071 +#define IDS_PROP_WARNING_FLAGS 1072 +#define IDS_PROP_WARNING 1073 +#define IDS_PROP_NUM_STREAMS 1074 +#define IDS_PROP_NUM_ALT_STREAMS 1075 +#define IDS_PROP_ALT_STREAMS_SIZE 1076 +#define IDS_PROP_VIRTUAL_SIZE 1077 +#define IDS_PROP_UNPACK_SIZE 1078 +#define IDS_PROP_TOTAL_PHY_SIZE 1079 +#define IDS_PROP_VOLUME_INDEX 1080 +#define IDS_PROP_SUBTYPE 1081 +#define IDS_PROP_SHORT_COMMENT 1082 +#define IDS_PROP_CODE_PAGE 1083 +#define IDS_PROP_IS_NOT_ARC_TYPE 1084 +#define IDS_PROP_PHY_SIZE_CANT_BE_DETECTED 1085 +#define IDS_PROP_ZEROS_TAIL_IS_ALLOWED 1086 +#define IDS_PROP_TAIL_SIZE 1087 +#define IDS_PROP_EMB_STUB_SIZE 1088 +#define IDS_PROP_NT_REPARSE 1089 +#define IDS_PROP_HARD_LINK 1090 +#define IDS_PROP_INODE 1091 +#define IDS_PROP_STREAM_ID 1092 +#define IDS_PROP_READ_ONLY 1093 +#define IDS_PROP_OUT_NAME 1094 +#define IDS_PROP_COPY_LINK 1095 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp new file mode 100644 index 00000000000..c8ea8b95aef --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.cpp @@ -0,0 +1,255 @@ +// SysIconUtils.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "../../../Common/StringConvert.h" +#endif + +#include "../../../Windows/FileDir.h" + +#include "SysIconUtils.h" + +#include <ShlObj.h> + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +int GetIconIndexForCSIDL(int csidl) +{ + LPITEMIDLIST pidl = 0; + SHGetSpecialFolderLocation(NULL, csidl, &pidl); + if (pidl) + { + SHFILEINFO shellInfo; + SHGetFileInfo(LPCTSTR(pidl), FILE_ATTRIBUTE_NORMAL, + &shellInfo, sizeof(shellInfo), + SHGFI_PIDL | SHGFI_SYSICONINDEX); + IMalloc *pMalloc; + SHGetMalloc(&pMalloc); + if (pMalloc) + { + pMalloc->Free(pidl); + pMalloc->Release(); + } + return shellInfo.iIcon; + } + return 0; +} + +#ifndef _UNICODE +typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags); + +struct CSHGetFileInfoInit +{ + SHGetFileInfoWP shGetFileInfoW; + CSHGetFileInfoInit() + { + shGetFileInfoW = (SHGetFileInfoWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW"); + } +} g_SHGetFileInfoInit; +#endif + +static DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) +{ + #ifdef _UNICODE + return SHGetFileInfo + #else + if (g_SHGetFileInfoInit.shGetFileInfoW == 0) + return 0; + return g_SHGetFileInfoInit.shGetFileInfoW + #endif + (pszPath, attrib, psfi, cbFileInfo, uFlags); +} + +DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + SHFILEINFO shellInfo; + DWORD_PTR res = ::SHGetFileInfo(fs2fas(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + iconIndex = shellInfo.iIcon; + return res; + } + else + #endif + { + SHFILEINFOW shellInfo; + DWORD_PTR res = ::MySHGetFileInfoW(fs2us(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + iconIndex = shellInfo.iIcon; + return res; + } +} + +/* +DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attrib, int &iconIndex, UString *typeName) +{ + #ifndef _UNICODE + if (!g_IsNT) + { + SHFILEINFO shellInfo; + shellInfo.szTypeName[0] = 0; + DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); + if (typeName) + *typeName = GetUnicodeString(shellInfo.szTypeName); + iconIndex = shellInfo.iIcon; + return res; + } + else + #endif + { + SHFILEINFOW shellInfo; + shellInfo.szTypeName[0] = 0; + DWORD_PTR res = ::MySHGetFileInfoW(fileName, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME); + if (typeName) + *typeName = shellInfo.szTypeName; + iconIndex = shellInfo.iIcon; + return res; + } +} +*/ + +static int FindInSorted_Attrib(const CRecordVector<CAttribIconPair> &vect, DWORD attrib, int &insertPos) +{ + unsigned left = 0, right = vect.Size(); + while (left != right) + { + unsigned mid = (left + right) / 2; + DWORD midAttrib = vect[mid].Attrib; + if (attrib == midAttrib) + return mid; + if (attrib < midAttrib) + right = mid; + else + left = mid + 1; + } + insertPos = left; + return -1; +} + +static int FindInSorted_Ext(const CObjectVector<CExtIconPair> &vect, const wchar_t *ext, int &insertPos) +{ + unsigned left = 0, right = vect.Size(); + while (left != right) + { + unsigned mid = (left + right) / 2; + int compare = MyStringCompareNoCase(ext, vect[mid].Ext); + if (compare == 0) + return mid; + if (compare < 0) + right = mid; + else + left = mid + 1; + } + insertPos = left; + return -1; +} + +int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UString *typeName */) +{ + int dotPos = -1; + unsigned i; + for (i = 0;; i++) + { + wchar_t c = fileName[i]; + if (c == 0) + break; + if (c == '.') + dotPos = i; + } + + /* + if (MyStringCompareNoCase(fileName, L"$Recycle.Bin") == 0) + { + char s[256]; + sprintf(s, "SPEC i = %3d, attr = %7x", _attribMap.Size(), attrib); + OutputDebugStringA(s); + OutputDebugStringW(fileName); + } + */ + + if ((attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 || dotPos < 0) + { + int insertPos = 0; + int index = FindInSorted_Attrib(_attribMap, attrib, insertPos); + if (index >= 0) + { + // if (typeName) *typeName = _attribMap[index].TypeName; + return _attribMap[index].IconIndex; + } + CAttribIconPair pair; + GetRealIconIndex( + #ifdef UNDER_CE + FTEXT("\\") + #endif + FTEXT("__DIR__") + , attrib, pair.IconIndex + // , pair.TypeName + ); + + /* + char s[256]; + sprintf(s, "i = %3d, attr = %7x", _attribMap.Size(), attrib); + OutputDebugStringA(s); + */ + + pair.Attrib = attrib; + _attribMap.Insert(insertPos, pair); + // if (typeName) *typeName = pair.TypeName; + return pair.IconIndex; + } + + const wchar_t *ext = fileName + dotPos + 1; + int insertPos = 0; + int index = FindInSorted_Ext(_extMap, ext, insertPos); + if (index >= 0) + { + const CExtIconPair &pa = _extMap[index]; + // if (typeName) *typeName = pa.TypeName; + return pa.IconIndex; + } + + for (i = 0;; i++) + { + wchar_t c = ext[i]; + if (c == 0) + break; + if (c < L'0' || c > L'9') + break; + } + if (i != 0 && ext[i] == 0) + { + // GetRealIconIndex is too slow for big number of split extensions: .001, .002, .003 + if (!SplitIconIndex_Defined) + { + GetRealIconIndex( + #ifdef UNDER_CE + FTEXT("\\") + #endif + FTEXT("__FILE__.001"), 0, SplitIconIndex); + SplitIconIndex_Defined = true; + } + return SplitIconIndex; + } + + CExtIconPair pair; + pair.Ext = ext; + GetRealIconIndex(us2fs(fileName + dotPos), attrib, pair.IconIndex); + _extMap.Insert(insertPos, pair); + // if (typeName) *typeName = pair.TypeName; + return pair.IconIndex; +} + +/* +int CExtToIconMap::GetIconIndex(DWORD attrib, const UString &fileName) +{ + return GetIconIndex(attrib, fileName, NULL); +} +*/ diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h new file mode 100644 index 00000000000..f1b27fa1541 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/SysIconUtils.h @@ -0,0 +1,62 @@ +// SysIconUtils.h + +#ifndef __SYS_ICON_UTILS_H +#define __SYS_ICON_UTILS_H + +#include "../../../Common/MyWindows.h" + +#include <commctrl.h> + +#include "../../../Common/MyString.h" + +struct CExtIconPair +{ + UString Ext; + int IconIndex; + // UString TypeName; + + // int Compare(const CExtIconPair &a) const { return MyStringCompareNoCase(Ext, a.Ext); } +}; + +struct CAttribIconPair +{ + DWORD Attrib; + int IconIndex; + // UString TypeName; + + // int Compare(const CAttribIconPair &a) const { return Ext.Compare(a.Ext); } +}; + +class CExtToIconMap +{ +public: + CRecordVector<CAttribIconPair> _attribMap; + CObjectVector<CExtIconPair> _extMap; + int SplitIconIndex; + int SplitIconIndex_Defined; + + CExtToIconMap(): SplitIconIndex_Defined(false) {} + + void Clear() + { + SplitIconIndex_Defined = false; + _extMap.Clear(); + _attribMap.Clear(); + } + int GetIconIndex(DWORD attrib, const wchar_t *fileName /* , UString *typeName */); + // int GetIconIndex(DWORD attrib, const UString &fileName); +}; + +DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex); +int GetIconIndexForCSIDL(int csidl); + +inline HIMAGELIST GetSysImageList(bool smallIcons) +{ + SHFILEINFO shellInfo; + return (HIMAGELIST)SHGetFileInfo(TEXT(""), + FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY, + &shellInfo, sizeof(shellInfo), + SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | (smallIcons ? SHGFI_SMALLICON : SHGFI_ICON)); +} + +#endif diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h new file mode 100644 index 00000000000..b7ca17f1b22 --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/resource.h @@ -0,0 +1,175 @@ +#include "resourceGui.h" + +#define IDR_MENUBAR1 70 +#define IDM_MENU 71 +#define IDR_ACCELERATOR1 72 + +#define IDB_ADD 100 +#define IDB_EXTRACT 101 +#define IDB_TEST 102 +#define IDB_COPY 103 +#define IDB_MOVE 104 +#define IDB_DELETE 105 +#define IDB_INFO 106 + +#define IDB_ADD2 150 +#define IDB_EXTRACT2 151 +#define IDB_TEST2 152 +#define IDB_COPY2 153 +#define IDB_MOVE2 154 +#define IDB_DELETE2 155 +#define IDB_INFO2 156 + +#define IDM_HASH_ALL 101 +#define IDM_CRC32 102 +#define IDM_CRC64 103 +#define IDM_SHA1 104 +#define IDM_SHA256 105 + +#define IDM_OPEN 540 +#define IDM_OPEN_INSIDE 541 +#define IDM_OPEN_OUTSIDE 542 +#define IDM_FILE_VIEW 543 +#define IDM_FILE_EDIT 544 +#define IDM_RENAME 545 +#define IDM_COPY_TO 546 +#define IDM_MOVE_TO 547 +#define IDM_DELETE 548 +#define IDM_SPLIT 549 +#define IDM_COMBINE 550 +#define IDM_PROPERTIES 551 +#define IDM_COMMENT 552 +#define IDM_CRC 553 +#define IDM_DIFF 554 +#define IDM_CREATE_FOLDER 555 +#define IDM_CREATE_FILE 556 +// #define IDM_EXIT 557 +#define IDM_LINK 558 +#define IDM_ALT_STREAMS 559 + +#define IDM_OPEN_INSIDE_ONE 590 +#define IDM_OPEN_INSIDE_PARSER 591 + +#define IDM_SELECT_ALL 600 +#define IDM_DESELECT_ALL 601 +#define IDM_INVERT_SELECTION 602 +#define IDM_SELECT 603 +#define IDM_DESELECT 604 +#define IDM_SELECT_BY_TYPE 605 +#define IDM_DESELECT_BY_TYPE 606 + +#define IDM_VIEW_LARGE_ICONS 700 +#define IDM_VIEW_SMALL_ICONS 701 +#define IDM_VIEW_LIST 702 +#define IDM_VIEW_DETAILS 703 + +#define IDM_VIEW_ARANGE_BY_NAME 710 +#define IDM_VIEW_ARANGE_BY_TYPE 711 +#define IDM_VIEW_ARANGE_BY_DATE 712 +#define IDM_VIEW_ARANGE_BY_SIZE 713 + +#define IDM_VIEW_ARANGE_NO_SORT 730 +#define IDM_VIEW_FLAT_VIEW 731 +#define IDM_VIEW_TWO_PANELS 732 +#define IDM_VIEW_TOOLBARS 733 +#define IDM_OPEN_ROOT_FOLDER 734 +#define IDM_OPEN_PARENT_FOLDER 735 +#define IDM_FOLDERS_HISTORY 736 +#define IDM_VIEW_REFRESH 737 +#define IDM_VIEW_AUTO_REFRESH 738 +// #define IDM_VIEW_SHOW_DELETED 739 +// #define IDM_VIEW_SHOW_STREAMS 740 + +#define IDM_VIEW_ARCHIVE_TOOLBAR 750 +#define IDM_VIEW_STANDARD_TOOLBAR 751 +#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 752 +#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 753 + +#define IDS_BOOKMARK 801 + +#define IDM_OPTIONS 900 +#define IDM_BENCHMARK 901 +#define IDM_BENCHMARK2 902 + +#define IDM_HELP_CONTENTS 960 +#define IDM_ABOUT 961 + +#define IDS_OPTIONS 2100 + +#define IDS_N_SELECTED_ITEMS 3002 + +#define IDS_FILE_EXIST 3008 +#define IDS_WANT_UPDATE_MODIFIED_FILE 3009 +#define IDS_CANNOT_UPDATE_FILE 3010 +#define IDS_CANNOT_START_EDITOR 3011 +#define IDS_VIRUS 3012 +#define IDS_MESSAGE_UNSUPPORTED_OPERATION_FOR_LONG_PATH_FOLDER 3013 +#define IDS_SELECT_ONE_FILE 3014 +#define IDS_SELECT_FILES 3015 +#define IDS_TOO_MANY_ITEMS 3016 + +#define IDS_COPY 6000 +#define IDS_MOVE 6001 +#define IDS_COPY_TO 6002 +#define IDS_MOVE_TO 6003 +#define IDS_COPYING 6004 +#define IDS_MOVING 6005 +#define IDS_RENAMING 6006 + +#define IDS_OPERATION_IS_NOT_SUPPORTED 6008 +#define IDS_ERROR_RENAMING 6009 +#define IDS_CONFIRM_FILE_COPY 6010 +#define IDS_WANT_TO_COPY_FILES 6011 + +#define IDS_CONFIRM_FILE_DELETE 6100 +#define IDS_CONFIRM_FOLDER_DELETE 6101 +#define IDS_CONFIRM_ITEMS_DELETE 6102 +#define IDS_WANT_TO_DELETE_FILE 6103 +#define IDS_WANT_TO_DELETE_FOLDER 6104 +#define IDS_WANT_TO_DELETE_ITEMS 6105 +#define IDS_DELETING 6106 +#define IDS_ERROR_DELETING 6107 +#define IDS_ERROR_LONG_PATH_TO_RECYCLE 6108 + +#define IDS_CREATE_FOLDER 6300 +#define IDS_CREATE_FILE 6301 +#define IDS_CREATE_FOLDER_NAME 6302 +#define IDS_CREATE_FILE_NAME 6303 +#define IDS_CREATE_FOLDER_DEFAULT_NAME 6304 +#define IDS_CREATE_FILE_DEFAULT_NAME 6305 +#define IDS_CREATE_FOLDER_ERROR 6306 +#define IDS_CREATE_FILE_ERROR 6307 + +#define IDS_COMMENT 6400 +#define IDS_COMMENT2 6401 +#define IDS_SELECT 6402 +#define IDS_DESELECT 6403 +#define IDS_SELECT_MASK 6404 + +#define IDS_PROPERTIES 6600 +#define IDS_FOLDERS_HISTORY 6601 + +#define IDS_COMPUTER 7100 +#define IDS_NETWORK 7101 +#define IDS_DOCUMENTS 7102 +#define IDS_SYSTEM 7103 + +#define IDS_ADD 7200 +#define IDS_EXTRACT 7201 +#define IDS_TEST 7202 +#define IDS_BUTTON_COPY 7203 +#define IDS_BUTTON_MOVE 7204 +#define IDS_BUTTON_DELETE 7205 +#define IDS_BUTTON_INFO 7206 + +#define IDS_SPLITTING 7303 +#define IDS_SPLIT_CONFIRM_TITLE 7304 +#define IDS_SPLIT_CONFIRM_MESSAGE 7305 +#define IDS_SPLIT_VOL_MUST_BE_SMALLER 7306 + +#define IDS_COMBINE 7400 +#define IDS_COMBINE_TO 7401 +#define IDS_COMBINING 7402 +#define IDS_COMBINE_SELECT_ONE_FILE 7403 +#define IDS_COMBINE_CANT_DETECT_SPLIT_FILE 7404 +#define IDS_COMBINE_CANT_FIND_MORE_THAN_ONE_PART 7405 diff --git a/3rdparty/lzma/CPP/7zip/UI/FileManager/resourceGui.h b/3rdparty/lzma/CPP/7zip/UI/FileManager/resourceGui.h new file mode 100644 index 00000000000..7c1b40e430b --- /dev/null +++ b/3rdparty/lzma/CPP/7zip/UI/FileManager/resourceGui.h @@ -0,0 +1,15 @@ +#define IDI_ICON 1 + +#define IDS_MESSAGE_NO_ERRORS 3001 + +#define IDS_PROGRESS_TESTING 3302 +#define IDS_OPENNING 3303 +#define IDS_SCANNING 3304 + +#define IDS_CHECKSUM_CALCULATING 7500 +#define IDS_CHECKSUM_INFORMATION 7501 +#define IDS_CHECKSUM_CRC_DATA 7502 +#define IDS_CHECKSUM_CRC_DATA_NAMES 7503 +#define IDS_CHECKSUM_CRC_STREAMS_NAMES 7504 + +#define IDS_INCORRECT_VOLUME_SIZE 7307 |