From 051769bbc577aeede90558b6ab5c9be187940ca0 Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Mon, 27 Aug 2007 00:00:00 +0000 Subject: 4.53 beta --- CPP/7zip/UI/FileManager/7zFM.exe.manifest | 1 + CPP/7zip/UI/FileManager/7zipLogo.ico | Bin 0 -> 9150 bytes CPP/7zip/UI/FileManager/AboutDialog.cpp | 60 + CPP/7zip/UI/FileManager/AboutDialog.h | 18 + CPP/7zip/UI/FileManager/AboutDialog.rc | 41 + CPP/7zip/UI/FileManager/AboutDialogRes.h | 6 + CPP/7zip/UI/FileManager/Add.bmp | Bin 0 -> 982 bytes CPP/7zip/UI/FileManager/Add2.bmp | Bin 0 -> 406 bytes CPP/7zip/UI/FileManager/App.cpp | 759 +++++++++++ CPP/7zip/UI/FileManager/App.h | 332 +++++ CPP/7zip/UI/FileManager/AppState.h | 114 ++ CPP/7zip/UI/FileManager/ClassDefs.cpp | 17 + CPP/7zip/UI/FileManager/ComboDialog.cpp | 53 + CPP/7zip/UI/FileManager/ComboDialog.h | 25 + CPP/7zip/UI/FileManager/ComboDialog.rc | 24 + CPP/7zip/UI/FileManager/ComboDialogRes.h | 4 + CPP/7zip/UI/FileManager/Copy.bmp | Bin 0 -> 982 bytes CPP/7zip/UI/FileManager/Copy2.bmp | Bin 0 -> 406 bytes CPP/7zip/UI/FileManager/CopyDialog.cpp | 81 ++ CPP/7zip/UI/FileManager/CopyDialog.h | 26 + CPP/7zip/UI/FileManager/CopyDialog.rc | 28 + CPP/7zip/UI/FileManager/CopyDialogRes.h | 7 + CPP/7zip/UI/FileManager/Delete.bmp | Bin 0 -> 982 bytes CPP/7zip/UI/FileManager/Delete2.bmp | Bin 0 -> 406 bytes CPP/7zip/UI/FileManager/EditPage.cpp | 91 ++ CPP/7zip/UI/FileManager/EditPage.h | 21 + CPP/7zip/UI/FileManager/EditPage.rc | 16 + CPP/7zip/UI/FileManager/EditPageRes.h | 4 + CPP/7zip/UI/FileManager/EnumFormatEtc.cpp | 108 ++ CPP/7zip/UI/FileManager/EnumFormatEtc.h | 10 + CPP/7zip/UI/FileManager/Extract.bmp | Bin 0 -> 982 bytes CPP/7zip/UI/FileManager/Extract2.bmp | Bin 0 -> 406 bytes CPP/7zip/UI/FileManager/ExtractCallback.cpp | 440 +++++++ CPP/7zip/UI/FileManager/ExtractCallback.h | 147 +++ CPP/7zip/UI/FileManager/FM.cpp | 803 ++++++++++++ CPP/7zip/UI/FileManager/FM.dsp | 1486 ++++++++++++++++++++++ CPP/7zip/UI/FileManager/FM.dsw | 29 + CPP/7zip/UI/FileManager/FM.ico | Bin 0 -> 4846 bytes CPP/7zip/UI/FileManager/FSDrives.cpp | 236 ++++ CPP/7zip/UI/FileManager/FSDrives.h | 49 + CPP/7zip/UI/FileManager/FSFolder.cpp | 682 ++++++++++ CPP/7zip/UI/FileManager/FSFolder.h | 118 ++ CPP/7zip/UI/FileManager/FSFolderCopy.cpp | 475 +++++++ CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp | 114 ++ CPP/7zip/UI/FileManager/FileFolderPluginOpen.h | 9 + CPP/7zip/UI/FileManager/FilePlugins.cpp | 112 ++ CPP/7zip/UI/FileManager/FilePlugins.h | 54 + CPP/7zip/UI/FileManager/FormatUtils.cpp | 40 + CPP/7zip/UI/FileManager/FormatUtils.h | 18 + CPP/7zip/UI/FileManager/HelpUtils.cpp | 23 + CPP/7zip/UI/FileManager/HelpUtils.h | 10 + CPP/7zip/UI/FileManager/IFolder.h | 145 +++ CPP/7zip/UI/FileManager/Info.bmp | Bin 0 -> 982 bytes CPP/7zip/UI/FileManager/Info2.bmp | Bin 0 -> 406 bytes CPP/7zip/UI/FileManager/LangPage.cpp | 90 ++ CPP/7zip/UI/FileManager/LangPage.h | 21 + CPP/7zip/UI/FileManager/LangPage.rc | 21 + CPP/7zip/UI/FileManager/LangPageRes.h | 6 + CPP/7zip/UI/FileManager/LangUtils.cpp | 207 +++ CPP/7zip/UI/FileManager/LangUtils.h | 41 + CPP/7zip/UI/FileManager/ListViewDialog.cpp | 100 ++ CPP/7zip/UI/FileManager/ListViewDialog.h | 30 + CPP/7zip/UI/FileManager/ListViewDialog.rc | 26 + CPP/7zip/UI/FileManager/ListViewDialogRes.h | 3 + CPP/7zip/UI/FileManager/MessagesDialog.cpp | 100 ++ CPP/7zip/UI/FileManager/MessagesDialog.h | 22 + CPP/7zip/UI/FileManager/MessagesDialog.rc | 25 + CPP/7zip/UI/FileManager/MessagesDialogRes.h | 3 + CPP/7zip/UI/FileManager/Move.bmp | Bin 0 -> 982 bytes CPP/7zip/UI/FileManager/Move2.bmp | Bin 0 -> 406 bytes CPP/7zip/UI/FileManager/MyCom2.h | 48 + CPP/7zip/UI/FileManager/MyLoadMenu.cpp | 694 ++++++++++ CPP/7zip/UI/FileManager/MyLoadMenu.h | 16 + CPP/7zip/UI/FileManager/NetFolder.cpp | 302 +++++ CPP/7zip/UI/FileManager/NetFolder.h | 49 + CPP/7zip/UI/FileManager/OpenCallback.cpp | 115 ++ CPP/7zip/UI/FileManager/OpenCallback.h | 85 ++ CPP/7zip/UI/FileManager/OptionsDialog.cpp | 65 + CPP/7zip/UI/FileManager/OverwriteDialog.cpp | 124 ++ CPP/7zip/UI/FileManager/OverwriteDialog.h | 34 + CPP/7zip/UI/FileManager/OverwriteDialog.rc | 47 + CPP/7zip/UI/FileManager/OverwriteDialogRes.h | 19 + CPP/7zip/UI/FileManager/Panel.cpp | 967 ++++++++++++++ CPP/7zip/UI/FileManager/Panel.h | 511 ++++++++ CPP/7zip/UI/FileManager/PanelCopy.cpp | 203 +++ CPP/7zip/UI/FileManager/PanelCrc.cpp | 365 ++++++ CPP/7zip/UI/FileManager/PanelDrag.cpp | 796 ++++++++++++ CPP/7zip/UI/FileManager/PanelFolderChange.cpp | 413 ++++++ CPP/7zip/UI/FileManager/PanelItemOpen.cpp | 546 ++++++++ CPP/7zip/UI/FileManager/PanelItems.cpp | 807 ++++++++++++ CPP/7zip/UI/FileManager/PanelKey.cpp | 297 +++++ CPP/7zip/UI/FileManager/PanelListNotify.cpp | 392 ++++++ CPP/7zip/UI/FileManager/PanelMenu.cpp | 558 ++++++++ CPP/7zip/UI/FileManager/PanelOperations.cpp | 443 +++++++ CPP/7zip/UI/FileManager/PanelSelect.cpp | 297 +++++ CPP/7zip/UI/FileManager/PanelSort.cpp | 163 +++ CPP/7zip/UI/FileManager/PanelSplitFile.cpp | 481 +++++++ CPP/7zip/UI/FileManager/PasswordDialog.cpp | 50 + CPP/7zip/UI/FileManager/PasswordDialog.h | 21 + CPP/7zip/UI/FileManager/PasswordDialog.rc | 26 + CPP/7zip/UI/FileManager/PasswordDialogRes.h | 4 + CPP/7zip/UI/FileManager/PhysDriveFolder.cpp | 299 +++++ CPP/7zip/UI/FileManager/PhysDriveFolder.h | 58 + CPP/7zip/UI/FileManager/PluginInterface.h | 42 + CPP/7zip/UI/FileManager/PluginLoader.h | 32 + CPP/7zip/UI/FileManager/PluginsPage.cpp | 223 ++++ CPP/7zip/UI/FileManager/PluginsPage.h | 26 + CPP/7zip/UI/FileManager/PluginsPage.rc | 19 + CPP/7zip/UI/FileManager/PluginsPageRes.h | 4 + CPP/7zip/UI/FileManager/ProgramLocation.cpp | 24 + CPP/7zip/UI/FileManager/ProgramLocation.h | 10 + CPP/7zip/UI/FileManager/ProgressDialog.cpp | 175 +++ CPP/7zip/UI/FileManager/ProgressDialog.h | 132 ++ CPP/7zip/UI/FileManager/ProgressDialog.rc | 20 + CPP/7zip/UI/FileManager/ProgressDialog2.cpp | 483 +++++++ CPP/7zip/UI/FileManager/ProgressDialog2.h | 226 ++++ CPP/7zip/UI/FileManager/ProgressDialog2.rc | 77 ++ CPP/7zip/UI/FileManager/ProgressDialog2Res.h | 26 + CPP/7zip/UI/FileManager/ProgressDialogRes.h | 3 + CPP/7zip/UI/FileManager/PropertyName.cpp | 83 ++ CPP/7zip/UI/FileManager/PropertyName.h | 10 + CPP/7zip/UI/FileManager/PropertyName.rc | 45 + CPP/7zip/UI/FileManager/PropertyNameRes.h | 37 + CPP/7zip/UI/FileManager/RegistryAssociations.cpp | 303 +++++ CPP/7zip/UI/FileManager/RegistryAssociations.h | 44 + CPP/7zip/UI/FileManager/RegistryPlugins.cpp | 146 +++ CPP/7zip/UI/FileManager/RegistryPlugins.h | 32 + CPP/7zip/UI/FileManager/RegistryUtils.cpp | 150 +++ CPP/7zip/UI/FileManager/RegistryUtils.h | 46 + CPP/7zip/UI/FileManager/RootFolder.cpp | 197 +++ CPP/7zip/UI/FileManager/RootFolder.h | 32 + CPP/7zip/UI/FileManager/SettingsPage.cpp | 113 ++ CPP/7zip/UI/FileManager/SettingsPage.h | 19 + CPP/7zip/UI/FileManager/SettingsPage.rc | 35 + CPP/7zip/UI/FileManager/SettingsPageRes.h | 11 + CPP/7zip/UI/FileManager/SplitDialog.cpp | 89 ++ CPP/7zip/UI/FileManager/SplitDialog.h | 27 + CPP/7zip/UI/FileManager/SplitDialog.rc | 32 + CPP/7zip/UI/FileManager/SplitDialogRes.h | 8 + CPP/7zip/UI/FileManager/SplitUtils.cpp | 85 ++ CPP/7zip/UI/FileManager/SplitUtils.h | 15 + CPP/7zip/UI/FileManager/StdAfx.cpp | 3 + CPP/7zip/UI/FileManager/StdAfx.h | 23 + CPP/7zip/UI/FileManager/StringUtils.cpp | 68 + CPP/7zip/UI/FileManager/StringUtils.h | 13 + CPP/7zip/UI/FileManager/SysIconUtils.cpp | 157 +++ CPP/7zip/UI/FileManager/SysIconUtils.h | 51 + CPP/7zip/UI/FileManager/SystemPage.cpp | 437 +++++++ CPP/7zip/UI/FileManager/SystemPage.h | 40 + CPP/7zip/UI/FileManager/SystemPage.rc | 28 + CPP/7zip/UI/FileManager/SystemPageRes.h | 7 + CPP/7zip/UI/FileManager/Test.bmp | Bin 0 -> 982 bytes CPP/7zip/UI/FileManager/Test2.bmp | Bin 0 -> 406 bytes CPP/7zip/UI/FileManager/TextPairs.cpp | 216 ++++ CPP/7zip/UI/FileManager/TextPairs.h | 31 + CPP/7zip/UI/FileManager/UpdateCallback100.cpp | 106 ++ CPP/7zip/UI/FileManager/UpdateCallback100.h | 74 ++ CPP/7zip/UI/FileManager/ViewSettings.cpp | 429 +++++++ CPP/7zip/UI/FileManager/ViewSettings.h | 98 ++ CPP/7zip/UI/FileManager/makefile | 194 +++ CPP/7zip/UI/FileManager/resource.h | 159 +++ CPP/7zip/UI/FileManager/resource.rc | 237 ++++ 162 files changed, 22278 insertions(+) create mode 100755 CPP/7zip/UI/FileManager/7zFM.exe.manifest create mode 100755 CPP/7zip/UI/FileManager/7zipLogo.ico create mode 100755 CPP/7zip/UI/FileManager/AboutDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/AboutDialog.h create mode 100755 CPP/7zip/UI/FileManager/AboutDialog.rc create mode 100755 CPP/7zip/UI/FileManager/AboutDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/Add.bmp create mode 100755 CPP/7zip/UI/FileManager/Add2.bmp create mode 100755 CPP/7zip/UI/FileManager/App.cpp create mode 100755 CPP/7zip/UI/FileManager/App.h create mode 100755 CPP/7zip/UI/FileManager/AppState.h create mode 100755 CPP/7zip/UI/FileManager/ClassDefs.cpp create mode 100755 CPP/7zip/UI/FileManager/ComboDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/ComboDialog.h create mode 100755 CPP/7zip/UI/FileManager/ComboDialog.rc create mode 100755 CPP/7zip/UI/FileManager/ComboDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/Copy.bmp create mode 100755 CPP/7zip/UI/FileManager/Copy2.bmp create mode 100755 CPP/7zip/UI/FileManager/CopyDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/CopyDialog.h create mode 100755 CPP/7zip/UI/FileManager/CopyDialog.rc create mode 100755 CPP/7zip/UI/FileManager/CopyDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/Delete.bmp create mode 100755 CPP/7zip/UI/FileManager/Delete2.bmp create mode 100755 CPP/7zip/UI/FileManager/EditPage.cpp create mode 100755 CPP/7zip/UI/FileManager/EditPage.h create mode 100755 CPP/7zip/UI/FileManager/EditPage.rc create mode 100755 CPP/7zip/UI/FileManager/EditPageRes.h create mode 100755 CPP/7zip/UI/FileManager/EnumFormatEtc.cpp create mode 100755 CPP/7zip/UI/FileManager/EnumFormatEtc.h create mode 100755 CPP/7zip/UI/FileManager/Extract.bmp create mode 100755 CPP/7zip/UI/FileManager/Extract2.bmp create mode 100755 CPP/7zip/UI/FileManager/ExtractCallback.cpp create mode 100755 CPP/7zip/UI/FileManager/ExtractCallback.h create mode 100755 CPP/7zip/UI/FileManager/FM.cpp create mode 100755 CPP/7zip/UI/FileManager/FM.dsp create mode 100755 CPP/7zip/UI/FileManager/FM.dsw create mode 100755 CPP/7zip/UI/FileManager/FM.ico create mode 100755 CPP/7zip/UI/FileManager/FSDrives.cpp create mode 100755 CPP/7zip/UI/FileManager/FSDrives.h create mode 100755 CPP/7zip/UI/FileManager/FSFolder.cpp create mode 100755 CPP/7zip/UI/FileManager/FSFolder.h create mode 100755 CPP/7zip/UI/FileManager/FSFolderCopy.cpp create mode 100755 CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp create mode 100755 CPP/7zip/UI/FileManager/FileFolderPluginOpen.h create mode 100755 CPP/7zip/UI/FileManager/FilePlugins.cpp create mode 100755 CPP/7zip/UI/FileManager/FilePlugins.h create mode 100755 CPP/7zip/UI/FileManager/FormatUtils.cpp create mode 100755 CPP/7zip/UI/FileManager/FormatUtils.h create mode 100755 CPP/7zip/UI/FileManager/HelpUtils.cpp create mode 100755 CPP/7zip/UI/FileManager/HelpUtils.h create mode 100755 CPP/7zip/UI/FileManager/IFolder.h create mode 100755 CPP/7zip/UI/FileManager/Info.bmp create mode 100755 CPP/7zip/UI/FileManager/Info2.bmp create mode 100755 CPP/7zip/UI/FileManager/LangPage.cpp create mode 100755 CPP/7zip/UI/FileManager/LangPage.h create mode 100755 CPP/7zip/UI/FileManager/LangPage.rc create mode 100755 CPP/7zip/UI/FileManager/LangPageRes.h create mode 100755 CPP/7zip/UI/FileManager/LangUtils.cpp create mode 100755 CPP/7zip/UI/FileManager/LangUtils.h create mode 100755 CPP/7zip/UI/FileManager/ListViewDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/ListViewDialog.h create mode 100755 CPP/7zip/UI/FileManager/ListViewDialog.rc create mode 100755 CPP/7zip/UI/FileManager/ListViewDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/MessagesDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/MessagesDialog.h create mode 100755 CPP/7zip/UI/FileManager/MessagesDialog.rc create mode 100755 CPP/7zip/UI/FileManager/MessagesDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/Move.bmp create mode 100755 CPP/7zip/UI/FileManager/Move2.bmp create mode 100755 CPP/7zip/UI/FileManager/MyCom2.h create mode 100755 CPP/7zip/UI/FileManager/MyLoadMenu.cpp create mode 100755 CPP/7zip/UI/FileManager/MyLoadMenu.h create mode 100755 CPP/7zip/UI/FileManager/NetFolder.cpp create mode 100755 CPP/7zip/UI/FileManager/NetFolder.h create mode 100755 CPP/7zip/UI/FileManager/OpenCallback.cpp create mode 100755 CPP/7zip/UI/FileManager/OpenCallback.h create mode 100755 CPP/7zip/UI/FileManager/OptionsDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/OverwriteDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/OverwriteDialog.h create mode 100755 CPP/7zip/UI/FileManager/OverwriteDialog.rc create mode 100755 CPP/7zip/UI/FileManager/OverwriteDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/Panel.cpp create mode 100755 CPP/7zip/UI/FileManager/Panel.h create mode 100755 CPP/7zip/UI/FileManager/PanelCopy.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelCrc.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelDrag.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelFolderChange.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelItemOpen.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelItems.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelKey.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelListNotify.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelMenu.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelOperations.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelSelect.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelSort.cpp create mode 100755 CPP/7zip/UI/FileManager/PanelSplitFile.cpp create mode 100755 CPP/7zip/UI/FileManager/PasswordDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/PasswordDialog.h create mode 100755 CPP/7zip/UI/FileManager/PasswordDialog.rc create mode 100755 CPP/7zip/UI/FileManager/PasswordDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/PhysDriveFolder.cpp create mode 100755 CPP/7zip/UI/FileManager/PhysDriveFolder.h create mode 100755 CPP/7zip/UI/FileManager/PluginInterface.h create mode 100755 CPP/7zip/UI/FileManager/PluginLoader.h create mode 100755 CPP/7zip/UI/FileManager/PluginsPage.cpp create mode 100755 CPP/7zip/UI/FileManager/PluginsPage.h create mode 100755 CPP/7zip/UI/FileManager/PluginsPage.rc create mode 100755 CPP/7zip/UI/FileManager/PluginsPageRes.h create mode 100755 CPP/7zip/UI/FileManager/ProgramLocation.cpp create mode 100755 CPP/7zip/UI/FileManager/ProgramLocation.h create mode 100755 CPP/7zip/UI/FileManager/ProgressDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/ProgressDialog.h create mode 100755 CPP/7zip/UI/FileManager/ProgressDialog.rc create mode 100755 CPP/7zip/UI/FileManager/ProgressDialog2.cpp create mode 100755 CPP/7zip/UI/FileManager/ProgressDialog2.h create mode 100755 CPP/7zip/UI/FileManager/ProgressDialog2.rc create mode 100755 CPP/7zip/UI/FileManager/ProgressDialog2Res.h create mode 100755 CPP/7zip/UI/FileManager/ProgressDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/PropertyName.cpp create mode 100755 CPP/7zip/UI/FileManager/PropertyName.h create mode 100755 CPP/7zip/UI/FileManager/PropertyName.rc create mode 100755 CPP/7zip/UI/FileManager/PropertyNameRes.h create mode 100755 CPP/7zip/UI/FileManager/RegistryAssociations.cpp create mode 100755 CPP/7zip/UI/FileManager/RegistryAssociations.h create mode 100755 CPP/7zip/UI/FileManager/RegistryPlugins.cpp create mode 100755 CPP/7zip/UI/FileManager/RegistryPlugins.h create mode 100755 CPP/7zip/UI/FileManager/RegistryUtils.cpp create mode 100755 CPP/7zip/UI/FileManager/RegistryUtils.h create mode 100755 CPP/7zip/UI/FileManager/RootFolder.cpp create mode 100755 CPP/7zip/UI/FileManager/RootFolder.h create mode 100755 CPP/7zip/UI/FileManager/SettingsPage.cpp create mode 100755 CPP/7zip/UI/FileManager/SettingsPage.h create mode 100755 CPP/7zip/UI/FileManager/SettingsPage.rc create mode 100755 CPP/7zip/UI/FileManager/SettingsPageRes.h create mode 100755 CPP/7zip/UI/FileManager/SplitDialog.cpp create mode 100755 CPP/7zip/UI/FileManager/SplitDialog.h create mode 100755 CPP/7zip/UI/FileManager/SplitDialog.rc create mode 100755 CPP/7zip/UI/FileManager/SplitDialogRes.h create mode 100755 CPP/7zip/UI/FileManager/SplitUtils.cpp create mode 100755 CPP/7zip/UI/FileManager/SplitUtils.h create mode 100755 CPP/7zip/UI/FileManager/StdAfx.cpp create mode 100755 CPP/7zip/UI/FileManager/StdAfx.h create mode 100755 CPP/7zip/UI/FileManager/StringUtils.cpp create mode 100755 CPP/7zip/UI/FileManager/StringUtils.h create mode 100755 CPP/7zip/UI/FileManager/SysIconUtils.cpp create mode 100755 CPP/7zip/UI/FileManager/SysIconUtils.h create mode 100755 CPP/7zip/UI/FileManager/SystemPage.cpp create mode 100755 CPP/7zip/UI/FileManager/SystemPage.h create mode 100755 CPP/7zip/UI/FileManager/SystemPage.rc create mode 100755 CPP/7zip/UI/FileManager/SystemPageRes.h create mode 100755 CPP/7zip/UI/FileManager/Test.bmp create mode 100755 CPP/7zip/UI/FileManager/Test2.bmp create mode 100755 CPP/7zip/UI/FileManager/TextPairs.cpp create mode 100755 CPP/7zip/UI/FileManager/TextPairs.h create mode 100755 CPP/7zip/UI/FileManager/UpdateCallback100.cpp create mode 100755 CPP/7zip/UI/FileManager/UpdateCallback100.h create mode 100755 CPP/7zip/UI/FileManager/ViewSettings.cpp create mode 100755 CPP/7zip/UI/FileManager/ViewSettings.h create mode 100755 CPP/7zip/UI/FileManager/makefile create mode 100755 CPP/7zip/UI/FileManager/resource.h create mode 100755 CPP/7zip/UI/FileManager/resource.rc (limited to 'CPP/7zip/UI/FileManager') diff --git a/CPP/7zip/UI/FileManager/7zFM.exe.manifest b/CPP/7zip/UI/FileManager/7zFM.exe.manifest new file mode 100755 index 00000000..06710e04 --- /dev/null +++ b/CPP/7zip/UI/FileManager/7zFM.exe.manifest @@ -0,0 +1 @@ +7-Zip File manager. diff --git a/CPP/7zip/UI/FileManager/7zipLogo.ico b/CPP/7zip/UI/FileManager/7zipLogo.ico new file mode 100755 index 00000000..973241c8 Binary files /dev/null and b/CPP/7zip/UI/FileManager/7zipLogo.ico differ diff --git a/CPP/7zip/UI/FileManager/AboutDialog.cpp b/CPP/7zip/UI/FileManager/AboutDialog.cpp new file mode 100755 index 00000000..fcdea7e0 --- /dev/null +++ b/CPP/7zip/UI/FileManager/AboutDialog.cpp @@ -0,0 +1,60 @@ +// AboutDialog.cpp + +#include "StdAfx.h" + +#include "AboutDialogRes.h" +#include "AboutDialog.h" +#include "HelpUtils.h" +#include "LangUtils.h" + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_ABOUT_STATIC_REGISTER_INFO, 0x01000103 }, + { IDC_ABOUT_BUTTON_SUPPORT, 0x01000104 }, + { IDC_ABOUT_BUTTON_REGISTER, 0x01000105 }, + { IDOK, 0x02000702 } +}; + +#define MY_HOME_PAGE TEXT("http://www.7-zip.org/") + +static LPCTSTR kHomePageURL = MY_HOME_PAGE; +static LPCTSTR kRegisterPageURL = MY_HOME_PAGE TEXT("register.html"); +static LPCTSTR kSupportPageURL = MY_HOME_PAGE TEXT("support.html"); + +static LPCWSTR kHelpTopic = L"start.htm"; + +bool CAboutDialog::OnInit() +{ + LangSetWindowText(HWND(*this), 0x01000100); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + return CModalDialog::OnInit(); +} + +void CAboutDialog::OnHelp() +{ + ShowHelpWindow(NULL, kHelpTopic); +} + +static void MyShellExecute(LPCTSTR url) +{ + ::ShellExecute(NULL, NULL, url, NULL, NULL, SW_SHOWNORMAL); +} + +bool CAboutDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_ABOUT_BUTTON_HOMEPAGE: + ::MyShellExecute(kHomePageURL); + break; + case IDC_ABOUT_BUTTON_REGISTER: + ::MyShellExecute(kRegisterPageURL); + break; + case IDC_ABOUT_BUTTON_SUPPORT: + ::MyShellExecute(kSupportPageURL); + break; + default: + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); + } + return true; +} diff --git a/CPP/7zip/UI/FileManager/AboutDialog.h b/CPP/7zip/UI/FileManager/AboutDialog.h new file mode 100755 index 00000000..c8a4ea9b --- /dev/null +++ b/CPP/7zip/UI/FileManager/AboutDialog.h @@ -0,0 +1,18 @@ +// AboutDialog.h + +#ifndef __ABOUTDIALOG_H +#define __ABOUTDIALOG_H + +#include "AboutDialogRes.h" +#include "Windows/Control/Dialog.h" + +class CAboutDialog: public NWindows::NControl::CModalDialog +{ +public: + virtual bool OnInit(); + virtual void OnHelp(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_ABOUT, wndParent); } +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/AboutDialog.rc b/CPP/7zip/UI/FileManager/AboutDialog.rc new file mode 100755 index 00000000..7e2438ff --- /dev/null +++ b/CPP/7zip/UI/FileManager/AboutDialog.rc @@ -0,0 +1,41 @@ +#include "AboutDialogRes.h" +#include "../../GuiCommon.rc" +#include "../../MyVersion.h" + +#define xSize2 224 +#define ySize2 158 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bXPos (xSize - marg - bXSize) +#define bYPos (ySize - marg - bYSize) + +#undef b2XSize +#undef b2XPos +#undef infoYPos +#undef infoYSize + +#define b2XSize 94 +#define b2XPos (xSize - marg - b2XSize) +#define gSpace 2 +#define gSize (xSize2 - gSpace - b2XSize) + +#define infoYPos 91 +#define infoYSize (ySize2 - infoYPos - bYSize - 2) + +IDI_LOGO ICON "7zipLogo.ico" + +IDD_ABOUT DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "About 7-Zip" +MY_FONT +BEGIN + PUSHBUTTON "OK", IDOK, bXPos, bYPos, bXSize, bYSize + PUSHBUTTON "www.7-zip.org", IDC_ABOUT_BUTTON_HOMEPAGE, b2XPos, 7, b2XSize, bYSize + PUSHBUTTON "Support", IDC_ABOUT_BUTTON_SUPPORT, b2XPos, 30, b2XSize, bYSize + PUSHBUTTON "Register", IDC_ABOUT_BUTTON_REGISTER, b2XPos, 53, b2XSize, bYSize + ICON IDI_LOGO, -1, marg, marg, 20, 20, SS_REALSIZEIMAGE + LTEXT MY_7ZIP_VERSION, -1, marg, 54, gSize, 9 + LTEXT MY_COPYRIGHT, -1, marg, 67, gSize, 17 + LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering.", + IDC_ABOUT_STATIC_REGISTER_INFO, marg, infoYPos, xSize2, infoYSize +END diff --git a/CPP/7zip/UI/FileManager/AboutDialogRes.h b/CPP/7zip/UI/FileManager/AboutDialogRes.h new file mode 100755 index 00000000..54475484 --- /dev/null +++ b/CPP/7zip/UI/FileManager/AboutDialogRes.h @@ -0,0 +1,6 @@ +#define IDD_ABOUT 100 +#define IDI_LOGO 138 +#define IDC_ABOUT_STATIC_REGISTER_INFO 1010 +#define IDC_ABOUT_BUTTON_HOMEPAGE 1020 +#define IDC_ABOUT_BUTTON_SUPPORT 1021 +#define IDC_ABOUT_BUTTON_REGISTER 1022 diff --git a/CPP/7zip/UI/FileManager/Add.bmp b/CPP/7zip/UI/FileManager/Add.bmp new file mode 100755 index 00000000..a8577fc7 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Add.bmp differ diff --git a/CPP/7zip/UI/FileManager/Add2.bmp b/CPP/7zip/UI/FileManager/Add2.bmp new file mode 100755 index 00000000..252fc253 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Add2.bmp differ diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp new file mode 100755 index 00000000..0f88ce47 --- /dev/null +++ b/CPP/7zip/UI/FileManager/App.cpp @@ -0,0 +1,759 @@ +// App.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/StringConvert.h" +#include "Windows/FileDir.h" +#include "Windows/Error.h" +#include "Windows/COM.h" +#include "Windows/Thread.h" +#include "IFolder.h" + +#include "App.h" + +#include "CopyDialog.h" + +#include "ExtractCallback.h" +#include "ViewSettings.h" +#include "RegistryUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +extern DWORD g_ComCtl32Version; +extern HINSTANCE g_hInstance; + +static LPCWSTR kTempDirPrefix = L"7zE"; + +void CPanelCallbackImp::OnTab() +{ + if (g_App.NumPanels != 1) + _app->Panels[1 - _index].SetFocusToList(); +} + +void CPanelCallbackImp::SetFocusToPath(int index) +{ + int newPanelIndex = index; + if (g_App.NumPanels == 1) + newPanelIndex = g_App.LastFocusedPanel; + _app->Panels[newPanelIndex]._headerComboBox.SetFocus(); +} + + +void CPanelCallbackImp::OnCopy(bool move, bool copyToSame) + { _app->OnCopy(move, copyToSame, _index); } + +void CPanelCallbackImp::OnSetSameFolder() + { _app->OnSetSameFolder(_index); } + +void CPanelCallbackImp::OnSetSubFolder() + { _app->OnSetSubFolder(_index); } + +void CPanelCallbackImp::PanelWasFocused() + { _app->SetFocusedPanel(_index); } + +void CPanelCallbackImp::DragBegin() + { _app->DragBegin(_index); } + +void CPanelCallbackImp::DragEnd() + { _app->DragEnd(); } + +void CApp::SetListSettings() +{ + bool showDots = ReadShowDots(); + bool showRealFileIcons = ReadShowRealFileIcons(); + + DWORD extendedStyle = LVS_EX_HEADERDRAGDROP; + if (ReadFullRow()) + extendedStyle |= LVS_EX_FULLROWSELECT; + if (ReadShowGrid()) + extendedStyle |= LVS_EX_GRIDLINES; + bool mySelectionMode = ReadAlternativeSelection(); + + /* + if (ReadSingleClick()) + { + extendedStyle |= LVS_EX_ONECLICKACTIVATE + | LVS_EX_TRACKSELECT; + if (ReadUnderline()) + extendedStyle |= LVS_EX_UNDERLINEHOT; + } + */ + + for (int i = 0; i < kNumPanelsMax; i++) + { + CPanel &panel = Panels[i]; + panel._mySelectMode = mySelectionMode; + panel._showDots = showDots; + panel._showRealFileIcons = showRealFileIcons; + panel._exStyle = extendedStyle; + + DWORD style = (DWORD)panel._listView.GetStyle(); + if (mySelectionMode) + style |= LVS_SINGLESEL; + else + style &= ~LVS_SINGLESEL; + panel._listView.SetStyle(style); + panel.SetExtendedStyle(); + } +} + +void CApp::SetShowSystemMenu() +{ + ShowSystemMenu = ReadShowSystemMenu(); +} + +void CApp::CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted) +{ + if (PanelsCreated[panelIndex]) + return; + m_PanelCallbackImp[panelIndex].Init(this, panelIndex); + UString path; + if (mainPath.IsEmpty()) + { + if (!::ReadPanelPath(panelIndex, path)) + path.Empty(); + } + else + path = mainPath; + int id = 1000 + 100 * panelIndex; + Panels[panelIndex].Create(_window, _window, + id, path, &m_PanelCallbackImp[panelIndex], &AppState, archiveIsOpened, encrypted); + PanelsCreated[panelIndex] = true; +} + +static void CreateToolbar( + HWND parent, + NWindows::NControl::CImageList &imageList, + NWindows::NControl::CToolBar &toolBar, + bool LargeButtons) +{ + toolBar.Attach(::CreateWindowEx(0, + TOOLBARCLASSNAME, + NULL, 0 + | WS_VISIBLE + | TBSTYLE_FLAT + | TBSTYLE_TOOLTIPS + | WS_CHILD + | CCS_NOPARENTALIGN + | CCS_NORESIZE + | CCS_NODIVIDER + // | TBSTYLE_AUTOSIZE + // | CCS_ADJUSTABLE + ,0,0,0,0, parent, NULL, g_hInstance, NULL)); + + // TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + toolBar.ButtonStructSize(); + + imageList.Create( + LargeButtons ? 48: 24, + LargeButtons ? 36: 24, + ILC_MASK, 0, 0); + toolBar.SetImageList(0, imageList); +} + +struct CButtonInfo +{ + UINT commandID; + UINT BitmapResID; + UINT Bitmap2ResID; + UINT StringResID; + UINT32 LangID; + UString GetText()const { return LangString(StringResID, LangID); }; +}; + +static CButtonInfo g_StandardButtons[] = +{ + { IDM_COPY_TO, IDB_COPY, IDB_COPY2, IDS_BUTTON_COPY, 0x03020420}, + { IDM_MOVE_TO, IDB_MOVE, IDB_MOVE2, IDS_BUTTON_MOVE, 0x03020421}, + { IDM_DELETE, IDB_DELETE, IDB_DELETE2, IDS_BUTTON_DELETE, 0x03020422} , + { IDM_FILE_PROPERTIES, IDB_INFO, IDB_INFO2, IDS_BUTTON_INFO, 0x03020423} +}; + +static CButtonInfo g_ArchiveButtons[] = +{ + { kAddCommand, IDB_ADD, IDB_ADD2, IDS_ADD, 0x03020400}, + { kExtractCommand, IDB_EXTRACT, IDB_EXTRACT2, IDS_EXTRACT, 0x03020401}, + { kTestCommand , IDB_TEST, IDB_TEST2, IDS_TEST, 0x03020402} +}; + +bool SetButtonText(UINT32 commandID, CButtonInfo *buttons, int numButtons, UString &s) +{ + for (int i = 0; i < numButtons; i++) + { + const CButtonInfo &b = buttons[i]; + if (b.commandID == commandID) + { + s = b.GetText(); + return true; + } + } + return false; +} + +void SetButtonText(UINT32 commandID, UString &s) +{ + if (SetButtonText(commandID, g_StandardButtons, + sizeof(g_StandardButtons) / sizeof(g_StandardButtons[0]), s)) + return; + SetButtonText(commandID, g_ArchiveButtons, + sizeof(g_ArchiveButtons) / sizeof(g_ArchiveButtons[0]), s); +} + +static void AddButton( + NControl::CImageList &imageList, + NControl::CToolBar &toolBar, + CButtonInfo &butInfo, + bool showText, + bool large) +{ + TBBUTTON but; + but.iBitmap = 0; + but.idCommand = butInfo.commandID; + but.fsState = TBSTATE_ENABLED; + but.fsStyle = BTNS_BUTTON + // | BTNS_AUTOSIZE + ; + but.dwData = 0; + + UString s = butInfo.GetText(); + but.iString = 0; + if (showText) + but.iString = (INT_PTR)(LPCWSTR)s; + + but.iBitmap = imageList.GetImageCount(); + HBITMAP b = ::LoadBitmap(g_hInstance, + large ? + MAKEINTRESOURCE(butInfo.BitmapResID): + MAKEINTRESOURCE(butInfo.Bitmap2ResID)); + if (b != 0) + { + imageList.AddMasked(b, RGB(255, 0, 255)); + ::DeleteObject(b); + } + #ifdef _UNICODE + toolBar.AddButton(1, &but); + #else + toolBar.AddButtonW(1, &but); + #endif +} + +static void AddBand(NControl::CReBar &reBar, NControl::CToolBar &toolBar) +{ + SIZE size; + toolBar.GetMaxSize(&size); + + RECT rect; + toolBar.GetWindowRect(&rect); + + REBARBANDINFO rbBand; + rbBand.cbSize = sizeof(REBARBANDINFO); // Required + rbBand.fMask = RBBIM_STYLE + | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; + rbBand.fStyle = RBBS_CHILDEDGE; // RBBS_NOGRIPPER; + rbBand.cxMinChild = size.cx; // rect.right - rect.left; + rbBand.cyMinChild = size.cy; // rect.bottom - rect.top; + rbBand.cyChild = rbBand.cyMinChild; + rbBand.cx = rbBand.cxMinChild; + rbBand.cxIdeal = rbBand.cxMinChild; + rbBand.hwndChild = toolBar; + reBar.InsertBand(-1, &rbBand); +} + +void CApp::ReloadToolbars() +{ + if (!_rebar) + return; + HWND parent = _rebar; + + while(_rebar.GetBandCount() > 0) + _rebar.DeleteBand(0); + + _archiveToolBar.Destroy(); + _archiveButtonsImageList.Destroy(); + + _standardButtonsImageList.Destroy(); + _standardToolBar.Destroy(); + + if (ShowArchiveToolbar) + { + CreateToolbar(parent, _archiveButtonsImageList, _archiveToolBar, LargeButtons); + for (int i = 0; i < sizeof(g_ArchiveButtons) / sizeof(g_ArchiveButtons[0]); i++) + AddButton(_archiveButtonsImageList, _archiveToolBar, g_ArchiveButtons[i], + ShowButtonsLables, LargeButtons); + AddBand(_rebar, _archiveToolBar); + } + + if (ShowStandardToolbar) + { + CreateToolbar(parent, _standardButtonsImageList, _standardToolBar, LargeButtons); + for (int i = 0; i < sizeof(g_StandardButtons) / sizeof(g_StandardButtons[0]); i++) + AddButton(_standardButtonsImageList, _standardToolBar, g_StandardButtons[i], + ShowButtonsLables, LargeButtons); + AddBand(_rebar, _standardToolBar); + } +} + +void CApp::ReloadRebar(HWND hwnd) +{ + _rebar.Destroy(); + if (!ShowArchiveToolbar && !ShowStandardToolbar) + return; + if (g_ComCtl32Version >= MAKELONG(71, 4)) + { + INITCOMMONCONTROLSEX icex; + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + _rebar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW, + REBARCLASSNAME, + NULL, + WS_VISIBLE + | WS_BORDER + | WS_CHILD + | WS_CLIPCHILDREN + | WS_CLIPSIBLINGS + // | CCS_NODIVIDER + // | CCS_NOPARENTALIGN // it's bead for moveing of two bands + // | CCS_TOP + | RBS_VARHEIGHT + | RBS_BANDBORDERS + // | RBS_AUTOSIZE + ,0,0,0,0, hwnd, NULL, g_hInstance, NULL)); + } + if (_rebar == 0) + return; + REBARINFO rbi; + rbi.cbSize = sizeof(REBARINFO); // Required when using this struct. + rbi.fMask = 0; + rbi.himl = (HIMAGELIST)NULL; + _rebar.SetBarInfo(&rbi); + ReloadToolbars(); +} + +void CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted) +{ + ReadToolbar(); + ReloadRebar(hwnd); + + int i; + for (i = 0; i < kNumPanelsMax; i++) + PanelsCreated[i] = false; + + _window.Attach(hwnd); + AppState.Read(); + SetListSettings(); + SetShowSystemMenu(); + if (LastFocusedPanel >= kNumPanelsMax) + LastFocusedPanel = 0; + + CListMode listMode; + ReadListMode(listMode); + for (i = 0; i < kNumPanelsMax; i++) + { + Panels[i]._ListViewMode = listMode.Panels[i]; + Panels[i]._xSize = xSizes[i]; + } + for (i = 0; i < kNumPanelsMax; i++) + if (NumPanels > 1 || i == LastFocusedPanel) + { + if (NumPanels == 1) + Panels[i]._xSize = xSizes[0] + xSizes[1]; + bool archiveIsOpened2 = false; + bool encrypted2 = false; + bool mainPanel = (i == LastFocusedPanel); + CreateOnePanel(i, mainPanel ? mainPath : L"", archiveIsOpened2, encrypted2); + if (mainPanel) + { + archiveIsOpened = archiveIsOpened2; + encrypted = encrypted2; + } + } + SetFocusedPanel(LastFocusedPanel); + Panels[LastFocusedPanel].SetFocusToList(); +} + +extern void MoveSubWindows(HWND hWnd); + +void CApp::SwitchOnOffOnePanel() +{ + if (NumPanels == 1) + { + NumPanels++; + bool archiveIsOpened, encrypted; + CreateOnePanel(1 - LastFocusedPanel, UString(), archiveIsOpened, encrypted); + Panels[1 - LastFocusedPanel].Enable(true); + Panels[1 - LastFocusedPanel].Show(SW_SHOWNORMAL); + } + else + { + NumPanels--; + Panels[1 - LastFocusedPanel].Enable(false); + Panels[1 - LastFocusedPanel].Show(SW_HIDE); + } + MoveSubWindows(_window); +} + +void CApp::Save() +{ + AppState.Save(); + CListMode listMode; + for (int i = 0; i < kNumPanelsMax; i++) + { + const CPanel &panel = Panels[i]; + UString path; + if (panel._parentFolders.IsEmpty()) + path = panel._currentFolderPrefix; + else + path = GetFolderPath(panel._parentFolders[0].ParentFolder); + SavePanelPath(i, path); + listMode.Panels[i] = panel.GetListViewMode(); + } + SaveListMode(listMode); +} + +void CApp::Release() +{ + // It's for unloading COM dll's: don't change it. + for (int i = 0; i < kNumPanelsMax; i++) + Panels[i].Release(); +} + +static bool IsThereFolderOfPath(const UString &path) +{ + CFileInfoW fileInfo; + if (!FindFile(path, fileInfo)) + return false; + return fileInfo.IsDirectory(); +} + +// reduces path to part that exists on disk +static void ReducePathToRealFileSystemPath(UString &path) +{ + while(!path.IsEmpty()) + { + if (IsThereFolderOfPath(path)) + { + NName::NormalizeDirPathPrefix(path); + break; + } + int pos = path.ReverseFind('\\'); + if (pos < 0) + path.Empty(); + else + { + path = path.Left(pos + 1); + if (path.Length() == 3 && path[1] == L':') + break; + path = path.Left(pos); + } + } +} + +// return true for dir\, if dir exist +static bool CheckFolderPath(const UString &path) +{ + UString pathReduced = path; + ReducePathToRealFileSystemPath(pathReduced); + return (pathReduced == path); +} + +static bool IsPathAbsolute(const UString &path) +{ + if ((path.Length() >= 1 && path[0] == L'\\') || + (path.Length() >= 3 && path[1] == L':' && path[2] == L'\\')) + return true; + return false; +} + +void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex) +{ + int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[destPanelIndex]; + + CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel); + CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel); + + if (!srcPanel.DoesItSupportOperations()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + + CRecordVector indices; + UString destPath; + bool useDestPanel = false; + + { + if (copyToSame) + { + int focusedItem = srcPanel._listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = srcPanel.GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex) + return; + indices.Add(realIndex); + destPath = srcPanel.GetItemName(realIndex); + } + else + { + srcPanel.GetOperatedItemIndices(indices); + if (indices.Size() == 0) + return; + destPath = destPanel._currentFolderPrefix; + if (NumPanels == 1) + ReducePathToRealFileSystemPath(destPath); + } + + CCopyDialog copyDialog; + UStringVector copyFolders; + ReadCopyHistory(copyFolders); + + copyDialog.Strings = copyFolders; + copyDialog.Value = destPath; + + copyDialog.Title = move ? + LangString(IDS_MOVE, 0x03020202): + LangString(IDS_COPY, 0x03020201); + copyDialog.Static = move ? + LangString(IDS_MOVE_TO, 0x03020204): + LangString(IDS_COPY_TO, 0x03020203); + + if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL) + return; + + destPath = copyDialog.Value; + + if (!IsPathAbsolute(destPath)) + { + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + destPath = srcPanel._currentFolderPrefix + destPath; + } + + if (indices.Size() > 1 || (destPath.Length() > 0 && destPath.ReverseFind('\\') == destPath.Length() - 1) || + IsThereFolderOfPath(destPath)) + { + NDirectory::CreateComplexDirectory(destPath); + NName::NormalizeDirPathPrefix(destPath); + if (!CheckFolderPath(destPath)) + { + if (NumPanels < 2 || destPath != destPanel._currentFolderPrefix || !destPanel.DoesItSupportOperations()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + useDestPanel = true; + } + } + else + { + int pos = destPath.ReverseFind('\\'); + if (pos >= 0) + { + UString prefix = destPath.Left(pos + 1); + NDirectory::CreateComplexDirectory(prefix); + if (!CheckFolderPath(prefix)) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + } + } + + AddUniqueStringToHeadOfList(copyFolders, destPath); + while (copyFolders.Size() > 20) + copyFolders.DeleteBack(); + SaveCopyHistory(copyFolders); + } + + bool useSrcPanel = (!useDestPanel || !srcPanel.IsFSFolder() || destPanel.IsFSFolder()); + bool useTemp = useSrcPanel && useDestPanel; + NFile::NDirectory::CTempDirectoryW tempDirectory; + UString tempDirPrefix; + if (useTemp) + { + tempDirectory.Create(kTempDirPrefix); + tempDirPrefix = tempDirectory.GetPath(); + NFile::NName::NormalizeDirPathPrefix(tempDirPrefix); + } + + CSelectedState srcSelState; + CSelectedState destSelState; + srcPanel.SaveSelectedState(srcSelState); + destPanel.SaveSelectedState(destSelState); + + HRESULT result; + if (useSrcPanel) + { + UString folder = useTemp ? tempDirPrefix : destPath; + result = srcPanel.CopyTo(indices, folder, move, true, 0); + if (result != S_OK) + { + disableTimerProcessing1.Restore(); + disableTimerProcessing2.Restore(); + // For Password: + srcPanel.SetFocusToList(); + if (result != E_ABORT) + srcPanel.MessageBoxError(result, L"Error"); + return; + } + } + + if (useDestPanel) + { + UStringVector filePaths; + UString folderPrefix; + if (useTemp) + folderPrefix = tempDirPrefix; + else + folderPrefix = srcPanel._currentFolderPrefix; + filePaths.Reserve(indices.Size()); + for(int i = 0; i < indices.Size(); i++) + filePaths.Add(srcPanel.GetItemRelPath(indices[i])); + + result = destPanel.CopyFrom(folderPrefix, filePaths, true, 0); + + if (result != S_OK) + { + disableTimerProcessing1.Restore(); + disableTimerProcessing2.Restore(); + // For Password: + srcPanel.SetFocusToList(); + if (result != E_ABORT) + srcPanel.MessageBoxError(result, L"Error"); + return; + } + } + + if (copyToSame || move) + { + srcPanel.RefreshListCtrl(srcSelState); + } + if (!copyToSame) + { + destPanel.RefreshListCtrl(destSelState); + srcPanel.KillSelection(); + } + disableTimerProcessing1.Restore(); + disableTimerProcessing2.Restore(); + srcPanel.SetFocusToList(); +} + +void CApp::OnSetSameFolder(int srcPanelIndex) +{ + if (NumPanels <= 1) + return; + const CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[1 - srcPanelIndex]; + destPanel.BindToPathAndRefresh(srcPanel._currentFolderPrefix); +} + +void CApp::OnSetSubFolder(int srcPanelIndex) +{ + if (NumPanels <= 1) + return; + const CPanel &srcPanel = Panels[srcPanelIndex]; + CPanel &destPanel = Panels[1 - srcPanelIndex]; + + int focusedItem = srcPanel._listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = srcPanel.GetRealItemIndex(focusedItem); + if (!srcPanel.IsItemFolder(realIndex)) + return; + + + /* + UString string = srcPanel._currentFolderPrefix + + srcPanel.GetItemName(realIndex) + L'\\'; + destPanel.BindToFolder(string); + */ + CMyComPtr newFolder; + if (realIndex == kParentIndex) + { + if (srcPanel._folder->BindToParentFolder(&newFolder) != S_OK) + return; + } + else + { + if (srcPanel._folder->BindToFolder(realIndex, &newFolder) != S_OK) + return; + } + destPanel.CloseOpenFolders(); + destPanel._folder = newFolder; + destPanel.RefreshListCtrl(); +} + +/* +int CApp::GetFocusedPanelIndex() const +{ + return LastFocusedPanel; + HWND hwnd = ::GetFocus(); + for (;;) + { + if (hwnd == 0) + return 0; + for (int i = 0; i < kNumPanelsMax; i++) + { + if (PanelsCreated[i] && + ((HWND)Panels[i] == hwnd || Panels[i]._listView == hwnd)) + return i; + } + hwnd = GetParent(hwnd); + } +} + */ + +static UString g_ToolTipBuffer; +static CSysString g_ToolTipBufferSys; + +void CApp::OnNotify(int /* ctrlID */, LPNMHDR pnmh) +{ + if (pnmh->hwndFrom == _rebar) + { + switch(pnmh->code) + { + case RBN_HEIGHTCHANGE: + { + MoveSubWindows(g_HWND); + return; + } + } + return ; + } + else + { + if (pnmh->code == TTN_GETDISPINFO) + { + LPNMTTDISPINFO info = (LPNMTTDISPINFO)pnmh; + info->hinst = 0; + g_ToolTipBuffer.Empty(); + SetButtonText((UINT32)info->hdr.idFrom, g_ToolTipBuffer); + g_ToolTipBufferSys = GetSystemString(g_ToolTipBuffer); + info->lpszText = (LPTSTR)(LPCTSTR)g_ToolTipBufferSys; + return; + } + #ifndef _UNICODE + if (pnmh->code == TTN_GETDISPINFOW) + { + LPNMTTDISPINFOW info = (LPNMTTDISPINFOW)pnmh; + info->hinst = 0; + g_ToolTipBuffer.Empty(); + SetButtonText((UINT32)info->hdr.idFrom, g_ToolTipBuffer); + info->lpszText = (LPWSTR)(LPCWSTR)g_ToolTipBuffer; + return; + } + #endif + } +} diff --git a/CPP/7zip/UI/FileManager/App.h b/CPP/7zip/UI/FileManager/App.h new file mode 100755 index 00000000..faa40afe --- /dev/null +++ b/CPP/7zip/UI/FileManager/App.h @@ -0,0 +1,332 @@ +// App.h + +#ifndef __APP_H +#define __APP_H + +#include "Panel.h" +#include "AppState.h" +#include "Windows/Control/ImageList.h" + +class CApp; + +extern CApp g_App; +extern HWND g_HWND; + +const int kNumPanelsMax = 2; + +extern void MoveSubWindows(HWND hWnd); + +enum +{ + kAddCommand = kToolbarStartID, + kExtractCommand, + kTestCommand +}; + +class CPanelCallbackImp: public CPanelCallback +{ + CApp *_app; + int _index; +public: + void Init(CApp *app, int index) + { + _app = app; + _index = index; + } + virtual void OnTab(); + virtual void SetFocusToPath(int index); + virtual void OnCopy(bool move, bool copyToSame); + virtual void OnSetSameFolder(); + virtual void OnSetSubFolder(); + virtual void PanelWasFocused(); + virtual void DragBegin(); + virtual void DragEnd(); +}; + +class CApp; + +class CDropTarget: + public IDropTarget, + public CMyUnknownImp +{ + CMyComPtr m_DataObject; + UStringVector m_SourcePaths; + int m_SelectionIndex; + bool m_DropIsAllowed; // = true, if data contain fillist + bool m_PanelDropIsAllowed; // = false, if current target_panel is source_panel. + // check it only if m_DropIsAllowed == true + int m_SubFolderIndex; + UString m_SubFolderName; + + CPanel *m_Panel; + bool m_IsAppTarget; // true, if we want to drop to app window (not to panel). + + bool m_SetPathIsOK; + + bool IsItSameDrive() const; + + void QueryGetData(IDataObject *dataObject); + bool IsFsFolderPath() const; + DWORD GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect); + void RemoveSelection(); + void PositionCursor(POINTL ptl); + UString GetTargetPath() const; + bool SetPath(bool enablePath) const; + bool SetPath(); + +public: + MY_UNKNOWN_IMP1_MT(IDropTarget) + STDMETHOD(DragEnter)(IDataObject * dataObject, DWORD keyState, + POINTL pt, DWORD *effect); + STDMETHOD(DragOver)(DWORD keyState, POINTL pt, DWORD * effect); + STDMETHOD(DragLeave)(); + STDMETHOD(Drop)(IDataObject * dataObject, DWORD keyState, + POINTL pt, DWORD *effect); + + CDropTarget(): + TargetPanelIndex(-1), + SrcPanelIndex(-1), + m_IsAppTarget(false), + m_Panel(0), + App(0), + m_PanelDropIsAllowed(false), + m_DropIsAllowed(false), + m_SelectionIndex(-1), + m_SubFolderIndex(-1), + m_SetPathIsOK(false) {} + + CApp *App; + int SrcPanelIndex; // index of D&D source_panel + int TargetPanelIndex; // what panel to use as target_panel of Application +}; + +class CApp +{ +public: + NWindows::CWindow _window; + bool ShowSystemMenu; + int NumPanels; + int LastFocusedPanel; + + bool ShowStandardToolbar; + bool ShowArchiveToolbar; + bool ShowButtonsLables; + bool LargeButtons; + + CAppState AppState; + CPanelCallbackImp m_PanelCallbackImp[kNumPanelsMax]; + CPanel Panels[kNumPanelsMax]; + bool PanelsCreated[kNumPanelsMax]; + + NWindows::NControl::CImageList _archiveButtonsImageList; + NWindows::NControl::CImageList _standardButtonsImageList; + + NWindows::NControl::CReBar _rebar; + NWindows::NControl::CToolBar _archiveToolBar; + NWindows::NControl::CToolBar _standardToolBar; + + CDropTarget *_dropTargetSpec; + CMyComPtr _dropTarget; + + void CreateDragTarget() + { + _dropTargetSpec = new CDropTarget(); + _dropTarget = _dropTargetSpec; + _dropTargetSpec->App = (this); + } + + void SetFocusedPanel(int index) + { + LastFocusedPanel = index; + _dropTargetSpec->TargetPanelIndex = LastFocusedPanel; + } + + void DragBegin(int panelIndex) + { + _dropTargetSpec->TargetPanelIndex = (NumPanels > 1) ? 1 - panelIndex : panelIndex; + _dropTargetSpec->SrcPanelIndex = panelIndex; + } + + void DragEnd() + { + _dropTargetSpec->TargetPanelIndex = LastFocusedPanel; + _dropTargetSpec->SrcPanelIndex = -1; + } + + + void OnCopy(bool move, bool copyToSame, int srcPanelIndex); + void OnSetSameFolder(int srcPanelIndex); + void OnSetSubFolder(int srcPanelIndex); + + void CreateOnePanel(int panelIndex, const UString &mainPath, bool &archiveIsOpened, bool &encrypted); + void Create(HWND hwnd, const UString &mainPath, int xSizes[2], bool &archiveIsOpened, bool &encrypted); + void Read(); + void Save(); + void Release(); + + + /* + void SetFocus(int panelIndex) + { Panels[panelIndex].SetFocusToList(); } + */ + void SetFocusToLastItem() + { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } + + int GetFocusedPanelIndex() const { return LastFocusedPanel; } + + bool IsPanelVisible(int index) const { return (NumPanels > 1 || index == LastFocusedPanel); } + + /* + void SetCurrentIndex() + { CurrentPanel = GetFocusedPanelIndex(); } + */ + + CApp(): NumPanels(2), LastFocusedPanel(0) {} + CPanel &GetFocusedPanel() + { return Panels[GetFocusedPanelIndex()]; } + + // File Menu + void OpenItem() + { GetFocusedPanel().OpenSelectedItems(true); } + void OpenItemInside() + { GetFocusedPanel().OpenFocusedItemAsInternal(); } + void OpenItemOutside() + { GetFocusedPanel().OpenSelectedItems(false); } + void EditItem() + { GetFocusedPanel().EditItem(); } + void Rename() + { GetFocusedPanel().RenameFile(); } + void CopyTo() + { OnCopy(false, false, GetFocusedPanelIndex()); } + void MoveTo() + { OnCopy(true, false, GetFocusedPanelIndex()); } + void Delete(bool toRecycleBin) + { GetFocusedPanel().DeleteItems(toRecycleBin); } + void CalculateCrc(); + void Split(); + void Combine(); + void Properties() + { GetFocusedPanel().Properties(); } + void Comment() + { GetFocusedPanel().ChangeComment(); } + + void CreateFolder() + { GetFocusedPanel().CreateFolder(); } + void CreateFile() + { GetFocusedPanel().CreateFile(); } + + // Edit + void EditCopy() + { GetFocusedPanel().EditCopy(); } + void EditPaste() + { GetFocusedPanel().EditPaste(); } + + void SelectAll(bool selectMode) + { GetFocusedPanel().SelectAll(selectMode); } + void InvertSelection() + { GetFocusedPanel().InvertSelection(); } + void SelectSpec(bool selectMode) + { GetFocusedPanel().SelectSpec(selectMode); } + void SelectByType(bool selectMode) + { GetFocusedPanel().SelectByType(selectMode); } + + void RefreshStatusBar() + { GetFocusedPanel().RefreshStatusBar(); } + + void SetListViewMode(UINT32 index) + { GetFocusedPanel().SetListViewMode(index); } + UINT32 GetListViewMode() + { return GetFocusedPanel().GetListViewMode(); } + + void SortItemsWithPropID(PROPID propID) + { GetFocusedPanel().SortItemsWithPropID(propID); } + + void OpenRootFolder() + { GetFocusedPanel().OpenDrivesFolder(); } + void OpenParentFolder() + { GetFocusedPanel().OpenParentFolder(); } + void FoldersHistory() + { GetFocusedPanel().FoldersHistory(); } + void RefreshView() + { GetFocusedPanel().OnReload(); } + void RefreshAllPanels() + { + for (int i = 0; i < NumPanels; i++) + { + int index = i; + if (NumPanels == 1) + index = LastFocusedPanel; + Panels[index].OnReload(); + } + } + void SetListSettings(); + void SetShowSystemMenu(); + void SwitchOnOffOnePanel(); + bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); } + void ChangeFlatMode() { Panels[LastFocusedPanel].ChangeFlatMode(); } + + void OpenBookmark(int index) + { GetFocusedPanel().OpenBookmark(index); } + void SetBookmark(int index) + { GetFocusedPanel().SetBookmark(index); } + + void ReloadRebar(HWND hwnd); + void ReloadToolbars(); + void ReadToolbar() + { + UINT32 mask = ReadToolbarsMask(); + ShowButtonsLables = ((mask & 1) != 0); + LargeButtons = ((mask & 2) != 0); + ShowStandardToolbar = ((mask & 4) != 0); + ShowArchiveToolbar = ((mask & 8) != 0); + } + void SaveToolbar() + { + UINT32 mask = 0; + if (ShowButtonsLables) mask |= 1; + if (LargeButtons) mask |= 2; + if (ShowStandardToolbar) mask |= 4; + if (ShowArchiveToolbar) mask |= 8; + SaveToolbarsMask(mask); + } + void SwitchStandardToolbar() + { + ShowStandardToolbar = !ShowStandardToolbar; + SaveToolbar(); + ReloadRebar(g_HWND); + MoveSubWindows(_window); + } + void SwitchArchiveToolbar() + { + ShowArchiveToolbar = !ShowArchiveToolbar; + SaveToolbar(); + ReloadRebar(g_HWND); + MoveSubWindows(_window); + } + void SwitchButtonsLables() + { + ShowButtonsLables = !ShowButtonsLables; + SaveToolbar(); + ReloadRebar(g_HWND); + MoveSubWindows(_window); + } + void SwitchLargeButtons() + { + LargeButtons = !LargeButtons; + SaveToolbar(); + ReloadRebar(g_HWND); + MoveSubWindows(_window); + } + + + void AddToArchive() + { GetFocusedPanel().AddToArchive(); } + void ExtractArchives() + { GetFocusedPanel().ExtractArchives(); } + void TestArchives() + { GetFocusedPanel().TestArchives(); } + + void OnNotify(int ctrlID, LPNMHDR pnmh); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/AppState.h b/CPP/7zip/UI/FileManager/AppState.h new file mode 100755 index 00000000..318c0258 --- /dev/null +++ b/CPP/7zip/UI/FileManager/AppState.h @@ -0,0 +1,114 @@ +// AppState.h + +#ifndef __APPSTATE_H +#define __APPSTATE_H + +#include "Windows/Synchronization.h" + +void inline AddUniqueStringToHead(UStringVector &list, + const UString &string) +{ + for(int i = 0; i < list.Size();) + if (string.CompareNoCase(list[i]) == 0) + list.Delete(i); + else + i++; + list.Insert(0, string); +} + +class CFastFolders +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; +public: + UStringVector Strings; + void SetString(int index, const UString &string) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + while(Strings.Size() <= index) + Strings.Add(UString()); + Strings[index] = string; + } + UString GetString(int index) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + if (index >= Strings.Size()) + return UString(); + return Strings[index]; + } + void Save() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + SaveFastFolders(Strings); + } + void Read() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + ReadFastFolders(Strings); + } +}; + +class CFolderHistory +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; + UStringVector Strings; +public: + + void GetList(UStringVector &foldersHistory) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + foldersHistory = Strings; + } + + void Normalize() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + const int kMaxSize = 100; + if (Strings.Size() > kMaxSize) + Strings.Delete(kMaxSize, Strings.Size() - kMaxSize); + } + + void AddString(const UString &string) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + AddUniqueStringToHead(Strings, string); + Normalize(); + } + + void RemoveAll() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + Strings.Clear(); + } + + void Save() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + SaveFolderHistory(Strings); + } + + void Read() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + ReadFolderHistory(Strings); + Normalize(); + } +}; + +struct CAppState +{ + CFastFolders FastFolders; + CFolderHistory FolderHistory; + void Save() + { + FastFolders.Save(); + FolderHistory.Save(); + } + void Read() + { + FastFolders.Read(); + FolderHistory.Read(); + } +}; + + +#endif \ No newline at end of file diff --git a/CPP/7zip/UI/FileManager/ClassDefs.cpp b/CPP/7zip/UI/FileManager/ClassDefs.cpp new file mode 100755 index 00000000..0b4c9093 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ClassDefs.cpp @@ -0,0 +1,17 @@ +// ClassDefs.cpp + +#include "StdAfx.h" + +#include + +#include "IFolder.h" +#include "../../IPassword.h" +#include "PluginInterface.h" +#include "ExtractCallback.h" +#include "../../ICoder.h" + +#include "../Agent/Agent.h" + +// {23170F69-40C1-278A-1000-000100020000} +DEFINE_GUID(CLSID_CZipContextMenu, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); diff --git a/CPP/7zip/UI/FileManager/ComboDialog.cpp b/CPP/7zip/UI/FileManager/ComboDialog.cpp new file mode 100755 index 00000000..83c142ff --- /dev/null +++ b/CPP/7zip/UI/FileManager/ComboDialog.cpp @@ -0,0 +1,53 @@ +// ComboDialog.cpp + +#include "StdAfx.h" +#include "ComboDialog.h" + +#include "Windows/Control/Static.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 } +}; +#endif + +bool CComboDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _comboBox.Attach(GetItem(IDC_COMBO_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(IDC_COMBO_STATIC)); + staticContol.SetText(Static); + _comboBox.SetText(Value); + for(int i = 0; i < Strings.Size(); i++) + _comboBox.AddString(Strings[i]); + return CModalDialog::OnInit(); +} + +void CComboDialog::OnOK() +{ + _comboBox.GetText(Value); + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/UI/FileManager/ComboDialog.h b/CPP/7zip/UI/FileManager/ComboDialog.h new file mode 100755 index 00000000..0a1addc5 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ComboDialog.h @@ -0,0 +1,25 @@ +// ComboDialog.h + +#ifndef __COMBODIALOG_H +#define __COMBODIALOG_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ComboBox.h" +#include "ComboDialogRes.h" + +class CComboDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _comboBox; + virtual void OnOK(); + virtual bool OnInit(); +public: + // bool Sorted; + UString Title; + UString Static; + UString Value; + UStringVector Strings; + // CComboDialog(): Sorted(false) {}; + INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_COMBO, parentWindow); } +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/ComboDialog.rc b/CPP/7zip/UI/FileManager/ComboDialog.rc new file mode 100755 index 00000000..7005e09e --- /dev/null +++ b/CPP/7zip/UI/FileManager/ComboDialog.rc @@ -0,0 +1,24 @@ +#include "ComboDialogRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 233 +#define ySize2 57 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + +IDD_DIALOG_COMBO DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Combo" +MY_FONT +BEGIN + LTEXT "", IDC_COMBO_STATIC, marg, marg, xSize2, 8 + COMBOBOX IDC_COMBO_COMBO, marg, 20, xSize2, 65, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END diff --git a/CPP/7zip/UI/FileManager/ComboDialogRes.h b/CPP/7zip/UI/FileManager/ComboDialogRes.h new file mode 100755 index 00000000..b5111ddf --- /dev/null +++ b/CPP/7zip/UI/FileManager/ComboDialogRes.h @@ -0,0 +1,4 @@ +#define IDD_DIALOG_COMBO 200 + +#define IDC_COMBO_STATIC 1000 +#define IDC_COMBO_COMBO 1001 diff --git a/CPP/7zip/UI/FileManager/Copy.bmp b/CPP/7zip/UI/FileManager/Copy.bmp new file mode 100755 index 00000000..0f28a324 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Copy.bmp differ diff --git a/CPP/7zip/UI/FileManager/Copy2.bmp b/CPP/7zip/UI/FileManager/Copy2.bmp new file mode 100755 index 00000000..ba88ded0 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Copy2.bmp differ diff --git a/CPP/7zip/UI/FileManager/CopyDialog.cpp b/CPP/7zip/UI/FileManager/CopyDialog.cpp new file mode 100755 index 00000000..77b62ec0 --- /dev/null +++ b/CPP/7zip/UI/FileManager/CopyDialog.cpp @@ -0,0 +1,81 @@ +// CopyDialog.cpp + +#include "StdAfx.h" +#include "CopyDialog.h" + +#include "Common/StringConvert.h" + +#include "Windows/Control/Static.h" +#include "Windows/Shell.h" +#include "Windows/FileName.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 } +}; +#endif + +bool CCopyDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _path.Attach(GetItem(IDC_COPY_COMBO)); + SetText(Title); + + NControl::CStatic staticContol; + staticContol.Attach(GetItem(IDC_COPY_STATIC)); + staticContol.SetText(Static); + for(int i = 0; i < Strings.Size(); i++) + _path.AddString(Strings[i]); + _path.SetText(Value); + return CModalDialog::OnInit(); +} + +bool CCopyDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_COPY_SET_PATH: + OnButtonSetPath(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CCopyDialog::OnButtonSetPath() +{ + UString currentPath; + _path.GetText(currentPath); + + /* + #ifdef LANG + UString title = LangLoadString(IDS_EXTRACT_SET_FOLDER, 0x02000881); + #else + UString title = MyLoadString(IDS_EXTRACT_SET_FOLDER); + #endif + */ + UString title = LangStringSpec(IDS_SET_FOLDER, 0x03020209); + // UString title = L"Specify a location for output folder"; + + UString resultPath; + if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + return; + NFile::NName::NormalizeDirPathPrefix(resultPath); + _path.SetCurSel(-1); + _path.SetText(resultPath); +} + +void CCopyDialog::OnOK() +{ + _path.GetText(Value); + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/UI/FileManager/CopyDialog.h b/CPP/7zip/UI/FileManager/CopyDialog.h new file mode 100755 index 00000000..ed894bf8 --- /dev/null +++ b/CPP/7zip/UI/FileManager/CopyDialog.h @@ -0,0 +1,26 @@ +// CopyDialog.h + +#ifndef __COPYDIALOG_H +#define __COPYDIALOG_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ComboBox.h" +#include "CopyDialogRes.h" + +class CCopyDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _path; + virtual void OnOK(); + virtual bool OnInit(); + void OnButtonSetPath(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + UString Title; + UString Static; + UString Value; + UStringVector Strings; + + INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_COPY, parentWindow); } +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/CopyDialog.rc b/CPP/7zip/UI/FileManager/CopyDialog.rc new file mode 100755 index 00000000..bf3aebde --- /dev/null +++ b/CPP/7zip/UI/FileManager/CopyDialog.rc @@ -0,0 +1,28 @@ +#include "CopyDialogRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 346 +#define ySize2 57 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + +IDD_DIALOG_COPY DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Copy" +MY_FONT +BEGIN + LTEXT "", IDC_COPY_STATIC, marg, marg, xSize2, 8 + COMBOBOX IDC_COPY_COMBO, marg, 20, xSize2 - bDotsSize - 12, 65, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...", IDC_COPY_SET_PATH, (xSize - marg - bDotsSize), 20, bDotsSize, 14, WS_GROUP + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_SET_FOLDER "Specify a location for output folder." +END diff --git a/CPP/7zip/UI/FileManager/CopyDialogRes.h b/CPP/7zip/UI/FileManager/CopyDialogRes.h new file mode 100755 index 00000000..7ec6162a --- /dev/null +++ b/CPP/7zip/UI/FileManager/CopyDialogRes.h @@ -0,0 +1,7 @@ +#define IDD_DIALOG_COPY 202 + +#define IDC_COPY_STATIC 1000 +#define IDC_COPY_COMBO 1001 +#define IDC_COPY_SET_PATH 1002 + +#define IDS_SET_FOLDER 210 diff --git a/CPP/7zip/UI/FileManager/Delete.bmp b/CPP/7zip/UI/FileManager/Delete.bmp new file mode 100755 index 00000000..d1004d82 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Delete.bmp differ diff --git a/CPP/7zip/UI/FileManager/Delete2.bmp b/CPP/7zip/UI/FileManager/Delete2.bmp new file mode 100755 index 00000000..60e08c6a Binary files /dev/null and b/CPP/7zip/UI/FileManager/Delete2.bmp differ diff --git a/CPP/7zip/UI/FileManager/EditPage.cpp b/CPP/7zip/UI/FileManager/EditPage.cpp new file mode 100755 index 00000000..06bde407 --- /dev/null +++ b/CPP/7zip/UI/FileManager/EditPage.cpp @@ -0,0 +1,91 @@ +// EditPage.cpp + +#include "StdAfx.h" +#include "EditPageRes.h" +#include "EditPage.h" + +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" +#include "Windows/CommonDialog.h" +// #include "Windows/FileFind.h" +// #include "Windows/FileDir.h" + +#include "RegistryUtils.h" +#include "HelpUtils.h" +#include "LangUtils.h" +#include "ProgramLocation.h" + +using namespace NWindows; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_EDIT_STATIC_EDITOR, 0x03010201} +}; + +static LPCWSTR kEditTopic = L"FM/options.htm#editor"; + +bool CEditPage::OnInit() +{ + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + _editorEdit.Attach(GetItem(IDC_EDIT_EDIT_EDITOR)); + UString editorPath; + ReadRegEditor(editorPath); + _editorEdit.SetText(editorPath); + return CPropertyPage::OnInit(); +} + +LONG CEditPage::OnApply() +{ + // int selectedIndex = _langCombo.GetCurSel(); + // int pathIndex = _langCombo.GetItemData(selectedIndex); + // ReloadLang(); + UString editorPath; + _editorEdit.GetText(editorPath); + SaveRegEditor(editorPath); + return PSNRET_NOERROR; +} + +void CEditPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kEditTopic); // change it +} + +bool CEditPage::OnButtonClicked(int aButtonID, HWND aButtonHWND) +{ + switch(aButtonID) + { + case IDC_EDIT_BUTTON_SET: + { + OnSetEditorButton(); + // if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, aResultPath)) + // return; + return true; + } + } + return CPropertyPage::OnButtonClicked(aButtonID, aButtonHWND); +} + +void CEditPage::OnSetEditorButton() +{ + UString editorPath; + _editorEdit.GetText(editorPath); + UString resPath; + if(!MyGetOpenFileName(HWND(*this), 0, editorPath, L"*.exe", resPath)) + return; + _editorEdit.SetText(resPath); + // Changed(); +} + +bool CEditPage::OnCommand(int code, int itemID, LPARAM param) +{ + if (code == EN_CHANGE && itemID == IDC_EDIT_EDIT_EDITOR) + { + Changed(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, param); +} + + diff --git a/CPP/7zip/UI/FileManager/EditPage.h b/CPP/7zip/UI/FileManager/EditPage.h new file mode 100755 index 00000000..26999dcf --- /dev/null +++ b/CPP/7zip/UI/FileManager/EditPage.h @@ -0,0 +1,21 @@ +// EditPage.h + +#ifndef __EDITPAGE_H +#define __EDITPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/Edit.h" + +class CEditPage: public NWindows::NControl::CPropertyPage +{ + NWindows::NControl::CEdit _editorEdit; + void OnSetEditorButton(); +public: + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnCommand(int code, int itemID, LPARAM param); + virtual LONG OnApply(); + virtual bool OnButtonClicked(int aButtonID, HWND aButtonHWND); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/EditPage.rc b/CPP/7zip/UI/FileManager/EditPage.rc new file mode 100755 index 00000000..ea261286 --- /dev/null +++ b/CPP/7zip/UI/FileManager/EditPage.rc @@ -0,0 +1,16 @@ +#include "EditPageRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +IDD_EDIT DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Editor" +MY_FONT +BEGIN + LTEXT "&Editor:", IDC_EDIT_STATIC_EDITOR, marg, marg, xSize2, 8 + EDITTEXT IDC_EDIT_EDIT_EDITOR, marg, 20, xSize2 - 12 - bDotsSize, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDC_EDIT_BUTTON_SET, (xSize - marg - bDotsSize), 20, bDotsSize, bYSize +END diff --git a/CPP/7zip/UI/FileManager/EditPageRes.h b/CPP/7zip/UI/FileManager/EditPageRes.h new file mode 100755 index 00000000..a2de1970 --- /dev/null +++ b/CPP/7zip/UI/FileManager/EditPageRes.h @@ -0,0 +1,4 @@ +#define IDD_EDIT 903 +#define IDC_EDIT_STATIC_EDITOR 1000 +#define IDC_EDIT_EDIT_EDITOR 1002 +#define IDC_EDIT_BUTTON_SET 1003 diff --git a/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp new file mode 100755 index 00000000..ef9463fb --- /dev/null +++ b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp @@ -0,0 +1,108 @@ +// EnumFormatEtc.cpp + +#include "StdAfx.h" + +#include "EnumFormatEtc.h" +#include "MyCom2.h" + +class CEnumFormatEtc : +public IEnumFORMATETC, +public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1_MT(IEnumFORMATETC) + + STDMETHOD(Next)(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched); + STDMETHOD(Skip)(ULONG celt); + STDMETHOD(Reset)(void); + STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc); + + CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats); + ~CEnumFormatEtc(); + +private: + LONG m_RefCount; + ULONG m_NumFormats; + FORMATETC *m_Formats; + ULONG m_Index; +}; + +static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src) +{ + *dest = *src; + if(src->ptd) + { + dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE)); + *(dest->ptd) = *(src->ptd); + } +} + +CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats) +{ + m_RefCount = 1; + m_Index = 0; + m_NumFormats = 0; + m_Formats = new FORMATETC[numFormats]; + if(m_Formats) + { + m_NumFormats = numFormats; + for(ULONG i = 0; i < numFormats; i++) + DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]); + } +} + +CEnumFormatEtc::~CEnumFormatEtc() +{ + if(m_Formats) + { + for(ULONG i = 0; i < m_NumFormats; i++) + if(m_Formats[i].ptd) + CoTaskMemFree(m_Formats[i].ptd); + delete[]m_Formats; + } +} + +STDMETHODIMP CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched) +{ + ULONG copied = 0; + if(celt == 0 || pFormatEtc == 0) + return E_INVALIDARG; + while(m_Index < m_NumFormats && copied < celt) + { + DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]); + copied++; + m_Index++; + } + if(pceltFetched != 0) + *pceltFetched = copied; + return (copied == celt) ? S_OK : S_FALSE; +} + +STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt) +{ + m_Index += celt; + return (m_Index <= m_NumFormats) ? S_OK : S_FALSE; +} + +STDMETHODIMP CEnumFormatEtc::Reset(void) +{ + m_Index = 0; + return S_OK; +} + +STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc) +{ + HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc); + if(hResult == S_OK) + ((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index; + return hResult; +} + +// replacement for SHCreateStdEnumFmtEtc +HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat) +{ + if(numFormats == 0 || formats == 0 || enumFormat == 0) + return E_INVALIDARG; + *enumFormat = new CEnumFormatEtc(formats, numFormats); + return (*enumFormat) ? S_OK : E_OUTOFMEMORY; +} diff --git a/CPP/7zip/UI/FileManager/EnumFormatEtc.h b/CPP/7zip/UI/FileManager/EnumFormatEtc.h new file mode 100755 index 00000000..6c476f1a --- /dev/null +++ b/CPP/7zip/UI/FileManager/EnumFormatEtc.h @@ -0,0 +1,10 @@ +// EnumFormatEtc.h + +#ifndef __ENUMFORMATETC_H +#define __ENUMFORMATETC_H + +#include + +HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat); + +#endif diff --git a/CPP/7zip/UI/FileManager/Extract.bmp b/CPP/7zip/UI/FileManager/Extract.bmp new file mode 100755 index 00000000..0aeba923 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Extract.bmp differ diff --git a/CPP/7zip/UI/FileManager/Extract2.bmp b/CPP/7zip/UI/FileManager/Extract2.bmp new file mode 100755 index 00000000..a7e57753 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Extract2.bmp differ diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp new file mode 100755 index 00000000..8b27b217 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ExtractCallback.cpp @@ -0,0 +1,440 @@ +// ExtractCallback.h + +#include "StdAfx.h" + +#include "ExtractCallback.h" + +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" +#include "Windows/Error.h" + +#include "OverwriteDialog.h" +#ifndef _NO_CRYPTO +#include "PasswordDialog.h" +#endif +#include "MessagesDialog.h" +#include "../GUI/ExtractRes.h" +#include "../GUI/resource.h" + +#include "Common/Wildcard.h" +#include "Common/StringConvert.h" + +#include "FormatUtils.h" + +#include "../../Common/FilePathAutoRename.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +CExtractCallbackImp::~CExtractCallbackImp() +{ + if (ShowMessages && !Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &Messages; + messagesDialog.Create(ParentWindow); + } +} + +void CExtractCallbackImp::Init() +{ + Messages.Clear(); + NumArchiveErrors = 0; + #ifndef _SFX + NumFolders = NumFiles = 0; + NeedAddFile = false; + #endif +} + +void CExtractCallbackImp::AddErrorMessage(LPCWSTR message) +{ + Messages.Add(message); +} + +STDMETHODIMP CExtractCallbackImp::SetNumFiles(UInt64 + #ifndef _SFX + numFiles + #endif + ) +{ + #ifndef _SFX + ProgressDialog.ProgressSynch.SetNumFilesTotal(numFiles); + #endif + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total) +{ + ProgressDialog.ProgressSynch.SetProgress(total, 0); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *value) +{ + for (;;) + { + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + if(!ProgressDialog.ProgressSynch.GetPaused()) + break; + ::Sleep(100); + } + if (value != NULL) + ProgressDialog.ProgressSynch.SetPos(*value); + return S_OK; +} + +#ifndef _SFX +STDMETHODIMP CExtractCallbackImp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + ProgressDialog.ProgressSynch.SetRatioInfo(inSize, outSize); + return S_OK; +} +#endif + +/* +STDMETHODIMP CExtractCallbackImp::SetTotalFiles(UInt64 total) +{ + ProgressDialog.ProgressSynch.SetNumFilesTotal(total); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetCompletedFiles(const UInt64 *value) +{ + if (value != NULL) + ProgressDialog.ProgressSynch.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.Time = *existTime; + dialog.OldFileInfo.SizeIsDefined = (existSize != NULL); + if (dialog.OldFileInfo.SizeIsDefined) + dialog.OldFileInfo.Size = *existSize; + dialog.OldFileInfo.Name = existName; + + if (newTime == 0) + dialog.NewFileInfo.TimeIsDefined = false; + else + { + dialog.NewFileInfo.TimeIsDefined = true; + dialog.NewFileInfo.Time = *newTime; + } + + dialog.NewFileInfo.SizeIsDefined = (newSize != NULL); + if (dialog.NewFileInfo.SizeIsDefined) + dialog.NewFileInfo.Size = *newSize; + dialog.NewFileInfo.Name = newName; + + /* + NOverwriteDialog::NResult::EEnum writeAnswer = + NOverwriteDialog::Execute(oldFileInfo, newFileInfo); + */ + INT_PTR writeAnswer = dialog.Create(NULL); // ParentWindow doesn't work with 7z + + switch(writeAnswer) + { + case IDCANCEL: + return E_ABORT; + // askResult = NAskOverwriteAnswer::kCancel; + // break; + case IDNO: + *answer = NOverwriteAnswer::kNo; + break; + case IDC_BUTTON_OVERWRITE_NO_TO_ALL: + *answer = NOverwriteAnswer::kNoToAll; + break; + case IDC_BUTTON_OVERWRITE_YES_TO_ALL: + *answer = NOverwriteAnswer::kYesToAll; + break; + case IDC_BUTTON_OVERWRITE_AUTO_RENAME: + *answer = NOverwriteAnswer::kAutoRename; + break; + case IDYES: + *answer = NOverwriteAnswer::kYes; + break; + default: + throw 20413; + } + return S_OK; +} + + +STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, bool isFolder, Int32 /* askExtractMode */, const UInt64 * /* position */) +{ + _isFolder = isFolder; + return SetCurrentFilePath2(name); +} + +STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message) +{ + AddErrorMessage(message); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *message) +{ + AddErrorMessage(message); + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 operationResult, bool encrypted) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + UINT messageID; + UInt32 langID; + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + messageID = IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD; + langID = 0x02000A91; + break; + case NArchive::NExtract::NOperationResult::kDataError: + messageID = encrypted ? + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED: + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR; + langID = encrypted ? 0x02000A94 : 0x02000A92; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + messageID = encrypted ? + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED: + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC; + langID = encrypted ? 0x02000A95 : 0x02000A93; + break; + default: + return E_FAIL; + } + if (_needWriteArchivePath) + { + AddErrorMessage(_currentArchivePath); + _needWriteArchivePath = false; + } + AddErrorMessage( + MyFormatNew(messageID, + #ifdef LANG + langID, + #endif + _currentFilePath)); + } + } + #ifndef _SFX + if (_isFolder) + NumFolders++; + else + NumFiles++; + ProgressDialog.ProgressSynch.SetNumFilesCur(NumFiles); + #endif + return S_OK; +} + +//////////////////////////////////////// +// IExtractCallbackUI + +HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name) +{ + #ifndef _SFX + ProgressDialog.ProgressSynch.SetTitleFileName(name); + #endif + _currentArchivePath = name; + return S_OK; +} + +HRESULT CExtractCallbackImp::SetCurrentFilePath2(const wchar_t *path) +{ + _currentFilePath = path; + #ifndef _SFX + ProgressDialog.ProgressSynch.SetCurrentFileName(path); + #endif + return S_OK; +} + +HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path) +{ + #ifndef _SFX + if (NeedAddFile) + NumFiles++; + NeedAddFile = true; + ProgressDialog.ProgressSynch.SetNumFilesCur(NumFiles); + #endif + return SetCurrentFilePath2(path); +} + +HRESULT CExtractCallbackImp::OpenResult(const wchar_t *name, HRESULT result, bool encrypted) +{ + if (result != S_OK) + { + MessageError(MyFormatNew(encrypted ? IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : IDS_CANT_OPEN_ARCHIVE, + #ifdef LANG + (encrypted ? 0x0200060A : 0x02000609), + #endif + name)); + NumArchiveErrors++; + } + _currentArchivePath = name; + _needWriteArchivePath = true; + return S_OK; +} + +HRESULT CExtractCallbackImp::ThereAreNoFiles() +{ + return S_OK; +} + +HRESULT CExtractCallbackImp::ExtractResult(HRESULT result) +{ + if (result == S_OK) + return result; + NumArchiveErrors++; + if (result == E_ABORT || result == ERROR_DISK_FULL) + return result; + MessageError(_currentFilePath); + MessageError(NError::MyFormatMessageW(result)); + return S_OK; +} + +HRESULT CExtractCallbackImp::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} + +STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + + Password = dialog.Password; + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + + return S_OK; +} + + +// IExtractCallBack3 +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; + /* + { + CMyComBSTR destPathResultBSTR = destPath; + *destPathResult = destPathResultBSTR.Detach(); + } + */ + *destPathResult = 0; + *writeAnswer = BoolToInt(false); + + UString destPathSpec = destPath; + UString destPathSys = destPathSpec; + bool srcIsFolderSpec = IntToBool(srcIsFolder); + CFileInfoW destFileInfo; + if (FindFile(destPathSys, destFileInfo)) + { + if (srcIsFolderSpec) + { + if (!destFileInfo.IsDirectory()) + { + UString message = UString(L"can not replace file \'") + + destPathSpec + + UString(L"\' with folder with same name"); + RINOK(MessageError(message)); + return E_ABORT; + } + *writeAnswer = BoolToInt(false); + return S_OK; + } + if (destFileInfo.IsDirectory()) + { + UString message = UString(L"can not replace folder \'") + + destPathSpec + + UString(L"\' with file with same name"); + RINOK(MessageError(message)); + return E_FAIL; + } + + switch(OverwriteMode) + { + case NExtract::NOverwriteMode::kSkipExisting: + return S_OK; + case NExtract::NOverwriteMode::kAskBefore: + { + Int32 overwiteResult; + RINOK(AskOverwrite( + destPathSpec, + &destFileInfo.LastWriteTime, &destFileInfo.Size, + srcPath, + srcTime, srcSize, + &overwiteResult)); + switch(overwiteResult) + { + case NOverwriteAnswer::kCancel: + return E_ABORT; + case NOverwriteAnswer::kNo: + return S_OK; + case NOverwriteAnswer::kNoToAll: + OverwriteMode = NExtract::NOverwriteMode::kSkipExisting; + return S_OK; + case NOverwriteAnswer::kYesToAll: + OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + break; + case NOverwriteAnswer::kYes: + break; + case NOverwriteAnswer::kAutoRename: + OverwriteMode = NExtract::NOverwriteMode::kAutoRename; + break; + default: + throw 20413; + } + } + } + if (OverwriteMode == NExtract::NOverwriteMode::kAutoRename) + { + if (!AutoRenamePath(destPathSys)) + { + UString message = UString(L"can not create name of file ") + + destPathSys; + RINOK(MessageError(message)); + return E_ABORT; + } + destPathResultTemp = destPathSys; + } + else + if (!NFile::NDirectory::DeleteFileAlways(destPathSys)) + { + UString message = UString(L"can not delete output file ") + + destPathSys; + RINOK(MessageError(message)); + return E_ABORT; + } + } + CMyComBSTR destPathResultBSTR = destPathResultTemp; + *destPathResult = destPathResultBSTR.Detach(); + *writeAnswer = BoolToInt(true); + return S_OK; +} + diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.h b/CPP/7zip/UI/FileManager/ExtractCallback.h new file mode 100755 index 00000000..13117871 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ExtractCallback.h @@ -0,0 +1,147 @@ +// ExtractCallback.h + +#ifndef __EXTRACTCALLBACK_H +#define __EXTRACTCALLBACK_H + +#include "../Agent/IFolderArchive.h" +#include "Common/MyString.h" + +#ifdef _SFX +#include "ProgressDialog.h" +#else +#include "ProgressDialog2.h" +#endif + +#include "Windows/ResourceString.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +#ifndef _NO_CRYPTO +#include "../../IPassword.h" +#endif +#include "Common/MyCom.h" +#include "IFolder.h" + +class CExtractCallbackImp: + public IExtractCallbackUI, + public IFolderOperationsExtractCallback, + // public IFolderArchiveExtractCallback, // mkultiple from IProgress + #ifndef _SFX + public ICompressProgressInfo, + #endif + #ifndef _NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public CMyUnknownImp +{ +public: + MY_QUERYINTERFACE_BEGIN2(IFolderOperationsExtractCallback) + MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback) + #ifndef _SFX + MY_QUERYINTERFACE_ENTRY(ICompressProgressInfo) + #endif + #ifndef _NO_CRYPTO + MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword) + #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + // IProgress + STDMETHOD(SetTotal)(UInt64 total); + STDMETHOD(SetCompleted)(const UInt64 *value); + + #ifndef _SFX + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); + #endif + + // IFolderArchiveExtractCallback + // STDMETHOD(SetTotalFiles)(UInt64 total); + // STDMETHOD(SetCompletedFiles)(const UInt64 *value); + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer); + STDMETHOD (PrepareOperation)(const wchar_t *name, bool isFolder, Int32 askExtractMode, const UInt64 *position); + + STDMETHOD(MessageError)(const wchar_t *message); + STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted); + + // IExtractCallbackUI + + HRESULT BeforeOpen(const wchar_t *name); + HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted); + HRESULT ThereAreNoFiles(); + HRESULT ExtractResult(HRESULT result); + + #ifndef _NO_CRYPTO + HRESULT SetPassword(const UString &password); + #endif + + // 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); + + // ICryptoGetTextPassword + #ifndef _NO_CRYPTO + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + #endif + +private: + // bool _extractMode; + UString _currentArchivePath; + bool _needWriteArchivePath; + + UString _currentFilePath; + bool _isFolder; + + // void CreateComplexDirectory(const UStringVector &aDirPathParts); + + HRESULT SetCurrentFilePath2(const wchar_t *filePath); + void AddErrorMessage(LPCWSTR message); +public: + CProgressDialog ProgressDialog; + UStringVector Messages; + bool ShowMessages; + #ifndef _SFX + UInt64 NumFolders; + UInt64 NumFiles; + bool NeedAddFile; + #endif + HWND ParentWindow; + INT_PTR StartProgressDialog(const UString &title) + { + return ProgressDialog.Create(title, ParentWindow); + } + UInt32 NumArchiveErrors; + NExtract::NOverwriteMode::EEnum OverwriteMode; + + #ifndef _NO_CRYPTO + bool PasswordIsDefined; + UString Password; + #endif + + CExtractCallbackImp(): + #ifndef _NO_CRYPTO + PasswordIsDefined(false), + #endif + OverwriteMode(NExtract::NOverwriteMode::kAskBefore), + ParentWindow(0), + ShowMessages(true) + {} + + ~CExtractCallbackImp(); + void Init(); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp new file mode 100755 index 00000000..b9a51193 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FM.cpp @@ -0,0 +1,803 @@ +// FM.cpp + +#include "StdAfx.h" + +#include "resource.h" +#include "Panel.h" + +extern "C" +{ + #include "../../../../C/Alloc.h" +} + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +// #include "Common/CommandLineParser.h" + +#include "Windows/Control/Toolbar.h" +#include "Windows/Error.h" +#include "Windows/COM.h" +#include "Windows/DLL.h" +#include "Windows/Security.h" +#include "Windows/MemoryLock.h" + +#include "ViewSettings.h" +#include "../GUI/ExtractRes.h" + +#include "App.h" +#include "StringUtils.h" + +#include "MyLoadMenu.h" +#include "LangUtils.h" +#include "FormatUtils.h" +#include "RegistryUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; +// using namespace NCommandLineParser; + +#define MAX_LOADSTRING 100 + +#define MENU_HEIGHT 26 + +#ifndef _UNICODE +bool g_IsNT = false; +#endif +HINSTANCE g_hInstance; +HWND g_HWND; +bool g_OpenArchive = false; +static UString g_MainPath; + +const int kNumDefaultPanels = 1; + +const int kSplitterWidth = 4; +int kSplitterRateMax = 1 << 16; + +// bool OnMenuCommand(HWND hWnd, int id); + +static UString GetProgramPath() +{ + UString s; + NDLL::MyGetModuleFileName(g_hInstance, s); + return s; +} + +UString GetProgramFolderPrefix() +{ + UString path = GetProgramPath(); + int pos = path.ReverseFind(L'\\'); + return path.Left(pos + 1); +} + + +class CSplitterPos +{ + int _ratio; // 10000 is max + int _pos; + int _fullWidth; + void SetRatioFromPos(HWND hWnd) + { _ratio = (_pos + kSplitterWidth / 2) * kSplitterRateMax / + MyMax(GetWidth(hWnd), 1); } +public: + int GetPos() const + { return _pos; } + int GetWidth(HWND hWnd) const + { + RECT rect; + ::GetClientRect(hWnd, &rect); + return rect.right; + } + void SetRatio(HWND hWnd, int aRatio) + { + _ratio = aRatio; + SetPosFromRatio(hWnd); + } + void SetPosPure(HWND hWnd, int pos) + { + int posMax = GetWidth(hWnd) - kSplitterWidth; + if (pos > posMax) + pos = posMax; + if (pos < 0) + pos = 0; + _pos = pos; + } + void SetPos(HWND hWnd, int pos) + { + _fullWidth = GetWidth(hWnd); + SetPosPure(hWnd, pos); + SetRatioFromPos(hWnd); + } + void SetPosFromRatio(HWND hWnd) + { + int fullWidth = GetWidth(hWnd); + if (_fullWidth != fullWidth) + { + _fullWidth = fullWidth; + SetPosPure(hWnd, GetWidth(hWnd) * _ratio / kSplitterRateMax - kSplitterWidth / 2); + } + } +}; + +bool g_CanChangeSplitter = false; +UINT32 g_SplitterPos = 0; +CSplitterPos g_Splitter; +bool g_PanelsInfoDefined = false; + +int g_StartCaptureMousePos; +int g_StartCaptureSplitterPos; + +CApp g_App; + +void MoveSubWindows(HWND hWnd); +void OnSize(HWND hWnd); + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + +const wchar_t *kWindowClass = L"FM"; + +#ifndef _UNICODE +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +// FUNCTION: InitInstance(HANDLE, int) +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + CWindow wnd; + + g_hInstance = hInstance; + + ReloadLangSmart(); + + // LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING); + + // LoadString(hInstance, IDS_APP_TITLE, title, MAX_LOADSTRING); + UString title = LangString(IDS_APP_TITLE, 0x03000000); + + /* + //If it is already running, then focus on the window + hWnd = FindWindow(windowClass, title); + if (hWnd) + { + SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01)); + return 0; + } + */ + + WNDCLASSW wc; + + // wc.style = CS_HREDRAW | CS_VREDRAW; + wc.style = 0; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FAM)); + + // wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hCursor = ::LoadCursor(0, IDC_SIZEWE); + // wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); + + wc.lpszMenuName = MAKEINTRESOURCEW(IDM_MENU); + wc.lpszClassName = kWindowClass; + + MyRegisterClass(&wc); + + // RECT rect; + // GetClientRect(hWnd, &rect); + + DWORD style = WS_OVERLAPPEDWINDOW; + // DWORD style = 0; + + RECT rect; + bool maximized = false; + int x , y, xSize, ySize; + x = y = xSize = ySize = CW_USEDEFAULT; + bool windowPosIsRead = ReadWindowSize(rect, maximized); + + if (windowPosIsRead) + { + // x = rect.left; + // y = rect.top; + xSize = rect.right - rect.left; + ySize = rect.bottom - rect.top; + } + + UINT32 numPanels, currentPanel; + g_PanelsInfoDefined = ReadPanelsInfo(numPanels, currentPanel, g_SplitterPos); + if (g_PanelsInfoDefined) + { + if (numPanels < 1 || numPanels > 2) + numPanels = kNumDefaultPanels; + if (currentPanel >= 2) + currentPanel = 0; + } + else + { + numPanels = kNumDefaultPanels; + currentPanel = 0; + } + g_App.NumPanels = numPanels; + g_App.LastFocusedPanel = currentPanel; + + if (!wnd.Create(kWindowClass, title, style, + x, y, xSize, ySize, NULL, NULL, hInstance, NULL)) + return FALSE; + g_HWND = (HWND)wnd; + + WINDOWPLACEMENT placement; + placement.length = sizeof(placement); + if (wnd.GetPlacement(&placement)) + { + if (nCmdShow == SW_SHOWNORMAL || nCmdShow == SW_SHOW || + nCmdShow == SW_SHOWDEFAULT) + { + if (maximized) + placement.showCmd = SW_SHOWMAXIMIZED; + else + placement.showCmd = SW_SHOWNORMAL; + } + else + placement.showCmd = nCmdShow; + if (windowPosIsRead) + placement.rcNormalPosition = rect; + wnd.SetPlacement(&placement); + // window.Show(nCmdShow); + } + else + wnd.Show(nCmdShow); + return TRUE; +} + +/* +static void GetCommands(const UString &aCommandLine, UString &aCommands) +{ + UString aProgramName; + aCommands.Empty(); + bool aQuoteMode = false; + for (int i = 0; i < aCommandLine.Length(); i++) + { + wchar_t aChar = aCommandLine[i]; + if (aChar == L'\"') + aQuoteMode = !aQuoteMode; + else if (aChar == L' ' && !aQuoteMode) + { + if (!aQuoteMode) + { + i++; + break; + } + } + else + aProgramName += aChar; + } + aCommands = aCommandLine.Mid(i); +} +*/ + +DWORD GetDllVersion(LPCTSTR lpszDllName) +{ + HINSTANCE hinstDll; + DWORD dwVersion = 0; + hinstDll = LoadLibrary(lpszDllName); + if(hinstDll) + { + DLLGETVERSIONPROC pDllGetVersion; + pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion"); + + /*Because some DLLs might not implement this function, you + must test for it explicitly. Depending on the particular + DLL, the lack of a DllGetVersion function can be a useful + indicator of the version. + */ + if(pDllGetVersion) + { + DLLVERSIONINFO dvi; + HRESULT hr; + + ZeroMemory(&dvi, sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + + hr = (*pDllGetVersion)(&dvi); + + if(SUCCEEDED(hr)) + { + dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion); + } + } + FreeLibrary(hinstDll); + } + return dwVersion; +} + +DWORD g_ComCtl32Version; + +/* +#ifndef _WIN64 +typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); + +static bool IsWow64() +{ + LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( + GetModuleHandle("kernel32"), "IsWow64Process"); + if (fnIsWow64Process == NULL) + return false; + BOOL isWow; + if (!fnIsWow64Process(GetCurrentProcess(),&isWow)) + return false; + return isWow != FALSE; +} +#endif +*/ + +bool IsLargePageSupported() +{ + #ifdef _WIN64 + return true; + #else + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + if (versionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || versionInfo.dwMajorVersion < 5) + return false; + if (versionInfo.dwMajorVersion > 5) + return true; + if (versionInfo.dwMinorVersion < 1) + return false; + if (versionInfo.dwMinorVersion > 1) + return true; + // return IsWow64(); + return false; + #endif +} + +static void SetMemoryLock() +{ + if (!IsLargePageSupported()) + return; + // if (ReadLockMemoryAdd()) + NSecurity::AddLockMemoryPrivilege(); + + if (ReadLockMemoryEnable()) + NSecurity::EnableLockMemoryPrivilege(); +} + +/* +static const int kNumSwitches = 1; + +namespace NKey { +enum Enum +{ + kOpenArachive = 0, +}; + +} + +static const CSwitchForm kSwitchForms[kNumSwitches] = + { + { L"SOA", NSwitchType::kSimple, false }, + }; +*/ + +// int APIENTRY WinMain2(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */); + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int nCmdShow) +{ + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + + #ifdef _WIN32 + SetLargePageSize(); + #endif + + InitCommonControls(); + + g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll")); + + // OleInitialize is required for drag and drop. + OleInitialize(NULL); + // Maybe needs CoInitializeEx also ? + // NCOM::CComInitializer comInitializer; + + UString programString, commandsString; + // MessageBoxW(0, GetCommandLineW(), L"", 0); + SplitStringToTwoStrings(GetCommandLineW(), programString, commandsString); + + commandsString.Trim(); + UString paramString, tailString; + SplitStringToTwoStrings(commandsString, paramString, tailString); + paramString.Trim(); + + if (!paramString.IsEmpty()) + { + g_MainPath = paramString; + // return WinMain2(hInstance, hPrevInstance, lpCmdLine, nCmdShow); + + // MessageBoxW(0, paramString, L"", 0); + } + /* + UStringVector commandStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + NCommandLineParser::CParser parser(kNumSwitches); + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + if(nonSwitchStrings.Size() > 1) + { + g_MainPath = nonSwitchStrings[1]; + // g_OpenArchive = parser[NKey::kOpenArachive].ThereIs; + CFileInfoW fileInfo; + if (FindFile(g_MainPath, fileInfo)) + { + if (!fileInfo.IsDirectory()) + g_OpenArchive = true; + } + } + } + catch(...) { } + */ + + + SetMemoryLock(); + + MSG msg; + if (!InitInstance (hInstance, nCmdShow)) + return FALSE; + + MyLoadMenu(g_HWND); + + #ifndef _UNICODE + if (g_IsNT) + { + HACCEL hAccels = LoadAcceleratorsW(hInstance, MAKEINTRESOURCEW(IDR_ACCELERATOR1)); + while (GetMessageW(&msg, NULL, 0, 0)) + { + if (TranslateAcceleratorW(g_HWND, hAccels, &msg) == 0) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + } + else + #endif + { + HACCEL hAccels = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); + while (GetMessage(&msg, NULL, 0, 0)) + { + if (TranslateAccelerator(g_HWND, hAccels, &msg) == 0) + { + // if (g_Hwnd != NULL || !IsDialogMessage(g_Hwnd, &msg)) + // if (!IsDialogMessage(g_Hwnd, &msg)) + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + + g_HWND = 0; + OleUninitialize(); + return (int)msg.wParam; +} + +static void SaveWindowInfo(HWND aWnd) +{ + /* + RECT rect; + if (!::GetWindowRect(aWnd, &rect)) + return; + */ + WINDOWPLACEMENT placement; + placement.length = sizeof(placement); + if (!::GetWindowPlacement(aWnd, &placement)) + return; + SaveWindowSize(placement.rcNormalPosition, + BOOLToBool(::IsZoomed(aWnd))); + SavePanelsInfo(g_App.NumPanels, g_App.LastFocusedPanel, + g_Splitter.GetPos()); +} + +void ExecuteCommand(UINT commandID) +{ + switch (commandID) + { + case kAddCommand: + g_App.AddToArchive(); + break; + case kExtractCommand: + g_App.ExtractArchives(); + break; + case kTestCommand: + g_App.TestArchives(); + break; + } +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + switch (message) + { + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + if ((HWND) lParam != NULL && wmEvent != 0) + break; + if (wmId >= kToolbarStartID) + { + ExecuteCommand(wmId); + return 0; + } + if (OnMenuCommand(hWnd, wmId)) + return 0; + break; + case WM_INITMENUPOPUP: + OnMenuActivating(hWnd, HMENU(wParam), LOWORD(lParam)); + break; + + /* + It doesn't help + case WM_EXITMENULOOP: + { + OnMenuUnActivating(hWnd); + break; + } + case WM_UNINITMENUPOPUP: + OnMenuUnActivating(hWnd, HMENU(wParam), lParam); + break; + */ + + case WM_CREATE: + { + + /* + INITCOMMONCONTROLSEX icex; + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + // Toolbar buttons used to create the first 4 buttons. + TBBUTTON tbb [ ] = + { + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + // {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + {VIEW_NEWFOLDER, ID_FILE_CREATEFOLDER, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + }; + + int baseID = 100; + NWindows::NControl::CToolBar aToolBar; + aToolBar.Attach(::CreateToolbarEx (hWnd, + WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS, // | TBSTYLE_FLAT + baseID + 2, 11, + (HINSTANCE)HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR, + (LPCTBBUTTON)&tbb, sizeof(tbb) / sizeof(tbb[0]), + 0, 0, 100, 30, sizeof (TBBUTTON))); + */ + // HCURSOR cursor = ::LoadCursor(0, IDC_SIZEWE); + // ::SetCursor(cursor); + + if (g_PanelsInfoDefined) + g_Splitter.SetPos(hWnd, g_SplitterPos); + else + { + g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2); + g_SplitterPos = g_Splitter.GetPos(); + } + + RECT rect; + ::GetClientRect(hWnd, &rect); + int xSize = rect.right; + int xSizes[2]; + xSizes[0] = g_Splitter.GetPos(); + xSizes[1] = xSize - kSplitterWidth - xSizes[0]; + if (xSizes[1] < 0) + xSizes[1] = 0; + + g_App.CreateDragTarget(); + bool archiveIsOpened; + bool encrypted; + bool needOpenFile = false; + if (!g_MainPath.IsEmpty() /* && g_OpenArchive */) + { + NFile::NFind::CFileInfoW fileInfo; + if (NFile::NFind::FindFile(g_MainPath, fileInfo)) + if (!fileInfo.IsDirectory()) + needOpenFile = true; + } + g_App.Create(hWnd, g_MainPath, xSizes, archiveIsOpened, encrypted); + + if (needOpenFile && !archiveIsOpened) + { + UString message; + if (encrypted) + message = MyFormatNew(IDS_CANT_OPEN_ENCRYPTED_ARCHIVE, 0x0200060A, g_MainPath); + else + message = MyFormatNew(IDS_CANT_OPEN_ARCHIVE, 0x02000609, g_MainPath); + MessageBoxW(0, message, L"7-zip", MB_ICONERROR); + return -1; + } + // g_SplitterPos = 0; + + // ::DragAcceptFiles(hWnd, TRUE); + RegisterDragDrop(hWnd, g_App._dropTarget); + + break; + } + case WM_DESTROY: + { + // ::DragAcceptFiles(hWnd, FALSE); + RevokeDragDrop(hWnd); + g_App._dropTarget.Release(); + + g_App.Save(); + g_App.Release(); + SaveWindowInfo(hWnd); + PostQuitMessage(0); + break; + } + /* + case WM_MOVE: + { + break; + } + */ + case WM_LBUTTONDOWN: + g_StartCaptureMousePos = LOWORD(lParam); + g_StartCaptureSplitterPos = g_Splitter.GetPos(); + ::SetCapture(hWnd); + break; + case WM_LBUTTONUP: + { + ::ReleaseCapture(); + break; + } + case WM_MOUSEMOVE: + { + if ((wParam & MK_LBUTTON) != 0 && ::GetCapture() == hWnd) + { + g_Splitter.SetPos(hWnd, g_StartCaptureSplitterPos + + (short)LOWORD(lParam) - g_StartCaptureMousePos); + MoveSubWindows(hWnd); + } + break; + } + + case WM_SIZE: + { + if (g_CanChangeSplitter) + g_Splitter.SetPosFromRatio(hWnd); + else + { + g_Splitter.SetPos(hWnd, g_SplitterPos ); + g_CanChangeSplitter = true; + } + + OnSize(hWnd); + /* + int xSize = LOWORD(lParam); + int ySize = HIWORD(lParam); + // int xSplitter = 2; + int xWidth = g_SplitPos; + // int xSplitPos = xWidth; + g_Panel[0]._listView.MoveWindow(0, 0, xWidth, ySize); + g_Panel[1]._listView.MoveWindow(xSize - xWidth, 0, xWidth, ySize); + */ + return 0; + break; + } + case WM_SETFOCUS: + // g_App.SetFocus(g_App.LastFocusedPanel); + g_App.SetFocusToLastItem(); + break; + /* + case WM_ACTIVATE: + { + int fActive = LOWORD(wParam); + switch (fActive) + { + case WA_INACTIVE: + { + // g_FocusIndex = g_App.LastFocusedPanel; + // g_App.LastFocusedPanel = g_App.GetFocusedPanelIndex(); + // return 0; + } + } + break; + } + */ + /* + case kLangWasChangedMessage: + MyLoadMenu(g_HWND); + return 0; + */ + + /* + case WM_SETTINGCHANGE: + break; + */ + case WM_NOTIFY: + { + g_App.OnNotify((int)wParam, (LPNMHDR)lParam); + break; + } + /* + case WM_DROPFILES: + { + g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam); + return 0 ; + } + */ + } + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(hWnd, message, wParam, lParam); + else + #endif + return DefWindowProc(hWnd, message, wParam, lParam); + +} + +void OnSize(HWND hWnd) +{ + /* + if (g_App._rebar) + { + RECT rect; + ::GetClientRect(hWnd, &rect); + int xSize = rect.right; + int ySize = rect.bottom; + // rect.bottom = 0; + // g_App._rebar.SizeToRect(&rect); + // g_App._rebar.Move(0, 0, xSize, ySize); + } + */ + MoveSubWindows(hWnd); +} + +void MoveSubWindows(HWND hWnd) +{ + RECT rect; + ::GetClientRect(hWnd, &rect); + int xSize = rect.right; + int kHeaderSize = 0; + int ySize = MyMax(int(rect.bottom - kHeaderSize), 0); + if (g_App._rebar) + { + RECT barRect; + g_App._rebar.GetWindowRect(&barRect); + kHeaderSize = barRect.bottom - barRect.top; + ySize = MyMax(int(rect.bottom - kHeaderSize), 0); + } + + // g_App._headerToolBar.Move(0, 2, xSize, kHeaderSize - 2); + RECT rect2 = rect; + rect2.bottom = 0; + // g_App._headerReBar.SizeToRect(&rect2); + if (g_App.NumPanels > 1) + { + g_App.Panels[0].Move(0, kHeaderSize, g_Splitter.GetPos(), ySize); + int xWidth1 = g_Splitter.GetPos() + kSplitterWidth; + g_App.Panels[1].Move(xWidth1, kHeaderSize, xSize - xWidth1, ySize); + } + else + { + /* + int otherPanel = 1 - g_App.LastFocusedPanel; + if (g_App.PanelsCreated[otherPanel]) + g_App.Panels[otherPanel].Move(0, kHeaderSize, 0, ySize); + */ + g_App.Panels[g_App.LastFocusedPanel].Move(0, kHeaderSize, xSize, ySize); + } +} diff --git a/CPP/7zip/UI/FileManager/FM.dsp b/CPP/7zip/UI/FileManager/FM.dsp new file mode 100755 index 00000000..1ba0bcf1 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FM.dsp @@ -0,0 +1,1486 @@ +# Microsoft Developer Studio Project File - Name="FM" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=FM - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "FM.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "FM.mak" CFG="FM - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "FM - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 ReleaseU" (based on "Win32 (x86) Application") +!MESSAGE "FM - Win32 DebugU" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "FM - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FM - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "FM - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "FM - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "WIN_LONG_PATH" /D "NEW_FOLDER_INTERFACE" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib Mpr.lib htmlhelp.lib Urlmon.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7zFM.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "FM - Win32 Release" +# Name "FM - Win32 Debug" +# Name "FM - Win32 ReleaseU" +# Name "FM - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\7zipLogo.ico +# End Source File +# Begin Source File + +SOURCE=.\add.bmp +# End Source File +# Begin Source File + +SOURCE=.\ClassDefs.cpp +# End Source File +# Begin Source File + +SOURCE=.\Copy.bmp +# End Source File +# Begin Source File + +SOURCE=.\Delete.bmp +# End Source File +# Begin Source File + +SOURCE=.\Extract.bmp +# End Source File +# Begin Source File + +SOURCE=.\FM.ico +# End Source File +# Begin Source File + +SOURCE=.\Move.bmp +# End Source File +# Begin Source File + +SOURCE=.\Parent.bmp +# End Source File +# Begin Source File + +SOURCE=.\Properties.bmp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# ADD BASE RSC /l 0x419 +# ADD RSC /l 0x409 +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=.\Test.bmp +# End Source File +# End Group +# Begin Group "Archive Interfaces" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Archive\IArchive.h +# End Source File +# End Group +# Begin Group "Folders" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\FSDrives.cpp +# End Source File +# Begin Source File + +SOURCE=.\FSDrives.h +# End Source File +# Begin Source File + +SOURCE=.\FSFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\FSFolder.h +# End Source File +# Begin Source File + +SOURCE=.\FSFolderCopy.cpp +# End Source File +# Begin Source File + +SOURCE=.\IFolder.h +# End Source File +# Begin Source File + +SOURCE=.\NetFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\NetFolder.h +# End Source File +# Begin Source File + +SOURCE=.\PhysDriveFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\PhysDriveFolder.h +# End Source File +# Begin Source File + +SOURCE=.\RootFolder.cpp +# End Source File +# Begin Source File + +SOURCE=.\RootFolder.h +# End Source File +# End Group +# Begin Group "Registry" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\RegistryAssociations.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryAssociations.h +# End Source File +# Begin Source File + +SOURCE=.\RegistryPlugins.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryPlugins.h +# End Source File +# Begin Source File + +SOURCE=.\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ViewSettings.cpp +# End Source File +# Begin Source File + +SOURCE=.\ViewSettings.h +# End Source File +# End Group +# Begin Group "Panel" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\App.cpp +# End Source File +# Begin Source File + +SOURCE=.\App.h +# End Source File +# Begin Source File + +SOURCE=.\AppState.h +# End Source File +# Begin Source File + +SOURCE=.\EnumFormatEtc.cpp +# End Source File +# Begin Source File + +SOURCE=.\EnumFormatEtc.h +# End Source File +# Begin Source File + +SOURCE=.\FileFolderPluginOpen.cpp +# End Source File +# Begin Source File + +SOURCE=.\FileFolderPluginOpen.h +# End Source File +# Begin Source File + +SOURCE=.\Panel.cpp +# End Source File +# Begin Source File + +SOURCE=.\Panel.h +# End Source File +# Begin Source File + +SOURCE=.\PanelCopy.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelCrc.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelDrag.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelFolderChange.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelItemOpen.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelItems.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelKey.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelListNotify.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelOperations.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSelect.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSort.cpp +# End Source File +# Begin Source File + +SOURCE=.\PanelSplitFile.cpp +# End Source File +# End Group +# Begin Group "Dialog" + +# PROP Default_Filter "" +# Begin Group "Options" + +# PROP Default_Filter "" +# Begin Group "Settings" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\SettingsPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\SettingsPage.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\EditPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\EditPage.h +# End Source File +# Begin Source File + +SOURCE=.\LangPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\LangPage.h +# End Source File +# Begin Source File + +SOURCE=.\PluginsPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginsPage.h +# End Source File +# Begin Source File + +SOURCE=.\SystemPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\SystemPage.h +# End Source File +# End Group +# Begin Group "Password" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\PasswordDialog.h +# End Source File +# End Group +# Begin Group "Progress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ProgressDialog2.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgressDialog2.h +# End Source File +# End Group +# Begin Group "About" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\AboutDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\AboutDialog.h +# End Source File +# End Group +# Begin Group "Split" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\SplitDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\SplitDialog.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ComboDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\ComboDialog.h +# End Source File +# Begin Source File + +SOURCE=CopyDialog.cpp +# End Source File +# Begin Source File + +SOURCE=CopyDialog.h +# End Source File +# Begin Source File + +SOURCE=.\ListViewDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\ListViewDialog.h +# End Source File +# Begin Source File + +SOURCE=MessagesDialog.cpp +# End Source File +# Begin Source File + +SOURCE=MessagesDialog.h +# End Source File +# Begin Source File + +SOURCE=OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=OverwriteDialog.h +# End Source File +# End Group +# Begin Group "FM Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=.\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=.\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=.\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.h +# End Source File +# End Group +# Begin Group "7-Zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\ProgressUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamObjects.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\7zCrc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Threads.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\CommandBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Edit.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ImageList.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ProgressBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ReBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Static.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\StatusBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ToolBar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Trackbar.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Window2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Window2.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Device.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDevice.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDevice.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileSystem.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Handle.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Memory.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Memory.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Net.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Net.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Process.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariant.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Security.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Security.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Thread.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Time.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Timer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CRC.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\DynamicBuffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyVector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "UI" + +# PROP Default_Filter "" +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\LoadCodecs.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\StdAfx.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.h +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\WorkDir.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Agent" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Agent\Agent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\Agent.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOpen.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFolderArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.h +# End Source File +# End Group +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "Interface" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\ICoder.h +# End Source File +# Begin Source File + +SOURCE=..\..\IDecl.h +# End Source File +# Begin Source File + +SOURCE=..\..\IPassword.h +# End Source File +# Begin Source File + +SOURCE=..\..\IProgress.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\7zFM.exe.manifest +# End Source File +# Begin Source File + +SOURCE=.\7zipLogo.ico +# End Source File +# Begin Source File + +SOURCE=.\Add2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Copy2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Delete2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Extract2.bmp +# End Source File +# Begin Source File + +SOURCE=.\FilePlugins.cpp +# End Source File +# Begin Source File + +SOURCE=.\FilePlugins.h +# End Source File +# Begin Source File + +SOURCE=.\FM.cpp +# End Source File +# Begin Source File + +SOURCE=.\Info.bmp +# End Source File +# Begin Source File + +SOURCE=.\Info2.bmp +# End Source File +# Begin Source File + +SOURCE=.\Move2.bmp +# End Source File +# Begin Source File + +SOURCE=.\MyCom2.h +# End Source File +# Begin Source File + +SOURCE=.\MyLoadMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\MyLoadMenu.h +# End Source File +# Begin Source File + +SOURCE=.\OpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallback.h +# End Source File +# Begin Source File + +SOURCE=.\OptionsDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginInterface.h +# End Source File +# Begin Source File + +SOURCE=.\PluginLoader.h +# End Source File +# Begin Source File + +SOURCE=.\PropertyName.cpp +# End Source File +# Begin Source File + +SOURCE=.\PropertyName.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\SplitUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\SplitUtils.h +# End Source File +# Begin Source File + +SOURCE=.\StringUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\StringUtils.h +# End Source File +# Begin Source File + +SOURCE=.\SysIconUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\SysIconUtils.h +# End Source File +# Begin Source File + +SOURCE=.\Test2.bmp +# End Source File +# Begin Source File + +SOURCE=.\TextPairs.cpp +# End Source File +# Begin Source File + +SOURCE=.\TextPairs.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/UI/FileManager/FM.dsw b/CPP/7zip/UI/FileManager/FM.dsw new file mode 100755 index 00000000..1c955d95 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FM.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "FM"=.\FM.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/FileManager/FM.ico b/CPP/7zip/UI/FileManager/FM.ico new file mode 100755 index 00000000..3a0a34da Binary files /dev/null and b/CPP/7zip/UI/FileManager/FM.ico differ diff --git a/CPP/7zip/UI/FileManager/FSDrives.cpp b/CPP/7zip/UI/FileManager/FSDrives.cpp new file mode 100755 index 00000000..42540287 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FSDrives.cpp @@ -0,0 +1,236 @@ +// FSDrives.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "FSDrives.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "../../PropID.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileDir.h" +#include "Windows/FileSystem.h" + +#include "SysIconUtils.h" +#include "FSFolder.h" +#include "PhysDriveFolder.h" +#include "LangUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +static const STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { L"Total Size", kpidTotalSize, VT_UI8}, + { L"Free Space", kpidFreeSpace, VT_UI8}, + { NULL, kpidType, VT_BSTR}, + { L"Label", kpidVolumeName, VT_BSTR}, + { L"File system", kpidFileSystem, VT_BSTR}, + { L"Cluster Size", kpidClusterSize, VT_UI8} +}; + +static const wchar_t *kDriveTypes[] = +{ + L"Unknown", + L"No Root Dir", + L"Removable", + L"Fixed", + L"Remote", + L"CD-ROM", + L"RAM disk" +}; + +STDMETHODIMP CFSDrives::LoadItems() +{ + _drives.Clear(); + + UStringVector driveStrings; + MyGetLogicalDriveStrings(driveStrings); + for (int i = 0; i < driveStrings.Size(); i++) + { + CDriveInfo driveInfo; + + const UString &driveName = driveStrings[i]; + + driveInfo.FullSystemName = driveName; + + driveInfo.Name = driveInfo.FullSystemName.Left( + driveInfo.FullSystemName.Length() - 1); + driveInfo.ClusterSize = 0; + driveInfo.DriveSize = 0; + driveInfo.FreeSpace = 0; + UINT driveType = NFile::NSystem::MyGetDriveType(driveName); + if (driveType < sizeof(kDriveTypes) / sizeof(kDriveTypes[0])) + { + driveInfo.Type = kDriveTypes[driveType]; + } + bool needRead = true; + if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) + { + /* + DWORD dwSerialNumber;` + if (!::GetVolumeInformation(driveInfo.FullSystemName, + NULL, 0, &dwSerialNumber, NULL, NULL, NULL, 0)) + */ + driveInfo.KnownSizes = false; + { + needRead = false; + } + } + if (needRead) + { + UString volumeName, fileSystemName; + DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags; + NFile::NSystem::MyGetVolumeInformation(driveName, + volumeName, + &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags, + fileSystemName); + driveInfo.VolumeName = volumeName; + driveInfo.FileSystemName = fileSystemName; + + NFile::NSystem::MyGetDiskFreeSpace(driveName, + driveInfo.ClusterSize, driveInfo.DriveSize, driveInfo.FreeSpace); + driveInfo.KnownSizes = true; + } + _drives.Add(driveInfo); + } + return S_OK; +} + +STDMETHODIMP CFSDrives::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _drives.Size(); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + if (itemIndex >= (UInt32)_drives.Size()) + return E_INVALIDARG; + NCOM::CPropVariant propVariant; + const CDriveInfo &driveInfo = _drives[itemIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + propVariant = driveInfo.Name; + break; + case kpidTotalSize: + if (driveInfo.KnownSizes) + propVariant = driveInfo.DriveSize; + break; + case kpidFreeSpace: + if (driveInfo.KnownSizes) + propVariant = driveInfo.FreeSpace; + break; + case kpidClusterSize: + if (driveInfo.KnownSizes) + propVariant = driveInfo.ClusterSize; + break; + case kpidType: + propVariant = driveInfo.Type; + break; + case kpidVolumeName: + propVariant = driveInfo.VolumeName; + break; + case kpidFileSystem: + propVariant = driveInfo.FileSystemName; + break; + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CFSDrives::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; + CMyComPtr subFolder = fsFolderSpec; + RINOK(fsFolderSpec->Init(name, 0)); + *resultFolder = subFolder.Detach(); + return S_OK; +} + +STDMETHODIMP CFSDrives::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + if (index >= (UInt32)_drives.Size()) + return E_INVALIDARG; + const CDriveInfo &driveInfo = _drives[index]; + if (_volumeMode) + { + *resultFolder = 0; + CPhysDriveFolder *folderSpec = new CPhysDriveFolder; + CMyComPtr subFolder = folderSpec; + RINOK(folderSpec->Init(driveInfo.Name)); + *resultFolder = subFolder.Detach(); + return S_OK; + } + return BindToFolderSpec(driveInfo.FullSystemName, resultFolder); +} + +STDMETHODIMP CFSDrives::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + return BindToFolderSpec(name, resultFolder); +} + +STDMETHODIMP CFSDrives::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + return S_OK; +} + +STDMETHODIMP CFSDrives::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CFSDrives::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + + +STDMETHODIMP CFSDrives::GetFolderProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidType: prop = L"FSDrives"; break; + case kpidPath: prop = LangString(IDS_COMPUTER, 0x03020300) + UString(L'\\'); break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + *iconIndex = 0; + const CDriveInfo &driveInfo = _drives[index]; + int iconIndexTemp; + if (GetRealIconIndex(driveInfo.FullSystemName, 0, iconIndexTemp) != 0) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + return GetLastError(); +} + diff --git a/CPP/7zip/UI/FileManager/FSDrives.h b/CPP/7zip/UI/FileManager/FSDrives.h new file mode 100755 index 00000000..527c2438 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FSDrives.h @@ -0,0 +1,49 @@ +// FSDrives.h + +#ifndef __FSDRIVES_H +#define __FSDRIVES_H + +#include "Common/MyString.h" +#include "Common/Types.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" +#include "Windows/PropVariant.h" + +#include "IFolder.h" + +struct CDriveInfo +{ + UString Name; + UString FullSystemName; + bool KnownSizes; + UInt64 DriveSize; + UInt64 FreeSpace; + UInt64 ClusterSize; + UString Type; + UString VolumeName; + UString FileSystemName; +}; + +class CFSDrives: + public IFolderFolder, + public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1( + IFolderGetSystemIconIndex + ) + + INTERFACE_FolderFolder(;) + + STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + +private: + HRESULT BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder); + CObjectVector _drives; + bool _volumeMode; +public: + void Init() { _volumeMode = false;} +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/FSFolder.cpp b/CPP/7zip/UI/FileManager/FSFolder.cpp new file mode 100755 index 00000000..9a88f674 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FSFolder.cpp @@ -0,0 +1,682 @@ +// FSFolder.cpp + +#include "StdAfx.h" + +#include "FSFolder.h" + +#include "Common/StringConvert.h" +#include "Common/StdInStream.h" +#include "Common/StdOutStream.h" +#include "Common/UTFConvert.h" +#include "Common/ComTry.h" + +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileDir.h" +#include "Windows/FileIO.h" + +#include "../../PropID.h" + +#include "SysIconUtils.h" +#include "FSDrives.h" +#include "NetFolder.h" + +namespace NWindows { +namespace NFile { + +bool GetLongPath(LPCWSTR path, UString &longPath); + +}} + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +namespace NFsFolder { + +static STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + // { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidCreationTime, VT_FILETIME}, + { NULL, kpidLastAccessTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidPackedSize, VT_UI8}, + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidPrefix, VT_BSTR} +}; + +HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder) +{ + _parentFolder = parentFolder; + _path = path; + + _findChangeNotification.FindFirst(_path, false, + FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_LAST_WRITE /*| + FILE_NOTIFY_CHANGE_LAST_ACCESS | + FILE_NOTIFY_CHANGE_CREATION | + FILE_NOTIFY_CHANGE_SECURITY */); + if (!_findChangeNotification.IsHandleAllocated()) + { + DWORD lastError = GetLastError(); + CFindFile findFile; + CFileInfoW fileInfo; + if (!findFile.FindFirst(_path + UString(L"*"), fileInfo)) + return lastError; + } + return S_OK; +} + +static HRESULT GetFolderSize(const UString &path, UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress) +{ + RINOK(progress->SetCompleted(NULL)); + numFiles = numFolders = size = 0; + CEnumeratorW enumerator(path + UString(L"\\*")); + CFileInfoW fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + { + UInt64 subFolders, subFiles, subSize; + RINOK(GetFolderSize(path + UString(L"\\") + fileInfo.Name, subFolders, subFiles, subSize, progress)); + numFolders += subFolders; + numFolders++; + numFiles += subFiles; + size += subSize; + } + else + { + numFiles++; + size += fileInfo.Size; + } + } + return S_OK; +} + +HRESULT CFSFolder::LoadSubItems(CDirItem &dirItem, const UString &path) +{ + { + CEnumeratorW enumerator(path + L"*"); + CDirItem fileInfo; + while (enumerator.Next(fileInfo)) + { + fileInfo.CompressedSizeIsDefined = false; + /* + if (!GetCompressedFileSize(_path + fileInfo.Name, + fileInfo.CompressedSize)) + fileInfo.CompressedSize = fileInfo.Size; + */ + if (fileInfo.IsDirectory()) + { + // fileInfo.Size = GetFolderSize(_path + fileInfo.Name); + fileInfo.Size = 0; + } + dirItem.Files.Add(fileInfo); + } + } + if (!_flatMode) + return S_OK; + + for (int i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + if (item.IsDirectory()) + LoadSubItems(item, path + item.Name + L'\\'); + } + return S_OK; +} + +void CFSFolder::AddRefs(CDirItem &dirItem) +{ + int i; + for (i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + item.Parent = &dirItem; + _refs.Add(&item); + } + if (!_flatMode) + return; + for (i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + if (item.IsDirectory()) + AddRefs(item); + } +} + +STDMETHODIMP CFSFolder::LoadItems() +{ + // OutputDebugString(TEXT("Start\n")); + INT32 dummy; + WasChanged(&dummy); + Clear(); + RINOK(LoadSubItems(_root, _path)); + AddRefs(_root); + + // OutputDebugString(TEXT("Finish\n")); + _commentsAreLoaded = false; + return S_OK; +} + +static const wchar_t *kDescriptionFileName = L"descript.ion"; + +bool CFSFolder::LoadComments() +{ + if (_commentsAreLoaded) + return true; + _comments.Clear(); + _commentsAreLoaded = true; + NIO::CInFile file; + if (!file.Open(_path + kDescriptionFileName)) + return false; + UInt64 length; + if (!file.GetLength(length)) + return false; + if (length >= (1 << 28)) + return false; + AString s; + char *p = s.GetBuffer((int)((size_t)length + 1)); + UInt32 processedSize; + file.Read(p, (UInt32)length, processedSize); + p[length] = 0; + s.ReleaseBuffer(); + s.Replace("\r\n", "\n"); + if (processedSize != length) + return false; + file.Close(); + UString unicodeString; + if (!ConvertUTF8ToUnicode(s, unicodeString)) + return false; + return _comments.ReadFromString(unicodeString); +} + +static bool IsAscii(const UString &testString) +{ + for (int i = 0; i < testString.Length(); i++) + if (testString[i] >= 0x80) + return false; + return true; +} + +bool CFSFolder::SaveComments() +{ + NIO::COutFile file; + if (!file.Create(_path + kDescriptionFileName, true)) + return false; + UString unicodeString; + _comments.SaveToString(unicodeString); + AString utfString; + ConvertUnicodeToUTF8(unicodeString, utfString); + UInt32 processedSize; + if (!IsAscii(unicodeString)) + { + Byte bom [] = { 0xEF, 0xBB, 0xBF, 0x0D, 0x0A }; + file.Write(bom , sizeof(bom), processedSize); + } + utfString.Replace("\n", "\r\n"); + file.Write(utfString, utfString.Length(), processedSize); + _commentsAreLoaded = false; + return true; +} + +STDMETHODIMP CFSFolder::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _refs.Size(); + return S_OK; +} + +/* +STDMETHODIMP CFSFolder::GetNumberOfSubFolders(UInt32 *numSubFolders) +{ + UInt32 numSubFoldersLoc = 0; + for (int i = 0; i < _files.Size(); i++) + if (_files[i].IsDirectory()) + numSubFoldersLoc++; + *numSubFolders = numSubFoldersLoc; + return S_OK; +} +*/ + +bool MyGetCompressedFileSizeW(LPCWSTR fileName, UInt64 &size) +{ + DWORD highPart; + DWORD lowPart = ::GetCompressedFileSizeW(fileName, &highPart); + if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR) + { + #ifdef WIN_LONG_PATH + { + UString longPath; + if (GetLongPath(fileName, longPath)) + lowPart = ::GetCompressedFileSizeW(longPath, &highPart); + } + #endif + if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR) + return false; + } + size = (UInt64(highPart) << 32) | lowPart; + return true; +} + +STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + if (itemIndex >= (UInt32)_refs.Size()) + return E_INVALIDARG; + CDirItem &fileInfo = *_refs[itemIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = fileInfo.IsDirectory(); + break; + case kpidName: + propVariant = fileInfo.Name; + break; + case kpidSize: + propVariant = fileInfo.Size; + break; + case kpidPackedSize: + if (!fileInfo.CompressedSizeIsDefined) + { + fileInfo.CompressedSizeIsDefined = true; + if (fileInfo.IsDirectory () || + !MyGetCompressedFileSizeW(_path + GetRelPath(fileInfo), fileInfo.CompressedSize)) + fileInfo.CompressedSize = fileInfo.Size; + } + propVariant = fileInfo.CompressedSize; + break; + case kpidAttributes: + propVariant = (UInt32)fileInfo.Attributes; + break; + case kpidCreationTime: + propVariant = fileInfo.CreationTime; + break; + case kpidLastAccessTime: + propVariant = fileInfo.LastAccessTime; + break; + case kpidLastWriteTime: + propVariant = fileInfo.LastWriteTime; + break; + case kpidComment: + { + LoadComments(); + UString comment; + if (_comments.GetValue(GetRelPath(fileInfo), comment)) + propVariant = comment; + break; + } + case kpidPrefix: + { + if (_flatMode) + { + propVariant = GetPrefix(fileInfo); + } + break; + } + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CFSFolder::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + CFSFolder *folderSpec = new CFSFolder; + CMyComPtr subFolder = folderSpec; + RINOK(folderSpec->Init(_path + name + UString(L'\\'), 0)); + *resultFolder = subFolder.Detach(); + return S_OK; +} + +UString CFSFolder::GetPrefix(const CDirItem &item) const +{ + UString path; + CDirItem *cur = item.Parent; + while (cur->Parent != 0) + { + path = cur->Name + UString('\\') + path; + cur = cur->Parent; + } + return path; +} + +UString CFSFolder::GetRelPath(const CDirItem &item) const +{ + return GetPrefix(item) + item.Name; +} + +STDMETHODIMP CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + const CDirItem &fileInfo = *_refs[index]; + if (!fileInfo.IsDirectory()) + return E_INVALIDARG; + return BindToFolderSpec(GetRelPath(fileInfo), resultFolder); +} + +STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + return BindToFolderSpec(name, resultFolder); +} + +STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + if (_parentFolder) + { + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + } + if (_path.IsEmpty()) + return E_INVALIDARG; + int pos = _path.ReverseFind(L'\\'); + if (pos < 0 || pos != _path.Length() - 1) + return E_FAIL; + UString parentPath = _path.Left(pos); + pos = parentPath.ReverseFind(L'\\'); + if (pos < 0) + { + parentPath.Empty(); + CFSDrives *drivesFolderSpec = new CFSDrives; + CMyComPtr drivesFolder = drivesFolderSpec; + drivesFolderSpec->Init(); + *resultFolder = drivesFolder.Detach(); + return S_OK; + } + UString parentPathReduced = parentPath.Left(pos); + parentPath = parentPath.Left(pos + 1); + pos = parentPathReduced.ReverseFind(L'\\'); + if (pos == 1) + { + if (parentPath[0] != L'\\') + return E_FAIL; + CNetFolder *netFolderSpec = new CNetFolder; + CMyComPtr netFolder = netFolderSpec; + netFolderSpec->Init(parentPath); + *resultFolder = netFolder.Detach(); + return S_OK; + } + CFSFolder *parentFolderSpec = new CFSFolder; + CMyComPtr parentFolder = parentFolderSpec; + RINOK(parentFolderSpec->Init(parentPath, 0)); + *resultFolder = parentFolder.Detach(); + return S_OK; +} + +STDMETHODIMP CFSFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + if (!_flatMode) + (*numProperties)--; + return S_OK; +} + +STDMETHODIMP CFSFolder::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + + +STDMETHODIMP CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidType: prop = L"FSFolder"; break; + case kpidPath: prop = _path; break; + } + prop.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CFSFolder::WasChanged(INT32 *wasChanged) +{ + bool wasChangedMain = false; + for (;;) + { + if (!_findChangeNotification.IsHandleAllocated()) + { + *wasChanged = BoolToInt(false); + return S_OK; + } + + DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0); + bool wasChangedLoc = (waitResult == WAIT_OBJECT_0); + if (wasChangedLoc) + { + _findChangeNotification.FindNext(); + wasChangedMain = true; + } + else + break; + } + *wasChanged = BoolToInt(wasChangedMain); + return S_OK; +} + +STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder) +{ + CFSFolder *fsFolderSpec = new CFSFolder; + CMyComPtr folderNew = fsFolderSpec; + fsFolderSpec->Init(_path, 0); + *resultFolder = folderNew.Detach(); + return S_OK; +} + +HRESULT CFSFolder::GetItemsFullSize(const UInt32 *indices, UInt32 numItems, + UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress) +{ + numFiles = numFolders = size = 0; + UInt32 i; + for (i = 0; i < numItems; i++) + { + int index = indices[i]; + if (index >= _refs.Size()) + return E_INVALIDARG; + const CDirItem &fileInfo = *_refs[index]; + if (fileInfo.IsDirectory()) + { + UInt64 subFolders, subFiles, subSize; + RINOK(GetFolderSize(_path + GetRelPath(fileInfo), subFolders, subFiles, subSize, progress)); + numFolders += subFolders; + numFolders++; + numFiles += subFiles; + size += subSize; + } + else + { + numFiles++; + size += fileInfo.Size; + } + } + return S_OK; +} + +HRESULT CFSFolder::GetItemFullSize(int index, UInt64 &size, IProgress *progress) +{ + const CDirItem &fileInfo = *_refs[index]; + if (fileInfo.IsDirectory()) + { + /* + CMyComPtr subFolder; + RINOK(BindToFolder(index, &subFolder)); + CMyComPtr aFolderReload; + subFolder.QueryInterface(&aFolderReload); + aFolderReload->Reload(); + UInt32 numItems; + RINOK(subFolder->GetNumberOfItems(&numItems)); + CMyComPtr aGetItemFullSize; + subFolder.QueryInterface(&aGetItemFullSize); + for (UInt32 i = 0; i < numItems; i++) + { + UInt64 size; + RINOK(aGetItemFullSize->GetItemFullSize(i, &size)); + *totalSize += size; + } + */ + UInt64 numFolders, numFiles; + return GetFolderSize(_path + GetRelPath(fileInfo), numFolders, numFiles, size, progress); + } + size = fileInfo.Size; + return S_OK; +} + +STDMETHODIMP CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress) +{ + NCOM::CPropVariant propVariant; + if (index >= (UInt32)_refs.Size()) + return E_INVALIDARG; + UInt64 size = 0; + HRESULT result = GetItemFullSize(index, size, progress); + propVariant = size; + propVariant.Detach(value); + return result; +} + +HRESULT CFSFolder::GetComplexName(const wchar_t *name, UString &resultPath) +{ + UString newName = name; + resultPath = _path + newName; + if (newName.Length() < 1) + return S_OK; + if (newName[0] == L'\\') + { + resultPath = newName; + return S_OK; + } + if (newName.Length() < 2) + return S_OK; + if (newName[1] == L':') + resultPath = newName; + return S_OK; +} + +STDMETHODIMP CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */) +{ + UString processedName; + RINOK(GetComplexName(name, processedName)); + if(NDirectory::MyCreateDirectory(processedName)) + return S_OK; + if(::GetLastError() == ERROR_ALREADY_EXISTS) + return ::GetLastError(); + if (!NDirectory::CreateComplexDirectory(processedName)) + return ::GetLastError(); + return S_OK; +} + +STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */) +{ + UString processedName; + RINOK(GetComplexName(name, processedName)); + NIO::COutFile outFile; + if (!outFile.Create(processedName, false)) + return ::GetLastError(); + return S_OK; +} + +STDMETHODIMP CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */) +{ + const CDirItem &fileInfo = *_refs[index]; + const UString fullPrefix = _path + GetPrefix(fileInfo); + if (!NDirectory::MyMoveFile(fullPrefix + fileInfo.Name, fullPrefix + newName)) + return GetLastError(); + return S_OK; +} + +STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress) +{ + RINOK(progress->SetTotal(numItems)); + for (UInt32 i = 0; i < numItems; i++) + { + const CDirItem &fileInfo = *_refs[indices[i]]; + const UString fullPath = _path + GetRelPath(fileInfo); + bool result; + if (fileInfo.IsDirectory()) + result = NDirectory::RemoveDirectoryWithSubItems(fullPath); + else + result = NDirectory::DeleteFileAlways(fullPath); + if (!result) + return GetLastError(); + UInt64 completed = i; + RINOK(progress->SetCompleted(&completed)); + } + return S_OK; +} + +STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID, + const PROPVARIANT *value, IProgress * /* progress */) +{ + if (index >= (UInt32)_refs.Size()) + return E_INVALIDARG; + CDirItem &fileInfo = *_refs[index]; + if (fileInfo.Parent->Parent != 0) + return E_NOTIMPL; + switch(propID) + { + case kpidComment: + { + UString filename = fileInfo.Name; + filename.Trim(); + if (value->vt == VT_EMPTY) + _comments.DeletePair(filename); + else if (value->vt == VT_BSTR) + { + CTextPair pair; + pair.ID = filename; + pair.ID.Trim(); + pair.Value = value->bstrVal; + pair.Value.Trim(); + if (pair.Value.IsEmpty()) + _comments.DeletePair(filename); + else + _comments.AddPair(pair); + } + else + return E_INVALIDARG; + SaveComments(); + break; + } + default: + return E_NOTIMPL; + } + return S_OK; +} + +STDMETHODIMP CFSFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + if (index >= (UInt32)_refs.Size()) + return E_INVALIDARG; + const CDirItem &fileInfo = *_refs[index]; + *iconIndex = 0; + int iconIndexTemp; + if (GetRealIconIndex(_path + GetRelPath(fileInfo), fileInfo.Attributes, iconIndexTemp) != 0) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + return GetLastError(); +} + +STDMETHODIMP CFSFolder::SetFlatMode(Int32 flatMode) +{ + _flatMode = IntToBool(flatMode); + return S_OK; +} + +} diff --git a/CPP/7zip/UI/FileManager/FSFolder.h b/CPP/7zip/UI/FileManager/FSFolder.h new file mode 100755 index 00000000..63de80cc --- /dev/null +++ b/CPP/7zip/UI/FileManager/FSFolder.h @@ -0,0 +1,118 @@ +// FSFolder.h + +#ifndef __FSFOLDER_H +#define __FSFOLDER_H + +#include "Common/MyString.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" +#include "Windows/PropVariant.h" + +#include "IFolder.h" + +#include "TextPairs.h" + +namespace NFsFolder { + +class CFSFolder; + +struct CFileInfoEx: public NWindows::NFile::NFind::CFileInfoW +{ + bool CompressedSizeIsDefined; + UInt64 CompressedSize; +}; + +struct CDirItem; + +struct CDirItem: public CFileInfoEx +{ + CDirItem *Parent; + CObjectVector Files; + + CDirItem(): Parent(0) {} + void Clear() + { + Files.Clear(); + Parent = 0; + } +}; + +class CFSFolder: + public IFolderFolder, + public IFolderWasChanged, + public IFolderOperations, + // public IFolderOperationsDeleteToRecycleBin, + public IFolderGetItemFullSize, + public IFolderClone, + public IFolderGetSystemIconIndex, + public IFolderSetFlatMode, + public CMyUnknownImp +{ + UInt64 GetSizeOfItem(int anIndex) const; +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IFolderWasChanged) + // MY_QUERYINTERFACE_ENTRY(IFolderOperationsDeleteToRecycleBin) + MY_QUERYINTERFACE_ENTRY(IFolderOperations) + MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize) + MY_QUERYINTERFACE_ENTRY(IFolderClone) + MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex) + MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + + INTERFACE_FolderFolder(;) + INTERFACE_FolderOperations(;) + + STDMETHOD(WasChanged)(INT32 *wasChanged); + STDMETHOD(Clone)(IFolderFolder **resultFolder); + STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress); + + STDMETHOD(SetFlatMode)(Int32 flatMode); + + STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + +private: + UString _path; + CDirItem _root; + CRecordVector _refs; + + CMyComPtr _parentFolder; + + bool _commentsAreLoaded; + CPairsStorage _comments; + + bool _flatMode; + + NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification; + + HRESULT GetItemsFullSize(const UInt32 *indices, UInt32 numItems, + UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress); + HRESULT GetItemFullSize(int index, UInt64 &size, IProgress *progress); + HRESULT GetComplexName(const wchar_t *name, UString &resultPath); + HRESULT BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder); + + bool LoadComments(); + bool SaveComments(); + HRESULT LoadSubItems(CDirItem &dirItem, const UString &path); + void AddRefs(CDirItem &dirItem); +public: + HRESULT Init(const UString &path, IFolderFolder *parentFolder); + + CFSFolder() : _flatMode(false) {} + + UString GetPrefix(const CDirItem &item) const; + UString GetRelPath(const CDirItem &item) const; + UString GetRelPath(UInt32 index) const { return GetRelPath(*_refs[index]); } + + void Clear() + { + _root.Clear(); + _refs.Clear(); + } +}; + +} + +#endif diff --git a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp new file mode 100755 index 00000000..1a1b2250 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp @@ -0,0 +1,475 @@ +// FSFolderCopy.cpp + +#include "StdAfx.h" + +#include + +#include "FSFolder.h" +#include "Windows/FileDir.h" +#include "Windows/Error.h" + +#include "Common/StringConvert.h" + +#include "../../Common/FilePathAutoRename.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NFsFolder { + +/* +static bool IsItWindows2000orHigher() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) && + (versionInfo.dwMajorVersion >= 5); +} +*/ + +struct CProgressInfo +{ + UInt64 StartPos; + IProgress *Progress; +}; + +static DWORD CALLBACK CopyProgressRoutine( + LARGE_INTEGER /* TotalFileSize */, // file size + LARGE_INTEGER TotalBytesTransferred, // bytes transferred + LARGE_INTEGER /* StreamSize */, // bytes in stream + LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream + DWORD /* dwStreamNumber */, // current stream + DWORD /* dwCallbackReason */, // callback reason + HANDLE /* hSourceFile */, // handle to source file + HANDLE /* hDestinationFile */, // handle to destination file + LPVOID lpData // from CopyFileEx +) +{ + CProgressInfo &progressInfo = *(CProgressInfo *)lpData; + UInt64 completed = progressInfo.StartPos + TotalBytesTransferred.QuadPart; + if (progressInfo.Progress->SetCompleted(&completed) != S_OK) + return PROGRESS_CANCEL; + return PROGRESS_CONTINUE; +} + +typedef BOOL (WINAPI * CopyFileExPointer)( + IN LPCSTR lpExistingFileName, + IN LPCSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN LPBOOL pbCancel OPTIONAL, + IN DWORD dwCopyFlags + ); + +typedef BOOL (WINAPI * CopyFileExPointerW)( + IN LPCWSTR lpExistingFileName, + IN LPCWSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN LPBOOL pbCancel OPTIONAL, + IN DWORD dwCopyFlags + ); + +#ifndef _UNICODE +static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } +static CSysString GetSysPath(LPCWSTR sysPath) + { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); } +#endif + +static bool MyCopyFile(LPCWSTR existingFile, LPCWSTR newFile, IProgress *progress, UInt64 &completedSize) +{ + CProgressInfo progressInfo; + progressInfo.Progress = progress; + progressInfo.StartPos = completedSize; + BOOL CancelFlag = FALSE; + #ifndef _UNICODE + if (g_IsNT) + #endif + { + CopyFileExPointerW copyFunctionW = (CopyFileExPointerW) + ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), + "CopyFileExW"); + if (copyFunctionW == 0) + return false; + if (copyFunctionW(existingFile, newFile, CopyProgressRoutine, + &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS)) + return true; + #ifdef WIN_LONG_PATH + UString longPathExisting, longPathNew; + if (!NDirectory::GetLongPaths(existingFile, newFile, longPathExisting, longPathNew)) + return false; + if (copyFunctionW(longPathExisting, longPathNew, CopyProgressRoutine, + &progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS)) + return true; + #endif + return false; + } + #ifndef _UNICODE + else + { + CopyFileExPointer copyFunction = (CopyFileExPointer) + ::GetProcAddress(::GetModuleHandleA("kernel32.dll"), + "CopyFileExA"); + if (copyFunction != 0) + { + if (copyFunction(GetSysPath(existingFile), GetSysPath(newFile), + CopyProgressRoutine,&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS)) + return true; + if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return false; + } + return BOOLToBool(::CopyFile(GetSysPath(existingFile), GetSysPath(newFile), TRUE)); + } + #endif +} + +typedef BOOL (WINAPI * MoveFileWithProgressPointer)( + IN LPCWSTR lpExistingFileName, + IN LPCWSTR lpNewFileName, + IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, + IN LPVOID lpData OPTIONAL, + IN DWORD dwFlags + ); + +static bool MyMoveFile(LPCWSTR existingFile, LPCWSTR newFile, IProgress *progress, UInt64 &completedSize) +{ + // if (IsItWindows2000orHigher()) + // { + CProgressInfo progressInfo; + progressInfo.Progress = progress; + progressInfo.StartPos = completedSize; + + MoveFileWithProgressPointer moveFunction = (MoveFileWithProgressPointer) + ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), + "MoveFileWithProgressW"); + if (moveFunction != 0) + { + if (moveFunction( + existingFile, newFile, CopyProgressRoutine, + &progressInfo, MOVEFILE_COPY_ALLOWED)) + return true; + if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + { + #ifdef WIN_LONG_PATH + UString longPathExisting, longPathNew; + if (!NDirectory::GetLongPaths(existingFile, newFile, longPathExisting, longPathNew)) + return false; + if (moveFunction(longPathExisting, longPathNew, CopyProgressRoutine, + &progressInfo, MOVEFILE_COPY_ALLOWED)) + return true; + #endif + if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return false; + } + } + // } + // else + return NDirectory::MyMoveFile(existingFile, newFile); +} + +static HRESULT MyCopyFile( + const UString &srcPath, + const CFileInfoW &srcFileInfo, + const UString &destPathSpec, + IFolderOperationsExtractCallback *callback, + UInt64 &completedSize) +{ + UString destPath = destPathSpec; + if (destPath.CompareNoCase(srcPath) == 0) + { + UString message = UString(L"can not move file \'") + destPath + UString(L"\' onto itself"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + + INT32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(callback->AskWrite( + srcPath, + BoolToInt(false), + &srcFileInfo.LastWriteTime, &srcFileInfo.Size, + destPath, + &destPathResult, + &writeAskResult)); + if (IntToBool(writeAskResult)) + { + UString destPathNew = UString(destPathResult); + RINOK(callback->SetCurrentFilePath(srcPath)); + if (!MyCopyFile(srcPath, destPathNew, callback, completedSize)) + { + UString message = NError::MyFormatMessageW(GetLastError()) + + UString(L" \'") + + UString(destPathNew) + + UString(L"\'"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + } + completedSize += srcFileInfo.Size; + return callback->SetCompleted(&completedSize); +} + +static HRESULT CopyFolder( + const UString &srcPath, + const UString &destPathSpec, + IFolderOperationsExtractCallback *callback, + UInt64 &completedSize) +{ + RINOK(callback->SetCompleted(&completedSize)); + + UString destPath = destPathSpec; + int len = srcPath.Length(); + if (destPath.Length() >= len && srcPath.CompareNoCase(destPath.Left(len)) == 0) + { + if (destPath.Length() == len || destPath[len] == L'\\') + { + UString message = UString(L"can not copy folder \'") + + destPath + UString(L"\' onto itself"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + } + + if (!NDirectory::CreateComplexDirectory(destPath)) + { + UString message = UString(L"can not create folder ") + destPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + CEnumeratorW enumerator(srcPath + UString(L"\\*")); + CFileInfoEx fileInfo; + while (enumerator.Next(fileInfo)) + { + const UString srcPath2 = srcPath + UString(L"\\") + fileInfo.Name; + const UString destPath2 = destPath + UString(L"\\") + fileInfo.Name; + if (fileInfo.IsDirectory()) + { + RINOK(CopyFolder(srcPath2, destPath2, callback, completedSize)); + } + else + { + RINOK(MyCopyFile(srcPath2, fileInfo, destPath2, callback, completedSize)); + } + } + return S_OK; +} + +STDMETHODIMP CFSFolder::CopyTo(const UInt32 *indices, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback) +{ + if (numItems == 0) + return S_OK; + + UInt64 numFolders, numFiles, totalSize; + GetItemsFullSize(indices, numItems, numFolders, numFiles, totalSize, callback); + RINOK(callback->SetTotal(totalSize)); + RINOK(callback->SetNumFiles(numFiles)); + + UString destPath = path; + if (destPath.IsEmpty()) + return E_INVALIDARG; + bool directName = (destPath[destPath.Length() - 1] != L'\\'); + if (directName) + { + if (numItems > 1) + return E_INVALIDARG; + } + /* + // doesn't work in network + else + if (!NDirectory::CreateComplexDirectory(destPath))) + { + DWORD lastError = ::GetLastError(); + UString message = UString(L"can not create folder ") + + destPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + */ + + UInt64 completedSize = 0; + RINOK(callback->SetCompleted(&completedSize)); + for (UInt32 i = 0; i < numItems; i++) + { + const CDirItem &fileInfo = *_refs[indices[i]]; + UString destPath2 = destPath; + if (!directName) + destPath2 += fileInfo.Name; + UString srcPath = _path + GetPrefix(fileInfo) + fileInfo.Name; + if (fileInfo.IsDirectory()) + { + RINOK(CopyFolder(srcPath, destPath2, callback, completedSize)); + } + else + { + RINOK(MyCopyFile(srcPath, fileInfo, destPath2, callback, completedSize)); + } + } + return S_OK; +} + +///////////////////////////////////////////////// +// Move Operations + +HRESULT MyMoveFile( + const UString &srcPath, + const CFileInfoW &srcFileInfo, + const UString &destPathSpec, + IFolderOperationsExtractCallback *callback, + UInt64 &completedSize) +{ + UString destPath = destPathSpec; + if (destPath.CompareNoCase(srcPath) == 0) + { + UString message = UString(L"can not move file \'") + + destPath + + UString(L"\' onto itself"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + + INT32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(callback->AskWrite( + srcPath, + BoolToInt(false), + &srcFileInfo.LastWriteTime, &srcFileInfo.Size, + destPath, + &destPathResult, + &writeAskResult)); + if (IntToBool(writeAskResult)) + { + UString destPathNew = UString(destPathResult); + RINOK(callback->SetCurrentFilePath(srcPath)); + if (!MyMoveFile(srcPath, destPathNew, callback, completedSize)) + { + UString message = UString(L"can not move to file ") + destPathNew; + RINOK(callback->ShowMessage(message)); + } + } + completedSize += srcFileInfo.Size; + RINOK(callback->SetCompleted(&completedSize)); + return S_OK; +} + +HRESULT MyMoveFolder( + const UString &srcPath, + const UString &destPathSpec, + IFolderOperationsExtractCallback *callback, + UInt64 &completedSize) +{ + UString destPath = destPathSpec; + int len = srcPath.Length(); + if (destPath.Length() >= len && srcPath.CompareNoCase(destPath.Left(len)) == 0) + { + if (destPath.Length() == len || destPath[len] == L'\\') + { + UString message = UString(L"can not move folder \'") + + destPath + UString(L"\' onto itself"); + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + } + + if (MyMoveFile(srcPath, destPath, callback, completedSize)) + return S_OK; + + if (!NDirectory::CreateComplexDirectory(destPath)) + { + UString message = UString(L"can not create folder ") + destPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + { + CEnumeratorW enumerator(srcPath + UString(L"\\*")); + CFileInfoEx fileInfo; + while (enumerator.Next(fileInfo)) + { + const UString srcPath2 = srcPath + UString(L"\\") + fileInfo.Name; + const UString destPath2 = destPath + UString(L"\\") + fileInfo.Name; + if (fileInfo.IsDirectory()) + { + RINOK(MyMoveFolder(srcPath2, destPath2, callback, completedSize)); + } + else + { + RINOK(MyMoveFile(srcPath2, fileInfo, destPath2, callback, completedSize)); + } + } + } + if (!NDirectory::MyRemoveDirectory(srcPath)) + { + UString message = UString(L"can not remove folder") + srcPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + return S_OK; +} + +STDMETHODIMP CFSFolder::MoveTo( + const UInt32 *indices, + UInt32 numItems, + const wchar_t *path, + IFolderOperationsExtractCallback *callback) +{ + if (numItems == 0) + return S_OK; + + UInt64 numFolders, numFiles, totalSize; + GetItemsFullSize(indices, numItems, numFolders, numFiles, totalSize, callback); + RINOK(callback->SetTotal(totalSize)); + RINOK(callback->SetNumFiles(numFiles)); + + UString destPath = path; + if (destPath.IsEmpty()) + return E_INVALIDARG; + bool directName = (destPath[destPath.Length() - 1] != L'\\'); + if (directName) + { + if (numItems > 1) + return E_INVALIDARG; + } + else + if (!NDirectory::CreateComplexDirectory(destPath)) + { + UString message = UString(L"can not create folder ") + + destPath; + RINOK(callback->ShowMessage(message)); + return E_ABORT; + } + + UInt64 completedSize = 0; + RINOK(callback->SetCompleted(&completedSize)); + for (UInt32 i = 0; i < numItems; i++) + { + const CDirItem &fileInfo = *_refs[indices[i]]; + UString destPath2 = destPath; + if (!directName) + destPath2 += fileInfo.Name; + UString srcPath = _path + GetPrefix(fileInfo) + fileInfo.Name; + if (fileInfo.IsDirectory()) + { + RINOK(MyMoveFolder(srcPath, destPath2, callback, completedSize)); + } + else + { + RINOK(MyMoveFile(srcPath, fileInfo, destPath2, callback, completedSize)); + } + } + return S_OK; +} + +STDMETHODIMP CFSFolder::CopyFrom(const wchar_t * /* fromFolderPath */, + const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} + +} diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp new file mode 100755 index 00000000..a3a19414 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp @@ -0,0 +1,114 @@ +// FileFolderPluginOpen.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/DLL.h" + +#include "IFolder.h" +#include "RegistryAssociations.h" +#include "RegistryPlugins.h" + +#include "OpenCallback.h" +#include "PluginLoader.h" +#include "../Agent/Agent.h" + +using namespace NWindows; +using namespace NRegistryAssociations; + +static int FindPlugin(const CObjectVector &plugins, + const UString &pluginName) +{ + for (int i = 0; i < plugins.Size(); i++) + if (plugins[i].Name.CompareNoCase(pluginName) == 0) + return i; + return -1; +} + +HRESULT OpenFileFolderPlugin( + const UString &path, + HMODULE *module, + IFolderFolder **resultFolder, + HWND parentWindow, + bool &encrypted) +{ + encrypted = false; + CObjectVector plugins; + ReadFileFolderPluginInfoList(plugins); + + UString extension; + UString name, pureName, dot; + + if(!NFile::NDirectory::GetOnlyName(path, name)) + return E_FAIL; + NFile::NName::SplitNameToPureNameAndExtension(name, pureName, dot, extension); + + + int slashPos = path.ReverseFind(L'\\'); + UString dirPrefix; + UString fileName; + if (slashPos >= 0) + { + dirPrefix = path.Left(slashPos + 1); + fileName = path.Mid(slashPos + 1); + } + else + fileName = path; + + if (!extension.IsEmpty()) + { + CExtInfo extInfo; + if (ReadInternalAssociation(extension, extInfo)) + { + for (int i = extInfo.Plugins.Size() - 1; i >= 0; i--) + { + int pluginIndex = FindPlugin(plugins, extInfo.Plugins[i]); + if (pluginIndex >= 0) + { + const CPluginInfo plugin = plugins[pluginIndex]; + plugins.Delete(pluginIndex); + plugins.Insert(0, plugin); + } + } + } + } + + for (int i = 0; i < plugins.Size(); i++) + { + const CPluginInfo &plugin = plugins[i]; + if (!plugin.ClassIDDefined) + continue; + CPluginLibrary library; + CMyComPtr folderManager; + CMyComPtr folder; + if (plugin.FilePath.IsEmpty()) + folderManager = new CArchiveFolderManager; + else if (library.LoadAndCreateManager(plugin.FilePath, plugin.ClassID, &folderManager) != S_OK) + continue; + + COpenArchiveCallback *openCallbackSpec = new COpenArchiveCallback; + CMyComPtr openCallback = openCallbackSpec; + openCallbackSpec->PasswordIsDefined = false; + openCallbackSpec->ParentWindow = parentWindow; + openCallbackSpec->LoadFileInfo(dirPrefix, fileName); + HRESULT result = folderManager->OpenFolderFile(path, &folder, openCallback); + if (openCallbackSpec->PasswordWasAsked) + encrypted = true; + if (result == S_OK) + { + *module = library.Detach(); + *resultFolder = folder.Detach(); + return S_OK; + } + continue; + + /* + if (result != S_FALSE) + return result; + */ + } + return S_FALSE; +} \ No newline at end of file diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h new file mode 100755 index 00000000..295048a9 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h @@ -0,0 +1,9 @@ +// FileFolderPluginOpen.h + +#ifndef __FILEFOLDERPLUGINOPEN_H +#define __FILEFOLDERPLUGINOPEN_H + +HRESULT OpenFileFolderPlugin(const UString &path, + HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow, bool &encrypted); + +#endif diff --git a/CPP/7zip/UI/FileManager/FilePlugins.cpp b/CPP/7zip/UI/FileManager/FilePlugins.cpp new file mode 100755 index 00000000..1812312e --- /dev/null +++ b/CPP/7zip/UI/FileManager/FilePlugins.cpp @@ -0,0 +1,112 @@ +// FilePlugins.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" + +#include "IFolder.h" +#include "FilePlugins.h" +#include "StringUtils.h" +#include "PluginLoader.h" +#include "../Agent/Agent.h" + +using namespace NRegistryAssociations; + +int CExtDatabase::FindExtInfoBig(const UString &ext) +{ + for (int i = 0; i < ExtBigItems.Size(); i++) + if (ExtBigItems[i].Ext.CompareNoCase(ext) == 0) + return i; + return -1; +} + +int CExtDatabase::FindPlugin(const UString &plugin) +{ + for (int i = 0; i < Plugins.Size(); i++) + if (Plugins[i].Name.CompareNoCase(plugin) == 0) + return i; + return -1; +} + +void CExtDatabase::Read() +{ + CObjectVector extItems; + ReadInternalAssociations(extItems); + ReadFileFolderPluginInfoList(Plugins); + for (int i = 0; i < extItems.Size(); i++) + { + const CExtInfo &extInfo = extItems[i]; + CExtInfoBig extInfoBig; + extInfoBig.Ext = extInfo.Ext; + extInfoBig.Associated = false; + for (int p = 0; p < extInfo.Plugins.Size(); p++) + { + int pluginIndex = FindPlugin(extInfo.Plugins[p]); + if (pluginIndex >= 0) + extInfoBig.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, true)); + } + ExtBigItems.Add(extInfoBig); + } + for (int pluginIndex = 0; pluginIndex < Plugins.Size(); pluginIndex++) + { + const CPluginInfo &pluginInfo = Plugins[pluginIndex]; + + CPluginLibrary pluginLibrary; + CMyComPtr folderManager; + + if (pluginInfo.FilePath.IsEmpty()) + folderManager = new CArchiveFolderManager; + else if (pluginLibrary.LoadAndCreateManager(pluginInfo.FilePath, + pluginInfo.ClassID, &folderManager) != S_OK) + continue; + CMyComBSTR extBSTR; + if (folderManager->GetExtensions(&extBSTR) != S_OK) + return; + const UString ext2 = (const wchar_t *)extBSTR; + UStringVector exts; + SplitString(ext2, exts); + for (int i = 0; i < exts.Size(); i++) + { + const UString &ext = exts[i]; + int index = FindExtInfoBig(ext); + if (index < 0) + { + CExtInfoBig extInfo; + extInfo.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, false)); + extInfo.Associated = false; + extInfo.Ext = ext; + ExtBigItems.Add(extInfo); + } + else + { + CExtInfoBig &extInfo = ExtBigItems[index]; + int pluginIndexIndex = extInfo.FindPlugin(pluginIndex); + if (pluginIndexIndex < 0) + extInfo.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, false)); + } + } + } +} + +void CExtDatabase::Save() +{ + CObjectVector extItems; + for (int i = 0; i < ExtBigItems.Size(); i++) + { + const CExtInfoBig &extInfoBig = ExtBigItems[i]; + CExtInfo extInfo; + // extInfo.Enabled = extInfoBig.Associated; + extInfo.Ext = extInfoBig.Ext; + for (int p = 0; p < extInfoBig.PluginsPairs.Size(); p++) + { + CPluginEnabledPair pluginPair = extInfoBig.PluginsPairs[p]; + if (pluginPair.Enabled) + extInfo.Plugins.Add(Plugins[pluginPair.Index].Name); + } + extItems.Add(extInfo); + } + WriteInternalAssociations(extItems); +} + + diff --git a/CPP/7zip/UI/FileManager/FilePlugins.h b/CPP/7zip/UI/FileManager/FilePlugins.h new file mode 100755 index 00000000..1becb9d1 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FilePlugins.h @@ -0,0 +1,54 @@ +// FilePlugins.h + +#ifndef __FILEPLUGINS_H +#define __FILEPLUGINS_H + +#include "RegistryPlugins.h" +#include "RegistryAssociations.h" + +struct CPluginEnabledPair +{ + int Index; + bool Enabled; + CPluginEnabledPair(int index, bool enabled): Index(index),Enabled(enabled) {} +}; + +struct CExtInfoBig +{ + UString Ext; + bool Associated; + CRecordVector PluginsPairs; + int FindPlugin(int pluginIndex) + { + for (int i = 0; i < PluginsPairs.Size(); i++) + if (PluginsPairs[i].Index == pluginIndex) + return i; + return -1; + } +}; + +class CExtDatabase +{ +public: + CObjectVector ExtBigItems; + CObjectVector Plugins; + int FindExtInfoBig(const UString &ext); + int FindPlugin(const UString &plugin); + + UString GetMainPluginNameForExtItem(int extIndex) const + { + const CExtInfoBig &extInfo = ExtBigItems[extIndex]; + if (extInfo.PluginsPairs.IsEmpty()) + return UString(); + else + return Plugins[extInfo.PluginsPairs.Front().Index].Name; + } + + void Read(); + void Save(); +}; + + +#endif + + diff --git a/CPP/7zip/UI/FileManager/FormatUtils.cpp b/CPP/7zip/UI/FileManager/FormatUtils.cpp new file mode 100755 index 00000000..553d8bcd --- /dev/null +++ b/CPP/7zip/UI/FileManager/FormatUtils.cpp @@ -0,0 +1,40 @@ +// FormatUtils.cpp + +#include "StdAfx.h" + +#include "FormatUtils.h" +#include "Common/IntToString.h" +#include "Windows/ResourceString.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +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, + #ifdef LANG + UInt32 langID, + #endif + const UString &argument) +{ + return MyFormatNew( + #ifdef LANG + LangString(resourceID, langID), + #else + NWindows::MyLoadStringW(resourceID), + #endif + argument); +} diff --git a/CPP/7zip/UI/FileManager/FormatUtils.h b/CPP/7zip/UI/FileManager/FormatUtils.h new file mode 100755 index 00000000..35536871 --- /dev/null +++ b/CPP/7zip/UI/FileManager/FormatUtils.h @@ -0,0 +1,18 @@ +// FormatUtils.h + +#ifndef __FORMATUTILS_H +#define __FORMATUTILS_H + +#include "Common/Types.h" +#include "Common/MyString.h" + +UString NumberToString(UInt64 number); + +UString MyFormatNew(const UString &format, const UString &argument); +UString MyFormatNew(UINT resourceID, + #ifdef LANG + UInt32 langID, + #endif + const UString &argument); + +#endif diff --git a/CPP/7zip/UI/FileManager/HelpUtils.cpp b/CPP/7zip/UI/FileManager/HelpUtils.cpp new file mode 100755 index 00000000..c2bf49a5 --- /dev/null +++ b/CPP/7zip/UI/FileManager/HelpUtils.cpp @@ -0,0 +1,23 @@ +// HelpUtils.cpp + +#include "StdAfx.h" + +#include + +#include "Common/StringConvert.h" +#include "HelpUtils.h" +#include "ProgramLocation.h" + +static LPCWSTR kHelpFileName = L"7-zip.chm::/"; + +void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile) +{ + UString path; + if (!::GetProgramFolderPath(path)) + return; + path += kHelpFileName; + path += topicFile; + HtmlHelp(hwnd, GetSystemString(path), HH_DISPLAY_TOPIC, NULL); +} + + diff --git a/CPP/7zip/UI/FileManager/HelpUtils.h b/CPP/7zip/UI/FileManager/HelpUtils.h new file mode 100755 index 00000000..2a7b85af --- /dev/null +++ b/CPP/7zip/UI/FileManager/HelpUtils.h @@ -0,0 +1,10 @@ +// HelpUtils.h + +#ifndef __HELPUTILS_H +#define __HELPUTILS_H + +#include "Common/MyString.h" + +void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile); + +#endif diff --git a/CPP/7zip/UI/FileManager/IFolder.h b/CPP/7zip/UI/FileManager/IFolder.h new file mode 100755 index 00000000..fdd9fa3c --- /dev/null +++ b/CPP/7zip/UI/FileManager/IFolder.h @@ -0,0 +1,145 @@ +// IFolder.h + +#ifndef __IFOLDER_H +#define __IFOLDER_H + +#include "../../IProgress.h" + +#define FOLDER_INTERFACE_SUB(i, b, x) DECL_INTERFACE_SUB(i, b, 8, x) +#define FOLDER_INTERFACE(i, x) FOLDER_INTERFACE_SUB(i, IUnknown, x) + +namespace NPlugin +{ + enum + { + kName = 0, + kType, + kClassID, + kOptionsClassID + }; +} + +#define INTERFACE_FolderFolder(x) \ + STDMETHOD(LoadItems)() x; \ + STDMETHOD(GetNumberOfItems)(UInt32 *numItems) x; \ + STDMETHOD(GetProperty)(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(BindToFolder)(UInt32 index, IFolderFolder **resultFolder) x; \ + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder) x; \ + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder) x; \ + STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties) x; \ + STDMETHOD(GetPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ + STDMETHOD(GetFolderProperty)(PROPID propID, PROPVARIANT *value) x; \ + +FOLDER_INTERFACE(IFolderFolder, 0x00) +{ + INTERFACE_FolderFolder(PURE) +}; + +FOLDER_INTERFACE(IFolderWasChanged, 0x04) +{ + STDMETHOD(WasChanged)(Int32 *wasChanged) PURE; +}; + +FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x0B) +{ + // STDMETHOD(SetTotalFiles)(UInt64 total) PURE; + // STDMETHOD(SetCompletedFiles)(const UInt64 *completedValue) PURE; + STDMETHOD(AskWrite)( + const wchar_t *srcPath, + Int32 srcIsFolder, + const FILETIME *srcTime, + const UInt64 *srcSize, + const wchar_t *destPathRequest, + BSTR *destPathResult, + Int32 *writeAnswer) PURE; + STDMETHOD(ShowMessage)(const wchar_t *message) PURE; + STDMETHOD(SetCurrentFilePath)(const wchar_t *filePath) PURE; + STDMETHOD(SetNumFiles)(UInt64 numFiles) PURE; +}; + +#define INTERFACE_FolderOperations(x) \ + STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress) x; \ + STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress) x; \ + STDMETHOD(Rename)(UInt32 index, const wchar_t *newName, IProgress *progress) x; \ + STDMETHOD(Delete)(const UInt32 *indices, UInt32 numItems, IProgress *progress) x; \ + STDMETHOD(CopyTo)(const UInt32 *indices, UInt32 numItems, \ + const wchar_t *path, IFolderOperationsExtractCallback *callback) x; \ + STDMETHOD(MoveTo)(const UInt32 *indices, UInt32 numItems, \ + const wchar_t *path, IFolderOperationsExtractCallback *callback) x; \ + STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath, \ + const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress) x; \ + STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) x; \ + +FOLDER_INTERFACE(IFolderOperations, 0x06) +{ + INTERFACE_FolderOperations(PURE) +}; + +/* +FOLDER_INTERFACE2(IFolderOperationsDeleteToRecycleBin, 0x06, 0x03) +{ + STDMETHOD(DeleteToRecycleBin)(const UInt32 *indices, UInt32 numItems, IProgress *progress) PURE; +}; +*/ + +FOLDER_INTERFACE(IFolderGetSystemIconIndex, 0x07) +{ + STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex) PURE; +}; + +FOLDER_INTERFACE(IFolderGetItemFullSize, 0x08) +{ + STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress) PURE; +}; + +FOLDER_INTERFACE(IFolderClone, 0x09) +{ + STDMETHOD(Clone)(IFolderFolder **resultFolder) PURE; +}; + +FOLDER_INTERFACE(IFolderSetFlatMode, 0x0A) +{ + STDMETHOD(SetFlatMode)(Int32 flatMode) PURE; +}; + +#define INTERFACE_FolderProperties(x) \ + STDMETHOD(GetNumberOfFolderProperties)(UInt32 *numProperties) x; \ + STDMETHOD(GetFolderPropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; \ + +FOLDER_INTERFACE(IFolderProperties, 0x0B) +{ + INTERFACE_FolderProperties(PURE) +}; + +#define INTERFACE_IFolderArchiveProperties(x) \ + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) x; \ + STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties) x; \ + STDMETHOD(GetArchivePropertyInfo)(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) x; + +FOLDER_INTERFACE(IFolderArchiveProperties, 0x0C) +{ + INTERFACE_IFolderArchiveProperties(PURE) +}; + +FOLDER_INTERFACE(IGetFolderArchiveProperties, 0x0D) +{ + STDMETHOD(GetFolderArchiveProperties)(IFolderArchiveProperties **object) PURE; +}; + +#define FOLDER_MANAGER_INTERFACE(i, x) DECL_INTERFACE(i, 9, x) + +#define INTERFACE_IFolderManager(x) \ + STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress) x; \ + STDMETHOD(GetExtensions)(BSTR *extensions) x; \ + STDMETHOD(GetIconPath)(const wchar_t *ext, BSTR *iconPath, Int32 *iconIndex) x; \ + + // STDMETHOD(GetTypes)(BSTR *types) PURE; + // STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress) PURE; + +FOLDER_MANAGER_INTERFACE(IFolderManager, 0x03) +{ + INTERFACE_IFolderManager(PURE); +}; + + +#endif diff --git a/CPP/7zip/UI/FileManager/Info.bmp b/CPP/7zip/UI/FileManager/Info.bmp new file mode 100755 index 00000000..d769a661 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Info.bmp differ diff --git a/CPP/7zip/UI/FileManager/Info2.bmp b/CPP/7zip/UI/FileManager/Info2.bmp new file mode 100755 index 00000000..af724d27 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Info2.bmp differ diff --git a/CPP/7zip/UI/FileManager/LangPage.cpp b/CPP/7zip/UI/FileManager/LangPage.cpp new file mode 100755 index 00000000..3300213b --- /dev/null +++ b/CPP/7zip/UI/FileManager/LangPage.cpp @@ -0,0 +1,90 @@ +// LangPage.cpp + +#include "StdAfx.h" +#include "LangPageRes.h" +#include "LangPage.h" + +#include "Common/StringConvert.h" + +#include "Windows/ResourceString.h" + +#include "RegistryUtils.h" +#include "HelpUtils.h" +#include "LangUtils.h" + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_LANG_STATIC_LANG, 0x01000401} +}; + +static LPCWSTR kLangTopic = L"fm/options.htm#language"; + +bool CLangPage::OnInit() +{ + _langWasChanged = false; + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + _langCombo.Attach(GetItem(IDC_LANG_COMBO_LANG)); + + UString s = NWindows::MyLoadStringW(IDS_LANG_ENGLISH); + s += L" ("; + s += NWindows::MyLoadStringW(IDS_LANG_NATIVE); + s += L")"; + int index = (int)_langCombo.AddString(s); + _langCombo.SetItemData(index, _paths.Size()); + _paths.Add(L"-"); + _langCombo.SetCurSel(0); + + CObjectVector langs; + LoadLangs(langs); + for (int i = 0; i < langs.Size(); i++) + { + const CLangEx &lang = langs[i]; + UString name; + UString englishName, nationalName; + if (lang.Lang.GetMessage(0x00000000, englishName)) + name = englishName; + else + name = lang.ShortName; + if (lang.Lang.GetMessage(0x00000001, nationalName)) + { + if (!nationalName.IsEmpty()) + { + name += L" ("; + name += nationalName; + name += L")"; + } + } + index = (int)_langCombo.AddString(name); + _langCombo.SetItemData(index, _paths.Size()); + _paths.Add(lang.ShortName); + if (g_LangID.CompareNoCase(lang.ShortName) == 0) + _langCombo.SetCurSel(index); + } + return CPropertyPage::OnInit(); +} + +LONG CLangPage::OnApply() +{ + int selectedIndex = _langCombo.GetCurSel(); + int pathIndex = (int)_langCombo.GetItemData(selectedIndex); + SaveRegLang(_paths[pathIndex]); + ReloadLang(); + _langWasChanged = true; + return PSNRET_NOERROR; +} + +void CLangPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kLangTopic); // change it +} + +bool CLangPage::OnCommand(int code, int itemID, LPARAM param) +{ + if (code == CBN_SELCHANGE && itemID == IDC_LANG_COMBO_LANG) + { + Changed(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, param); +} diff --git a/CPP/7zip/UI/FileManager/LangPage.h b/CPP/7zip/UI/FileManager/LangPage.h new file mode 100755 index 00000000..b28d6984 --- /dev/null +++ b/CPP/7zip/UI/FileManager/LangPage.h @@ -0,0 +1,21 @@ +// LangPage.h + +#ifndef __LANGPAGE_H +#define __LANGPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/ComboBox.h" + +class CLangPage: public NWindows::NControl::CPropertyPage +{ + NWindows::NControl::CComboBox _langCombo; + UStringVector _paths; +public: + bool _langWasChanged; + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnCommand(int code, int itemID, LPARAM param); + virtual LONG OnApply(); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/LangPage.rc b/CPP/7zip/UI/FileManager/LangPage.rc new file mode 100755 index 00000000..0e06406c --- /dev/null +++ b/CPP/7zip/UI/FileManager/LangPage.rc @@ -0,0 +1,21 @@ +#include "LangPageRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 238 +#define ySize2 204 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +IDD_LANG DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Language" +MY_FONT +BEGIN + LTEXT "Language:", IDC_LANG_STATIC_LANG, marg, marg, xSize2, 8 + COMBOBOX IDC_LANG_COMBO_LANG, marg, 20, 146, ySize2 - 12, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP +END + +STRINGTABLE +BEGIN + IDS_LANG_ENGLISH "English" + IDS_LANG_NATIVE "English" +END diff --git a/CPP/7zip/UI/FileManager/LangPageRes.h b/CPP/7zip/UI/FileManager/LangPageRes.h new file mode 100755 index 00000000..39571e53 --- /dev/null +++ b/CPP/7zip/UI/FileManager/LangPageRes.h @@ -0,0 +1,6 @@ +#define IDD_LANG 900 +#define IDS_LANG_ENGLISH 995 +#define IDS_LANG_NATIVE 996 + +#define IDC_LANG_STATIC_LANG 1000 +#define IDC_LANG_COMBO_LANG 1001 diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp new file mode 100755 index 00000000..f41e764e --- /dev/null +++ b/CPP/7zip/UI/FileManager/LangUtils.cpp @@ -0,0 +1,207 @@ +// LangUtils.cpp + +#include "StdAfx.h" + +#include "LangUtils.h" +#include "Common/StringConvert.h" +#include "Common/StringToInt.h" +#include "Windows/Synchronization.h" +#include "Windows/Window.h" +#include "Windows/FileFind.h" +#include "RegistryUtils.h" +#include "ProgramLocation.h" + +using namespace NWindows; + +static CLang g_Lang; +UString g_LangID; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +void ReloadLang() +{ + ReadRegLang(g_LangID); + g_Lang.Clear(); + if (!g_LangID.IsEmpty() && g_LangID != L"-") + { + UString langPath = g_LangID; + if (langPath.Find('\\') < 0) + { + if (langPath.Find('.') < 0) + langPath += L".txt"; + UString folderPath; + if (GetProgramFolderPath(folderPath)) + langPath = folderPath + UString(L"Lang\\") + langPath; + } + g_Lang.Open(GetSystemString(langPath)); + } +} + +static bool g_Loaded = false; +static NSynchronization::CCriticalSection g_CriticalSection; + +void LoadLangOneTime() +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + if (g_Loaded) + return; + g_Loaded = true; + ReloadLang(); +} + +void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems) +{ + for (int i = 0; i < numItems; i++) + { + const CIDLangPair &idLangPair = idLangPairs[i]; + UString message; + if (g_Lang.GetMessage(idLangPair.LangID, message)) + { + NWindows::CWindow window(GetDlgItem(dialogWindow, idLangPair.ControlID)); + window.SetText(message); + } + } +} + +void LangSetWindowText(HWND window, UInt32 langID) +{ + UString message; + if (g_Lang.GetMessage(langID, message)) + MySetWindowText(window, message); +} + +UString LangString(UInt32 langID) +{ + UString message; + if (g_Lang.GetMessage(langID, message)) + return message; + return UString(); +} + +UString LangString(UINT resourceID, UInt32 langID) +{ + UString message; + if (g_Lang.GetMessage(langID, message)) + return message; + return NWindows::MyLoadStringW(resourceID); +} + +void LoadLangs(CObjectVector &langs) +{ + langs.Clear(); + UString folderPath; + if (!::GetProgramFolderPath(folderPath)) + return; + folderPath += L"Lang\\"; + NWindows::NFile::NFind::CEnumeratorW enumerator(folderPath + L"*.txt"); + NWindows::NFile::NFind::CFileInfoW fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + continue; + CLangEx lang; + UString filePath = folderPath + fileInfo.Name; + const int kExtSize = 4; + if (fileInfo.Name.Right(kExtSize) != L".txt") + continue; + lang.ShortName = fileInfo.Name.Left(fileInfo.Name.Length() - kExtSize); + if (lang.Lang.Open(GetSystemString(filePath))) + langs.Add(lang); + } +} + +bool SplidID(const UString &id, WORD &primID, WORD &subID) +{ + primID = 0; + subID = 0; + const wchar_t *start = id; + const wchar_t *end; + UInt64 value = ConvertStringToUInt64(start, &end); + if (start == end) + return false; + primID = (WORD)value; + if (*end == 0) + return true; + if (*end != L'-') + return false; + start = end + 1; + value = ConvertStringToUInt64(start, &end); + if (start == end) + return false; + subID = (WORD)value; + return (*end == 0); +} + +typedef LANGID (WINAPI *GetUserDefaultUILanguageP)(); + +void FindMatchLang(UString &shortName) +{ + shortName.Empty(); + + LANGID SystemDefaultLangID = GetSystemDefaultLangID(); // Lang for non-Unicode in XP64 + LANGID UserDefaultLangID = GetUserDefaultLangID(); // Standarts and formats in XP64 + + if (SystemDefaultLangID != UserDefaultLangID) + return; + LANGID langID = UserDefaultLangID; + /* + LANGID SystemDefaultUILanguage; // english in XP64 + LANGID UserDefaultUILanguage; // english in XP64 + + GetUserDefaultUILanguageP fn = (GetUserDefaultUILanguageP)GetProcAddress( + GetModuleHandle("kernel32"), "GetUserDefaultUILanguage"); + if (fn != NULL) + UserDefaultUILanguage = fn(); + fn = (GetUserDefaultUILanguageP)GetProcAddress( + GetModuleHandle("kernel32"), "GetSystemDefaultUILanguage"); + if (fn != NULL) + SystemDefaultUILanguage = fn(); + */ + + WORD primLang = (WORD)(PRIMARYLANGID(langID)); + WORD subLang = (WORD)(SUBLANGID(langID)); + CObjectVector langs; + LoadLangs(langs); + for (int i = 0; i < langs.Size(); i++) + { + const CLangEx &lang = langs[i]; + UString id; + if (lang.Lang.GetMessage(0x00000002, id)) + { + WORD primID; + WORD subID; + if (SplidID(id, primID, subID)) + if (primID == primLang) + { + if (subID == 0) + shortName = lang.ShortName; + if (subLang == subID) + { + shortName = lang.ShortName; + return; + } + } + } + } +} + +void ReloadLangSmart() +{ + #ifndef _UNICODE + if (g_IsNT) + #endif + { + ReadRegLang(g_LangID); + if (g_LangID.IsEmpty()) + { + UString shortName; + FindMatchLang(shortName); + if (shortName.IsEmpty()) + shortName = L"-"; + SaveRegLang(shortName); + } + } + ReloadLang(); +} diff --git a/CPP/7zip/UI/FileManager/LangUtils.h b/CPP/7zip/UI/FileManager/LangUtils.h new file mode 100755 index 00000000..40debdfe --- /dev/null +++ b/CPP/7zip/UI/FileManager/LangUtils.h @@ -0,0 +1,41 @@ +// LangUtils.h + +#ifndef __LANGUTILS_H +#define __LANGUTILS_H + +#include "Common/Lang.h" +#include "Windows/ResourceString.h" + +extern UString g_LangID; + +struct CIDLangPair +{ + int ControlID; + UInt32 LangID; +}; + +void ReloadLang(); +void LoadLangOneTime(); +void ReloadLangSmart(); + +struct CLangEx +{ + CLang Lang; + UString ShortName; +}; + +void LoadLangs(CObjectVector &langs); + +void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems); +void LangSetWindowText(HWND window, UInt32 langID); + +UString LangString(UInt32 langID); +UString LangString(UINT resourceID, UInt32 langID); + +#ifdef LANG +#define LangStringSpec(resourceID, langID) LangString(resourceID, langID) +#else +#define LangStringSpec(resourceID, langID) NWindows::MyLoadStringW(resourceID) +#endif + +#endif diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp new file mode 100755 index 00000000..67423501 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp @@ -0,0 +1,100 @@ +// ListViewDialog.cpp + +#include "StdAfx.h" +#include "ListViewDialog.h" + +#ifdef LANG +#include "LangUtils.h" +static CIDLangPair kIDLangPairs[] = +{ + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 } +}; +#endif + +bool CListViewDialog::OnInit() +{ + #ifdef LANG + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _listView.Attach(GetItem(IDC_LISTVIEW_LIST)); + SetText(Title); + + LVCOLUMN columnInfo; + columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; + columnInfo.fmt = LVCFMT_LEFT; + columnInfo.iSubItem = 0; + columnInfo.cx = 1000; + + _listView.InsertColumn(0, &columnInfo); + + for(int i = 0; i < Strings.Size(); i++) + { + LVITEMW item; + item.mask = LVIF_TEXT; + item.iItem = i; + item.pszText = (LPWSTR)(LPCWSTR)Strings[i]; + item.iSubItem = 0; + _listView.InsertItem(&item); + } + if (Strings.Size() > 0) + _listView.SetItemState(0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); + StringsWereChanged = false; + return CModalDialog::OnInit(); +} + +bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) +{ + if (header->hwndFrom != _listView) + return false; + switch(header->code) + { + case LVN_KEYDOWN: + { + LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); + switch(keyDownInfo->wVKey) + { + case VK_DELETE: + { + if (!DeleteIsAllowed) + return false; + int focusedIndex = _listView.GetFocusedItem(); + if (focusedIndex < 0) + focusedIndex = 0; + for (;;) + { + int index = _listView.GetNextSelectedItem(-1); + if (index < 0) + break; + StringsWereChanged = true; + _listView.DeleteItem(index); + Strings.Delete(index); + } + if (focusedIndex >= _listView.GetItemCount()) + focusedIndex = _listView.GetItemCount() - 1; + if (focusedIndex >= 0) + _listView.SetItemState(focusedIndex, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); + return true; + } + case 'A': + { + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + if (ctrl) + { + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + _listView.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); + return true; + } + } + } + } + } + return false; +} + +void CListViewDialog::OnOK() +{ + FocusedItemIndex = _listView.GetFocusedItem(); + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.h b/CPP/7zip/UI/FileManager/ListViewDialog.h new file mode 100755 index 00000000..57375c8b --- /dev/null +++ b/CPP/7zip/UI/FileManager/ListViewDialog.h @@ -0,0 +1,30 @@ +// ListViewDialog.h + +#ifndef __LISTVIEWDIALOG_H +#define __LISTVIEWDIALOG_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ListView.h" +#include "ListViewDialogRes.h" + +class CListViewDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CListView _listView; + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnNotify(UINT controlID, LPNMHDR header); + +public: + UString Title; + bool DeleteIsAllowed; + UStringVector Strings; + bool StringsWereChanged; + int FocusedItemIndex; + + INT_PTR Create(HWND wndParent = 0) { return CModalDialog::Create(IDD_DIALOG_LISTVIEW, wndParent); } + + CListViewDialog(): DeleteIsAllowed(false) {} + +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.rc b/CPP/7zip/UI/FileManager/ListViewDialog.rc new file mode 100755 index 00000000..e83f3330 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ListViewDialog.rc @@ -0,0 +1,26 @@ +#include "ListViewDialogRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 342 +#define ySize2 220 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + +IDD_DIALOG_LISTVIEW DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "ListView" +MY_FONT +BEGIN + CONTROL "List1", IDC_LISTVIEW_LIST, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | + LVS_AUTOARRANGE | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP, + marg, marg, xSize2, ySize2 - bYSize - 10 + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END + + diff --git a/CPP/7zip/UI/FileManager/ListViewDialogRes.h b/CPP/7zip/UI/FileManager/ListViewDialogRes.h new file mode 100755 index 00000000..440d14b0 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ListViewDialogRes.h @@ -0,0 +1,3 @@ +#define IDD_DIALOG_LISTVIEW 201 + +#define IDC_LISTVIEW_LIST 1000 diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.cpp b/CPP/7zip/UI/FileManager/MessagesDialog.cpp new file mode 100755 index 00000000..57879d64 --- /dev/null +++ b/CPP/7zip/UI/FileManager/MessagesDialog.cpp @@ -0,0 +1,100 @@ +// MessagesDialog.cpp + +#include "StdAfx.h" +#include "MessagesDialog.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Windows/ResourceString.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDOK, 0x02000713 } +}; +#endif + +void CMessagesDialog::AddMessageDirect(LPCWSTR message) +{ + int itemIndex = _messageList.GetItemCount(); + LVITEMW item; + item.mask = LVIF_TEXT; + item.iItem = itemIndex; + + wchar_t sz[32]; + ConvertInt64ToString(itemIndex, sz); + + item.pszText = sz; + item.iSubItem = 0; + _messageList.InsertItem(&item); + + item.pszText = (LPWSTR)message; + item.iSubItem = 1; + _messageList.SetItem(&item); +} + +void CMessagesDialog::AddMessage(LPCWSTR message) +{ + UString s = message; + while (!s.IsEmpty()) + { + int pos = s.Find(L'\n'); + if (pos < 0) + break; + AddMessageDirect(s.Left(pos)); + s.Delete(0, pos + 1); + } + AddMessageDirect(s); +} + +bool CMessagesDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000A00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _messageList.Attach(GetItem(IDC_MESSAGE_LIST)); + _messageList.SetUnicodeFormat(true); + + LVCOLUMNW columnInfo; + columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + columnInfo.fmt = LVCFMT_LEFT; + columnInfo.pszText = L"#"; + columnInfo.iSubItem = 0; + columnInfo.cx = 30; + + _messageList.InsertColumn(0, &columnInfo); + + + columnInfo.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + columnInfo.fmt = LVCFMT_LEFT; + UString s = + #ifdef LANG + LangString(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN, 0x02000A80); + #else + MyLoadStringW(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN); + #endif + + columnInfo.pszText = (LPWSTR)(LPCWSTR)s; + columnInfo.iSubItem = 1; + columnInfo.cx = 600; + + _messageList.InsertColumn(1, &columnInfo); + + for(int i = 0; i < Messages->Size(); i++) + AddMessage((*Messages)[i]); + + /* + if(_messageList.GetItemCount() > 0) + { + UINT aState = LVIS_SELECTED | LVIS_FOCUSED; + _messageList.SetItemState(0, aState, aState); + } + */ + return CModalDialog::OnInit(); +} diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.h b/CPP/7zip/UI/FileManager/MessagesDialog.h new file mode 100755 index 00000000..6df0d46c --- /dev/null +++ b/CPP/7zip/UI/FileManager/MessagesDialog.h @@ -0,0 +1,22 @@ +// MessagesDialog.h + +#ifndef __MESSAGESDIALOG_H +#define __MESSAGESDIALOG_H + +#include "MessagesDialogRes.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ListView.h" + +class CMessagesDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CListView _messageList; + void AddMessageDirect(LPCWSTR message); + void AddMessage(LPCWSTR message); + virtual bool OnInit(); +public: + const UStringVector *Messages; + INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_DIALOG_MESSAGES, parent); } +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.rc b/CPP/7zip/UI/FileManager/MessagesDialog.rc new file mode 100755 index 00000000..fdefb172 --- /dev/null +++ b/CPP/7zip/UI/FileManager/MessagesDialog.rc @@ -0,0 +1,25 @@ +#include "MessagesDialogRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 430 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) +#define bXPos (xSize - marg - bXSize) +#define bYPos (ySize - marg - bYSize) + + +IDD_DIALOG_MESSAGES DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "7-Zip: Diagnostic messages" +MY_FONT +BEGIN + DEFPUSHBUTTON "&Close", IDOK, bXPos, bYPos, bXSize, bYSize + CONTROL "List1",IDC_MESSAGE_LIST,"SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + marg, marg, xSize2, ySize2 - bYSize - 6 +END + +STRINGTABLE +BEGIN + IDS_MESSAGES_DIALOG_MESSAGE_COLUMN "Message" +END diff --git a/CPP/7zip/UI/FileManager/MessagesDialogRes.h b/CPP/7zip/UI/FileManager/MessagesDialogRes.h new file mode 100755 index 00000000..39d49f57 --- /dev/null +++ b/CPP/7zip/UI/FileManager/MessagesDialogRes.h @@ -0,0 +1,3 @@ +#define IDS_MESSAGES_DIALOG_MESSAGE_COLUMN 503 +#define IDD_DIALOG_MESSAGES 503 +#define IDC_MESSAGE_LIST 1000 diff --git a/CPP/7zip/UI/FileManager/Move.bmp b/CPP/7zip/UI/FileManager/Move.bmp new file mode 100755 index 00000000..eb5f20f9 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Move.bmp differ diff --git a/CPP/7zip/UI/FileManager/Move2.bmp b/CPP/7zip/UI/FileManager/Move2.bmp new file mode 100755 index 00000000..58679eff Binary files /dev/null and b/CPP/7zip/UI/FileManager/Move2.bmp differ diff --git a/CPP/7zip/UI/FileManager/MyCom2.h b/CPP/7zip/UI/FileManager/MyCom2.h new file mode 100755 index 00000000..756a8169 --- /dev/null +++ b/CPP/7zip/UI/FileManager/MyCom2.h @@ -0,0 +1,48 @@ +// MyCom2.h + +#ifndef __MYCOM2_H +#define __MYCOM2_H + +#include "Common/MyCom.h" + +#define MY_ADDREF_RELEASE_MT \ +STDMETHOD_(ULONG, AddRef)() { InterlockedIncrement((LONG *)&__m_RefCount); return __m_RefCount; } \ +STDMETHOD_(ULONG, Release)() { InterlockedDecrement((LONG *)&__m_RefCount); if (__m_RefCount != 0) \ + return __m_RefCount; delete this; return 0; } + +#define MY_UNKNOWN_IMP_SPEC_MT(i) \ + MY_QUERYINTERFACE_BEGIN \ + MY_QUERYINTERFACE_ENTRY(IUnknown) \ + i \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE_MT + +#define MY_UNKNOWN_IMP_SPEC_MT2(i1, i) \ + MY_QUERYINTERFACE_BEGIN \ + if (iid == IID_IUnknown) \ + { *outObject = (void *)(IUnknown *)(i1 *)this; AddRef(); return S_OK; } i \ + MY_QUERYINTERFACE_END \ + MY_ADDREF_RELEASE_MT + + +#define MY_UNKNOWN_IMP_MT MY_UNKNOWN_IMP_SPEC_MT(;) + +#define MY_UNKNOWN_IMP1_MT(i) MY_UNKNOWN_IMP_SPEC_MT2( \ + i, \ + MY_QUERYINTERFACE_ENTRY(i) \ + ) + +#define MY_UNKNOWN_IMP2_MT(i1, i2) MY_UNKNOWN_IMP_SPEC_MT2( \ + i1, \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + ) + +#define MY_UNKNOWN_IMP3_MT(i1, i2, i3) MY_UNKNOWN_IMP_SPEC_MT2( \ + i1, \ + MY_QUERYINTERFACE_ENTRY(i1) \ + MY_QUERYINTERFACE_ENTRY(i2) \ + MY_QUERYINTERFACE_ENTRY(i3) \ + ) + +#endif diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp new file mode 100755 index 00000000..a2a6c202 --- /dev/null +++ b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp @@ -0,0 +1,694 @@ +// MyLoadMenu + +#include "StdAfx.h" + +#include "Common/StringConvert.h" + +#include "Windows/Menu.h" +#include "Windows/Error.h" + +#include "../../PropID.h" + +#include "resource.h" +#include "App.h" +#include "AboutDialog.h" +#include "../Common/CompressCall.h" + +#include "HelpUtils.h" +#include "LangUtils.h" +#include "PluginInterface.h" + +static const UINT kOpenBookmarkMenuID = 730; +static const UINT kSetBookmarkMenuID = 740; + +extern HINSTANCE g_hInstance; + +static LPCWSTR kFMHelpTopic = L"FM/index.htm"; + +extern void OptionsDialog(HWND hwndOwner, HINSTANCE hInstance); + +using namespace NWindows; + +static const int kFileMenuIndex = 0; +static const int kViewMenuIndex = 2; +static const int kBookmarksMenuIndex = kViewMenuIndex + 1; + +struct CStringLangPair +{ + wchar_t *String; + UINT32 LangID; +}; + +static CStringLangPair kStringLangPairs[] = +{ + { L"&File", 0x03000102 }, + { L"&Edit", 0x03000103 }, + { L"&View", 0x03000104 }, + { L"&Bookmarks", 0x03000107 }, + { L"&Tools", 0x03000105 }, + { L"&Help", 0x03000106 }, +}; + +UINT32 kAddToFavoritesLangID = 0x03000710; +UINT32 kToolbarsLangID = 0x03000451; + +/* +static int FindStringLangItem(const UString &anItem) +{ + for (int i = 0; i < sizeof(kStringLangPairs) / + sizeof(kStringLangPairs[0]); i++) + if (anItem.CompareNoCase(kStringLangPairs[i].String) == 0) + return i; + return -1; +} +*/ + +static CIDLangPair kIDLangPairs[] = +{ + // File + { IDM_FILE_OPEN, 0x03000210 }, + { IDM_FILE_OPEN_INSIDE, 0x03000211 }, + { IDM_FILE_OPEN_OUTSIDE, 0x03000212 }, + { IDM_FILE_VIEW, 0x03000220 }, + { IDM_FILE_EDIT, 0x03000221 }, + { IDM_RENAME, 0x03000230 }, + { IDM_COPY_TO, 0x03000231 }, + { IDM_MOVE_TO, 0x03000232 }, + { IDM_DELETE, 0x03000233 }, + { IDM_FILE_PROPERTIES, 0x03000240 }, + { IDM_FILE_COMMENT, 0x03000241 }, + { IDM_FILE_CRC, 0x03000242 }, + { IDM_FILE_SPLIT, 0x03000270 }, + { IDM_FILE_COMBINE, 0x03000271 }, + { IDM_CREATE_FOLDER, 0x03000250 }, + { IDM_CREATE_FILE, 0x03000251 }, + { IDCLOSE, 0x03000260 }, + + // Edit + { IDM_EDIT_CUT, 0x03000320 }, + { IDM_EDIT_COPY, 0x03000321 }, + { IDM_EDIT_PASTE, 0x03000322 }, + + { IDM_SELECT_ALL, 0x03000330 }, + { IDM_DESELECT_ALL, 0x03000331 }, + { IDM_INVERT_SELECTION, 0x03000332 }, + { IDM_SELECT, 0x03000333 }, + { IDM_DESELECT, 0x03000334 }, + { IDM_SELECT_BY_TYPE, 0x03000335 }, + { IDM_DESELECT_BY_TYPE, 0x03000336 }, + + { IDM_VIEW_LARGE_ICONS, 0x03000410 }, + { IDM_VIEW_SMALL_ICONS, 0x03000411 }, + { IDM_VIEW_LIST, 0x03000412 }, + { IDM_VIEW_DETAILS, 0x03000413 }, + + { IDM_VIEW_ARANGE_BY_NAME, 0x02000204 }, + { IDM_VIEW_ARANGE_BY_TYPE, 0x02000214 }, + { IDM_VIEW_ARANGE_BY_DATE, 0x0200020C }, + { IDM_VIEW_ARANGE_BY_SIZE, 0x02000207 }, + { IDM_VIEW_ARANGE_NO_SORT, 0x03000420 }, + + { IDM_OPEN_ROOT_FOLDER, 0x03000430 }, + { IDM_OPEN_PARENT_FOLDER, 0x03000431 }, + { IDM_FOLDERS_HISTORY, 0x03000432 }, + + { IDM_VIEW_REFRESH, 0x03000440 }, + + { IDM_VIEW_FLAT_VIEW, 0x03000449 }, + { IDM_VIEW_TWO_PANELS, 0x03000450 }, + { IDM_VIEW_ARCHIVE_TOOLBAR, 0x03000460 }, + { IDM_VIEW_STANDARD_TOOLBAR, 0x03000461 }, + { IDM_VIEW_TOOLBARS_LARGE_BUTTONS, 0x03000462 }, + { IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, 0x03000463 }, + + { IDM_OPTIONS, 0x03000510 }, + { IDM_BENCHMARK, 0x03000511 }, + + { IDM_HELP_CONTENTS, 0x03000610 }, + { IDM_ABOUT, 0x03000620 } +}; + + +static int FindLangItem(int ControlID) +{ + for (int i = 0; i < sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]); i++) + if (kIDLangPairs[i].ControlID == ControlID) + return i; + return -1; +} + + +/* +static bool g_IsNew_fMask = true; + +class CInit_fMask +{ +public: + CInit_fMask() + { + g_IsNew_fMask = false; + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + if (::GetVersionEx(&vi)) + { + g_IsNew_fMask = (vi.dwMajorVersion > 4 || + (vi.dwMajorVersion == 4 && vi.dwMinorVersion > 0)); + } + g_IsNew_fMask = false; + } +} g_Init_fMask; + +// it's hack for supporting Windows NT +// constants are from WinUser.h + +#if(WINVER < 0x0500) +#define MIIM_STRING 0x00000040 +#define MIIM_BITMAP 0x00000080 +#define MIIM_FTYPE 0x00000100 +#endif + +static UINT Get_fMaskForString() +{ + return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE; +} + +static UINT Get_fMaskForFTypeAndString() +{ + return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE; +} +*/ + +static UINT Get_fMaskForString() +{ + return MIIM_TYPE; +} + +static UINT Get_fMaskForFTypeAndString() +{ + return MIIM_TYPE; +} + + + +static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex) +{ + CMenu menu; + menu.Attach(menuLoc); + for (int i = 0; i < menu.GetItemCount(); i++) + { + CMenuItem item; + item.fMask = Get_fMaskForString() | MIIM_SUBMENU | MIIM_ID; + item.fType = MFT_STRING; + if (menu.GetItem(i, true, item)) + { + UString newString; + if (item.hSubMenu) + { + if (level == 1 && menuIndex == kBookmarksMenuIndex) + newString = LangString(kAddToFavoritesLangID); + else + { + MyChangeMenu(item.hSubMenu, level + 1, i); + if (level == 1 && menuIndex == kViewMenuIndex) + { + newString = LangString(kToolbarsLangID); + } + else + { + if (level == 0 && i < sizeof(kStringLangPairs) / + sizeof(kStringLangPairs[0])) + newString = LangString(kStringLangPairs[i].LangID); + else + continue; + } + } + if (newString.IsEmpty()) + continue; + } + else + { + int langPos = FindLangItem(item.wID); + if (langPos < 0) + continue; + newString = LangString(kIDLangPairs[langPos].LangID); + if (newString.IsEmpty()) + continue; + UString shorcutString = item.StringValue; + int tabPos = shorcutString.ReverseFind(wchar_t('\t')); + if (tabPos >= 0) + newString += shorcutString.Mid(tabPos); + } + { + item.StringValue = newString; + item.fMask = Get_fMaskForString(); + item.fType = MFT_STRING; + menu.SetItem(i, true, item); + } + } + } +} + +CMenu g_FileMenu; + +class CFileMenuDestroyer +{ +public: + ~CFileMenuDestroyer() + { + if ((HMENU)g_FileMenu != 0) + g_FileMenu.Destroy(); + } +} g_FileMenuDestroyer; + + +void MyLoadMenu(HWND hWnd) +{ + if ((HMENU)g_FileMenu != 0) + g_FileMenu.Destroy(); + HMENU oldMenu = ::GetMenu(hWnd); + HMENU baseMenu = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_MENU)); + ::SetMenu(hWnd, baseMenu); + ::DestroyMenu(oldMenu); + if (!g_LangID.IsEmpty()) + { + HMENU menuOld = ::GetMenu(hWnd); + MyChangeMenu(menuOld, 0, 0); + } + ::DrawMenuBar(hWnd); +} + +extern HWND g_HWND; +void MyLoadMenu() +{ + MyLoadMenu(g_HWND); +} + +static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec) +{ + CMenu srcMenu; + srcMenu.Attach(srcMenuSpec); + CMenu destMenu; + destMenu.Attach(destMenuSpec); + int startPos = 0; + for (int i = 0; i < srcMenu.GetItemCount(); i++) + { + CMenuItem item; + item.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString(); + item.fType = MFT_STRING; + if (srcMenu.GetItem(i, true, item)) + if (destMenu.InsertItem(startPos, true, item)) + startPos++; + } +} + +void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position) +{ + if (::GetSubMenu(::GetMenu(g_HWND), position) != hMenu) + return; + if (position == kFileMenuIndex) + { + if ((HMENU)g_FileMenu == 0) + { + g_FileMenu.CreatePopup(); + CopyMenu(hMenu, g_FileMenu); + } + CMenu menu; + menu.Attach(hMenu); + while (menu.GetItemCount() > 0) + { + if (!menu.RemoveItem(0, MF_BYPOSITION)) + break; + } + // CopyMenu(g_FileMenu, hMenu); + g_App.GetFocusedPanel().CreateFileMenu(hMenu); + + } + else if (position == kViewMenuIndex) + { + // View; + CMenu menu; + menu.Attach(hMenu); + menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS, + IDM_VIEW_LARGE_ICONS + g_App.GetListViewMode(), MF_BYCOMMAND); + menu.CheckItem(IDM_VIEW_TWO_PANELS, MF_BYCOMMAND | + ((g_App.NumPanels == 2) ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_FLAT_VIEW, MF_BYCOMMAND | + ((g_App.GetFlatMode()) ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_ARCHIVE_TOOLBAR, MF_BYCOMMAND | + (g_App.ShowArchiveToolbar ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_STANDARD_TOOLBAR, MF_BYCOMMAND | + (g_App.ShowStandardToolbar ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_TOOLBARS_LARGE_BUTTONS, MF_BYCOMMAND | + (g_App.LargeButtons ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, MF_BYCOMMAND | + (g_App.ShowButtonsLables ? MF_CHECKED : MF_UNCHECKED)); + } + else if (position == kBookmarksMenuIndex) + { + CMenu menu; + menu.Attach(hMenu); + + CMenu subMenu; + subMenu.Attach(menu.GetSubMenu(0)); + while (subMenu.GetItemCount() > 0) + subMenu.RemoveItem(subMenu.GetItemCount() - 1, MF_BYPOSITION); + int i; + for (i = 0; i < 10; i++) + { + UString s = LangString(IDS_BOOKMARK, 0x03000720); + s += L" "; + wchar_t c = (wchar_t)(L'0' + i); + s += c; + s += L"\tAlt+Shift+"; + s += c; + subMenu.AppendItem(MF_STRING, kSetBookmarkMenuID + i, s); + } + + while (menu.GetItemCount() > 2) + menu.RemoveItem(menu.GetItemCount() - 1, MF_BYPOSITION); + + for (i = 0; i < 10; i++) + { + UString path = g_App.AppState.FastFolders.GetString(i); + const int kMaxSize = 100; + const int kFirstPartSize = kMaxSize / 2; + if (path.Length() > kMaxSize) + { + path = path.Left(kFirstPartSize) + UString(L" ... ") + + path.Right(kMaxSize - kFirstPartSize); + } + UString s = path; + if (s.IsEmpty()) + s = L"-"; + s += L"\tAlt+"; + s += (wchar_t)(L'0' + i); + menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s); + } + } +} + +/* +It doesn't help +void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id) +{ + if (::GetSubMenu(::GetMenu(g_HWND), 0) != hMenu) + return; + // g_App.GetFocusedPanel()._contextMenu.Release(); +} + +void OnMenuUnActivating(HWND hWnd) +{ +} +*/ + + +void LoadFileMenu(HMENU hMenu, int startPos, bool /* forFileMode */, bool programMenu) +{ + { + CMenu srcMenu; + srcMenu.Attach(::GetSubMenu(::GetMenu(g_HWND), 0)); + if ((HMENU)g_FileMenu == 0) + { + g_FileMenu.CreatePopup(); + CopyMenu(srcMenu, g_FileMenu); + } + } + + CMenu destMenu; + destMenu.Attach(hMenu); + + for (int i = 0; i < g_FileMenu.GetItemCount(); i++) + { + CMenuItem item; + + item.fMask = MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString(); + item.fType = MFT_STRING; + if (g_FileMenu.GetItem(i, true, item)) + { + if (!programMenu) + if (item.wID == IDCLOSE) + continue; + /* + bool createItem = (item.wID == IDM_CREATE_FOLDER || item.wID == IDM_CREATE_FILE); + if (forFileMode) + { + if (createItem) + continue; + } + else + { + if (!createItem) + continue; + } + */ + if (destMenu.InsertItem(startPos, true, item)) + startPos++; + } + } + while (destMenu.GetItemCount() > 0) + { + CMenuItem item; + item.fMask = MIIM_TYPE; + item.fType = 0; + // item.dwTypeData = 0; + int lastIndex = destMenu.GetItemCount() - 1; + if (!destMenu.GetItem(lastIndex, true, item)) + break; + if(item.fType != MFT_SEPARATOR) + break; + if (!destMenu.RemoveItem(lastIndex, MF_BYPOSITION)) + break; + } +} + +bool ExecuteFileCommand(int id) +{ + if (id >= kPluginMenuStartID) + { + g_App.GetFocusedPanel().InvokePluginCommand(id); + g_App.GetFocusedPanel()._sevenZipContextMenu.Release(); + g_App.GetFocusedPanel()._systemContextMenu.Release(); + return true; + } + + switch (id) + { + // File + case IDM_FILE_OPEN: + g_App.OpenItem(); + break; + case IDM_FILE_OPEN_INSIDE: + g_App.OpenItemInside(); + break; + case IDM_FILE_OPEN_OUTSIDE: + g_App.OpenItemOutside(); + break; + case IDM_FILE_VIEW: + break; + case IDM_FILE_EDIT: + g_App.EditItem(); + break; + case IDM_RENAME: + g_App.Rename(); + break; + case IDM_COPY_TO: + g_App.CopyTo(); + break; + case IDM_MOVE_TO: + g_App.MoveTo(); + break; + case IDM_DELETE: + { + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + g_App.Delete(!shift); + break; + } + case IDM_FILE_CRC: + g_App.CalculateCrc(); + break; + case IDM_FILE_SPLIT: + g_App.Split(); + break; + case IDM_FILE_COMBINE: + g_App.Combine(); + break; + case IDM_FILE_PROPERTIES: + g_App.Properties(); + break; + case IDM_FILE_COMMENT: + g_App.Comment(); + break; + + case IDM_CREATE_FOLDER: + g_App.CreateFolder(); + break; + case IDM_CREATE_FILE: + g_App.CreateFile(); + break; + default: + return false; + } + return true; +} + +bool OnMenuCommand(HWND hWnd, int id) +{ + if (ExecuteFileCommand(id)) + return true; + + switch (id) + { + // File + case IDCLOSE: + SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); + SendMessage (hWnd, WM_CLOSE, 0, 0); + break; + + // Edit + case IDM_EDIT_COPY: + g_App.EditCopy(); + break; + case IDM_EDIT_PASTE: + g_App.EditPaste(); + break; + case IDM_SELECT_ALL: + g_App.SelectAll(true); + g_App.RefreshStatusBar(); + break; + case IDM_DESELECT_ALL: + g_App.SelectAll(false); + g_App.RefreshStatusBar(); + break; + case IDM_INVERT_SELECTION: + g_App.InvertSelection(); + g_App.RefreshStatusBar(); + break; + case IDM_SELECT: + g_App.SelectSpec(true); + g_App.RefreshStatusBar(); + break; + case IDM_DESELECT: + g_App.SelectSpec(false); + g_App.RefreshStatusBar(); + break; + case IDM_SELECT_BY_TYPE: + g_App.SelectByType(true); + g_App.RefreshStatusBar(); + break; + case IDM_DESELECT_BY_TYPE: + g_App.SelectByType(false); + g_App.RefreshStatusBar(); + break; + + //View + case IDM_VIEW_LARGE_ICONS: + case IDM_VIEW_SMALL_ICONS: + case IDM_VIEW_LIST: + case IDM_VIEW_DETAILS: + { + UINT index = id - IDM_VIEW_LARGE_ICONS; + if (index < 4) + { + g_App.SetListViewMode(index); + /* + CMenu menu; + menu.Attach(::GetSubMenu(::GetMenu(hWnd), kViewMenuIndex)); + menu.CheckRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS, + id, MF_BYCOMMAND); + */ + } + break; + } + case IDM_VIEW_ARANGE_BY_NAME: + { + g_App.SortItemsWithPropID(kpidName); + break; + } + case IDM_VIEW_ARANGE_BY_TYPE: + { + g_App.SortItemsWithPropID(kpidExtension); + break; + } + case IDM_VIEW_ARANGE_BY_DATE: + { + g_App.SortItemsWithPropID(kpidLastWriteTime); + break; + } + case IDM_VIEW_ARANGE_BY_SIZE: + { + g_App.SortItemsWithPropID(kpidSize); + break; + } + case IDM_VIEW_ARANGE_NO_SORT: + { + g_App.SortItemsWithPropID(kpidNoProperty); + break; + } + + case IDM_OPEN_ROOT_FOLDER: + g_App.OpenRootFolder(); + break; + case IDM_OPEN_PARENT_FOLDER: + g_App.OpenParentFolder(); + break; + case IDM_FOLDERS_HISTORY: + g_App.FoldersHistory(); + break; + case IDM_VIEW_REFRESH: + g_App.RefreshView(); + break; + case IDM_VIEW_FLAT_VIEW: + g_App.ChangeFlatMode(); + break; + case IDM_VIEW_TWO_PANELS: + g_App.SwitchOnOffOnePanel(); + break; + case IDM_VIEW_STANDARD_TOOLBAR: + g_App.SwitchStandardToolbar(); + break; + case IDM_VIEW_ARCHIVE_TOOLBAR: + g_App.SwitchArchiveToolbar(); + break; + case IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT: + g_App.SwitchButtonsLables(); + break; + case IDM_VIEW_TOOLBARS_LARGE_BUTTONS: + g_App.SwitchLargeButtons(); + break; + + // Tools + case IDM_OPTIONS: + OptionsDialog(hWnd, g_hInstance); + break; + + case IDM_BENCHMARK: + Benchmark(); + break; + // Help + case IDM_HELP_CONTENTS: + ShowHelpWindow(NULL, kFMHelpTopic); + break; + case IDM_ABOUT: + { + CAboutDialog dialog; + dialog.Create(hWnd); + break; + } + default: + { + if (id >= kOpenBookmarkMenuID && id <= kOpenBookmarkMenuID + 9) + { + g_App.OpenBookmark(id - kOpenBookmarkMenuID); + return true; + } + else if (id >= kSetBookmarkMenuID && id <= kSetBookmarkMenuID + 9) + { + g_App.SetBookmark(id - kSetBookmarkMenuID); + return true; + } + return false; + } + } + return true; +} + diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.h b/CPP/7zip/UI/FileManager/MyLoadMenu.h new file mode 100755 index 00000000..490dc6d8 --- /dev/null +++ b/CPP/7zip/UI/FileManager/MyLoadMenu.h @@ -0,0 +1,16 @@ +// MyLoadMenu.h + +#ifndef __MYLOADMENU_H +#define __MYLOADMENU_H + +void OnMenuActivating(HWND hWnd, HMENU hMenu, int position); +// void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id); +// void OnMenuUnActivating(HWND hWnd); + +void MyLoadMenu(HWND hWnd); +bool OnMenuCommand(HWND hWnd, int id); +void MyLoadMenu(); +void LoadFileMenu(HMENU hMenu, int startPos, bool forFileMode, bool programMenu); +bool ExecuteFileCommand(int id); + +#endif diff --git a/CPP/7zip/UI/FileManager/NetFolder.cpp b/CPP/7zip/UI/FileManager/NetFolder.cpp new file mode 100755 index 00000000..7bd5d2e5 --- /dev/null +++ b/CPP/7zip/UI/FileManager/NetFolder.cpp @@ -0,0 +1,302 @@ +// NetFolder.cpp + +#include "StdAfx.h" + +#include "NetFolder.h" + +#include "Common/StringConvert.h" +#include "../../PropID.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileFind.h" + +#include "SysIconUtils.h" +#include "FSFolder.h" + +using namespace NWindows; +using namespace NNet; + +static const STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + { NULL, kpidLocalName, VT_BSTR}, + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidProvider, VT_BSTR} +}; + +void CNetFolder::Init(const UString &path) +{ + /* + if (path.Length() > 2) + { + if (path[0] == L'\\' && path[1] == L'\\') + { + CResource netResource; + netResource.RemoteName = GetSystemString(path.Left(path.Length() - 1)); + netResource.Scope = RESOURCE_GLOBALNET; + netResource.Type = RESOURCETYPE_DISK; + netResource.DisplayType = RESOURCEDISPLAYTYPE_SERVER; + netResource.Usage = RESOURCEUSAGE_CONTAINER; + Init(&netResource, 0, path); + return; + } + } + Init(0, 0 , L""); + */ + CResourceW resource; + resource.RemoteNameIsDefined = true; + resource.RemoteName = path.Left(path.Length() - 1); + resource.ProviderIsDefined = false; + resource.LocalNameIsDefined = false; + resource.CommentIsDefined = false; + resource.Type = RESOURCETYPE_DISK; + resource.Scope = RESOURCE_GLOBALNET; + resource.Usage = 0; + resource.DisplayType = 0; + CResourceW destResource; + UString systemPathPart; + DWORD result = GetResourceInformation(resource, destResource, systemPathPart); + if (result == NO_ERROR) + Init(&destResource, 0, path); + else + Init(0, 0 , L""); + return; +} + +void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource, + IFolderFolder *parentFolder, const UString &path) +{ + _path = path; + if (netResource == 0) + _netResourcePointer = 0; + else + { + _netResource = *netResource; + _netResourcePointer = &_netResource; + + // if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER) + _path = _netResource.RemoteName + L'\\'; + } + _parentFolder = parentFolder; +} + +STDMETHODIMP CNetFolder::LoadItems() +{ + _items.Clear(); + CEnum enumerator; + + for (;;) + { + DWORD result = enumerator.Open( + RESOURCE_GLOBALNET, + RESOURCETYPE_DISK, + 0, // enumerate all resources + _netResourcePointer + ); + if (result == NO_ERROR) + break; + if (result != ERROR_ACCESS_DENIED) + return result; + if (_netResourcePointer != 0) + result = AddConnection2(_netResource, + 0, 0, CONNECT_INTERACTIVE); + if (result != NO_ERROR) + return result; + } + + for (;;) + { + CResourceEx resource; + DWORD result = enumerator.Next(resource); + if (result == NO_ERROR) + { + if (!resource.RemoteNameIsDefined) // For Win 98, I don't know what's wrong + resource.RemoteName = resource.Comment; + resource.Name = resource.RemoteName; + int aPos = resource.Name.ReverseFind(L'\\'); + if (aPos >= 0) + { + // _path = resource.Name.Left(aPos + 1); + resource.Name = resource.Name.Mid(aPos + 1); + } + _items.Add(resource); + } + else if (result == ERROR_NO_MORE_ITEMS) + break; + else + return result; + } + + /* + It's too slow for some systems. + if (_netResourcePointer && _netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER) + { + for (char c = 'a'; c <= 'z'; c++) + { + CResourceEx resource; + resource.Name = UString(wchar_t(c)) + L'$'; + resource.RemoteNameIsDefined = true; + resource.RemoteName = _path + resource.Name; + + NFile::NFind::CFindFile findFile; + NFile::NFind::CFileInfoW fileInfo; + if (!findFile.FindFirst(resource.RemoteName + UString(L"\\*"), fileInfo)) + continue; + resource.Usage = RESOURCEUSAGE_CONNECTABLE; + resource.LocalNameIsDefined = false; + resource.CommentIsDefined = false; + resource.ProviderIsDefined = false; + _items.Add(resource); + } + } + */ + return S_OK; +} + + +STDMETHODIMP CNetFolder::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size(); + return S_OK; +} + +STDMETHODIMP CNetFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + const CResourceEx &item = _items[itemIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + // if (item.RemoteNameIsDefined) + propVariant = item.Name; + break; + case kpidLocalName: + if (item.LocalNameIsDefined) + propVariant = item.LocalName; + break; + case kpidComment: + if (item.CommentIsDefined) + propVariant = item.Comment; + break; + case kpidProvider: + if (item.ProviderIsDefined) + propVariant = item.Provider; + break; + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + const CResourceEx &resource = _items[index]; + if (resource.Usage == RESOURCEUSAGE_CONNECTABLE || + resource.DisplayType == RESOURCEDISPLAYTYPE_SHARE) + { + NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; + CMyComPtr subFolder = fsFolderSpec; + RINOK(fsFolderSpec->Init(resource.RemoteName + L'\\', this)); + *resultFolder = subFolder.Detach(); + } + else + { + CNetFolder *netFolder = new CNetFolder; + CMyComPtr subFolder = netFolder; + netFolder->Init(&resource, this, resource.Name + L'\\'); + *resultFolder = subFolder.Detach(); + } + return S_OK; +} + +STDMETHODIMP CNetFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CNetFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + if (_parentFolder) + { + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + } + if (_netResourcePointer != 0) + { + CResourceW resourceParent; + DWORD result = GetResourceParent(_netResource, resourceParent); + if (result != NO_ERROR) + return result; + if (!_netResource.RemoteNameIsDefined) + return S_OK; + + CNetFolder *netFolder = new CNetFolder; + CMyComPtr subFolder = netFolder; + netFolder->Init(&resourceParent, 0, L'\\'); + *resultFolder = subFolder.Detach(); + } + return S_OK; +} + +STDMETHODIMP CNetFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CNetFolder::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CNetFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidType: prop = L"NetFolder"; break; + case kpidPath: prop = _path; break; + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CNetFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + if (index >= (UInt32)_items.Size()) + return E_INVALIDARG; + *iconIndex = 0; + const CResourceW &resource = _items[index]; + int iconIndexTemp; + if (resource.DisplayType == RESOURCEDISPLAYTYPE_SERVER || + resource.Usage == RESOURCEUSAGE_CONNECTABLE) + { + if (GetRealIconIndex(resource.RemoteName, 0, iconIndexTemp)) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + } + else + { + if (GetRealIconIndex(TEXT(""), FILE_ATTRIBUTE_DIRECTORY, iconIndexTemp)) + { + *iconIndex = iconIndexTemp; + return S_OK; + } + // *anIconIndex = GetRealIconIndex(0, L"\\\\HOME"); + } + return GetLastError(); +} diff --git a/CPP/7zip/UI/FileManager/NetFolder.h b/CPP/7zip/UI/FileManager/NetFolder.h new file mode 100755 index 00000000..0214cfdb --- /dev/null +++ b/CPP/7zip/UI/FileManager/NetFolder.h @@ -0,0 +1,49 @@ +// NetFolder.h + +#ifndef __NETFOLDER_H +#define __NETFOLDER_H + +#include "Common/MyString.h" +#include "Common/Buffer.h" +#include "Common/MyCom.h" +#include "Windows/PropVariant.h" +#include "Windows/Net.h" + +#include "IFolder.h" + +struct CResourceEx: public NWindows::NNet::CResourceW +{ + UString Name; +}; + +class CNetFolder: + public IFolderFolder, + public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1( + IFolderGetSystemIconIndex + ) + + INTERFACE_FolderFolder(;) + + STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + +private: + NWindows::NNet::CResourceW _netResource; + NWindows::NNet::CResourceW *_netResourcePointer; + + CObjectVector _items; + + CMyComPtr _parentFolder; + UString _path; + +public: + void Init(const UString &path); + void Init(const NWindows::NNet::CResourceW *netResource, + IFolderFolder *parentFolder, const UString &path); + CNetFolder(): _netResourcePointer(0) {} +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/OpenCallback.cpp b/CPP/7zip/UI/FileManager/OpenCallback.cpp new file mode 100755 index 00000000..70ec3f39 --- /dev/null +++ b/CPP/7zip/UI/FileManager/OpenCallback.cpp @@ -0,0 +1,115 @@ +// OpenCallback.cpp + +#include "StdAfx.h" + +#include "OpenCallback.h" + +#include "Common/StringConvert.h" +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +#include "PasswordDialog.h" + +STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 * /* numFiles */, const UINT64 * /* numBytes */) +{ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 * /* numFiles */, const UINT64 * /* numBytes */) +{ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 /* total */) +{ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 * /* completed */) +{ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + if (_subArchiveMode) + { + switch(propID) + { + case kpidName: + propVariant = _subArchiveName; + break; + } + propVariant.Detach(value); + return S_OK; + } + switch(propID) + { + case kpidName: + propVariant = _fileInfo.Name; + break; + case kpidIsFolder: + propVariant = _fileInfo.IsDirectory(); + break; + case kpidSize: + propVariant = _fileInfo.Size; + break; + case kpidAttributes: + propVariant = (UINT32)_fileInfo.Attributes; + break; + case kpidLastAccessTime: + propVariant = _fileInfo.LastAccessTime; + break; + case kpidCreationTime: + propVariant = _fileInfo.CreationTime; + break; + case kpidLastWriteTime: + propVariant = _fileInfo.LastWriteTime; + break; + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, + IInStream **inStream) +{ + *inStream = NULL; + if (_subArchiveMode) + return S_FALSE; + + NWindows::NFile::NFind::CFileInfoW fileInfo; + + UString fullPath = _folderPrefix + name; + if (!NWindows::NFile::NFind::FindFile(fullPath, fileInfo)) + return S_FALSE; + _fileInfo = fileInfo; + if (_fileInfo.IsDirectory()) + return S_FALSE; + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password) +{ + PasswordWasAsked = true; + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + + Password = dialog.Password; + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} diff --git a/CPP/7zip/UI/FileManager/OpenCallback.h b/CPP/7zip/UI/FileManager/OpenCallback.h new file mode 100755 index 00000000..15b50168 --- /dev/null +++ b/CPP/7zip/UI/FileManager/OpenCallback.h @@ -0,0 +1,85 @@ +// OpenCallback.h + +#ifndef __OPENCALLBACK_H +#define __OPENCALLBACK_H + +#include "Common/MyString.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" + +#include "../../IPassword.h" + +#include "../../Archive/IArchive.h" + +class COpenArchiveCallback: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + public IArchiveOpenSetSubArchiveName, + public IProgress, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ + UString _folderPrefix; + NWindows::NFile::NFind::CFileInfoW _fileInfo; +public: + bool PasswordIsDefined; + UString Password; + bool PasswordWasAsked; + HWND ParentWindow; + + bool _subArchiveMode; + UString _subArchiveName; + +public: + MY_UNKNOWN_IMP5( + IArchiveOpenCallback, + IArchiveOpenVolumeCallback, + IArchiveOpenSetSubArchiveName, + IProgress, + ICryptoGetTextPassword) + + // IProgress + STDMETHOD(SetTotal)(UINT64 total); + STDMETHOD(SetCompleted)(const UINT64 *completeValue); + + // IArchiveOpenCallback + STDMETHOD(SetTotal)(const UINT64 *numFiles, const UINT64 *numBytes); + STDMETHOD(SetCompleted)(const UINT64 *numFiles, const UINT64 *numBytes); + + // IArchiveOpenVolumeCallback + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + STDMETHOD(SetSubArchiveName(const wchar_t *name)) + { + _subArchiveMode = true; + _subArchiveName = name; + return S_OK; + } + + COpenArchiveCallback() + { + _subArchiveMode = false; + PasswordIsDefined = false; + PasswordWasAsked = false; + } + /* + void Init() + { + PasswordIsDefined = false; + _subArchiveMode = false; + } + */ + void LoadFileInfo(const UString &folderPrefix, const UString &fileName) + { + _folderPrefix = folderPrefix; + if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo)) + throw 1; + } + void ShowMessage(const UINT64 *completed); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/OptionsDialog.cpp b/CPP/7zip/UI/FileManager/OptionsDialog.cpp new file mode 100755 index 00000000..09d74705 --- /dev/null +++ b/CPP/7zip/UI/FileManager/OptionsDialog.cpp @@ -0,0 +1,65 @@ +// OptionsDialog.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/StringConvert.h" + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Error.h" + +#include "LangPage.h" +#include "LangPageRes.h" +#include "PluginsPage.h" +#include "PluginsPageRes.h" +#include "SystemPage.h" +#include "SystemPageRes.h" +#include "EditPage.h" +#include "EditPageRes.h" +#include "SettingsPage.h" +#include "SettingsPageRes.h" + +#include "LangUtils.h" +#include "MyLoadMenu.h" +#include "App.h" + +using namespace NWindows; + +void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */) +{ + CSystemPage systemPage; + CPluginsPage pluginsPage; + CEditPage editPage; + CSettingsPage settingsPage; + CLangPage langPage; + + CObjectVector pages; + UINT32 langIDs[] = { 0x03010300, 0x03010100, 0x03010200, 0x03010400, 0x01000400}; + UINT pageIDs[] = { IDD_SYSTEM, IDD_PLUGINS, IDD_EDIT, IDD_SETTINGS, IDD_LANG}; + NControl::CPropertyPage *pagePinters[] = { &systemPage, &pluginsPage, &editPage, &settingsPage, &langPage }; + const int kNumPages = sizeof(langIDs) / sizeof(langIDs[0]); + for (int i = 0; i < kNumPages; i++) + { + NControl::CPageInfo page; + page.Title = LangString(langIDs[i]); + page.ID = pageIDs[i]; + page.Page = pagePinters[i]; + pages.Add(page); + } + + INT_PTR res = NControl::MyPropertySheet(pages, hwndOwner, LangString(IDS_OPTIONS, 0x03010000)); + if (res != -1 && res != 0) + { + if (langPage._langWasChanged) + { + g_App._window.SetText(LangString(IDS_APP_TITLE, 0x03000000)); + MyLoadMenu(); + } + g_App.SetListSettings(); + g_App.SetShowSystemMenu(); + g_App.RefreshAllPanels(); + g_App.ReloadToolbars(); + // ::PostMessage(hwndOwner, kLangWasChangedMessage, 0 , 0); + } +} diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.cpp b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp new file mode 100755 index 00000000..442df929 --- /dev/null +++ b/CPP/7zip/UI/FileManager/OverwriteDialog.cpp @@ -0,0 +1,124 @@ +// OverwriteDialog.cpp + +#include "StdAfx.h" + +#include "OverwriteDialog.h" + +#include "Common/StringConvert.h" +#include "Windows/FileName.h" +#include "Windows/Defs.h" +#include "Windows/ResourceString.h" +#include "Windows/Control/Static.h" +#include "Windows/PropVariantConversions.h" + +#include "FormatUtils.h" + +// #include "../resource.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_OVERWRITE_HEADER, 0x02000901}, + { IDC_STATIC_OVERWRITE_QUESTION_BEGIN, 0x02000902 }, + { IDC_STATIC_OVERWRITE_QUESTION_END, 0x02000903 }, + { IDYES, 0x02000705 }, + { IDC_BUTTON_OVERWRITE_YES_TO_ALL, 0x02000707 }, + { IDNO, 0x02000709 }, + { IDC_BUTTON_OVERWRITE_NO_TO_ALL,0x0200070B }, + { IDC_BUTTON_OVERWRITE_AUTO_RENAME, 0x02000911 }, + { IDCANCEL, 0x02000711 } +}; +#endif + +void COverwriteDialog::SetFileInfoControl(int textID, int iconID, + const NOverwriteDialog::CFileInfo &fileInfo) +{ + UString sizeString; + if (fileInfo.SizeIsDefined) + sizeString = MyFormatNew(IDS_FILE_SIZE, + #ifdef LANG + 0x02000982, + #endif + NumberToString(fileInfo.Size)); + + UString reducedName; + const int kLineSize = 88; + for (int i = 0; i < fileInfo.Name.Length();) + { + reducedName += fileInfo.Name.Mid(i, kLineSize); + reducedName += L" "; + i += kLineSize; + } + + UString fullString = reducedName; + fullString += L"\n"; + fullString += sizeString; + fullString += L"\n"; + + if (fileInfo.TimeIsDefined) + { + UString timeString; + FILETIME localFileTime; + if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) + throw 4190402; + timeString = ConvertFileTimeToString(localFileTime); + + fullString += + #ifdef LANG + LangString(IDS_FILE_MODIFIED, 0x02000983); + #else + MyLoadStringW(IDS_FILE_MODIFIED); + #endif + + fullString += L" "; + fullString += timeString; + } + + NWindows::NControl::CDialogChildControl control; + control.Init(*this, textID); + control.SetText(fullString); + + 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(HWND(*this), 0x02000900); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + SetFileInfoControl(IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME, + IDC_STATIC_OVERWRITE_OLD_FILE_ICON, OldFileInfo); + SetFileInfoControl(IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME, + IDC_STATIC_OVERWRITE_NEW_FILE_ICON, NewFileInfo); + return CModalDialog::OnInit(); +} + +bool COverwriteDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDYES: + case IDC_BUTTON_OVERWRITE_YES_TO_ALL: + case IDNO: + case IDC_BUTTON_OVERWRITE_NO_TO_ALL: + case IDC_BUTTON_OVERWRITE_AUTO_RENAME: + End(buttonID); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.h b/CPP/7zip/UI/FileManager/OverwriteDialog.h new file mode 100755 index 00000000..fd7444eb --- /dev/null +++ b/CPP/7zip/UI/FileManager/OverwriteDialog.h @@ -0,0 +1,34 @@ +// OverwriteDialog.h + +#ifndef __OVERWRITEDIALOG_H +#define __OVERWRITEDIALOG_H + +#include "OverwriteDialogRes.h" +#include "Windows/Control/Dialog.h" + +namespace NOverwriteDialog +{ + struct CFileInfo + { + bool SizeIsDefined; + UINT64 Size; + bool TimeIsDefined; + FILETIME Time; + UString Name; + }; +} + +class COverwriteDialog: public NWindows::NControl::CModalDialog +{ + void SetFileInfoControl(int textID, int iconID, + const NOverwriteDialog::CFileInfo &fileInfo); + virtual bool OnInit(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + INT_PTR Create(HWND parent = 0) { return CModalDialog::Create(IDD_DIALOG_OVERWRITE, parent); } + + NOverwriteDialog::CFileInfo OldFileInfo; + NOverwriteDialog::CFileInfo NewFileInfo; +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/OverwriteDialog.rc b/CPP/7zip/UI/FileManager/OverwriteDialog.rc new file mode 100755 index 00000000..1cce0876 --- /dev/null +++ b/CPP/7zip/UI/FileManager/OverwriteDialog.rc @@ -0,0 +1,47 @@ +#include "OverwriteDialogRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 357 +#define ySize2 204 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#undef iconSize +#define iconSize 20 + +#undef fiXPos +#undef fiXSize +#undef fiYSize +#define fiXPos (iconSize + 12) +#define fiXSize (xSize2 - fiXPos) +#define fiYSize 50 + +#define b1YPos (ySize - marg - bYSize) +#define b2YPos (b1YPos - bYSize - 10) + +IDD_DIALOG_OVERWRITE DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Confirm File Replace" +MY_FONT +BEGIN + LTEXT "Destination folder already contains processed file.", IDC_STATIC_OVERWRITE_HEADER, marg, 7, xSize2, 8 + LTEXT "Would you like to replace the existing file", IDC_STATIC_OVERWRITE_QUESTION_BEGIN, marg, 28, xSize2, 8 + ICON "", IDC_STATIC_OVERWRITE_OLD_FILE_ICON, marg, 44, iconSize, iconSize + LTEXT "", IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME, fiXPos, 44, fiXSize, fiYSize, SS_NOPREFIX + LTEXT "with this one?",IDC_STATIC_OVERWRITE_QUESTION_END, marg, 98, xSize2, 8 + ICON "",IDC_STATIC_OVERWRITE_NEW_FILE_ICON, marg, 114, iconSize, iconSize + LTEXT "",IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME, fiXPos, 114, fiXSize, fiYSize, SS_NOPREFIX + PUSHBUTTON "&Yes", IDYES, 78, b2YPos, bXSize, bYSize + PUSHBUTTON "Yes to &All", IDC_BUTTON_OVERWRITE_YES_TO_ALL, 152, b2YPos, bXSize, bYSize + PUSHBUTTON "&No", IDNO, 226, b2YPos, bXSize, bYSize + PUSHBUTTON "No to A&ll", IDC_BUTTON_OVERWRITE_NO_TO_ALL, 300, b2YPos, bXSize, bYSize + PUSHBUTTON "A&uto Rename", IDC_BUTTON_OVERWRITE_AUTO_RENAME, 181, b1YPos, 109, bYSize + PUSHBUTTON "&Cancel", IDCANCEL, 300, b1YPos, bXSize, bYSize +END + + +STRINGTABLE +BEGIN + IDS_FILE_MODIFIED "modified on" + IDS_FILE_SIZE "{0} bytes" +END diff --git a/CPP/7zip/UI/FileManager/OverwriteDialogRes.h b/CPP/7zip/UI/FileManager/OverwriteDialogRes.h new file mode 100755 index 00000000..66710f84 --- /dev/null +++ b/CPP/7zip/UI/FileManager/OverwriteDialogRes.h @@ -0,0 +1,19 @@ +#define IDS_FILE_MODIFIED 600 +#define IDS_FILE_SIZE 601 + +#define IDD_DIALOG_OVERWRITE 502 + +#define IDC_STATIC_OVERWRITE_HEADER 1000 + +#define IDC_STATIC_OVERWRITE_QUESTION_BEGIN 1001 +#define IDC_STATIC_OVERWRITE_QUESTION_END 1002 + +#define IDC_STATIC_OVERWRITE_OLD_FILE_ICON 1003 +#define IDC_STATIC_OVERWRITE_NEW_FILE_ICON 1004 + +#define IDC_STATIC_OVERWRITE_OLD_FILE_SIZE_TIME 1005 +#define IDC_STATIC_OVERWRITE_NEW_FILE_SIZE_TIME 1006 + +#define IDC_BUTTON_OVERWRITE_YES_TO_ALL 1010 +#define IDC_BUTTON_OVERWRITE_NO_TO_ALL 1011 +#define IDC_BUTTON_OVERWRITE_AUTO_RENAME 1012 diff --git a/CPP/7zip/UI/FileManager/Panel.cpp b/CPP/7zip/UI/FileManager/Panel.cpp new file mode 100755 index 00000000..b1ef614f --- /dev/null +++ b/CPP/7zip/UI/FileManager/Panel.cpp @@ -0,0 +1,967 @@ +// Panel.cpp + +#include "StdAfx.h" + +#include + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Windows/Error.h" +#include "Windows/PropVariant.h" +#include "Windows/Thread.h" + +#include "../../PropID.h" + +#include "Panel.h" +#include "RootFolder.h" +#include "FSFolder.h" +#include "FormatUtils.h" +#include "App.h" +#include "ExtractCallback.h" + +#include "resource.h" + +#include "../Agent/IFolderArchive.h" + +#include "../Common/CompressCall.h" +#include "../Common/ArchiveName.h" + +using namespace NWindows; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +static const UINT_PTR kTimerID = 1; +static const UINT kTimerElapse = 1000; + +static LPCWSTR kSelectOneFile = L"Select one file"; +static LPCWSTR kSelectFiles = L"Select files"; + +static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT }; + +// static const int kCreateFolderID = 101; +// static const UINT kFileChangeNotifyMessage = WM_APP; + +extern HINSTANCE g_hInstance; +extern DWORD g_ComCtl32Version; + +void CPanel::Release() +{ + // It's for unloading COM dll's: don't change it. + CloseOpenFolders(); + _sevenZipContextMenu.Release(); + _systemContextMenu.Release(); +} + +CPanel::~CPanel() +{ + CloseOpenFolders(); +} + +static LPCWSTR kClassName = L"7-Zip::Panel"; + + +LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id, + const UString ¤tFolderPrefix, CPanelCallback *panelCallback, CAppState *appState, + bool &archiveIsOpened, bool &encrypted) +{ + _mainWindow = mainWindow; + _processTimer = true; + _processNotify = true; + + _panelCallback = panelCallback; + _appState = appState; + // _index = index; + _baseID = id; + _comboBoxID = _baseID + 3; + _statusBarID = _comboBoxID + 1; + + UString cfp = currentFolderPrefix; + + if (!currentFolderPrefix.IsEmpty()) + if (currentFolderPrefix[0] == L'.') + if (!NFile::NDirectory::MyGetFullPathName(currentFolderPrefix, cfp)) + cfp = currentFolderPrefix; + BindToPath(cfp, archiveIsOpened, encrypted); + + if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE, + 0, 0, _xSize, 260, + parentWindow, (HMENU)(UINT_PTR)id, g_hInstance)) + return E_FAIL; + return S_OK; +} + +LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case kShiftSelectMessage: + OnShiftSelectMessage(); + return 0; + case kReLoadMessage: + RefreshListCtrl(_selectedState); + return 0; + case kSetFocusToListView: + _listView.SetFocus(); + return 0; + case kOpenItemChanged: + return OnOpenItemChanged(lParam); + case kRefreshStatusBar: + OnRefreshStatusBar(); + return 0; + case WM_TIMER: + OnTimer(); + return 0; + case WM_CONTEXTMENU: + if (OnContextMenu(HANDLE(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) + return 0; + break; + /* + case WM_DROPFILES: + CompressDropFiles(HDROP(wParam)); + return 0; + */ + } + return CWindow2::OnMessage(message, wParam, lParam); +} + +static LRESULT APIENTRY ListViewSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(hwnd); + CMyListView *w = (CMyListView *)(tempDialog.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_CHAR) + { + UINT scanCode = (UINT)((lParam >> 16) & 0xFF); + bool extended = ((lParam & 0x1000000) != 0); + UINT virtualKey = MapVirtualKey(scanCode, 1); + if (virtualKey == VK_MULTIPLY || virtualKey == VK_ADD || + virtualKey == VK_SUBTRACT) + return 0; + if ((wParam == '/' && extended) + || wParam == '\\' || wParam == '/') + { + _panel->OpenDrivesFolder(); + return 0; + } + } + else if (message == WM_SYSCHAR) + { + // For Alt+Enter Beep disabling + UINT scanCode = (UINT)(lParam >> 16) & 0xFF; + UINT virtualKey = MapVirtualKey(scanCode, 1); + if (virtualKey == VK_RETURN || virtualKey == VK_MULTIPLY || + virtualKey == VK_ADD || virtualKey == VK_SUBTRACT) + return 0; + } + /* + else if (message == WM_SYSKEYDOWN) + { + // return 0; + } + */ + else if (message == WM_KEYDOWN) + { + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0; + // bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + switch(wParam) + { + case VK_RETURN: + { + if (shift && !alt && !ctrl) + { + _panel->OpenSelectedItems(false); + return 0; + } + break; + } + case VK_NEXT: + { + if (ctrl && !alt && !shift) + { + _panel->OpenFocusedItemAsInternal(); + return 0; + } + break; + } + case VK_PRIOR: + if (ctrl && !alt && !shift) + { + _panel->OpenParentFolder(); + return 0; + } + } + } + else if (message == WM_SETFOCUS) + { + _panel->_lastFocusedIsList = true; + _panel->_panelCallback->PanelWasFocused(); + } + #ifndef _UNICODE + if (g_IsNT) + return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam); + else + #endif + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} + +/* +static LRESULT APIENTRY ComboBoxSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(hwnd); + CMyComboBox *w = (CMyComboBox *)(tempDialog.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +LRESULT CMyComboBox::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} +*/ +static LRESULT APIENTRY ComboBoxEditSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + CWindow tempDialog(hwnd); + CMyComboBoxEdit *w = (CMyComboBoxEdit *)(tempDialog.GetUserDataLongPtr()); + if (w == NULL) + return 0; + return w->OnMessage(message, wParam, lParam); +} + +LRESULT CMyComboBoxEdit::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + // See MSDN / Subclassing a Combo Box / Creating a Combo-box Toolbar + switch (message) + { + case WM_SYSKEYDOWN: + switch (wParam) + { + case VK_F1: + case VK_F2: + { + // check ALT + if ((lParam & (1<<29)) == 0) + break; + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + if (alt && !ctrl && !shift) + { + _panel->_panelCallback->SetFocusToPath(wParam == VK_F1 ? 0 : 1); + return 0; + } + break; + } + } + break; + case WM_KEYDOWN: + switch (wParam) + { + case VK_TAB: + // SendMessage(hwndMain, WM_ENTER, 0, 0); + _panel->SetFocusToList(); + return 0; + case VK_F9: + { + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + if (!alt && !ctrl && !shift) + { + g_App.SwitchOnOffOnePanel();; + return 0; + } + break; + } + } + break; + case WM_CHAR: + switch (wParam) + { + case VK_TAB: + case VK_ESCAPE: + return 0; + } + } + #ifndef _UNICODE + if (g_IsNT) + return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam); + else + #endif + return CallWindowProc(_origWindowProc, *this, message, wParam, lParam); +} + +bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */) +{ + // _virtualMode = false; + // _sortIndex = 0; + _sortID = kpidName; + _ascending = true; + _lastFocusedIsList = true; + + DWORD style = WS_CHILD | WS_VISIBLE; // | WS_BORDER ; // | LVS_SHAREIMAGELISTS; // | LVS_SHOWSELALWAYS;; + + style |= LVS_SHAREIMAGELISTS; + // style |= LVS_AUTOARRANGE; + style |= WS_CLIPCHILDREN; + style |= WS_CLIPSIBLINGS; + + const UInt32 kNumListModes = sizeof(kStyles) / sizeof(kStyles[0]); + if (_ListViewMode >= kNumListModes) + _ListViewMode = kNumListModes - 1; + + style |= kStyles[_ListViewMode] + | WS_TABSTOP + | LVS_EDITLABELS; + if (_mySelectMode) + style |= LVS_SINGLESEL; + + /* + if (_virtualMode) + style |= LVS_OWNERDATA; + */ + + DWORD exStyle; + exStyle = WS_EX_CLIENTEDGE; + + if (!_listView.CreateEx(exStyle, style, 0, 0, 116, 260, + HWND(*this), (HMENU)(UINT_PTR)(_baseID + 1), g_hInstance, NULL)) + return false; + + _listView.SetUnicodeFormat(true); + + _listView.SetUserDataLongPtr(LONG_PTR(&_listView)); + _listView._panel = this; + + #ifndef _UNICODE + if(g_IsNT) + _listView._origWindowProc = + (WNDPROC)_listView.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc)); + else + #endif + _listView._origWindowProc = + (WNDPROC)_listView.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc)); + + SHFILEINFO shellInfo; + HIMAGELIST imageList = (HIMAGELIST)SHGetFileInfo(TEXT(""), + FILE_ATTRIBUTE_NORMAL | + FILE_ATTRIBUTE_DIRECTORY, + &shellInfo, sizeof(shellInfo), + SHGFI_USEFILEATTRIBUTES | + SHGFI_SYSICONINDEX | + SHGFI_SMALLICON + ); + _listView.SetImageList(imageList, LVSIL_SMALL); + imageList = (HIMAGELIST)SHGetFileInfo(TEXT(""), + FILE_ATTRIBUTE_NORMAL | + FILE_ATTRIBUTE_DIRECTORY, + &shellInfo, sizeof(shellInfo), + SHGFI_USEFILEATTRIBUTES | + SHGFI_SYSICONINDEX | + SHGFI_ICON + ); + _listView.SetImageList(imageList, LVSIL_NORMAL); + + // _exStyle |= LVS_EX_HEADERDRAGDROP; + // DWORD extendedStyle = _listView.GetExtendedListViewStyle(); + // extendedStyle |= _exStyle; + // _listView.SetExtendedListViewStyle(extendedStyle); + SetExtendedStyle(); + + _listView.Show(SW_SHOW); + _listView.InvalidateRect(NULL, true); + _listView.Update(); + + // Ensure that the common control DLL is loaded. + INITCOMMONCONTROLSEX icex; + + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + TBBUTTON tbb [ ] = + { + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0}, + // {VIEW_NEWFOLDER, kCreateFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0}, + }; + + if (g_ComCtl32Version >= MAKELONG(71, 4)) + { + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES; + InitCommonControlsEx(&icex); + + _headerReBar.Attach(::CreateWindowEx(WS_EX_TOOLWINDOW, + REBARCLASSNAME, + NULL, WS_VISIBLE | WS_BORDER | WS_CHILD | + WS_CLIPCHILDREN | WS_CLIPSIBLINGS + | CCS_NODIVIDER + | CCS_NOPARENTALIGN + | CCS_TOP + | RBS_VARHEIGHT + | RBS_BANDBORDERS + ,0,0,0,0, HWND(*this), NULL, g_hInstance, NULL)); + } + + DWORD toolbarStyle = WS_CHILD | WS_VISIBLE ; + if (_headerReBar) + { + toolbarStyle |= 0 + // | WS_CLIPCHILDREN + // | WS_CLIPSIBLINGS + + | TBSTYLE_TOOLTIPS + | CCS_NODIVIDER + | CCS_NORESIZE + | TBSTYLE_FLAT + ; + } + + _headerToolBar.Attach(::CreateToolbarEx ((*this), toolbarStyle, + _baseID + 2, 11, + (HINSTANCE)HINST_COMMCTRL, + IDB_VIEW_SMALL_COLOR, + (LPCTBBUTTON)&tbb, sizeof(tbb) / sizeof(tbb[0]), + 0, 0, 0, 0, sizeof (TBBUTTON))); + + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_USEREX_CLASSES; + InitCommonControlsEx(&icex); + + _headerComboBox.CreateEx(0, WC_COMBOBOXEXW, NULL, + WS_BORDER | WS_VISIBLE |WS_CHILD | CBS_DROPDOWN | CBS_AUTOHSCROLL, + 0, 0, 100, 20, + ((_headerReBar == 0) ? HWND(*this) : _headerToolBar), + (HMENU)(UINT_PTR)(_comboBoxID), + g_hInstance, NULL); + // _headerComboBox.SendMessage(CBEM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0); + + + _headerComboBox.SetExtendedStyle(CBES_EX_PATHWORDBREAKPROC, CBES_EX_PATHWORDBREAKPROC); + + /* + _headerComboBox.SetUserDataLongPtr(LONG_PTR(&_headerComboBox)); + _headerComboBox._panel = this; + _headerComboBox._origWindowProc = + (WNDPROC)_headerComboBox.SetLongPtr(GWLP_WNDPROC, + LONG_PTR(ComboBoxSubclassProc)); + */ + _comboBoxEdit.Attach(_headerComboBox.GetEditControl()); + + // _comboBoxEdit.SendMessage(CCM_SETUNICODEFORMAT, (WPARAM)(BOOL)TRUE, 0); + + _comboBoxEdit.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit)); + _comboBoxEdit._panel = this; + #ifndef _UNICODE + if(g_IsNT) + _comboBoxEdit._origWindowProc = + (WNDPROC)_comboBoxEdit.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc)); + else + #endif + _comboBoxEdit._origWindowProc = + (WNDPROC)_comboBoxEdit.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc)); + + + + if (_headerReBar) + { + REBARINFO rbi; + rbi.cbSize = sizeof(REBARINFO); // Required when using this struct. + rbi.fMask = 0; + rbi.himl = (HIMAGELIST)NULL; + _headerReBar.SetBarInfo(&rbi); + + // Send the TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + // _headerToolBar.SendMessage(TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + SIZE size; + _headerToolBar.GetMaxSize(&size); + + REBARBANDINFO rbBand; + rbBand.cbSize = sizeof(REBARBANDINFO); // Required + rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; + rbBand.fStyle = RBBS_NOGRIPPER; + rbBand.cxMinChild = size.cx; + rbBand.cyMinChild = size.cy; + rbBand.cyChild = size.cy; + rbBand.cx = size.cx; + rbBand.hwndChild = _headerToolBar; + _headerReBar.InsertBand(-1, &rbBand); + + RECT rc; + ::GetWindowRect(_headerComboBox, &rc); + rbBand.cxMinChild = 30; + rbBand.cyMinChild = rc.bottom - rc.top; + rbBand.cx = 1000; + rbBand.hwndChild = _headerComboBox; + _headerReBar.InsertBand(-1, &rbBand); + // _headerReBar.MaximizeBand(1, false); + } + + _statusBar.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID); + // _statusBar2.Create(WS_CHILD | WS_VISIBLE, L"Status", (*this), _statusBarID + 1); + + int sizes[] = {150, 200, 250, -1}; + _statusBar.SetParts(4, sizes); + // _statusBar2.SetParts(5, sizes); + + /* + RECT rect; + GetClientRect(&rect); + OnSize(0, rect.right - rect.left, rect.top - rect.bottom); + */ + + SetTimer(kTimerID, kTimerElapse); + + // InitListCtrl(); + RefreshListCtrl(); + RefreshStatusBar(); + + return true; +} + +void CPanel::OnDestroy() +{ + SaveListViewInfo(); + CWindow2::OnDestroy(); +} + +void CPanel::ChangeWindowSize(int xSize, int ySize) +{ + int kHeaderSize; + int kStatusBarSize; + // int kStatusBar2Size; + RECT rect; + if (_headerReBar) + _headerReBar.GetWindowRect(&rect); + else + _headerToolBar.GetWindowRect(&rect); + + kHeaderSize = rect.bottom - rect.top; + + _statusBar.GetWindowRect(&rect); + kStatusBarSize = rect.bottom - rect.top; + + // _statusBar2.GetWindowRect(&rect); + // kStatusBar2Size = rect.bottom - rect.top; + + int yListViewSize = MyMax(ySize - kHeaderSize - kStatusBarSize, 0); + const int kStartXPos = 32; + if (_headerReBar) + { + } + else + { + _headerToolBar.Move(0, 0, xSize, 0); + _headerComboBox.Move(kStartXPos, 2, + MyMax(xSize - kStartXPos - 10, kStartXPos), 0); + } + _listView.Move(0, kHeaderSize, xSize, yListViewSize); + _statusBar.Move(0, kHeaderSize + yListViewSize, xSize, kStatusBarSize); + // _statusBar2.MoveWindow(0, kHeaderSize + yListViewSize + kStatusBarSize, xSize, kStatusBar2Size); + // _statusBar.MoveWindow(0, 100, xSize, kStatusBarSize); + // _statusBar2.MoveWindow(0, 200, xSize, kStatusBar2Size); +} + +bool CPanel::OnSize(WPARAM /* wParam */, int xSize, int ySize) +{ + if (_headerReBar) + _headerReBar.Move(0, 0, xSize, 0); + ChangeWindowSize(xSize, ySize); + return true; +} + +bool CPanel::OnNotifyReBar(LPNMHDR header, LRESULT & /* result */) +{ + switch(header->code) + { + case RBN_HEIGHTCHANGE: + { + RECT rect; + GetWindowRect(&rect); + ChangeWindowSize(rect.right - rect.left, rect.bottom - rect.top); + return false; + } + } + return false; +} + +bool CPanel::OnNotify(UINT /* controlID */, LPNMHDR header, LRESULT &result) +{ + if (!_processNotify) + return false; + if (header->hwndFrom == _headerComboBox) + return OnNotifyComboBox(header, result); + else if (header->hwndFrom == _headerReBar) + return OnNotifyReBar(header, result); + // if (header->hwndFrom == _listView) + else if (header->hwndFrom == _listView) + return OnNotifyList(header, result); + else if (::GetParent(header->hwndFrom) == _listView && + header->code == NM_RCLICK) + return OnRightClick((LPNMITEMACTIVATE)header, result); + return false; +} + +bool CPanel::OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result) +{ + if (itemID == kParentFolderID) + { + OpenParentFolder(); + result = 0; + return true; + } + /* + if (itemID == kCreateFolderID) + { + CreateFolder(); + result = 0; + return true; + } + */ + if (itemID == _comboBoxID) + { + OnComboBoxCommand(code, lParam); + } + return CWindow2::OnCommand(code, itemID, lParam, result); +} + +void CPanel::MessageBoxInfo(LPCWSTR message, LPCWSTR caption) + { ::MessageBoxW(HWND(*this), message, caption, MB_OK); } +void CPanel::MessageBox(LPCWSTR message, LPCWSTR caption) + { ::MessageBoxW(HWND(*this), message, caption, MB_OK | MB_ICONSTOP); } +void CPanel::MessageBox(LPCWSTR message) + { MessageBox(message, L"7-Zip"); } +void CPanel::MessageBoxMyError(LPCWSTR message) + { MessageBox(message, L"Error"); } +void CPanel::MessageBoxError(HRESULT errorCode, LPCWSTR caption) + { MessageBox(NError::MyFormatMessageW(errorCode), caption); } +void CPanel::MessageBoxError(HRESULT errorCode) + { MessageBoxError(errorCode, L"7-Zip"); } +void CPanel::MessageBoxLastError(LPCWSTR caption) + { MessageBoxError(::GetLastError(), caption); } +void CPanel::MessageBoxLastError() + { MessageBoxLastError(L"Error"); } + +void CPanel::SetFocusToList() +{ + _listView.SetFocus(); + // SetCurrentPathText(); +} + +void CPanel::SetFocusToLastRememberedItem() +{ + if (_lastFocusedIsList) + SetFocusToList(); + else + _headerComboBox.SetFocus(); +} + +UString CPanel::GetFolderTypeID() const +{ + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(kpidType, &prop) == S_OK) + if (prop.vt == VT_BSTR) + return (const wchar_t *)prop.bstrVal; + return L""; +} + +bool CPanel::IsRootFolder() const +{ + return (GetFolderTypeID() == L"RootFolder"); +} + +bool CPanel::IsFSFolder() const +{ + return (GetFolderTypeID() == L"FSFolder"); +} + +bool CPanel::IsFSDrivesFolder() const +{ + return (GetFolderTypeID() == L"FSDrives"); +} + +UString CPanel::GetFsPath() const +{ + if (IsFSDrivesFolder()) + return UString(); + return _currentFolderPrefix; +} + +UString CPanel::GetDriveOrNetworkPrefix() const +{ + if (!IsFSFolder()) + return UString(); + UString drive = GetFsPath(); + if (drive.Length() < 3) + return UString(); + if (drive[0] == L'\\' && drive[1] == L'\\') + { + // if network + int pos = drive.Find(L'\\', 2); + if (pos < 0) + return UString(); + pos = drive.Find(L'\\', pos + 1); + if (pos < 0) + return UString(); + return drive.Left(pos + 1); + } + if (drive[1] != L':' || drive[2] != L'\\') + return UString(); + return drive.Left(3); +} + +bool CPanel::DoesItSupportOperations() const +{ + CMyComPtr folderOperations; + return _folder.QueryInterface(IID_IFolderOperations, &folderOperations) == S_OK; +} + +void CPanel::SetListViewMode(UInt32 index) +{ + if (index >= 4) + return; + _ListViewMode = index; + DWORD oldStyle = (DWORD)_listView.GetStyle(); + DWORD newStyle = kStyles[index]; + if ((oldStyle & LVS_TYPEMASK) != newStyle) + _listView.SetStyle((oldStyle & ~LVS_TYPEMASK) | newStyle); + // RefreshListCtrlSaveFocused(); +} + +void CPanel::ChangeFlatMode() +{ + _flatMode = !_flatMode; + RefreshListCtrlSaveFocused(); +} + + +void CPanel::RefreshStatusBar() +{ + PostMessage(kRefreshStatusBar); +} + +void CPanel::AddToArchive() +{ + CRecordVector indices; + GetOperatedItemIndices(indices); + if (!IsFSFolder()) + { + MessageBox(L"Compress operation is not supported for that folder"); + return; + } + if (indices.Size() == 0) + { + MessageBox(kSelectFiles); + return; + } + UStringVector names; + for (int i = 0; i < indices.Size(); i++) + { + int index = indices[i]; + names.Add(_currentFolderPrefix + GetItemRelPath(index)); + } + const UString archiveName = CreateArchiveName( + names.Front(), (names.Size() > 1), false); + HRESULT res = CompressFiles(_currentFolderPrefix, archiveName, L"", names, false, true, false); + if (res != S_OK) + { + if (_currentFolderPrefix.Length() >= MAX_PATH) + MessageBox(L"Can't call this operation for file with long path"); + else + MessageBoxError(res, L"Error"); + } + // KillSelection(); +} + +static UString GetSubFolderNameForExtract(const UString &archiveName) +{ + int slashPos = archiveName.ReverseFind(L'\\'); + int dotPos = archiveName.ReverseFind(L'.'); + if (dotPos < 0 || slashPos > dotPos) + return archiveName + UString(L"~"); + UString res = archiveName.Left(dotPos); + res.TrimRight(); + return res; +} + +void CPanel::ExtractArchives() +{ + if (_parentFolders.Size() > 0) + { + _panelCallback->OnCopy(false, false); + return; + } + CRecordVector indices; + GetOperatedItemIndices(indices); + UStringVector paths; + if (indices.Size() == 0) + { + // GetAllItemIndices(indices); + MessageBox(kSelectOneFile); + return; + } + for (int i = 0; i < indices.Size(); i++) + { + int index = indices[i]; + if (IsItemFolder(index)) + { + MessageBox(kSelectOneFile); + return; + } + paths.Add(_currentFolderPrefix + GetItemRelPath(index)); + } + UString folderName; + if (indices.Size() == 1) + folderName = GetSubFolderNameForExtract(GetItemRelPath(indices[0])); + else + folderName = L"*"; + ::ExtractArchives(paths, _currentFolderPrefix + folderName + UString(L"\\"), true); +} + +struct CThreadTest +{ + CRecordVector Indices; + CExtractCallbackImp *ExtractCallbackSpec; + CMyComPtr ExtractCallback; + CMyComPtr ArchiveFolder; + HRESULT Result; + + DWORD Test() + { + ExtractCallbackSpec->ProgressDialog.WaitCreating(); + Result = ArchiveFolder->Extract(&Indices[0], Indices.Size(), + NExtract::NPathMode::kFullPathnames, NExtract::NOverwriteMode::kAskBefore, + NULL, BoolToInt(true), ExtractCallback); + ExtractCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadTest*)param)->Test(); + } +}; + +static void AddValuePair(UINT resourceID, UInt32 langID, UInt64 values, UString &s) +{ + wchar_t sz[32]; + s += LangString(resourceID, langID); + s += L" "; + ConvertUInt64ToString(values, sz); + s += sz; + s += L"\n"; +} + +/* +static void AddSizePair(UINT resourceID, UInt32 langID, UInt64 value, UString &s) +{ + wchar_t sz[32]; + s += LangString(resourceID, langID); + s += L" "; + ConvertUInt64ToString(value, sz); + s += sz; + ConvertUInt64ToString(value >> 20, sz); + s += L" ("; + s += sz; + s += L" MB)"; + s += L"\n"; +} +*/ + +void CPanel::TestArchives() +{ + CRecordVector indices; + GetOperatedItemIndices(indices); + CMyComPtr archiveFolder; + _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder); + if (archiveFolder) + { + CThreadTest extracter; + + extracter.ArchiveFolder = archiveFolder; + extracter.ExtractCallbackSpec = new CExtractCallbackImp; + extracter.ExtractCallback = extracter.ExtractCallbackSpec; + extracter.ExtractCallbackSpec->ParentWindow = GetParent(); + extracter.ExtractCallbackSpec->ShowMessages = true; + + if (indices.IsEmpty()) + GetAllItemIndices(indices); + if (indices.IsEmpty()) + return; + + extracter.Indices = indices; + + UString title = LangString(IDS_PROGRESS_TESTING, 0x02000F90); + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + + extracter.ExtractCallbackSpec->ProgressDialog.CompressingMode = false; + extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = GetParent(); + extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle; + extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" "; + + extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + extracter.ExtractCallbackSpec->Init(); + + NWindows::CThread extractThread; + if (extractThread.Create(CThreadTest::MyThreadFunction, &extracter) != S_OK) + return; + extracter.ExtractCallbackSpec->StartProgressDialog(title); + + if (extracter.ExtractCallbackSpec->Messages.IsEmpty() && extracter.Result == S_OK) + { + UString s; + AddValuePair(IDS_FOLDERS_COLON, 0x02000321, extracter.ExtractCallbackSpec->NumFolders, s); + AddValuePair(IDS_FILES_COLON, 0x02000320, extracter.ExtractCallbackSpec->NumFiles, s); + // AddSizePair(IDS_SIZE_COLON, 0x02000322, extracter.Stat.UnpackSize, s); + // AddSizePair(IDS_COMPRESSED_COLON, 0x02000323, extracter.Stat.PackSize, s); + s += L"\n"; + s += LangString(IDS_MESSAGE_NO_ERRORS, 0x02000608); + MessageBoxInfo(s, LangString(IDS_PROGRESS_TESTING, 0x02000F90)); + } + else + { + if (extracter.Result != S_OK && extracter.Result != E_ABORT) + MessageBoxError(extracter.Result, L"Testing Error"); + } + return; + } + + if (!IsFSFolder()) + { + MessageBox(L"Test archive operation is not supported for that folder"); + return; + } + UStringVector paths; + if (indices.Size() == 0) + { + MessageBox(kSelectOneFile); + return; + } + for (int i = 0; i < indices.Size(); i++) + { + int index = indices[i]; + if (IsItemFolder(index)) + { + MessageBox(kSelectOneFile); + return; + } + paths.Add(_currentFolderPrefix + GetItemRelPath(index)); + } + ::TestArchives(paths); +} + diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h new file mode 100755 index 00000000..1f6dc140 --- /dev/null +++ b/CPP/7zip/UI/FileManager/Panel.h @@ -0,0 +1,511 @@ +// Panel.h + +#ifndef __PANEL_H +#define __PANEL_H + +#include "Common/MyCom.h" + +#include "Windows/DLL.h" +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" +#include "Windows/Synchronization.h" +#include "Windows/Handle.h" + +#include "Windows/Control/ToolBar.h" +#include "Windows/Control/ReBar.h" +#include "Windows/Control/ListView.h" +#include "Windows/Control/Static.h" +#include "Windows/Control/Edit.h" +#include "Windows/Control/ComboBox.h" +#include "Windows/Control/Window2.h" +#include "Windows/Control/StatusBar.h" + +#include "SysIconUtils.h" +#include "IFolder.h" +#include "ViewSettings.h" +#include "AppState.h" +#include "MyCom2.h" + +const int kParentFolderID = 100; +const int kPluginMenuStartID = 1000; +const int kToolbarStartID = 2000; + +const int kParentIndex = -1; + +class CPanelCallback +{ +public: + virtual void OnTab() = 0; + virtual void SetFocusToPath(int index) = 0; + virtual void OnCopy(bool move, bool copyToSame) = 0; + virtual void OnSetSameFolder() = 0; + virtual void OnSetSubFolder() = 0; + virtual void PanelWasFocused() = 0; + virtual void DragBegin() = 0; + virtual void DragEnd() = 0; +}; + +void PanelCopyItems(); + +struct CItemProperty +{ + UString Name; + PROPID ID; + VARTYPE Type; + int Order; + bool IsVisible; + UInt32 Width; +}; + +inline bool operator<(const CItemProperty &a1, const CItemProperty &a2) + { return (a1.Order < a2.Order); } + +inline bool operator==(const CItemProperty &a1, const CItemProperty &a2) + { return (a1.Order == a2.Order); } + +class CItemProperties: public CObjectVector +{ +public: + int FindItemWithID(PROPID id) + { + for (int i = 0; i < Size(); i++) + if ((*this)[i].ID == id) + return i; + return -1; + } +}; + +struct CTempFileInfo +{ + UString ItemName; + UString FolderPath; + UString FilePath; + NWindows::NFile::NFind::CFileInfoW FileInfo; + void DeleteDirAndFile() + { + NWindows::NFile::NDirectory::DeleteFileAlways(FilePath); + NWindows::NFile::NDirectory::MyRemoveDirectory(FolderPath); + } +}; + +struct CFolderLink: public CTempFileInfo +{ + NWindows::NDLL::CLibrary Library; + CMyComPtr ParentFolder; +}; + +enum MyMessages +{ + kShiftSelectMessage = WM_USER + 1, + kReLoadMessage, + kSetFocusToListView, + kOpenItemChanged, + kRefreshStatusBar +}; + +UString GetFolderPath(IFolderFolder * folder); + +class CPanel; + +class CMyListView: public NWindows::NControl::CListView +{ +public: + WNDPROC _origWindowProc; + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; + +/* +class CMyComboBox: public NWindows::NControl::CComboBoxEx +{ +public: + WNDPROC _origWindowProc; + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; +*/ +class CMyComboBoxEdit: public NWindows::NControl::CEdit +{ +public: + WNDPROC _origWindowProc; + CPanel *_panel; + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); +}; + +struct CSelectedState +{ + int FocusedItem; + UString FocusedName; + bool SelectFocused; + UStringVector SelectedNames; + CSelectedState(): FocusedItem(-1), SelectFocused(false) {} +}; + +class CPanel:public NWindows::NControl::CWindow2 +{ + HWND _mainWindow; + + CExtToIconMap _extToIconMap; + UINT _baseID; + int _comboBoxID; + UINT _statusBarID; + + CAppState *_appState; + + bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result); + LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnCreate(CREATESTRUCT *createStruct); + virtual bool OnSize(WPARAM wParam, int xSize, int ySize); + virtual void OnDestroy(); + virtual bool OnNotify(UINT controlID, LPNMHDR lParam, LRESULT &result); + void OnComboBoxCommand(UINT code, LPARAM &aParam); + bool OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result); + #ifndef _UNICODE + bool OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result); + #endif + bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result); + bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result); + void OnItemChanged(NMLISTVIEW *item); + bool OnNotifyList(LPNMHDR lParam, LRESULT &result); + void OnDrag(LPNMLISTVIEW nmListView); + bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result); + BOOL OnBeginLabelEdit(LV_DISPINFOW * lpnmh); + BOOL OnEndLabelEdit(LV_DISPINFOW * lpnmh); + void OnColumnClick(LPNMLISTVIEW info); + bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result); + +public: + CPanelCallback *_panelCallback; + + void DeleteItems(bool toRecycleBin); + void DeleteItemsInternal(CRecordVector &indices); + void CreateFolder(); + void CreateFile(); + +private: + + void ChangeWindowSize(int xSize, int ySize); + + void InitColumns(); + // void InitColumns2(PROPID sortID); + void InsertColumn(int index); + + void SetFocusedSelectedItem(int index, bool select); + void RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, + const UStringVector &selectedNames); + + void OnShiftSelectMessage(); + void OnArrowWithShift(); + + void OnInsert(); + // void OnUpWithShift(); + // void OnDownWithShift(); +public: + void UpdateSelection(); + void SelectSpec(bool selectMode); + void SelectByType(bool selectMode); + void SelectAll(bool selectMode); + void InvertSelection(); +private: + + // UString GetFileType(UInt32 index); + LRESULT SetItemText(LVITEMW &item); + + // CRecordVector m_ColumnsPropIDs; + +public: + NWindows::NControl::CReBar _headerReBar; + NWindows::NControl::CToolBar _headerToolBar; + NWindows::NControl::CComboBoxEx _headerComboBox; + // CMyComboBox _headerComboBox; + CMyComboBoxEdit _comboBoxEdit; + CMyListView _listView; + NWindows::NControl::CStatusBar _statusBar; + bool _lastFocusedIsList; + // NWindows::NControl::CStatusBar _statusBar2; + + DWORD _exStyle; + bool _showDots; + bool _showRealFileIcons; + // bool _virtualMode; + // CUIntVector _realIndices; + bool _enableItemChangeNotify; + bool _mySelectMode; + CBoolVector _selectedStatusVector; + + CSelectedState _selectedState; + + UInt32 GetRealIndex(const LVITEMW &item) const + { + /* + if (_virtualMode) + return _realIndices[item.iItem]; + */ + return (UInt32)item.lParam; + } + int GetRealItemIndex(int indexInListView) const + { + /* + if (_virtualMode) + return indexInListView; + */ + LPARAM param; + if (!_listView.GetItemParam(indexInListView, param)) + throw 1; + return (int)param; + } + + UInt32 _ListViewMode; + int _xSize; + + bool _flatMode; + + bool _dontShowMode; + + + UString _currentFolderPrefix; + + CObjectVector _parentFolders; + NWindows::NDLL::CLibrary _library; + CMyComPtr _folder; + // CMyComPtr _folderGetSystemIconIndex; + + UStringVector _fastFolders; + + void GetSelectedNames(UStringVector &selectedNames); + void SaveSelectedState(CSelectedState &s); + void RefreshListCtrl(const CSelectedState &s); + void RefreshListCtrlSaveFocused(); + + UString GetItemName(int itemIndex) const; + UString GetItemPrefix(int itemIndex) const; + UString GetItemRelPath(int itemIndex) const; + bool IsItemFolder(int itemIndex) const; + UInt64 GetItemSize(int itemIndex) const; + + //////////////////////// + // PanelFolderChange.cpp + + void SetToRootFolder(); + HRESULT BindToPath(const UString &fullPath, bool &archiveIsOpened, bool &encrypted); // can be prefix + HRESULT BindToPathAndRefresh(const UString &path); + void OpenDrivesFolder(); + + void SetBookmark(int index); + void OpenBookmark(int index); + + void LoadFullPath(); + void LoadFullPathAndShow(); + void FoldersHistory(); + void OpenParentFolder(); + void CloseOpenFolders(); + void OpenRootFolder(); + + + LRESULT Create(HWND mainWindow, HWND parentWindow, + UINT id, + const UString ¤tFolderPrefix, + CPanelCallback *panelCallback, + CAppState *appState, bool &archiveIsOpened, bool &encrypted); + void SetFocusToList(); + void SetFocusToLastRememberedItem(); + + + void ReadListViewInfo(); + void SaveListViewInfo(); + + CPanel() : + // _virtualMode(flase), + _exStyle(0), + _showDots(false), + _showRealFileIcons(false), + _needSaveInfo(false), + _startGroupSelect(0), + _selectionIsDefined(false), + _ListViewMode(3), + _flatMode(false), + _xSize(300), + _mySelectMode(false), + _enableItemChangeNotify(true), + _dontShowMode(false) + {} + + void SetExtendedStyle() + { + if (_listView != 0) + _listView.SetExtendedListViewStyle(_exStyle); + } + + + bool _needSaveInfo; + UString _typeIDString; + CListViewInfo _listViewInfo; + CItemProperties _properties; + CItemProperties _visibleProperties; + + PROPID _sortID; + // int _sortIndex; + bool _ascending; + + void Release(); + ~CPanel(); + void OnLeftClick(LPNMITEMACTIVATE itemActivate); + bool OnRightClick(LPNMITEMACTIVATE itemActivate, LRESULT &result); + + void OnTimer(); + void OnReload(); + bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos); + + CMyComPtr _sevenZipContextMenu; + CMyComPtr _systemContextMenu; + HRESULT CreateShellContextMenu( + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu); + void CreateSystemMenu(HMENU menu, + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu); + void CreateSevenZipMenu(HMENU menu, + const CRecordVector &operatedIndices, + CMyComPtr &sevenZipContextMenu); + void CreateFileMenu(HMENU menu, + CMyComPtr &sevenZipContextMenu, + CMyComPtr &systemContextMenu, + bool programMenu); + void CreateFileMenu(HMENU menu); + bool InvokePluginCommand(int id); + bool InvokePluginCommand(int id, IContextMenu *sevenZipContextMenu, + IContextMenu *systemContextMenu); + + void InvokeSystemCommand(const char *command); + void Properties(); + void EditCopy(); + void EditPaste(); + + int _startGroupSelect; + + bool _selectionIsDefined; + bool _selectMark; + int _prevFocusedItem; + + + // void SortItems(int index); + void SortItemsWithPropID(PROPID propID); + + void GetSelectedItemsIndices(CRecordVector &indices) const; + void GetOperatedItemIndices(CRecordVector &indices) const; + void GetAllItemIndices(CRecordVector &indices) const; + // void GetOperatedListViewIndices(CRecordVector &indices) const; + void KillSelection(); + + UString GetFolderTypeID() const; + bool IsRootFolder() const; + bool IsFSFolder() const; + bool IsFSDrivesFolder() const; + + UString GetFsPath() const; + UString GetDriveOrNetworkPrefix() const; + + bool DoesItSupportOperations() const; + + bool _processTimer; + bool _processNotify; + + class CDisableTimerProcessing + { + bool _processTimerMem; + bool _processNotifyMem; + + CPanel &_panel; + public: + + CDisableTimerProcessing(CPanel &panel): _panel(panel) + { + Disable(); + } + void Disable() + { + _processTimerMem = _panel._processTimer; + _processNotifyMem = _panel._processNotify; + _panel._processTimer = false; + _panel._processNotify = false; + } + void Restore() + { + _panel._processTimer = _processTimerMem; + _panel._processNotify = _processNotifyMem; + } + ~CDisableTimerProcessing() + { + Restore(); + } + CDisableTimerProcessing& operator=(const CDisableTimerProcessing &) {; } + }; + + // bool _passwordIsDefined; + // UString _password; + + void RefreshListCtrl(); + + void MessageBoxInfo(LPCWSTR message, LPCWSTR caption); + void MessageBox(LPCWSTR message); + void MessageBox(LPCWSTR message, LPCWSTR caption); + void MessageBoxMyError(LPCWSTR message); + void MessageBoxError(HRESULT errorCode, LPCWSTR caption); + void MessageBoxError(HRESULT errorCode); + void MessageBoxLastError(LPCWSTR caption); + void MessageBoxLastError(); + + + void OpenFocusedItemAsInternal(); + void OpenSelectedItems(bool internal); + + void OpenFolderExternal(int index); + + void OpenFolder(int index); + HRESULT OpenParentArchiveFolder(); + HRESULT OpenItemAsArchive(const UString &name, + const UString &folderPath, + const UString &filePath, bool &encrypted); + HRESULT OpenItemAsArchive(const UString &aName); + HRESULT OpenItemAsArchive(int index); + void OpenItemInArchive(int index, bool tryInternal, bool tryExternal, + bool editMode); + HRESULT OnOpenItemChanged(const UString &folderPath, const UString &itemName); + LRESULT OnOpenItemChanged(LPARAM lParam); + + void OpenItem(int index, bool tryInternal, bool tryExternal); + void EditItem(); + void EditItem(int index); + + void RenameFile(); + void ChangeComment(); + + void SetListViewMode(UInt32 index); + UInt32 GetListViewMode() const { return _ListViewMode; }; + + void ChangeFlatMode(); + bool GetFlatMode() const { return _flatMode; }; + + void RefreshStatusBar(); + void OnRefreshStatusBar(); + + void AddToArchive(); + void ExtractArchives(); + void TestArchives(); + + HRESULT CopyTo(const CRecordVector &indices, const UString &folder, + bool moveMode, bool showErrorMessages, UStringVector *messages); + + HRESULT CopyFrom(const UString &folderPrefix, const UStringVector &filePaths, + bool showErrorMessages, UStringVector *messages); + + void CopyFrom(const UStringVector &filePaths); + + // empty folderPath means create new Archive to path of first fileName. + void DropObject(IDataObject * dataObject, const UString &folderPath); + + // empty folderPath means create new Archive to path of first fileName. + void CompressDropFiles(const UStringVector &fileNames, const UString &folderPath); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/PanelCopy.cpp b/CPP/7zip/UI/FileManager/PanelCopy.cpp new file mode 100755 index 00000000..0bb5dafa --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelCopy.cpp @@ -0,0 +1,203 @@ +// PanelExtract.cpp + +#include "StdAfx.h" + +#include "Panel.h" +#include "resource.h" +#include "LangUtils.h" +#include "ExtractCallback.h" +#include "Windows/Thread.h" +//////////////////////////////////////////////////////////////// + +#include "UpdateCallback100.h" + +using namespace NWindows; + +struct CThreadExtractInArchive2 +{ + CMyComPtr FolderOperations; + CRecordVector Indices; + UString DestPath; + CExtractCallbackImp *ExtractCallbackSpec; + CMyComPtr ExtractCallback; + HRESULT Result; + bool MoveMode; + + CThreadExtractInArchive2(): MoveMode(false) {} + + DWORD Extract() + { + ExtractCallbackSpec->ProgressDialog.WaitCreating(); + if (MoveMode) + Result = FolderOperations->MoveTo(&Indices.Front(), Indices.Size(), + DestPath, ExtractCallback); + else + Result = FolderOperations->CopyTo(&Indices.Front(), Indices.Size(), + DestPath, ExtractCallback); + ExtractCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadExtractInArchive2 *)param)->Extract(); + } +}; + +HRESULT CPanel::CopyTo(const CRecordVector &indices, const UString &folder, + bool moveMode, bool showErrorMessages, UStringVector *messages) +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); + if (showErrorMessages) + MessageBox(errorMessage); + else if (messages != 0) + messages->Add(errorMessage); + return E_FAIL; + } + + CThreadExtractInArchive2 extracter; + + extracter.ExtractCallbackSpec = new CExtractCallbackImp; + extracter.ExtractCallback = extracter.ExtractCallbackSpec; + extracter.ExtractCallbackSpec->ParentWindow = GetParent(); + extracter.ExtractCallbackSpec->ShowMessages = showErrorMessages; + extracter.ExtractCallbackSpec->ProgressDialog.CompressingMode = false; + + UString title = moveMode ? + LangString(IDS_MOVING, 0x03020206): + LangString(IDS_COPYING, 0x03020205); + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + + extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = GetParent(); + extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle; + extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" "; + + extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + extracter.ExtractCallbackSpec->Init(); + extracter.Indices = indices; + extracter.DestPath = folder; + extracter.FolderOperations = folderOperations; + extracter.MoveMode = moveMode; + + NWindows::CThread extractThread; + RINOK(extractThread.Create(CThreadExtractInArchive2::MyThreadFunction, &extracter)); + extracter.ExtractCallbackSpec->StartProgressDialog(title); + + if (messages != 0) + *messages = extracter.ExtractCallbackSpec->Messages; + return extracter.Result; +} + + +struct CThreadUpdate +{ + CMyComPtr FolderOperations; + UString FolderPrefix; + UStringVector FileNames; + CRecordVector FileNamePointers; + CMyComPtr UpdateCallback; + CUpdateCallback100Imp *UpdateCallbackSpec; + HRESULT Result; + + DWORD Process() + { + UpdateCallbackSpec->ProgressDialog.WaitCreating(); + Result = FolderOperations->CopyFrom( + FolderPrefix, + &FileNamePointers.Front(), + FileNamePointers.Size(), + UpdateCallback); + UpdateCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadUpdate *)param)->Process(); + } +}; + + +HRESULT CPanel::CopyFrom(const UString &folderPrefix, const UStringVector &filePaths, + bool showErrorMessages, UStringVector *messages) +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); + if (showErrorMessages) + MessageBox(errorMessage); + else if (messages != 0) + messages->Add(errorMessage); + return E_FAIL; + } + + CThreadUpdate updater; + updater.UpdateCallbackSpec = new CUpdateCallback100Imp; + updater.UpdateCallback = updater.UpdateCallbackSpec; + + UString title = LangString(IDS_COPYING, 0x03020205); + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + + updater.UpdateCallbackSpec->ProgressDialog.MainWindow = GetParent(); + updater.UpdateCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle; + updater.UpdateCallbackSpec->ProgressDialog.MainAddTitle = title + UString(L" "); + + updater.UpdateCallbackSpec->Init((HWND)*this, false, L""); + updater.FolderOperations = folderOperations; + updater.FolderPrefix = folderPrefix; + updater.FileNames.Reserve(filePaths.Size()); + int i; + for(i = 0; i < filePaths.Size(); i++) + updater.FileNames.Add(filePaths[i]); + updater.FileNamePointers.Reserve(updater.FileNames.Size()); + for(i = 0; i < updater.FileNames.Size(); i++) + updater.FileNamePointers.Add(updater.FileNames[i]); + + NWindows::CThread thread; + RINOK(thread.Create(CThreadUpdate::MyThreadFunction, &updater)); + updater.UpdateCallbackSpec->StartProgressDialog(title); + + if (messages != 0) + *messages = updater.UpdateCallbackSpec->Messages; + + return updater.Result; +} + +void CPanel::CopyFrom(const UStringVector &filePaths) +{ + UString title = LangString(IDS_CONFIRM_FILE_COPY, 0x03020222); + UString message = LangString(IDS_WANT_TO_COPY_FILES, 0x03020223); + message += L"\n\'"; + message += _currentFolderPrefix; + message += L"\' ?"; + int res = ::MessageBoxW(*(this), message, title, MB_YESNOCANCEL | MB_ICONQUESTION | MB_SYSTEMMODAL); + if (res != IDYES) + return; + + CDisableTimerProcessing disableTimerProcessing(*this); + + CSelectedState srcSelState; + SaveSelectedState(srcSelState); + + HRESULT result = CopyFrom(L"", filePaths, true, 0); + + if (result != S_OK) + { + disableTimerProcessing.Restore(); + // For Password: + SetFocusToList(); + if (result != E_ABORT) + MessageBoxError(result); + return; + } + + RefreshListCtrl(srcSelState); + + disableTimerProcessing.Restore(); + SetFocusToList(); +} + diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp new file mode 100755 index 00000000..b2163742 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp @@ -0,0 +1,365 @@ +// PanelSplitFile.cpp + +#include "StdAfx.h" + +#include "resource.h" + +extern "C" +{ + #include "../../../../C/Alloc.h" + #include "../../../../C/7zCrc.h" +} + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/FileIO.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/Thread.h" +#include "Windows/Error.h" + +#include "ProgressDialog2.h" +#include "OverwriteDialogRes.h" + +#include "App.h" +#include "FormatUtils.h" +#include "LangUtils.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +static const UInt32 kBufSize = (1 << 15); + +struct CDirEnumerator +{ + bool FlatMode; + UString BasePrefix; + UStringVector FileNames; + + CObjectVector Enumerators; + UStringVector Prefixes; + int Index; + bool GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &fullPath, DWORD &errorCode); + void Init(); + + CDirEnumerator(): FlatMode(false) {}; +}; + +void CDirEnumerator::Init() +{ + Enumerators.Clear(); + Prefixes.Clear(); + Index = 0; +} + +bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &resPath, DWORD &errorCode) +{ + filled = false; + for (;;) + { + if (Enumerators.IsEmpty()) + { + if (Index >= FileNames.Size()) + return true; + const UString &path = FileNames[Index]; + int pos = path.ReverseFind('\\'); + resPath.Empty(); + if (pos >= 0) + resPath = path.Left(pos + 1); + if (!NFind::FindFile(BasePrefix + path, fileInfo)) + { + errorCode = ::GetLastError(); + resPath = path; + return false; + } + Index++; + break; + } + bool found; + if (!Enumerators.Back().Next(fileInfo, found)) + { + errorCode = ::GetLastError(); + resPath = Prefixes.Back(); + return false; + } + if (found) + { + resPath = Prefixes.Back(); + break; + } + Enumerators.DeleteBack(); + Prefixes.DeleteBack(); + } + resPath += fileInfo.Name; + if (!FlatMode && fileInfo.IsDirectory()) + { + UString prefix = resPath + (UString)(wchar_t)kDirDelimiter; + Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)kAnyStringWildcard)); + Prefixes.Add(prefix); + } + filled = true; + return true; +} + +struct CThreadCrc +{ + class CMyBuffer + { + void *_data; + public: + CMyBuffer(): _data(0) {} + operator void *() { return _data; } + bool Allocate(size_t size) + { + if (_data != 0) + return false; + _data = ::MidAlloc(size); + return _data != 0; + } + ~CMyBuffer() { ::MidFree(_data); } + }; + + CProgressDialog *ProgressDialog; + + CDirEnumerator DirEnumerator; + + UInt64 NumFiles; + UInt64 NumFolders; + UInt64 DataSize; + UInt32 DataCrcSum; + UInt32 DataNameCrcSum; + + HRESULT Result; + DWORD ErrorCode; + UString ErrorPath; + UString Error; + bool ThereIsError; + + void Process2() + { + DataSize = NumFolders = NumFiles = DataCrcSum = DataNameCrcSum = 0; + ProgressDialog->WaitCreating(); + + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + { + Error = L"Can not allocate memory"; + ThereIsError = true; + return; + } + Byte *buffer = (Byte *)(void *)bufferObject; + + UInt64 totalSize = 0; + + DirEnumerator.Init(); + + UString scanningStr = LangString(IDS_SCANNING, 0x03020800); + scanningStr += L" "; + + for (;;) + { + NFile::NFind::CFileInfoW fileInfo; + bool filled; + UString resPath; + if (!DirEnumerator.GetNextFile(fileInfo, filled, resPath, ErrorCode)) + { + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (!filled) + break; + if (!fileInfo.IsDirectory()) + totalSize += fileInfo.Size; + ProgressDialog->ProgressSynch.SetCurrentFileName(scanningStr + resPath); + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(0); + if (Result != S_OK) + return; + } + + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + + DirEnumerator.Init(); + + for (;;) + { + NFile::NFind::CFileInfoW fileInfo; + bool filled; + UString resPath; + if (!DirEnumerator.GetNextFile(fileInfo, filled, resPath, ErrorCode)) + { + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (!filled) + break; + + UInt32 crc = CRC_INIT_VAL; + if (fileInfo.IsDirectory()) + NumFolders++; + else + { + NFile::NIO::CInFile inFile; + if (!inFile.Open(DirEnumerator.BasePrefix + resPath)) + { + ErrorCode = ::GetLastError(); + ThereIsError = true; + ErrorPath = resPath; + return; + } + NumFiles++; + ProgressDialog->ProgressSynch.SetCurrentFileName(resPath); + for (;;) + { + UInt32 processedSize; + if (!inFile.Read(buffer, kBufSize, processedSize)) + { + ErrorCode = ::GetLastError(); + ThereIsError = true; + ErrorPath = resPath; + return; + } + if (processedSize == 0) + break; + crc = CrcUpdate(crc, buffer, processedSize); + DataSize += processedSize; + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(DataSize); + if (Result != S_OK) + return; + } + DataCrcSum += CRC_GET_DIGEST(crc); + } + for (int i = 0; i < resPath.Length(); i++) + { + wchar_t c = resPath[i]; + crc = CRC_UPDATE_BYTE(crc, ((Byte)(c & 0xFF))); + crc = CRC_UPDATE_BYTE(crc, ((Byte)((c >> 8) & 0xFF))); + } + DataNameCrcSum += CRC_GET_DIGEST(crc); + Result = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(DataSize); + if (Result != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(...) { Error = L"Error"; ThereIsError = true;} + ProgressDialog->MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadCrc *)param)->Process(); + } +}; + +static void ConvertUInt32ToHex(UInt32 value, wchar_t *s) +{ + for (int i = 0; i < 8; i++) + { + int t = value & 0xF; + value >>= 4; + s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10))); + } + s[8] = L'\0'; +} + +void CApp::CalculateCrc() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CRecordVector indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + + CThreadCrc combiner; + for (int i = 0; i < indices.Size(); i++) + combiner.DirEnumerator.FileNames.Add(srcPanel.GetItemRelPath(indices[i])); + combiner.DirEnumerator.BasePrefix = srcPanel._currentFolderPrefix; + combiner.DirEnumerator.FlatMode = GetFlatMode(); + + CProgressDialog progressDialog; + combiner.ProgressDialog = &progressDialog; + combiner.ErrorCode = 0; + combiner.Result = S_OK; + combiner.ThereIsError = false; + + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + UString title = LangString(IDS_CHECKSUM_CALCULATING, 0x03020710); + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title + UString(L" "); + + NWindows::CThread thread; + if (thread.Create(CThreadCrc::MyThreadFunction, &combiner) != S_OK) + return; + progressDialog.Create(title, _window); + + if (combiner.Result != S_OK) + { + if (combiner.Result != E_ABORT) + srcPanel.MessageBoxError(combiner.Result); + } + else if (combiner.ThereIsError) + { + if (combiner.Error.IsEmpty()) + { + UString message = combiner.DirEnumerator.BasePrefix + combiner.ErrorPath; + message += L"\n"; + message += NError::MyFormatMessageW(combiner.ErrorCode); + srcPanel.MessageBoxMyError(message); + } + else + srcPanel.MessageBoxMyError(combiner.Error); + } + else + { + UString s; + { + wchar_t sz[32]; + + s += LangString(IDS_FILES_COLON, 0x02000320); + s += L" "; + ConvertUInt64ToString(combiner.NumFiles, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_FOLDERS_COLON, 0x02000321); + s += L" "; + ConvertUInt64ToString(combiner.NumFolders, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_SIZE_COLON, 0x02000322); + s += L" "; + ConvertUInt64ToString(combiner.DataSize, sz); + s += MyFormatNew(IDS_FILE_SIZE, 0x02000982, sz);; + s += L"\n"; + + s += LangString(IDS_CHECKSUM_CRC_DATA, 0x03020721); + s += L" "; + ConvertUInt32ToHex(combiner.DataCrcSum, sz); + s += sz; + s += L"\n"; + + s += LangString(IDS_CHECKSUM_CRC_DATA_NAMES, 0x03020722); + s += L" "; + ConvertUInt32ToHex(combiner.DataNameCrcSum, sz); + s += sz; + } + srcPanel.MessageBoxInfo(s, LangString(IDS_CHECKSUM_INFORMATION, 0x03020720)); + } +} diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp new file mode 100755 index 00000000..0baa151a --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp @@ -0,0 +1,796 @@ +// PanelDrag.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" + +#include "Windows/Memory.h" +#include "Windows/FileDir.h" +#include "Windows/Shell.h" + +#include "../Common/ArchiveName.h" +#include "../Common/CompressCall.h" + +#include "MessagesDialog.h" + +#include "App.h" +#include "EnumFormatEtc.h" + +using namespace NWindows; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +static wchar_t *kTempDirPrefix = L"7zE"; +static LPCTSTR kSvenZipSetFolderFormat = TEXT("7-Zip::SetTargetFolder"); + +//////////////////////////////////////////////////////// + +class CDataObject: + public IDataObject, + public CMyUnknownImp +{ +private: + FORMATETC m_Etc; + UINT m_SetFolderFormat; + +public: + MY_UNKNOWN_IMP1_MT(IDataObject) + + STDMETHODIMP GetData(LPFORMATETC pformatetcIn, LPSTGMEDIUM medium); + STDMETHODIMP GetDataHere(LPFORMATETC pformatetc, LPSTGMEDIUM medium); + STDMETHODIMP QueryGetData(LPFORMATETC pformatetc ); + + STDMETHODIMP GetCanonicalFormatEtc ( LPFORMATETC /* pformatetc */, LPFORMATETC pformatetcOut) + { pformatetcOut->ptd = NULL; return ResultFromScode(E_NOTIMPL); } + + STDMETHODIMP SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL release); + STDMETHODIMP EnumFormatEtc(DWORD drection, LPENUMFORMATETC *enumFormatEtc); + + STDMETHODIMP DAdvise(FORMATETC * /* etc */, DWORD /* advf */, LPADVISESINK /* pAdvSink */, DWORD * /* pdwConnection */) + { return OLE_E_ADVISENOTSUPPORTED; } + STDMETHODIMP DUnadvise(DWORD /* dwConnection */) { return OLE_E_ADVISENOTSUPPORTED; } + STDMETHODIMP EnumDAdvise( LPENUMSTATDATA * /* ppenumAdvise */) { return OLE_E_ADVISENOTSUPPORTED; } + + CDataObject(); + + NMemory::CGlobal hGlobal; + UString Path; +}; + +CDataObject::CDataObject() +{ + m_SetFolderFormat = RegisterClipboardFormat(kSvenZipSetFolderFormat); + m_Etc.cfFormat = CF_HDROP; + m_Etc.ptd = NULL; + m_Etc.dwAspect = DVASPECT_CONTENT; + m_Etc.lindex = -1; + m_Etc.tymed = TYMED_HGLOBAL; +} + +STDMETHODIMP CDataObject::SetData(LPFORMATETC etc, STGMEDIUM *medium, BOOL /* release */) +{ + if (etc->cfFormat == m_SetFolderFormat && etc->tymed == TYMED_HGLOBAL && + etc->dwAspect == DVASPECT_CONTENT && medium->tymed == TYMED_HGLOBAL) + { + Path.Empty(); + if (medium->hGlobal == 0) + return S_OK; + size_t size = GlobalSize(medium->hGlobal) / sizeof(wchar_t); + const wchar_t *src = (const wchar_t *)GlobalLock(medium->hGlobal); + if (src != 0) + { + for (size_t i = 0; i < size; i++) + { + wchar_t c = src[i]; + if (c == 0) + break; + Path += c; + } + GlobalUnlock(medium->hGlobal); + return S_OK; + } + } + return E_NOTIMPL; +} + +static HGLOBAL DuplicateGlobalMem(HGLOBAL srcGlobal) +{ + SIZE_T size = GlobalSize(srcGlobal); + const void *src = GlobalLock(srcGlobal); + if (src == 0) + return 0; + HGLOBAL destGlobal = GlobalAlloc(GHND | GMEM_SHARE, size); + if (destGlobal != 0) + { + void *dest = GlobalLock(destGlobal); + if (dest == 0) + { + GlobalFree(destGlobal); + destGlobal = 0; + } + else + { + memcpy(dest, src, size); + GlobalUnlock(destGlobal); + } + } + GlobalUnlock(srcGlobal); + return destGlobal; +} + +STDMETHODIMP CDataObject::GetData(LPFORMATETC etc, LPSTGMEDIUM medium) +{ + RINOK(QueryGetData(etc)); + medium->tymed = m_Etc.tymed; + medium->pUnkForRelease = 0; + medium->hGlobal = DuplicateGlobalMem(hGlobal); + if (medium->hGlobal == 0) + return E_OUTOFMEMORY; + return S_OK; +} + +STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC /* etc */, LPSTGMEDIUM /* medium */) +{ + // Seems Windows doesn't call it, so we will not implement it. + return E_UNEXPECTED; +} + + +STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC etc) +{ + if ((m_Etc.tymed & etc->tymed) && + m_Etc.cfFormat == etc->cfFormat && + m_Etc.dwAspect == etc->dwAspect) + return S_OK; + return DV_E_FORMATETC; +} + +STDMETHODIMP CDataObject::EnumFormatEtc(DWORD direction, LPENUMFORMATETC FAR* enumFormatEtc) +{ + if(direction != DATADIR_GET) + return E_NOTIMPL; + return CreateEnumFormatEtc(1, &m_Etc, enumFormatEtc); +} + +//////////////////////////////////////////////////////// + +class CDropSource: + public IDropSource, + public CMyUnknownImp +{ + DWORD m_Effect; +public: + MY_UNKNOWN_IMP1_MT(IDropSource) + STDMETHOD(QueryContinueDrag)(BOOL escapePressed, DWORD keyState); + STDMETHOD(GiveFeedback)(DWORD effect); + + + bool NeedExtract; + CPanel *Panel; + CRecordVector Indices; + UString Folder; + CDataObject *DataObjectSpec; + CMyComPtr DataObject; + + bool NeedPostCopy; + HRESULT Result; + UStringVector Messages; + + CDropSource(): NeedPostCopy(false), Panel(0), Result(S_OK), m_Effect(DROPEFFECT_NONE) {} +}; + +STDMETHODIMP CDropSource::QueryContinueDrag(BOOL escapePressed, DWORD keyState) +{ + if(escapePressed == TRUE) + return DRAGDROP_S_CANCEL; + if((keyState & MK_LBUTTON) == 0) + { + if (m_Effect == DROPEFFECT_NONE) + return DRAGDROP_S_CANCEL; + Result = S_OK; + bool needExtract = NeedExtract; + // MoveMode = (((keyState & MK_SHIFT) != 0) && MoveIsAllowed); + if (!DataObjectSpec->Path.IsEmpty()) + { + needExtract = false; + NeedPostCopy = true; + } + if (needExtract) + { + Result = Panel->CopyTo(Indices, Folder, + false, // moveMode, + false, // showMessages + &Messages); + if (Result != S_OK || !Messages.IsEmpty()) + return DRAGDROP_S_CANCEL; + } + return DRAGDROP_S_DROP; + } + return S_OK; +} + +STDMETHODIMP CDropSource::GiveFeedback(DWORD effect) +{ + m_Effect = effect; + return DRAGDROP_S_USEDEFAULTCURSORS; +} + +static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &names) +{ + size_t totalLength = 1; + + #ifndef _UNICODE + if (!g_IsNT) + { + AStringVector namesA; + int i; + for (i = 0; i < names.Size(); i++) + namesA.Add(GetSystemString(names[i])); + for (i = 0; i < names.Size(); i++) + totalLength += namesA[i].Length() + 1; + + if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLength * sizeof(CHAR) + sizeof(DROPFILES))) + return false; + + NMemory::CGlobalLock dropLock(hgDrop); + DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); + if (dropFiles == 0) + return false; + dropFiles->fNC = FALSE; + dropFiles->pt.x = 0; + dropFiles->pt.y = 0; + dropFiles->pFiles = sizeof(DROPFILES); + dropFiles->fWide = FALSE; + CHAR *p = (CHAR *)((BYTE *)dropFiles + sizeof(DROPFILES)); + for (i = 0; i < names.Size(); i++) + { + const AString &s = namesA[i]; + int fullLength = s.Length() + 1; + MyStringCopy(p, (const char *)s); + p += fullLength; + totalLength -= fullLength; + } + *p = 0; + } + else + #endif + { + int i; + for (i = 0; i < names.Size(); i++) + totalLength += names[i].Length() + 1; + + if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLength * sizeof(WCHAR) + sizeof(DROPFILES))) + return false; + + NMemory::CGlobalLock dropLock(hgDrop); + DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); + if (dropFiles == 0) + return false; + dropFiles->fNC = FALSE; + dropFiles->pt.x = 0; + dropFiles->pt.y = 0; + dropFiles->pFiles = sizeof(DROPFILES); + dropFiles->fWide = TRUE; + WCHAR *p = (WCHAR *)((BYTE *)dropFiles + sizeof(DROPFILES)); + for (i = 0; i < names.Size(); i++) + { + const UString &s = names[i]; + int fullLength = s.Length() + 1; + MyStringCopy(p, (const WCHAR *)s); + p += fullLength; + totalLength -= fullLength; + } + *p = 0; + } + return true; +} + +void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */) +{ + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + if (!DoesItSupportOperations()) + return; + CRecordVector indices; + GetOperatedItemIndices(indices); + if (indices.Size() == 0) + return; + + // CSelectedState selState; + // SaveSelectedState(selState); + + UString dirPrefix; + NFile::NDirectory::CTempDirectoryW tempDirectory; + + bool isFSFolder = IsFSFolder(); + if (isFSFolder) + dirPrefix = _currentFolderPrefix; + else + { + tempDirectory.Create(kTempDirPrefix); + dirPrefix = tempDirectory.GetPath(); + NFile::NName::NormalizeDirPathPrefix(dirPrefix); + } + + CDataObject *dataObjectSpec = new CDataObject; + CMyComPtr dataObject = dataObjectSpec; + + { + UStringVector names; + for (int i = 0; i < indices.Size(); i++) + { + UInt32 index = indices[i]; + UString s; + if (isFSFolder) + s = GetItemRelPath(index); + else + s = GetItemName(index); + names.Add(dirPrefix + s); + } + if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names)) + return; + } + + CDropSource *dropSourceSpec = new CDropSource; + CMyComPtr dropSource = dropSourceSpec; + dropSourceSpec->NeedExtract = !isFSFolder; + dropSourceSpec->Panel = this; + dropSourceSpec->Indices = indices; + dropSourceSpec->Folder = dirPrefix; + dropSourceSpec->DataObjectSpec = dataObjectSpec; + dropSourceSpec->DataObject = dataObjectSpec; + + bool moveIsAllowed = isFSFolder; + + DWORD effectsOK = DROPEFFECT_COPY; + if (moveIsAllowed) + effectsOK |= DROPEFFECT_MOVE; + DWORD effect; + _panelCallback->DragBegin(); + HRESULT res = DoDragDrop(dataObject, dropSource, effectsOK, &effect); + _panelCallback->DragEnd(); + bool canceled = (res == DRAGDROP_S_CANCEL); + if (res == DRAGDROP_S_DROP) + { + res = dropSourceSpec->Result; + if (dropSourceSpec->NeedPostCopy) + if (!dataObjectSpec->Path.IsEmpty()) + { + NFile::NName::NormalizeDirPathPrefix(dataObjectSpec->Path); + res = CopyTo(indices, dataObjectSpec->Path, + (effect == DROPEFFECT_MOVE),// dropSourceSpec->MoveMode, + false, // showErrorMessages + &dropSourceSpec->Messages); + } + /* + if (effect == DROPEFFECT_MOVE) + RefreshListCtrl(selState); + */ + } + else + { + if (res != DRAGDROP_S_CANCEL && res != S_OK) + MessageBoxError(res); + res = dropSourceSpec->Result; + } + + if (!dropSourceSpec->Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &dropSourceSpec->Messages; + messagesDialog.Create((*this)); + } + if (res != S_OK && res != E_ABORT) + MessageBoxError(res); + if (res == S_OK && dropSourceSpec->Messages.IsEmpty() && !canceled) + KillSelection(); +} + +void CDropTarget::QueryGetData(IDataObject *dataObject) +{ + FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + m_DropIsAllowed = (dataObject->QueryGetData(&etc) == S_OK); + +} + +static void MySetDropHighlighted(HWND hWnd, int index, bool enable) +{ + LVITEM item; + item.mask = LVIF_STATE; + item.iItem = index; + item.iSubItem = 0; + item.state = enable ? LVIS_DROPHILITED : 0; + item.stateMask = LVIS_DROPHILITED; + item.pszText = 0; + ListView_SetItem(hWnd, &item); +} + +void CDropTarget::RemoveSelection() +{ + if (m_SelectionIndex >= 0 && m_Panel != 0) + MySetDropHighlighted(m_Panel->_listView, m_SelectionIndex, false); + m_SelectionIndex = -1; +} + +void CDropTarget::PositionCursor(POINTL ptl) +{ + m_SubFolderIndex = -1; + POINT pt; + pt.x = ptl.x; + pt.y = ptl.y; + + RemoveSelection(); + m_IsAppTarget = true; + m_Panel = NULL; + + m_PanelDropIsAllowed = true; + if (!m_DropIsAllowed) + return; + { + POINT pt2 = pt; + App->_window.ScreenToClient(&pt2); + for (int i = 0; i < kNumPanelsMax; i++) + if (App->IsPanelVisible(i)) + if (App->Panels[i].IsEnabled()) + if (ChildWindowFromPointEx(App->_window, pt2, + CWP_SKIPINVISIBLE | CWP_SKIPDISABLED) == (HWND)App->Panels[i]) + { + m_Panel = &App->Panels[i]; + m_IsAppTarget = false; + if (i == SrcPanelIndex) + { + m_PanelDropIsAllowed = false; + return; + } + break; + } + if (m_IsAppTarget) + { + if (TargetPanelIndex >= 0) + m_Panel = &App->Panels[TargetPanelIndex]; + return; + } + } + + /* + m_PanelDropIsAllowed = m_Panel->DoesItSupportOperations(); + if (!m_PanelDropIsAllowed) + return; + */ + + if (!m_Panel->IsFSFolder() && !m_Panel->IsFSDrivesFolder()) + return; + + if (WindowFromPoint(pt) != (HWND)m_Panel->_listView) + return; + + LVHITTESTINFO info; + m_Panel->_listView.ScreenToClient(&pt); + info.pt = pt; + int index = ListView_HitTest(m_Panel->_listView, &info); + if (index < 0) + return; + int realIndex = m_Panel->GetRealItemIndex(index); + if (realIndex == kParentIndex) + return; + if (!m_Panel->IsItemFolder(realIndex)) + return; + m_SubFolderIndex = realIndex; + m_SubFolderName = m_Panel->GetItemName(m_SubFolderIndex); + MySetDropHighlighted(m_Panel->_listView, index, true); + m_SelectionIndex = index; +} + +bool CDropTarget::IsFsFolderPath() const +{ + if (!m_IsAppTarget && m_Panel != 0) + return (m_Panel->IsFSFolder() || (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0)); + return false; +} + +static void ReadUnicodeStrings(const wchar_t *p, size_t size, UStringVector &names) +{ + names.Clear(); + UString name; + for (;size > 0; size--) + { + wchar_t c = *p++; + if (c == 0) + { + if (name.IsEmpty()) + break; + names.Add(name); + name.Empty(); + } + else + name += c; + } +} + +static void ReadAnsiStrings(const char *p, size_t size, UStringVector &names) +{ + names.Clear(); + AString name; + for (;size > 0; size--) + { + char c = *p++; + if (c == 0) + { + if (name.IsEmpty()) + break; + names.Add(GetUnicodeString(name)); + name.Empty(); + } + else + name += c; + } +} + +static void GetNamesFromDataObject(IDataObject *dataObject, UStringVector &names) +{ + names.Clear(); + FORMATETC etc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM medium; + HRESULT res = dataObject->GetData(&etc, &medium); + if (res != S_OK) + return; + if (medium.tymed != TYMED_HGLOBAL) + return; + { + NMemory::CGlobal global; + global.Attach(medium.hGlobal); + size_t blockSize = GlobalSize(medium.hGlobal); + NMemory::CGlobalLock dropLock(medium.hGlobal); + const DROPFILES* dropFiles = (DROPFILES*)dropLock.GetPointer(); + if (dropFiles == 0) + return; + if (blockSize < dropFiles->pFiles) + return; + size_t size = blockSize - dropFiles->pFiles; + const void *namesData = (const Byte *)dropFiles + dropFiles->pFiles; + if (dropFiles->fWide) + ReadUnicodeStrings((const wchar_t *)namesData, size / sizeof(wchar_t), names); + else + ReadAnsiStrings((const char *)namesData, size, names); + } +} + +bool CDropTarget::IsItSameDrive() const +{ + if (m_Panel == 0) + return false; + if (!IsFsFolderPath()) + return false; + UString drive; + if (m_Panel->IsFSFolder()) + { + drive = m_Panel->GetDriveOrNetworkPrefix(); + if (drive.IsEmpty()) + return false; + } + else if (m_Panel->IsFSDrivesFolder() && m_SelectionIndex >= 0) + drive = m_SubFolderName + L'\\'; + else + return false; + + if (m_SourcePaths.Size() == 0) + return false; + for (int i = 0; i < m_SourcePaths.Size(); i++) + { + const UString &path = m_SourcePaths[i]; + if (drive.CompareNoCase(path.Left(drive.Length())) != 0) + return false; + } + return true; + +} + +DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect) +{ + if (!m_DropIsAllowed || !m_PanelDropIsAllowed) + return DROPEFFECT_NONE; + + if (!IsFsFolderPath()) + allowedEffect &= ~DROPEFFECT_MOVE; + + if (!m_SetPathIsOK) + allowedEffect &= ~DROPEFFECT_MOVE; + + DWORD effect = 0; + if (keyState & MK_CONTROL) + effect = allowedEffect & DROPEFFECT_COPY; + else if (keyState & MK_SHIFT) + effect = allowedEffect & DROPEFFECT_MOVE; + if(effect == 0) + { + if(allowedEffect & DROPEFFECT_COPY) + effect = DROPEFFECT_COPY; + if(allowedEffect & DROPEFFECT_MOVE) + { + if (IsItSameDrive()) + effect = DROPEFFECT_MOVE; + } + } + if(effect == 0) + return DROPEFFECT_NONE; + return effect; +} + +UString CDropTarget::GetTargetPath() const +{ + if (!IsFsFolderPath()) + return UString(); + UString path = m_Panel->_currentFolderPrefix; + if (m_Panel->IsFSDrivesFolder()) + path.Empty(); + if (m_SubFolderIndex >= 0 && !m_SubFolderName.IsEmpty()) + { + path += m_SubFolderName; + path += L"\\"; + } + return path; +} + +bool CDropTarget::SetPath(bool enablePath) const +{ + UINT setFolderFormat = RegisterClipboardFormat(kSvenZipSetFolderFormat); + + FORMATETC etc = { (CLIPFORMAT)setFolderFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM medium; + medium.tymed = etc.tymed; + medium.pUnkForRelease = 0; + UString path; + if (enablePath) + path = GetTargetPath(); + size_t size = path.Length() + 1; + medium.hGlobal = GlobalAlloc(GHND | GMEM_SHARE, size * sizeof(wchar_t)); + if (medium.hGlobal == 0) + return false; + wchar_t *dest = (wchar_t *)GlobalLock(medium.hGlobal); + if (dest == 0) + { + GlobalUnlock(medium.hGlobal); + return false; + } + MyStringCopy(dest, (const wchar_t *)path); + GlobalUnlock(medium.hGlobal); + bool res = m_DataObject->SetData(&etc, &medium, FALSE) == S_OK; + GlobalFree(medium.hGlobal); + return res; +} + +bool CDropTarget::SetPath() +{ + m_SetPathIsOK = SetPath(m_DropIsAllowed && m_PanelDropIsAllowed && IsFsFolderPath()); + return m_SetPathIsOK; +} + +STDMETHODIMP CDropTarget::DragEnter(IDataObject * dataObject, DWORD keyState, + POINTL pt, DWORD *effect) +{ + GetNamesFromDataObject(dataObject, m_SourcePaths); + QueryGetData(dataObject); + m_DataObject = dataObject; + return DragOver(keyState, pt, effect); +} + + +STDMETHODIMP CDropTarget::DragOver(DWORD keyState, POINTL pt, DWORD *effect) +{ + PositionCursor(pt); + SetPath(); + *effect = GetEffect(keyState, pt, *effect); + return S_OK; +} + + +STDMETHODIMP CDropTarget::DragLeave() +{ + RemoveSelection(); + SetPath(false); + m_DataObject.Release(); + return S_OK; +} + +// We suppose that there was ::DragOver for same POINTL_pt before ::Drop +// So SetPath() is same as in Drop. + +STDMETHODIMP CDropTarget::Drop(IDataObject *dataObject, DWORD keyState, + POINTL pt, DWORD * effect) +{ + QueryGetData(dataObject); + PositionCursor(pt); + m_DataObject = dataObject; + bool needDrop = true; + if(m_DropIsAllowed && m_PanelDropIsAllowed) + if (IsFsFolderPath()) + needDrop = !SetPath(); + *effect = GetEffect(keyState, pt, *effect); + if(m_DropIsAllowed && m_PanelDropIsAllowed) + { + if (needDrop) + { + UString path = GetTargetPath(); + if (m_IsAppTarget && m_Panel) + if (m_Panel->IsFSFolder()) + path = m_Panel->_currentFolderPrefix; + m_Panel->DropObject(dataObject, path); + } + } + RemoveSelection(); + m_DataObject.Release(); + return S_OK; +} + +void CPanel::DropObject(IDataObject *dataObject, const UString &folderPath) +{ + UStringVector names; + GetNamesFromDataObject(dataObject, names); + CompressDropFiles(names, folderPath); +} + +/* +void CPanel::CompressDropFiles(HDROP dr) +{ + UStringVector fileNames; + { + NShell::CDrop drop(true); + drop.Attach(dr); + drop.QueryFileNames(fileNames); + } + CompressDropFiles(fileNamesUnicode); +} +*/ + +static bool IsFolderInTemp(const UString &path) +{ + UString tempPath; + if (!NFile::NDirectory::MyGetTempPath(tempPath)) + return false; + if (tempPath.IsEmpty()) + return false; + return (tempPath.CompareNoCase(path.Left(tempPath.Length())) == 0); +} + +static bool AreThereNamesFromTemp(const UStringVector &fileNames) +{ + UString tempPath; + if (!NFile::NDirectory::MyGetTempPath(tempPath)) + return false; + if (tempPath.IsEmpty()) + return false; + for (int i = 0; i < fileNames.Size(); i++) + if (tempPath.CompareNoCase(fileNames[i].Left(tempPath.Length())) == 0) + return true; + return false; +} + +void CPanel::CompressDropFiles(const UStringVector &fileNames, const UString &folderPath) +{ + if (fileNames.Size() == 0) + return; + const UString archiveName = CreateArchiveName(fileNames.Front(), + (fileNames.Size() > 1), false); + bool createNewArchive = true; + if (!IsFSFolder()) + createNewArchive = !DoesItSupportOperations(); + + if (createNewArchive) + { + UString folderPath2 = folderPath; + if (folderPath2.IsEmpty()) + { + NFile::NDirectory::GetOnlyDirPrefix(fileNames.Front(), folderPath2); + if (IsFolderInTemp(folderPath2)) + folderPath2 = L"C:\\"; // fix it + } + CompressFiles(folderPath2, archiveName, L"", fileNames, + false, // email + true, // showDialog + AreThereNamesFromTemp(fileNames) // waitFinish + ); + } + else + CopyFrom(fileNames); +} diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp new file mode 100755 index 00000000..a8cfb3be --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp @@ -0,0 +1,413 @@ +// PanelFolderChange.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" +#include "Windows/FileDir.h" + +#include "../../PropID.h" + +#include "Panel.h" +#include "ListViewDialog.h" +#include "RootFolder.h" +#include "ViewSettings.h" +#include "FSDrives.h" +#include "LangUtils.h" +#include "resource.h" + +using namespace NWindows; +using namespace NFile; +using namespace NFind; + +void CPanel::SetToRootFolder() +{ + _folder.Release(); + _library.Free(); + CRootFolder *rootFolderSpec = new CRootFolder; + _folder = rootFolderSpec; + rootFolderSpec->Init(); +} + +HRESULT CPanel::BindToPath(const UString &fullPath, bool &archiveIsOpened, bool &encrypted) +{ + archiveIsOpened = false; + encrypted = false; + CDisableTimerProcessing disableTimerProcessing1(*this); + CloseOpenFolders(); + UString sysPath = fullPath; + CFileInfoW fileInfo; + UStringVector reducedParts; + while(!sysPath.IsEmpty()) + { + if (FindFile(sysPath, fileInfo)) + break; + int pos = sysPath.ReverseFind(L'\\'); + if (pos < 0) + sysPath.Empty(); + else + { + if (reducedParts.Size() > 0 || pos < sysPath.Length() - 1) + reducedParts.Add(sysPath.Mid(pos + 1)); + sysPath = sysPath.Left(pos); + } + } + SetToRootFolder(); + CMyComPtr newFolder; + if (sysPath.IsEmpty()) + { + if (_folder->BindToFolder(fullPath, &newFolder) == S_OK) + _folder = newFolder; + } + else if (fileInfo.IsDirectory()) + { + NName::NormalizeDirPathPrefix(sysPath); + if (_folder->BindToFolder(sysPath, &newFolder) == S_OK) + _folder = newFolder; + } + else + { + UString dirPrefix; + if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix)) + dirPrefix.Empty(); + if (_folder->BindToFolder(dirPrefix, &newFolder) == S_OK) + { + _folder = newFolder; + LoadFullPath(); + UString fileName; + if (NDirectory::GetOnlyName(sysPath, fileName)) + { + if (OpenItemAsArchive(fileName, _currentFolderPrefix, + _currentFolderPrefix + fileName, encrypted) == S_OK) + { + archiveIsOpened = true; + for (int i = reducedParts.Size() - 1; i >= 0; i--) + { + CMyComPtr newFolder; + _folder->BindToFolder(reducedParts[i], &newFolder); + if (!newFolder) + break; + _folder = newFolder; + } + } + } + } + } + return S_OK; +} + +HRESULT CPanel::BindToPathAndRefresh(const UString &path) +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + bool archiveIsOpened, encrypted; + RINOK(BindToPath(path, archiveIsOpened, encrypted)); + RefreshListCtrl(UString(), -1, true, UStringVector()); + return S_OK; +} + +void CPanel::SetBookmark(int index) +{ + _appState->FastFolders.SetString(index, _currentFolderPrefix); +} + +void CPanel::OpenBookmark(int index) +{ + BindToPathAndRefresh(_appState->FastFolders.GetString(index)); +} + +UString GetFolderPath(IFolderFolder *folder) +{ + NCOM::CPropVariant prop; + if (folder->GetFolderProperty(kpidPath, &prop) == S_OK) + if (prop.vt == VT_BSTR) + return (wchar_t *)prop.bstrVal; + return UString(); +} + +void CPanel::LoadFullPath() +{ + _currentFolderPrefix.Empty(); + for (int i = 0; i < _parentFolders.Size(); i++) + { + const CFolderLink &folderLink = _parentFolders[i]; + _currentFolderPrefix += GetFolderPath(folderLink.ParentFolder); + _currentFolderPrefix += folderLink.ItemName; + _currentFolderPrefix += L'\\'; + } + if (_folder) + _currentFolderPrefix += GetFolderPath(_folder); +} + +void CPanel::LoadFullPathAndShow() +{ + LoadFullPath(); + _appState->FolderHistory.AddString(_currentFolderPrefix); + + // _headerComboBox.SendMessage(CB_RESETCONTENT, 0, 0); + _headerComboBox.SetText(_currentFolderPrefix); + + /* + for (int i = 0; i < g_Folders.m_Strings.Size(); i++) + { + UString string = g_Folders.m_Strings[i]; + COMBOBOXEXITEM item; + item.mask = CBEIF_TEXT; + item.iItem = i; + item.pszText = (LPTSTR)(LPCTSTR)string; + _headerComboBox.InsertItem(&item); + } + */ +} + +bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result) +{ + if (info->iWhy == CBENF_ESCAPE) + { + _headerComboBox.SetText(_currentFolderPrefix); + PostMessage(kSetFocusToListView); + result = FALSE; + return true; + } + if (info->iWhy == CBENF_DROPDOWN) + { + result = FALSE; + return true; + } + + if (info->iWhy == CBENF_RETURN) + { + UString s; + _headerComboBox.GetText(s); + // length of NMCBEENDEDITW.szText is limited by MAX_PATH + // if (BindToPathAndRefresh(info->szText) != S_OK) + if (BindToPathAndRefresh(s) != S_OK) + { + result = TRUE; + return true; + } + result = FALSE; + PostMessage(kSetFocusToListView); + return true; + } + return false; +} + +#ifndef _UNICODE +bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result) +{ + if (info->iWhy == CBENF_ESCAPE) + { + _headerComboBox.SetText(_currentFolderPrefix); + PostMessage(kSetFocusToListView); + result = FALSE; + return true; + } + if (info->iWhy == CBENF_DROPDOWN) + { + result = FALSE; + return true; + } + + if (info->iWhy == CBENF_RETURN) + { + if (BindToPathAndRefresh(GetUnicodeString(info->szText)) != S_OK) + { + result = TRUE; + return true; + } + result = FALSE; + PostMessage(kSetFocusToListView); + return true; + } + return false; +} +#endif + +void CPanel::OnComboBoxCommand(UINT /* code */, LPARAM & /* param */) +{ + /* + if (code == CBN_SELENDOK) + { + UString path; + if (!_headerComboBox.GetText(path)) + return; + CRootFolder *rootFolderSpec = new CRootFolder; + CMyComPtr rootFolder = rootFolderSpec; + rootFolderSpec->Init(); + CMyComPtr newFolder; + if (rootFolder->BindToFolder(path, &newFolder) != S_OK) + return; + _folder = newFolder; + SetCurrentPathText(); + RefreshListCtrl(UString(), -1, UStringVector()); + PostMessage(kSetFocusToListView); + } + */ +} + +bool CPanel::OnNotifyComboBox(LPNMHDR header, LRESULT &result) +{ + switch(header->code) + { + case CBEN_BEGINEDIT: + { + _lastFocusedIsList = false; + _panelCallback->PanelWasFocused(); + } + #ifndef _UNICODE + case CBEN_ENDEDIT: + { + return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result); + } + #endif + case CBEN_ENDEDITW: + { + return OnNotifyComboBoxEndEdit((PNMCBEENDEDITW)header, result); + } + } + return false; +} + + +void CPanel::FoldersHistory() +{ + CListViewDialog listViewDialog; + listViewDialog.DeleteIsAllowed = true; + listViewDialog.Title = LangString(IDS_FOLDERS_HISTORY, 0x03020260); + _appState->FolderHistory.GetList(listViewDialog.Strings); + if (listViewDialog.Create(GetParent()) == IDCANCEL) + return; + UString selectString; + if (listViewDialog.StringsWereChanged) + { + _appState->FolderHistory.RemoveAll(); + for (int i = listViewDialog.Strings.Size() - 1; i >= 0; i--) + _appState->FolderHistory.AddString(listViewDialog.Strings[i]); + if (listViewDialog.FocusedItemIndex >= 0) + selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; + } + else + { + if (listViewDialog.FocusedItemIndex >= 0) + selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; + } + if (listViewDialog.FocusedItemIndex >= 0) + BindToPathAndRefresh(selectString); +} + +void CPanel::OpenParentFolder() +{ + LoadFullPath(); // Maybe we don't need it ?? + UString focucedName; + if (!_currentFolderPrefix.IsEmpty()) + { + UString string = _currentFolderPrefix; + string.Delete(string.Length() - 1); + int pos = string.ReverseFind(L'\\'); + if (pos < 0) + pos = 0; + else + pos++; + focucedName = string.Mid(pos); + } + + CDisableTimerProcessing disableTimerProcessing1(*this); + CMyComPtr newFolder; + _folder->BindToParentFolder(&newFolder); + if (newFolder) + _folder = newFolder; + else + { + if (_parentFolders.IsEmpty()) + { + SetToRootFolder(); + if (focucedName.IsEmpty()) + focucedName = GetItemName(0); + } + else + { + _folder.Release(); + _library.Free(); + CFolderLink &link = _parentFolders.Back(); + _folder = link.ParentFolder; + _library.Attach(link.Library.Detach()); + focucedName = link.ItemName; + if (_parentFolders.Size () > 1) + OpenParentArchiveFolder(); + _parentFolders.DeleteBack(); + } + } + + UStringVector selectedItems; + /* + if (!focucedName.IsEmpty()) + selectedItems.Add(focucedName); + */ + LoadFullPath(); + // ::SetCurrentDirectory(::_currentFolderPrefix); + RefreshListCtrl(focucedName, -1, true, selectedItems); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); + RefreshStatusBar(); +} + +void CPanel::CloseOpenFolders() +{ + while(_parentFolders.Size() > 0) + { + _folder.Release(); + _library.Free(); + _folder = _parentFolders.Back().ParentFolder; + _library.Attach(_parentFolders.Back().Library.Detach()); + if (_parentFolders.Size () > 1) + OpenParentArchiveFolder(); + _parentFolders.DeleteBack(); + } + _folder.Release(); + _library.Free(); +} + +void CPanel::OpenRootFolder() +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + _parentFolders.Clear(); + SetToRootFolder(); + RefreshListCtrl(UString(), -1, true, UStringVector()); + // ::SetCurrentDirectory(::_currentFolderPrefix); + /* + BeforeChangeFolder(); + _currentFolderPrefix.Empty(); + AfterChangeFolder(); + SetCurrentPathText(); + RefreshListCtrl(UString(), 0, UStringVector()); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); + */ +} + +void CPanel::OpenDrivesFolder() +{ + CloseOpenFolders(); + CFSDrives *fsFolderSpec = new CFSDrives; + _folder = fsFolderSpec; + fsFolderSpec->Init(); + RefreshListCtrl(); +} + +void CPanel::OpenFolder(int index) +{ + if (index == kParentIndex) + { + OpenParentFolder(); + return; + } + CMyComPtr newFolder; + _folder->BindToFolder(index, &newFolder); + if (!newFolder) + return; + _folder = newFolder; + LoadFullPath(); + // ::SetCurrentDirectory(::_currentFolderPrefix); + RefreshListCtrl(); + UINT state = LVIS_SELECTED; + _listView.SetItemState(_listView.GetFocusedItem(), state, state); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp new file mode 100755 index 00000000..1795da41 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp @@ -0,0 +1,546 @@ +// PanelItemOpen.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/StringConvert.h" +#include "Common/Random.h" +#include "Common/StringConvert.h" +#include "Common/AutoPtr.h" + +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" +#include "Windows/Synchronization.h" +#include "Windows/Error.h" +// #include "Windows/COM.h" + +#include "ExtractCallback.h" +#include "IFolder.h" +#include "FileFolderPluginOpen.h" +#include "FormatUtils.h" +#include "Panel.h" +#include "RegistryUtils.h" + +using namespace NWindows; +using namespace NSynchronization; +using namespace NFile; +using namespace NDirectory; + +extern HWND g_HWND; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +static wchar_t *kTempDirPrefix = L"7zO"; + +static const wchar_t *virusMessage = L"File looks like virus (file name has long spaces in name). 7-Zip will not open it"; + +static bool IsNameVirus(const UString &name) +{ + return (name.Find(L" ") >= 0); +} + +struct CTmpProcessInfo: public CTempFileInfo +{ + HANDLE ProcessHandle; + HWND Window; + UString FullPathFolderPrefix; +}; + +class CTmpProcessInfoRelease +{ + CTmpProcessInfo *_tmpProcessInfo; +public: + bool _needDelete; + CTmpProcessInfoRelease(CTmpProcessInfo &tmpProcessInfo): + _tmpProcessInfo(&tmpProcessInfo), _needDelete(true) {} + ~CTmpProcessInfoRelease() + { + if (_needDelete) + _tmpProcessInfo->DeleteDirAndFile(); + } +}; + +HRESULT CPanel::OpenItemAsArchive(const UString &name, + const UString &folderPath, const UString &filePath, bool &encrypted) +{ + encrypted = false; + CFolderLink folderLink; + if (!NFile::NFind::FindFile(filePath, folderLink.FileInfo)) + return E_FAIL; + if (folderLink.FileInfo.IsDirectory()) + return S_FALSE; + + folderLink.FilePath = filePath; + folderLink.FolderPath = folderPath; + + CMyComPtr newFolder; + + // _passwordIsDefined = false; + // _password.Empty(); + + NDLL::CLibrary library; + RINOK(OpenFileFolderPlugin(filePath, &library, &newFolder, GetParent(), encrypted)); + + folderLink.ParentFolder = _folder; + folderLink.ItemName = name; + _parentFolders.Add(folderLink); + _parentFolders.Back().Library.Attach(_library.Detach()); + + _folder.Release(); + _library.Free(); + _folder = newFolder; + _library.Attach(library.Detach()); + + return S_OK; +} + +HRESULT CPanel::OpenItemAsArchive(const UString &name) +{ + bool encrypted; + return OpenItemAsArchive(name, _currentFolderPrefix, _currentFolderPrefix + name, encrypted); +} + +HRESULT CPanel::OpenItemAsArchive(int index) +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + RINOK(OpenItemAsArchive(GetItemRelPath(index))); + RefreshListCtrl(); + return S_OK; +} + +HRESULT CPanel::OpenParentArchiveFolder() +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + if (_parentFolders.Size() < 2) + return S_OK; + CFolderLink &folderLink = _parentFolders.Back(); + NFind::CFileInfoW newFileInfo; + if (NFind::FindFile(folderLink.FilePath, newFileInfo)) + { + if (newFileInfo.Size != folderLink.FileInfo.Size || + CompareFileTime(&newFileInfo.LastWriteTime, + &folderLink.FileInfo.LastWriteTime) != 0) + { + UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, + 0x03020280, folderLink.ItemName); + if (::MessageBoxW(HWND(*this), message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) + { + if (OnOpenItemChanged(folderLink.FolderPath, folderLink.ItemName) != S_OK) + { + ::MessageBoxW(HWND(*this), MyFormatNew(IDS_CANNOT_UPDATE_FILE, + 0x03020281, folderLink.FilePath), L"7-Zip", MB_OK | MB_ICONSTOP); + return S_OK; + } + } + } + } + folderLink.DeleteDirAndFile(); + return S_OK; +} + +static const wchar_t *kStartExtensions[] = +{ + L"exe", L"bat", L"com", + L"chm", + L"msi", L"doc", L"xls", L"ppt", + L"odt", L"ods", + L"pdf" +}; + +static bool DoItemAlwaysStart(const UString &name) +{ + int extPos = name.ReverseFind('.'); + if (extPos < 0) + return false; + UString ext = name.Mid(extPos + 1); + ext.MakeLower(); + for (int i = 0; i < sizeof(kStartExtensions) / sizeof(kStartExtensions[0]); i++) + if (ext.Compare(kStartExtensions[i]) == 0) + return true; + return false; +} + +static HANDLE StartEditApplication(const UString &path, HWND window) +{ + UString command; + ReadRegEditor(command); + if (command.IsEmpty()) + { + if (!MyGetWindowsDirectory(command)) + return 0; + NFile::NName::NormalizeDirPathPrefix(command); + command += L"notepad.exe"; + } + command = UString(L"\"") + command + UString(L"\""); + command += L" \""; + command += UString(path); + command += L"\""; + + PROCESS_INFORMATION processInformation; + BOOL result; + #ifndef _UNICODE + if (!g_IsNT) + { + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + result = ::CreateProcessA(NULL, (CHAR *)(const CHAR *)GetSystemString(command), + NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation); + } + else + #endif + { + STARTUPINFOW startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + result = ::CreateProcessW(NULL, (WCHAR *)(const WCHAR *)command, + NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInformation); + } + + if (result != FALSE) + { + ::CloseHandle(processInformation.hThread); + return processInformation.hProcess; + } + ::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR, 0x03020282), + L"7-Zip", MB_OK | MB_ICONSTOP); + return 0; +} + +#ifndef _UNICODE +typedef BOOL (WINAPI * ShellExecuteExWP)(LPSHELLEXECUTEINFOW lpExecInfo); +#endif + +static HANDLE StartApplication(const UString &path, HWND window) +{ + UINT32 result; + HANDLE hProcess; + #ifndef _UNICODE + if (g_IsNT) + { + SHELLEXECUTEINFOW execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + execInfo.lpFile = path; + execInfo.lpParameters = NULL; + execInfo.lpDirectory = NULL; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = 0; + ShellExecuteExWP shellExecuteExW = (ShellExecuteExWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "ShellExecuteExW"); + if (shellExecuteExW == 0) + return 0; + shellExecuteExW(&execInfo); + result = (UINT32)(UINT_PTR)execInfo.hInstApp; + hProcess = execInfo.hProcess; + } + else + #endif + { + SHELLEXECUTEINFO execInfo; + execInfo.cbSize = sizeof(execInfo); + execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; + execInfo.hwnd = NULL; + execInfo.lpVerb = NULL; + const CSysString sysPath = GetSystemString(path); + execInfo.lpFile = sysPath; + execInfo.lpParameters = NULL; + execInfo.lpDirectory = NULL; + execInfo.nShow = SW_SHOWNORMAL; + execInfo.hProcess = 0; + ::ShellExecuteEx(&execInfo); + result = (UINT32)(UINT_PTR)execInfo.hInstApp; + hProcess = execInfo.hProcess; + } + if(result <= 32) + { + switch(result) + { + case SE_ERR_NOASSOC: + ::MessageBoxW(window, + NError::MyFormatMessageW(::GetLastError()), + // L"There is no application associated with the given file name extension", + L"7-Zip", MB_OK | MB_ICONSTOP); + } + } + return hProcess; +} + +void CPanel::EditItem(int index) +{ + if (!_parentFolders.IsEmpty()) + { + OpenItemInArchive(index, false, true, true); + return; + } + HANDLE hProcess = StartEditApplication(_currentFolderPrefix + GetItemRelPath(index), (HWND)*this); + if (hProcess != 0) + ::CloseHandle(hProcess); +} + +void CPanel::OpenFolderExternal(int index) +{ + HANDLE hProcess = StartApplication(GetFsPath() + GetItemRelPath(index), (HWND)*this); + if (hProcess != 0) + ::CloseHandle(hProcess); +} + +void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal) +{ + CDisableTimerProcessing disableTimerProcessing1(*this); + if (!_parentFolders.IsEmpty()) + { + OpenItemInArchive(index, tryInternal, tryExternal, false); + return; + } + UString name = GetItemRelPath(index); + if (IsNameVirus(name)) + { + MessageBoxMyError(virusMessage); + return; + } + UString fullPath = _currentFolderPrefix + name; + if (tryInternal) + if (!tryExternal || !DoItemAlwaysStart(name)) + if (OpenItemAsArchive(index) == S_OK) + return; + if (tryExternal) + { + NDirectory::MySetCurrentDirectory(_currentFolderPrefix); + HANDLE hProcess = StartApplication(fullPath, (HWND)*this); + if (hProcess != 0) + ::CloseHandle(hProcess); + } +} + +HRESULT CPanel::OnOpenItemChanged(const UString &folderPath, const UString &itemName) +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return E_FAIL; + } + UStringVector fileNames; + CRecordVector fileNamePointers; + fileNames.Add(itemName); + fileNamePointers.Add(fileNames[0]); + + UString pathPrefix = folderPath; + NName::NormalizeDirPathPrefix(pathPrefix); + return folderOperations->CopyFrom(pathPrefix, &fileNamePointers.Front(),fileNamePointers.Size(), NULL); +} + +LRESULT CPanel::OnOpenItemChanged(LPARAM lParam) +{ + CTmpProcessInfo &tmpProcessInfo = *(CTmpProcessInfo *)lParam; + // LoadCurrentPath() + if (tmpProcessInfo.FullPathFolderPrefix != _currentFolderPrefix) + return 0; + + CSelectedState state; + SaveSelectedState(state); + + HRESULT result = OnOpenItemChanged(tmpProcessInfo.FolderPath, tmpProcessInfo.ItemName); + if (result != S_OK) + return 0; + RefreshListCtrl(state); + return 1; +} + +/* +class CTmpProcessInfoList +{ +public: + CObjectVector _items; +} g_TmpProcessInfoList; +*/ + +class CExitEventLauncher +{ +public: + NWindows::NSynchronization::CManualResetEvent _exitEvent; + CExitEventLauncher() + { + if (_exitEvent.Create(false) != S_OK) + throw 9387173; + }; + ~CExitEventLauncher() { _exitEvent.Set(); } +} g_ExitEventLauncher; + +static THREAD_FUNC_DECL MyThreadFunction(void *param) +{ + CMyAutoPtr tmpProcessInfoPtr((CTmpProcessInfo *)param); + CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get(); + + HANDLE hProcess = tmpProcessInfo->ProcessHandle; + HANDLE events[2] = { g_ExitEventLauncher._exitEvent, hProcess}; + DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE); + ::CloseHandle(hProcess); + if (waitResult == WAIT_OBJECT_0 + 0) + return 0; + if (waitResult != WAIT_OBJECT_0 + 1) + return 1; + Sleep(200); + NFind::CFileInfoW newFileInfo; + if (NFind::FindFile(tmpProcessInfo->FilePath, newFileInfo)) + { + if (newFileInfo.Size != tmpProcessInfo->FileInfo.Size || + CompareFileTime(&newFileInfo.LastWriteTime, + &tmpProcessInfo->FileInfo.LastWriteTime) != 0) + { + UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, + 0x03020280, tmpProcessInfo->ItemName); + if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK) + { + if (SendMessage(tmpProcessInfo->Window, kOpenItemChanged, 0, (LONG_PTR)tmpProcessInfo) != 1) + { + ::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE, + 0x03020281, tmpProcessInfo->FilePath), L"7-Zip", MB_OK | MB_ICONSTOP); + return 0; + } + } + } + } + tmpProcessInfo->DeleteDirAndFile(); + return 0; +} + +void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, + bool editMode) +{ + const UString name = GetItemName(index); + if (IsNameVirus(name)) + { + MessageBoxMyError(virusMessage); + return; + } + + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + + NFile::NDirectory::CTempDirectoryW tempDirectory; + tempDirectory.Create(kTempDirPrefix); + UString tempDir = tempDirectory.GetPath(); + UString tempDirNorm = tempDir; + NFile::NName::NormalizeDirPathPrefix(tempDirNorm); + + CRecordVector indices; + indices.Add(index); + + UStringVector messages; + HRESULT result = CopyTo(indices, tempDirNorm, false, true, &messages); + + if (!messages.IsEmpty()) + return; + if (result != S_OK) + { + if (result != E_ABORT) + MessageBoxError(result); + return; + } + + UString tempFilePath = tempDirNorm + name; + + CMyAutoPtr tmpProcessInfoPtr(new CTmpProcessInfo()); + CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get(); + tmpProcessInfo->FolderPath = tempDir; + tmpProcessInfo->FilePath = tempFilePath; + if (!NFind::FindFile(tempFilePath, tmpProcessInfo->FileInfo)) + return; + + if (tryInternal) + { + if (!tryExternal || !DoItemAlwaysStart(name)) + { + bool encrypted; + if (OpenItemAsArchive(name, tempDir, tempFilePath, encrypted) == S_OK) + { + RefreshListCtrl(); + return; + } + } + } + + CTmpProcessInfoRelease tmpProcessInfoRelease(*tmpProcessInfo); + + if (!tryExternal) + return; + + HANDLE hProcess; + if (editMode) + hProcess = StartEditApplication(tempFilePath, (HWND)*this); + else + hProcess = StartApplication(tempFilePath, (HWND)*this); + + if (hProcess == 0) + return; + + tmpProcessInfo->Window = (HWND)(*this); + tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix; + tmpProcessInfo->ItemName = name; + tmpProcessInfo->ProcessHandle = hProcess; + + NWindows::CThread thread; + if (thread.Create(MyThreadFunction, tmpProcessInfo) != S_OK) + throw 271824; + tempDirectory.DisableDeleting(); + tmpProcessInfoPtr.release(); + tmpProcessInfoRelease._needDelete = false; +} + +/* +static const UINT64 kTimeLimit = UINT64(10000000) * 3600 * 24; + +static bool CheckDeleteItem(UINT64 currentFileTime, UINT64 folderFileTime) +{ + return (currentFileTime - folderFileTime > kTimeLimit && + folderFileTime - currentFileTime > kTimeLimit); +} + +void DeleteOldTempFiles() +{ + UString tempPath; + if(!NFile::NDirectory::MyGetTempPath(tempPath)) + throw 1; + + SYSTEMTIME systemTime; + ::GetSystemTime(&systemTime); + UINT64 currentFileTime; + if(!::SystemTimeToFileTime(&systemTime, (FILETIME *)¤tFileTime)) + throw 2; + UString searchWildCard = tempPath + kTempDirPrefix + L"*.tmp"; + searchWildCard += WCHAR(NName::kAnyStringWildcard); + NFind::CEnumeratorW enumerator(searchWildCard); + NFind::CFileInfoW fileInfo; + while(enumerator.Next(fileInfo)) + { + if (!fileInfo.IsDirectory()) + continue; + const UINT64 &creationTime = *(const UINT64 *)(&fileInfo.CreationTime); + if(CheckDeleteItem(creationTime, currentFileTime)) + RemoveDirectoryWithSubItems(tempPath + fileInfo.Name); + } +} +*/ diff --git a/CPP/7zip/UI/FileManager/PanelItems.cpp b/CPP/7zip/UI/FileManager/PanelItems.cpp new file mode 100755 index 00000000..41ef45dd --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelItems.cpp @@ -0,0 +1,807 @@ +// PanelItems.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/Menu.h" + +#include "../../PropID.h" + +#include "Panel.h" +#include "resource.h" + +#include "RootFolder.h" + +#include "PropertyName.h" +#include "LangUtils.h" + +extern "C" +{ + #include "../../../../C/Sort.h" +} + +using namespace NWindows; + +static int GetColumnAlign(PROPID propID, VARTYPE varType) +{ + switch(propID) + { + case kpidCreationTime: + case kpidLastAccessTime: + case kpidLastWriteTime: + return LVCFMT_LEFT; + } + switch(varType) + { + case VT_UI1: + case VT_I2: + case VT_UI2: + case VT_I4: + case VT_INT: + case VT_UI4: + case VT_UINT: + case VT_I8: + case VT_UI8: + case VT_BOOL: + return LVCFMT_RIGHT; + + case VT_EMPTY: + case VT_I1: + case VT_FILETIME: + case VT_BSTR: + return LVCFMT_LEFT; + + default: + return LVCFMT_CENTER; + } +} + +void CPanel::InitColumns() +{ + if (_needSaveInfo) + SaveListViewInfo(); + + _listView.DeleteAllItems(); + _selectedStatusVector.Clear(); + + ReadListViewInfo(); + + + PROPID sortID; + /* + if (_listViewInfo.SortIndex >= 0) + sortID = _listViewInfo.Columns[_listViewInfo.SortIndex].PropID; + */ + sortID = _listViewInfo.SortID; + + _ascending = _listViewInfo.Ascending; + + _properties.Clear(); + + _needSaveInfo = true; + + UInt32 numProperties; + _folder->GetNumberOfProperties(&numProperties); + int i; + for (i = 0; i < (int)numProperties; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE varType; + + if (_folder->GetPropertyInfo(i, &name, &propID, &varType) != S_OK) + throw 1; + + CItemProperty destProperty; + destProperty.Type = varType; + destProperty.ID = propID; + if (propID == kpidIsFolder) + continue; + { + if (name != NULL) + destProperty.Name = name; + else + destProperty.Name = L"Error"; + } + UString propName = GetNameOfProperty(propID); + if (!propName.IsEmpty()) + destProperty.Name = propName; + destProperty.Order = -1; + destProperty.IsVisible = true; + destProperty.Width = 100; + _properties.Add(destProperty); + } + // InitColumns2(sortID); + + for (;;) + if (!_listView.DeleteColumn(0)) + break; + + int order = 0; + for(i = 0; i < _listViewInfo.Columns.Size(); i++) + { + const CColumnInfo &columnInfo = _listViewInfo.Columns[i]; + int index = _properties.FindItemWithID(columnInfo.PropID); + if (index >= 0) + { + CItemProperty &item = _properties[index]; + item.IsVisible = columnInfo.IsVisible; + item.Width = columnInfo.Width; + if (columnInfo.IsVisible) + item.Order = order++; + continue; + } + } + for(i = 0; i < _properties.Size(); i++) + { + CItemProperty &item = _properties[i]; + if (item.Order < 0) + item.Order = order++; + } + + _visibleProperties.Clear(); + for (i = 0; i < _properties.Size(); i++) + { + const CItemProperty &property = _properties[i]; + if (property.IsVisible) + _visibleProperties.Add(property); + } + + // _sortIndex = 0; + _sortID = kpidName; + /* + if (_listViewInfo.SortIndex >= 0) + { + int sortIndex = _properties.FindItemWithID(sortID); + if (sortIndex >= 0) + _sortIndex = sortIndex; + } + */ + _sortID = _listViewInfo.SortID; + + for (i = 0; i < _visibleProperties.Size(); i++) + { + InsertColumn(i); + } +} + +void CPanel::InsertColumn(int index) +{ + const CItemProperty &property = _visibleProperties[index]; + LV_COLUMNW column; + column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_ORDER; + column.cx = property.Width; + column.fmt = GetColumnAlign(property.ID, property.Type); + column.iOrder = property.Order; + column.iSubItem = index; + UString propertyName = GetNameOfProperty(property.ID); + if (propertyName.IsEmpty()) + propertyName = property.Name; + column.pszText = (wchar_t *)(const wchar_t *)propertyName; + _listView.InsertColumn(index, &column); +} + +void CPanel::RefreshListCtrl() +{ + RefreshListCtrl(UString(), -1, true, UStringVector()); +} + +int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData); + + +void CPanel::GetSelectedNames(UStringVector &selectedNames) +{ + selectedNames.Clear(); + + CRecordVector indices; + GetSelectedItemsIndices(indices); + selectedNames.Reserve(indices.Size()); + for (int i = 0; i < indices.Size(); i++) + selectedNames.Add(GetItemRelPath(indices[i])); + + /* + for (int i = 0; i < _listView.GetItemCount(); i++) + { + const int kSize = 1024; + WCHAR name[kSize + 1]; + LVITEMW item; + item.iItem = i; + item.pszText = name; + item.cchTextMax = kSize; + item.iSubItem = 0; + item.mask = LVIF_TEXT | LVIF_PARAM; + if (!_listView.GetItem(&item)) + continue; + int realIndex = GetRealIndex(item); + if (realIndex == kParentIndex) + continue; + if (_selectedStatusVector[realIndex]) + selectedNames.Add(item.pszText); + } + */ + selectedNames.Sort(); +} + +void CPanel::SaveSelectedState(CSelectedState &s) +{ + s.FocusedName.Empty(); + s.SelectedNames.Clear(); + s.FocusedItem = _listView.GetFocusedItem(); + { + if (s.FocusedItem >= 0) + { + int realIndex = GetRealItemIndex(s.FocusedItem); + if (realIndex != kParentIndex) + s.FocusedName = GetItemRelPath(realIndex); + /* + const int kSize = 1024; + WCHAR name[kSize + 1]; + LVITEMW item; + item.iItem = focusedItem; + item.pszText = name; + item.cchTextMax = kSize; + item.iSubItem = 0; + item.mask = LVIF_TEXT; + if (_listView.GetItem(&item)) + focusedName = item.pszText; + */ + } + } + GetSelectedNames(s.SelectedNames); +} + +void CPanel::RefreshListCtrl(const CSelectedState &s) +{ + bool selectFocused = s.SelectFocused; + if (_mySelectMode) + selectFocused = true; + RefreshListCtrl(s.FocusedName, s.FocusedItem, selectFocused, s.SelectedNames); +} + +void CPanel::RefreshListCtrlSaveFocused() +{ + CSelectedState state; + SaveSelectedState(state); + RefreshListCtrl(state); +} + +void CPanel::SetFocusedSelectedItem(int index, bool select) +{ + UINT state = LVIS_FOCUSED; + if (select) + state |= LVIS_SELECTED; + _listView.SetItemState(index, state, state); + if (!_mySelectMode && select) + { + int realIndex = GetRealItemIndex(index); + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = true; + } +} + +void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, + const UStringVector &selectedNames) +{ + _dontShowMode = false; + LoadFullPathAndShow(); + // OutputDebugStringA("=======\n"); + // OutputDebugStringA("s1 \n"); + CDisableTimerProcessing timerProcessing(*this); + + if (focusedPos < 0) + focusedPos = 0; + + _listView.SetRedraw(false); + // m_RedrawEnabled = false; + + LVITEMW item; + ZeroMemory(&item, sizeof(item)); + + _listView.DeleteAllItems(); + _selectedStatusVector.Clear(); + // _realIndices.Clear(); + _startGroupSelect = 0; + + _selectionIsDefined = false; + + // m_Files.Clear(); + // _folder.Release(); + + if (!_folder) + { + // throw 1; + SetToRootFolder(); + } + + _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder()); + + CMyComPtr folderSetFlatMode; + _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode); + if (folderSetFlatMode) + folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode)); + + if (_folder->LoadItems() != S_OK) + return; + + InitColumns(); + + + // OutputDebugString(TEXT("Start Dir\n")); + UInt32 numItems; + _folder->GetNumberOfItems(&numItems); + + bool showDots = _showDots && !IsRootFolder(); + + _listView.SetItemCount(numItems + (showDots ? 1 : 0)); + + _selectedStatusVector.Reserve(numItems); + int cursorIndex = -1; + + CMyComPtr folderGetSystemIconIndex; + if (!IsFSFolder() || _showRealFileIcons) + _folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex); + + if (showDots) + { + UString itemName = L".."; + item.iItem = _listView.GetItemCount(); + if (itemName.CompareNoCase(focusedName) == 0) + cursorIndex = item.iItem; + 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; + UInt32 attributes = FILE_ATTRIBUTE_DIRECTORY; + item.iImage = _extToIconMap.GetIconIndex(attributes, itemName); + if (item.iImage < 0) + item.iImage = 0; + if(_listView.InsertItem(&item) == -1) + return; + } + + // OutputDebugStringA("S1\n"); + + for(UInt32 i = 0; i < numItems; i++) + { + UString itemName = GetItemName(i); + const UString relPath = GetItemRelPath(i); + if (relPath.CompareNoCase(focusedName) == 0) + cursorIndex = _listView.GetItemCount(); + bool selected = false; + if (selectedNames.FindInSorted(relPath) >= 0) + selected = true; + _selectedStatusVector.Add(selected); + + item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + + if (!_mySelectMode) + if (selected) + { + item.mask |= LVIF_STATE; + item.state = LVIS_SELECTED; + } + + int subItem = 0; + item.iItem = _listView.GetItemCount(); + + item.iSubItem = subItem++; + item.lParam = i; + + UString correctedName; + if (itemName.Find(L" ") >= 0) + { + int pos = 0; + for (;;) + { + int posNew = itemName.Find(L" ", pos); + if (posNew < 0) + { + correctedName += itemName.Mid(pos); + break; + } + correctedName += itemName.Mid(pos, posNew - pos); + correctedName += L" ... "; + pos = posNew; + while (itemName[++pos] == ' '); + } + item.pszText = (wchar_t *)(const wchar_t *)correctedName; + } + else + item.pszText = (wchar_t *)(const wchar_t *)itemName; + + NCOM::CPropVariant propVariant; + _folder->GetProperty(i, kpidAttributes, &propVariant); + UInt32 attributes = 0; + if (propVariant.vt == VT_UI4) + attributes = propVariant.ulVal; + else + { + if (IsItemFolder(i)) + attributes |= FILE_ATTRIBUTE_DIRECTORY; + } + + bool defined = false; + + if (folderGetSystemIconIndex) + { + folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage); + defined = (item.iImage > 0); + } + if (!defined) + { + if (_currentFolderPrefix.IsEmpty()) + { + int iconIndexTemp; + GetRealIconIndex(itemName + L"\\", attributes, iconIndexTemp); + item.iImage = iconIndexTemp; + } + else + { + item.iImage = _extToIconMap.GetIconIndex(attributes, itemName); + } + } + if (item.iImage < 0) + item.iImage = 0; + + if(_listView.InsertItem(&item) == -1) + return; // error + } + // OutputDebugStringA("End2\n"); + + if(_listView.GetItemCount() > 0 && cursorIndex >= 0) + SetFocusedSelectedItem(cursorIndex, selectFocused); + _listView.SortItems(CompareItems, (LPARAM)this); + if (cursorIndex < 0 && _listView.GetItemCount() > 0) + { + if (focusedPos >= _listView.GetItemCount()) + focusedPos = _listView.GetItemCount() - 1; + SetFocusedSelectedItem(focusedPos, true); + } + // m_RedrawEnabled = true; + _listView.EnsureVisible(_listView.GetFocusedItem(), false); + _listView.SetRedraw(true); + _listView.InvalidateRect(NULL, true); + // OutputDebugStringA("End1\n"); + /* + _listView.UpdateWindow(); + */ +} + +void CPanel::GetSelectedItemsIndices(CRecordVector &indices) const +{ + indices.Clear(); + /* + int itemIndex = -1; + while ((itemIndex = _listView.GetNextItem(itemIndex, LVNI_SELECTED)) != -1) + { + LPARAM param; + if (_listView.GetItemParam(itemIndex, param)) + indices.Add(param); + } + */ + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (_selectedStatusVector[i]) + indices.Add(i); + HeapSort(&indices.Front(), indices.Size()); +} + +void CPanel::GetOperatedItemIndices(CRecordVector &indices) const +{ + GetSelectedItemsIndices(indices); + if (!indices.IsEmpty()) + return; + if (_listView.GetSelectedCount() == 0) + return; + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + { + if(_listView.GetItemState(focusedItem, LVIS_SELECTED) == LVIS_SELECTED) + { + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) + indices.Add(realIndex); + } + } +} + +void CPanel::GetAllItemIndices(CRecordVector &indices) const +{ + indices.Clear(); + UInt32 numItems; + if (_folder->GetNumberOfItems(&numItems) == S_OK) + for (UInt32 i = 0; i < numItems; i++) + indices.Add(i); +} + +/* +void CPanel::GetOperatedListViewIndices(CRecordVector &indices) const +{ + indices.Clear(); + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + { + int realIndex = GetRealItemIndex(i); + if (realIndex >= 0) + if (_selectedStatusVector[realIndex]) + indices.Add(i); + } + if (indices.IsEmpty()) + { + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + indices.Add(focusedItem); + } +} +*/ + +void CPanel::EditItem() +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex) + return; + if (!IsItemFolder(realIndex)) + EditItem(realIndex); +} + +void CPanel::OpenFocusedItemAsInternal() +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + if (IsItemFolder(realIndex)) + OpenFolder(realIndex); + else + OpenItem(realIndex, true, false); +} + +void CPanel::OpenSelectedItems(bool tryInternal) +{ + CRecordVector indices; + GetOperatedItemIndices(indices); + if (indices.Size() > 20) + { + MessageBox(LangString(IDS_TOO_MANY_ITEMS, 0x02000606)); + return; + } + + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem >= 0) + { + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex == kParentIndex && (tryInternal || indices.Size() == 0)) + indices.Insert(0, realIndex); + } + + bool dirIsStarted = false; + for(int i = 0; i < indices.Size(); i++) + { + UInt32 index = indices[i]; + // CFileInfo &aFile = m_Files[index]; + if (IsItemFolder(index)) + { + if (!dirIsStarted) + { + if (tryInternal) + { + OpenFolder(index); + dirIsStarted = true; + break; + } + else + OpenFolderExternal(index); + } + } + else + OpenItem(index, (tryInternal && indices.Size() == 1), true); + } +} + +UString CPanel::GetItemName(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return L".."; + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidName, &propVariant) != S_OK) + throw 2723400; + if (propVariant.vt != VT_BSTR) + throw 2723401; + return (propVariant.bstrVal); +} + +UString CPanel::GetItemPrefix(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return UString(); + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidPrefix, &propVariant) != S_OK) + throw 2723400; + UString prefix; + if (propVariant.vt == VT_BSTR) + prefix = propVariant.bstrVal; + return prefix; +} + +UString CPanel::GetItemRelPath(int itemIndex) const +{ + return GetItemPrefix(itemIndex) + GetItemName(itemIndex); +} + + +bool CPanel::IsItemFolder(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return true; + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidIsFolder, &propVariant) != S_OK) + throw 2723400; + if (propVariant.vt == VT_BOOL) + return VARIANT_BOOLToBool(propVariant.boolVal); + if (propVariant.vt == VT_EMPTY) + return false; + return false; +} + +UINT64 CPanel::GetItemSize(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return 0; + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidSize, &propVariant) != S_OK) + throw 2723400; + if (propVariant.vt == VT_EMPTY) + return 0; + return ConvertPropVariantToUInt64(propVariant); +} + +void CPanel::ReadListViewInfo() +{ + _typeIDString = GetFolderTypeID(); + if (!_typeIDString.IsEmpty()) + ::ReadListViewInfo(_typeIDString, _listViewInfo); +} + +void CPanel::SaveListViewInfo() +{ + int i; + for(i = 0; i < _visibleProperties.Size(); i++) + { + CItemProperty &property = _visibleProperties[i]; + LVCOLUMN winColumnInfo; + winColumnInfo.mask = LVCF_ORDER | LVCF_WIDTH; + if (!_listView.GetColumn(i, &winColumnInfo)) + throw 1; + property.Order = winColumnInfo.iOrder; + property.Width = winColumnInfo.cx; + } + + CListViewInfo viewInfo; + + // PROPID sortPropID = _properties[_sortIndex].ID; + PROPID sortPropID = _sortID; + + _visibleProperties.Sort(); + for(i = 0; i < _visibleProperties.Size(); i++) + { + const CItemProperty &property = _visibleProperties[i]; + CColumnInfo columnInfo; + columnInfo.IsVisible = property.IsVisible; + columnInfo.PropID = property.ID; + columnInfo.Width = property.Width; + viewInfo.Columns.Add(columnInfo); + } + for(i = 0; i < _properties.Size(); i++) + { + const CItemProperty &property = _properties[i]; + if (!property.IsVisible) + { + CColumnInfo columnInfo; + columnInfo.IsVisible = property.IsVisible; + columnInfo.PropID = property.ID; + columnInfo.Width = property.Width; + viewInfo.Columns.Add(columnInfo); + } + } + + // viewInfo.SortIndex = viewInfo.FindColumnWithID(sortPropID); + viewInfo.SortID = sortPropID; + + viewInfo.Ascending = _ascending; + if (!_listViewInfo.IsEqual(viewInfo)) + { + ::SaveListViewInfo(_typeIDString, viewInfo); + _listViewInfo = viewInfo; + } +} + +bool CPanel::OnRightClick(LPNMITEMACTIVATE itemActiveate, LRESULT &result) +{ + if(itemActiveate->hdr.hwndFrom == HWND(_listView)) + return false; + + POINT point; + ::GetCursorPos(&point); + + CMenu menu; + CMenuDestroyer menuDestroyer(menu); + + menu.CreatePopup(); + + const int kCommandStart = 100; + for(int i = 0; i < _properties.Size(); i++) + { + const CItemProperty &property = _properties[i]; + UINT flags = MF_STRING; + if (property.IsVisible) + flags |= MF_CHECKED; + if (i == 0) + flags |= MF_GRAYED; + menu.AppendItem(flags, kCommandStart + i, GetSystemString(property.Name)); + } + int menuResult = menu.Track(TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY, + point.x, point.y, _listView); + if (menuResult >= kCommandStart && menuResult <= kCommandStart + _properties.Size()) + { + int index = menuResult - kCommandStart; + CItemProperty &property = _properties[index]; + property.IsVisible = !property.IsVisible; + + if (property.IsVisible) + { + int prevVisibleSize = _visibleProperties.Size(); + property.Order = prevVisibleSize; + _visibleProperties.Add(property); + InsertColumn(prevVisibleSize); + } + else + { + int visibleIndex = _visibleProperties.FindItemWithID(property.ID); + _visibleProperties.Delete(visibleIndex); + /* + if (_sortIndex == index) + { + _sortIndex = 0; + _ascending = true; + } + */ + if (_sortID == property.ID) + { + _sortID = kpidName; + _ascending = true; + } + + _listView.DeleteColumn(visibleIndex); + } + } + result = TRUE; + return true; +} + +void CPanel::OnReload() +{ + RefreshListCtrlSaveFocused(); + OnRefreshStatusBar(); +} + +void CPanel::OnTimer() +{ + if (!_processTimer) + return; + CMyComPtr folderWasChanged; + if (_folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged) != S_OK) + return; + INT32 wasChanged; + if (folderWasChanged->WasChanged(&wasChanged) != S_OK) + return; + if (wasChanged == 0) + return; + OnReload(); +} + diff --git a/CPP/7zip/UI/FileManager/PanelKey.cpp b/CPP/7zip/UI/FileManager/PanelKey.cpp new file mode 100755 index 00000000..5f002de9 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelKey.cpp @@ -0,0 +1,297 @@ +// PanelKey.cpp + +#include "StdAfx.h" + +#include "Panel.h" +#include "HelpUtils.h" + +#include "../../PropID.h" +#include "App.h" + +// static LPCWSTR kHelpTopic = L"FM/index.htm"; + +struct CVKeyPropIDPair +{ + WORD VKey; + PROPID PropID; +}; + +static CVKeyPropIDPair g_VKeyPropIDPairs[] = +{ + { VK_F3, kpidName }, + { VK_F4, kpidExtension }, + { VK_F5, kpidLastWriteTime }, + { VK_F6, kpidSize }, + { VK_F7, kpidNoProperty } +}; + +static int FindVKeyPropIDPair(WORD vKey) +{ + for (int i = 0; i < sizeof(g_VKeyPropIDPairs) / sizeof(g_VKeyPropIDPairs[0]); i++) + if (g_VKeyPropIDPairs[i].VKey == vKey) + return i; + return -1; +} + + +bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) +{ + if (keyDownInfo->wVKey == VK_TAB && keyDownInfo->hdr.hwndFrom == _listView) + { + _panelCallback->OnTab(); + return false; + } + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0; + bool rightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + result = 0; + + if (keyDownInfo->wVKey >= '0' && keyDownInfo->wVKey <= '9' && + (rightCtrl || alt)) + { + int index = keyDownInfo->wVKey - '0'; + if (shift) + { + SetBookmark(index); + return true; + } + else + { + OpenBookmark(index); + return true; + } + } + + if ((keyDownInfo->wVKey == VK_F2 || + keyDownInfo->wVKey == VK_F1) && alt && !ctrl && !shift) + { + _panelCallback->SetFocusToPath(keyDownInfo->wVKey == VK_F1 ? 0 : 1); + return true; + } + + if ((keyDownInfo->wVKey == VK_F9) && !alt && !ctrl && !shift) + { + g_App.SwitchOnOffOnePanel(); + } + + if(keyDownInfo->wVKey >= VK_F3 && keyDownInfo->wVKey <= VK_F12 && ctrl) + { + int index = FindVKeyPropIDPair(keyDownInfo->wVKey); + if (index >= 0) + SortItemsWithPropID(g_VKeyPropIDPairs[index].PropID); + } + + switch(keyDownInfo->wVKey) + { + case VK_SHIFT: + { + _selectionIsDefined = false; + _prevFocusedItem = _listView.GetFocusedItem(); + break; + } + /* + case VK_F1: + { + // ShowHelpWindow(NULL, kHelpTopic); + break; + } + */ + case VK_F2: + { + if (!alt && !ctrl &&!shift) + { + RenameFile(); + return true; + } + break; + } + case VK_F4: + { + if (!alt && !ctrl && !shift) + { + EditItem(); + return true; + } + if (!alt && !ctrl && shift) + { + CreateFile(); + return true; + } + break; + } + case VK_F5: + { + if (!alt && !ctrl) + { + _panelCallback->OnCopy(false, shift); + return true; + } + break; + } + case VK_F6: + { + if (!alt && !ctrl) + { + _panelCallback->OnCopy(true, shift); + return true; + } + break; + } + /* + case VK_F7: + { + if (!alt && !ctrl && !shift) + { + CreateFolder(); + return true; + } + break; + } + */ + case VK_DELETE: + { + DeleteItems(!shift); + return true; + } + case VK_INSERT: + { + OnInsert(); + return true; + } + case VK_DOWN: + { + if(shift) + OnArrowWithShift(); + return false; + } + case VK_UP: + { + if (alt) + _panelCallback->OnSetSameFolder(); + else if(shift) + OnArrowWithShift(); + return false; + } + case VK_RIGHT: + { + if (alt) + _panelCallback->OnSetSubFolder(); + else if(shift) + OnArrowWithShift(); + return false; + } + case VK_LEFT: + { + if (alt) + _panelCallback->OnSetSubFolder(); + else if(shift) + OnArrowWithShift(); + return false; + } + case VK_NEXT: + { + if (ctrl && !alt && !shift) + { + // EnterToFocused(); + return true; + } + break; + } + case VK_ADD: + { + if (alt) + SelectByType(true); + else if (shift) + SelectAll(true); + else if(!ctrl) + SelectSpec(true); + return true; + } + case VK_SUBTRACT: + { + if (alt) + SelectByType(false); + else if (shift) + SelectAll(false); + else + SelectSpec(false); + return true; + } + /* + case VK_DELETE: + CommandDelete(); + return 0; + case VK_F1: + CommandHelp(); + return 0; + */ + case VK_BACK: + OpenParentFolder(); + return true; + /* + case VK_DIVIDE: + case '\\': + case '/': + case VK_OEM_5: + { + // OpenRootFolder(); + OpenDrivesFolder(); + + return true; + } + */ + case 'A': + if(ctrl) + { + SelectAll(true); + return true; + } + return false; + case 'N': + if (ctrl) + { + CreateFile(); + return true; + } + return false; + case 'R': + if(ctrl) + { + OnReload(); + return true; + } + return false; + case 'Z': + if(ctrl) + { + ChangeComment(); + return true; + } + return false; + case '1': + case '2': + case '3': + case '4': + if(ctrl) + { + int styleIndex = keyDownInfo->wVKey - '1'; + SetListViewMode(styleIndex); + return true; + } + return false; + case VK_MULTIPLY: + { + InvertSelection(); + return true; + } + case VK_F12: + if (alt && !ctrl && !shift) + { + FoldersHistory(); + return true; + } + } + return false; +} diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp new file mode 100755 index 00000000..69b06119 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp @@ -0,0 +1,392 @@ +// PanelListNotify.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +// #include "Windows/COM.h" + +#include "../Common/PropIDUtils.h" +#include "../../PropID.h" + +#include "Panel.h" +#include "FormatUtils.h" + +using namespace NWindows; + +static UString ConvertSizeToString(UINT64 value) +{ + wchar_t s[64]; + if (value < (UINT64(10000) << 0) /*&& ((value & 0x3FF) != 0 || value == 0)*/) + { + ConvertUInt64ToString(value, s); + return UString(s) + L" B"; + } + if (value < (UINT64(10000) << 10)) + { + ConvertUInt64ToString((value >> 10), s); + return UString(s) + L" K"; + } + if (value < (UINT64(10000) << 20)) + { + ConvertUInt64ToString((value >> 20), s); + return UString(s) + L" M"; + } + ConvertUInt64ToString((value >> 30), s); + return UString(s) + L" G"; +} + +LRESULT CPanel::SetItemText(LVITEMW &item) +{ + if (_dontShowMode) + return 0; + + UINT32 realIndex = GetRealIndex(item); + /* + if ((item.mask & LVIF_IMAGE) != 0) + { + bool defined = false; + CComPtr folderGetSystemIconIndex; + _folder.QueryInterface(&folderGetSystemIconIndex); + if (folderGetSystemIconIndex) + { + folderGetSystemIconIndex->GetSystemIconIndex(index, &item.iImage); + defined = (item.iImage > 0); + } + if (!defined) + { + NCOM::CPropVariant propVariant; + _folder->GetProperty(index, kpidAttributes, &propVariant); + UINT32 attributes = 0; + if (propVariant.vt == VT_UI4) + attributes = propVariant.ulVal; + else + { + if (IsItemFolder(index)) + attributes |= FILE_ATTRIBUTE_DIRECTORY; + } + if (_currentFolderPrefix.IsEmpty()) + { + throw 1; + } + else + item.iImage = _extToIconMap.GetIconIndex(attributes, + GetSystemString(GetItemName(index))); + } + // item.iImage = 1; + } + */ + + if ((item.mask & LVIF_TEXT) == 0) + return 0; + + if (realIndex == kParentIndex) + return 0; + UString s; + UINT32 subItemIndex = item.iSubItem; + PROPID propID = _visibleProperties[subItemIndex].ID; + /* + { + NCOM::CPropVariant property; + if(propID == kpidType) + string = GetFileType(index); + else + { + HRESULT result = m_ArchiveFolder->GetProperty(index, propID, &property); + if (result != S_OK) + { + // PrintMessage("GetPropertyValue error"); + return 0; + } + string = ConvertPropertyToString(property, propID, false); + } + } + */ + // const NFind::CFileInfo &aFileInfo = m_Files[index]; + + NCOM::CPropVariant propVariant; + /* + bool needRead = true; + if (propID == kpidSize) + { + CComPtr getItemFullSize; + if (_folder.QueryInterface(&getItemFullSize) == S_OK) + { + if (getItemFullSize->GetItemFullSize(index, &propVariant) == S_OK) + needRead = false; + } + } + if (needRead) + */ + + if (_folder->GetProperty(realIndex, propID, &propVariant) != S_OK) + throw 2723407; + + if ((propID == kpidSize || propID == kpidPackedSize || + propID == kpidTotalSize || propID == kpidFreeSpace || + propID == kpidClusterSize) + && + (propVariant.vt == VT_UI8 || propVariant.vt == VT_UI4)) + s = ConvertSizeToString(ConvertPropVariantToUInt64(propVariant)); + else + s = ConvertPropertyToString(propVariant, propID, false); + + { + s.Replace(wchar_t(0xA), L' '); + s.Replace(wchar_t(0xD), L' '); + } + int size = item.cchTextMax; + if(size > 0) + { + if(s.Length() + 1 > size) + s = s.Left(size - 1); + MyStringCopy(item.pszText, (const wchar_t *)s); + } + return 0; +} + +extern DWORD g_ComCtl32Version; + +void CPanel::OnItemChanged(NMLISTVIEW *item) +{ + int index = (int)item->lParam; + if (index == kParentIndex) + return; + bool oldSelected = (item->uOldState & LVIS_SELECTED) != 0; + bool newSelected = (item->uNewState & LVIS_SELECTED) != 0; + // Don't change this code. It works only with such check + if(oldSelected != newSelected) + _selectedStatusVector[index] = newSelected; +} + +bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) +{ + // bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + // bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + switch(header->code) + { + case LVN_ITEMCHANGED: + { + if (_enableItemChangeNotify) + { + if (!_mySelectMode) + OnItemChanged((LPNMLISTVIEW)header); + RefreshStatusBar(); + } + return false; + } + /* + + case LVN_ODSTATECHANGED: + { + break; + } + */ + + case LVN_GETDISPINFOW: + { + LV_DISPINFOW *dispInfo = (LV_DISPINFOW *)header; + + //is the sub-item information being requested? + + if((dispInfo->item.mask & LVIF_TEXT) != 0 || + (dispInfo->item.mask & LVIF_IMAGE) != 0) + SetItemText(dispInfo->item); + return false; + } + case LVN_KEYDOWN: + { + bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header), result); + RefreshStatusBar(); + return boolResult; + } + + case LVN_COLUMNCLICK: + OnColumnClick(LPNMLISTVIEW(header)); + return false; + /* + case LVN_ITEMACTIVATE: + RefreshStatusBar(); + if (!alt && !ctrl && !shift) + OpenSelectedItems(true); + return false; + */ + + case NM_DBLCLK: + RefreshStatusBar(); + OpenSelectedItems(true); + return false; + case NM_RETURN: + { + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0; + // bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0; + bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; + if (!shift && alt && !ctrl) + { + Properties(); + return false; + } + OpenSelectedItems(true); + return false; + } + case NM_RCLICK: + RefreshStatusBar(); + break; + + /* + return OnRightClick((LPNMITEMACTIVATE)header, result); + */ + /* + case NM_CLICK: + SendRefreshStatusBarMessage(); + return 0; + + // TODO : Handler default action... + return 0; + case LVN_ITEMCHANGED: + { + NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh; + SelChange(pNMLV); + return TRUE; + } + case NM_SETFOCUS: + return onSetFocus(NULL); + case NM_KILLFOCUS: + return onKillFocus(NULL); + */ + case NM_CLICK: + { + // we need SetFocusToList, if we drag-select items from other panel. + SetFocusToList(); + RefreshStatusBar(); + if(_mySelectMode) + if(g_ComCtl32Version >= MAKELONG(71, 4)) + OnLeftClick((LPNMITEMACTIVATE)header); + return false; + } + case LVN_BEGINLABELEDITW: + result = OnBeginLabelEdit((LV_DISPINFOW *)header); + return true; + case LVN_ENDLABELEDITW: + result = OnEndLabelEdit((LV_DISPINFOW *)header); + return true; + + case NM_CUSTOMDRAW: + { + if (_mySelectMode) + return OnCustomDraw((LPNMLVCUSTOMDRAW)header, result); + break; + } + case LVN_BEGINDRAG: + { + OnDrag((LPNMLISTVIEW)header); + RefreshStatusBar(); + break; + } + // case LVN_BEGINRDRAG: + } + return false; +} + +bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result) +{ + switch(lplvcd->nmcd.dwDrawStage) + { + case CDDS_PREPAINT : + result = CDRF_NOTIFYITEMDRAW; + return true; + + case CDDS_ITEMPREPAINT: + /* + SelectObject(lplvcd->nmcd.hdc, + GetFontForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam) ); + lplvcd->clrText = GetColorForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam); + lplvcd->clrTextBk = GetBkColorForItem(lplvcd->nmcd.dwItemSpec, + lplvcd->nmcd.lItemlParam); + */ + int realIndex = (int)lplvcd->nmcd.lItemlParam; + bool selected = false; + if (realIndex != kParentIndex) + selected = _selectedStatusVector[realIndex]; + if (selected) + lplvcd->clrTextBk = RGB(255, 192, 192); + // lplvcd->clrText = RGB(255, 0, 128); + else + lplvcd->clrTextBk = _listView.GetBkColor(); + // lplvcd->clrText = RGB(0, 0, 0); + // result = CDRF_NEWFONT; + result = CDRF_NOTIFYITEMDRAW; + return true; + + // return false; + // return true; + /* + case CDDS_SUBITEM | CDDS_ITEMPREPAINT: + if (lplvcd->iSubItem == 0) + { + // lplvcd->clrText = RGB(255, 0, 0); + lplvcd->clrTextBk = RGB(192, 192, 192); + } + else + { + lplvcd->clrText = RGB(0, 0, 0); + lplvcd->clrTextBk = RGB(255, 255, 255); + } + return true; + */ + + /* At this point, you can change the background colors for the item + and any subitems and return CDRF_NEWFONT. If the list-view control + is in report mode, you can simply return CDRF_NOTIFYSUBITEMREDRAW + to customize the item's subitems individually */ + } + return false; +} + +void CPanel::OnRefreshStatusBar() +{ + CRecordVector indices; + GetOperatedItemIndices(indices); + + _statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, 0x02000301, NumberToString(indices.Size()))); + + UString selectSizeString; + + if (indices.Size() > 0) + { + UINT64 totalSize = 0; + for (int i = 0; i < indices.Size(); i++) + totalSize += GetItemSize(indices[i]); + selectSizeString = ConvertSizeToString(totalSize); + } + _statusBar.SetText(1, selectSizeString); + + int focusedItem = _listView.GetFocusedItem(); + UString sizeString; + UString dateString; + if (focusedItem >= 0 && _listView.GetSelectedCount() > 0) + { + int realIndex = GetRealItemIndex(focusedItem); + if (realIndex != kParentIndex) + { + sizeString = ConvertSizeToString(GetItemSize(realIndex)); + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(realIndex, kpidLastWriteTime, &propVariant) == S_OK) + dateString = ConvertPropertyToString(propVariant, kpidLastWriteTime, false); + } + } + _statusBar.SetText(2, sizeString); + _statusBar.SetText(3, dateString); + // _statusBar.SetText(4, nameString); + // _statusBar2.SetText(1, MyFormatNew(L"{0} bytes", NumberToStringW(totalSize))); +} diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp new file mode 100755 index 00000000..58d457cb --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp @@ -0,0 +1,558 @@ +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Windows/Menu.h" +#include "Windows/COM.h" +#include "Windows/PropVariant.h" +#include "../Common/PropIDUtils.h" +#include "../../PropID.h" + +#include "Panel.h" +#include "PluginInterface.h" +#include "MyLoadMenu.h" +#include "App.h" +#include "LangUtils.h" +#include "resource.h" +#include "PropertyName.h" +#include "PropertyNameRes.h" + +using namespace NWindows; + +// {23170F69-40C1-278A-1000-000100020000} +DEFINE_GUID(CLSID_CZipContextMenu, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); + +static const UINT kSevenZipStartMenuID = kPluginMenuStartID ; +static const UINT kSystemStartMenuID = kPluginMenuStartID + 100; + +void CPanel::InvokeSystemCommand(const char *command) +{ + if (!IsFSFolder() && !IsFSDrivesFolder()) + return; + CRecordVector operatedIndices; + GetOperatedItemIndices(operatedIndices); + if (operatedIndices.IsEmpty()) + return; + CMyComPtr contextMenu; + if (CreateShellContextMenu(operatedIndices, contextMenu) != S_OK) + return; + + CMINVOKECOMMANDINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(CMINVOKECOMMANDINFO); + ci.hwnd = GetParent(); + ci.lpVerb = command; + contextMenu->InvokeCommand(&ci); +} + +static const wchar_t *kSeparator = L"--------------------------------------\n"; +static const wchar_t *kPropValueSeparator = L": "; + +static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR, + const NCOM::CPropVariant &prop, UString &s) +{ + if (prop.vt != VT_EMPTY) + { + UString name = GetNameOfProperty(propID); + if (name.IsEmpty() && nameBSTR != NULL) + name = nameBSTR; + if (name.IsEmpty()) + name = L"?"; + + const UString val = ConvertPropertyToString(prop, propID); + if (!val.IsEmpty()) + { + s += name; + s += kPropValueSeparator; + /* + if (propID == kpidComment) + s += L'\n'; + */ + s += val; + s += L'\n'; + } + } +} + +void CPanel::Properties() +{ + CMyComPtr getFolderArchiveProperties; + _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties); + if (!getFolderArchiveProperties) + { + InvokeSystemCommand("properties"); + return; + } + + { + UString message; + + CRecordVector operatedIndices; + GetOperatedItemIndices(operatedIndices); + if (operatedIndices.Size() == 1) + { + UInt32 index = operatedIndices[0]; + // message += L"Item:\n"; + UInt32 numProps; + if (_folder->GetNumberOfProperties(&numProps) == S_OK) + { + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE varType; + + if (_folder->GetPropertyInfo(i, &name, &propID, &varType) != S_OK) + continue; + + NCOM::CPropVariant prop; + if (_folder->GetProperty(index, propID, &prop) != S_OK) + continue; + AddPropertyString(propID, name, prop, message); + } + } + message += kSeparator; + } + + message += LangString(IDS_PROPERTY_FILE_TYPE, 0x02000214); + message += kPropValueSeparator; + message += GetFolderTypeID(); + message += L"\n"; + + { + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(kpidPath, &prop) == S_OK) + { + AddPropertyString(kpidName, L"Path", prop, message); + } + } + + CMyComPtr folderProperties; + _folder.QueryInterface(IID_IFolderProperties, &folderProperties); + if (folderProperties) + { + UInt32 numProps; + if (folderProperties->GetNumberOfFolderProperties(&numProps) == S_OK) + { + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (folderProperties->GetFolderPropertyInfo(i, &name, &propID, &vt) != S_OK) + continue; + NCOM::CPropVariant prop; + if (_folder->GetFolderProperty(propID, &prop) != S_OK) + continue; + AddPropertyString(propID, name, prop, message); + } + } + } + + CMyComPtr getFolderArchiveProperties; + _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties); + if (getFolderArchiveProperties) + { + CMyComPtr getProps; + getFolderArchiveProperties->GetFolderArchiveProperties(&getProps); + if (getProps) + { + UInt32 numProps; + if (getProps->GetNumberOfArchiveProperties(&numProps) == S_OK) + { + if (numProps > 0) + message += kSeparator; + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (getProps->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK) + continue; + NCOM::CPropVariant prop; + if (getProps->GetArchiveProperty(propID, &prop) != S_OK) + continue; + AddPropertyString(propID, name, prop, message); + } + } + } + } + ::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES, 0x03020900), MB_OK); + } +} + +// Copy and paste do not work, if you know why write me. + +void CPanel::EditCopy() +{ + NCOM::CComInitializer comInitializer; + InvokeSystemCommand("copy"); +} + +void CPanel::EditPaste() +{ + NCOM::CComInitializer comInitializer; + InvokeSystemCommand("paste"); +} + +HRESULT CPanel::CreateShellContextMenu( + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu) +{ + systemContextMenu.Release(); + UString folderPath = GetFsPath(); + + CMyComPtr desktopFolder; + RINOK(::SHGetDesktopFolder(&desktopFolder)); + if (!desktopFolder) + { + // ShowMessage("Failed to get Desktop folder."); + return E_FAIL; + } + + // Separate the file from the folder. + + + // Get a pidl for the folder the file + // is located in. + LPITEMIDLIST parentPidl; + DWORD eaten; + RINOK(desktopFolder->ParseDisplayName( + GetParent(), 0, (wchar_t *)(const wchar_t *)folderPath, + &eaten, &parentPidl, 0)); + + // Get an IShellFolder for the folder + // the file is located in. + CMyComPtr parentFolder; + RINOK(desktopFolder->BindToObject(parentPidl, + 0, IID_IShellFolder, (void**)&parentFolder)); + if (!parentFolder) + { + // ShowMessage("Invalid file name."); + return E_FAIL; + } + + // Get a pidl for the file itself. + CRecordVector pidls; + pidls.Reserve(operatedIndices.Size()); + for (int i = 0; i < operatedIndices.Size(); i++) + { + LPITEMIDLIST pidl; + UString fileName = GetItemRelPath(operatedIndices[i]); + if (IsFSDrivesFolder()) + fileName += L'\\'; + RINOK(parentFolder->ParseDisplayName(GetParent(), 0, + (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0)); + pidls.Add(pidl); + } + + ITEMIDLIST temp; + if (pidls.Size() == 0) + { + temp.mkid.cb = 0; + /* + LPITEMIDLIST pidl; + HRESULT result = parentFolder->ParseDisplayName(GetParent(), 0, + L".\\", &eaten, &pidl, 0); + if (result != NOERROR) + return; + */ + pidls.Add(&temp); + } + + // Get the IContextMenu for the file. + CMyComPtr cm; + RINOK( parentFolder->GetUIObjectOf(GetParent(), pidls.Size(), + (LPCITEMIDLIST *)&pidls.Front(), IID_IContextMenu, 0, (void**)&cm)); + if (!cm) + { + // ShowMessage("Unable to get context menu interface."); + return E_FAIL; + } + systemContextMenu = cm; + return S_OK; +} + +void CPanel::CreateSystemMenu(HMENU menuSpec, + const CRecordVector &operatedIndices, + CMyComPtr &systemContextMenu) +{ + systemContextMenu.Release(); + + CreateShellContextMenu(operatedIndices, systemContextMenu); + + if (systemContextMenu == 0) + return; + + // Set up a CMINVOKECOMMANDINFO structure. + CMINVOKECOMMANDINFO ci; + ZeroMemory(&ci, sizeof(ci)); + ci.cbSize = sizeof(CMINVOKECOMMANDINFO); + ci.hwnd = GetParent(); + + /* + if (Sender == GoBtn) + { + // Verbs that can be used are cut, paste, + // properties, delete, and so on. + String action; + if (CutRb->Checked) + action = "cut"; + else if (CopyRb->Checked) + action = "copy"; + else if (DeleteRb->Checked) + action = "delete"; + else if (PropertiesRb->Checked) + action = "properties"; + + ci.lpVerb = action.c_str(); + result = cm->InvokeCommand(&ci); + if (result) + ShowMessage( + "Error copying file to clipboard."); + + } + else + */ + { + // HMENU hMenu = CreatePopupMenu(); + CMenu popupMenu; + // CMenuDestroyer menuDestroyer(popupMenu); + if(!popupMenu.CreatePopup()) + throw 210503; + + HMENU hMenu = popupMenu; + + DWORD Flags = CMF_EXPLORE; + // Optionally the shell will show the extended + // context menu on some operating systems when + // the shift key is held down at the time the + // context menu is invoked. The following is + // commented out but you can uncommnent this + // line to show the extended context menu. + // Flags |= 0x00000080; + systemContextMenu->QueryContextMenu(hMenu, 0, kSystemStartMenuID, 0x7FFF, Flags); + + + { + CMenu menu; + menu.Attach(menuSpec); + CMenuItem menuItem; + menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID; + menuItem.fType = MFT_STRING; + menuItem.hSubMenu = popupMenu.Detach(); + // menuDestroyer.Disable(); + menuItem.StringValue = LangString(IDS_SYSTEM, 0x030202A0); + menu.InsertItem(0, true, menuItem); + } + /* + if (Cmd < 100 && Cmd != 0) + { + ci.lpVerb = MAKEINTRESOURCE(Cmd - 1); + ci.lpParameters = ""; + ci.lpDirectory = ""; + ci.nShow = SW_SHOWNORMAL; + cm->InvokeCommand(&ci); + } + // If Cmd is > 100 then it's one of our + // inserted menu items. + else + // Find the menu item. + for (int i = 0; i < popupMenu1->Items->Count; i++) + { + TMenuItem* menu = popupMenu1->Items->Items[i]; + // Call its OnClick handler. + if (menu->Command == Cmd - 100) + menu->OnClick(this); + } + // Release the memory allocated for the menu. + DestroyMenu(hMenu); + */ + } +} + +void CPanel::CreateFileMenu(HMENU menuSpec) +{ + CreateFileMenu(menuSpec, _sevenZipContextMenu, _systemContextMenu, true); +} + +void CPanel::CreateSevenZipMenu(HMENU menuSpec, + const CRecordVector &operatedIndices, + CMyComPtr &sevenZipContextMenu) +{ + sevenZipContextMenu.Release(); + + CMenu menu; + menu.Attach(menuSpec); + // CMenuDestroyer menuDestroyer(menu); + // menu.CreatePopup(); + + bool sevenZipMenuCreated = false; + + CMyComPtr contextMenu; + if (contextMenu.CoCreateInstance(CLSID_CZipContextMenu, IID_IContextMenu) == S_OK) + { + CMyComPtr initContextMenu; + if (contextMenu.QueryInterface(IID_IInitContextMenu, &initContextMenu) != S_OK) + return; + UString currentFolderUnicode = _currentFolderPrefix; + UStringVector names; + int i; + for(i = 0; i < operatedIndices.Size(); i++) + names.Add(currentFolderUnicode + GetItemRelPath(operatedIndices[i])); + CRecordVector namePointers; + for(i = 0; i < operatedIndices.Size(); i++) + namePointers.Add(names[i]); + + // NFile::NDirectory::MySetCurrentDirectory(currentFolderUnicode); + if (initContextMenu->InitContextMenu(currentFolderUnicode, &namePointers.Front(), + operatedIndices.Size()) == S_OK) + { + HRESULT res = contextMenu->QueryContextMenu(menu, 0, kSevenZipStartMenuID, + kSystemStartMenuID - 1, 0); + sevenZipMenuCreated = (HRESULT_SEVERITY(res) == SEVERITY_SUCCESS); + if (sevenZipMenuCreated) + sevenZipContextMenu = contextMenu; + // int code = HRESULT_CODE(res); + // int nextItemID = code; + } + } +} + +void CPanel::CreateFileMenu(HMENU menuSpec, + CMyComPtr &sevenZipContextMenu, + CMyComPtr &systemContextMenu, + bool programMenu) +{ + sevenZipContextMenu.Release(); + systemContextMenu.Release(); + + CRecordVector operatedIndices; + GetOperatedItemIndices(operatedIndices); + + CMenu menu; + menu.Attach(menuSpec); + + CreateSevenZipMenu(menu, operatedIndices, sevenZipContextMenu); + if (g_App.ShowSystemMenu) + CreateSystemMenu(menu, operatedIndices, systemContextMenu); + + if (menu.GetItemCount() > 0) + menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)0); + + LoadFileMenu(menu, menu.GetItemCount(), !operatedIndices.IsEmpty(), programMenu); +} + +bool CPanel::InvokePluginCommand(int id) +{ + return InvokePluginCommand(id, _sevenZipContextMenu, _systemContextMenu); +} + +bool CPanel::InvokePluginCommand(int id, + IContextMenu *sevenZipContextMenu, IContextMenu *systemContextMenu) +{ + UInt32 offset; + bool isSystemMenu = (id >= kSystemStartMenuID); + if (isSystemMenu) + offset = id - kSystemStartMenuID; + else + offset = id - kSevenZipStartMenuID; + + CMINVOKECOMMANDINFOEX commandInfo; + commandInfo.cbSize = sizeof(commandInfo); + commandInfo.fMask = CMIC_MASK_UNICODE; + commandInfo.hwnd = GetParent(); + commandInfo.lpVerb = (LPCSTR)(MAKEINTRESOURCE(offset)); + commandInfo.lpParameters = NULL; + CSysString currentFolderSys = GetSystemString(_currentFolderPrefix); + commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys); + commandInfo.nShow = SW_SHOW; + commandInfo.lpTitle = ""; + commandInfo.lpVerbW = (LPCWSTR)(MAKEINTRESOURCEW(offset)); + commandInfo.lpParameters = NULL; + UString currentFolderUnicode = _currentFolderPrefix; + commandInfo.lpDirectoryW = currentFolderUnicode; + commandInfo.lpTitleW = L""; + // commandInfo.ptInvoke.x = xPos; + // commandInfo.ptInvoke.y = yPos; + commandInfo.ptInvoke.x = 0; + commandInfo.ptInvoke.y = 0; + HRESULT result; + if (isSystemMenu) + result = systemContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo)); + else + result = sevenZipContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo)); + if (result == NOERROR) + { + KillSelection(); + return true; + } + return false; +} + +bool CPanel::OnContextMenu(HANDLE windowHandle, int xPos, int yPos) +{ + if (windowHandle != _listView) + return false; + /* + POINT point; + point.x = xPos; + point.y = yPos; + if (!_listView.ScreenToClient(&point)) + return false; + + LVHITTESTINFO info; + info.pt = point; + int index = _listView.HitTest(&info); + */ + + CRecordVector operatedIndices; + GetOperatedItemIndices(operatedIndices); + + if (xPos < 0 || yPos < 0) + { + if (operatedIndices.Size() == 0) + { + xPos = 0; + yPos = 0; + } + else + { + int itemIndex = _listView.GetNextItem(-1, LVNI_FOCUSED); + if (itemIndex == -1) + return false; + RECT rect; + if (!_listView.GetItemRect(itemIndex, &rect, LVIR_ICON)) + return false; + xPos = (rect.left + rect.right) / 2; + yPos = (rect.top + rect.bottom) / 2; + } + POINT point = {xPos, yPos}; + _listView.ClientToScreen(&point); + xPos = point.x; + yPos = point.y; + } + + CMenu menu; + CMenuDestroyer menuDestroyer(menu); + menu.CreatePopup(); + + CMyComPtr sevenZipContextMenu; + CMyComPtr systemContextMenu; + CreateFileMenu(menu, sevenZipContextMenu, systemContextMenu, false); + + int result = menu.Track(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, + xPos, yPos, _listView); + + if (result == 0) + return true; + + if (result >= kPluginMenuStartID) + { + InvokePluginCommand(result, sevenZipContextMenu, systemContextMenu); + return true; + } + if (ExecuteFileCommand(result)) + return true; + return true; +} diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp new file mode 100755 index 00000000..392ca370 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp @@ -0,0 +1,443 @@ +// PanelOperations.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Panel.h" + +#include "Common/StringConvert.h" +#include "Common/DynamicBuffer.h" +#include "Windows/FileDir.h" +#include "Windows/ResourceString.h" +#include "Windows/Thread.h" +#include "Windows/COM.h" + +#include "ComboDialog.h" + +#include "FSFolder.h" +#include "LangUtils.h" +#include "FormatUtils.h" + +#include "UpdateCallback100.h" + +using namespace NWindows; +using namespace NFile; + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +struct CThreadDelete +{ + CMyComPtr FolderOperations; + CRecordVector Indices; + CMyComPtr UpdateCallback; + CUpdateCallback100Imp *UpdateCallbackSpec; + HRESULT Result; + + DWORD Process() + { + NCOM::CComInitializer comInitializer; + UpdateCallbackSpec->ProgressDialog.WaitCreating(); + Result = FolderOperations->Delete(&Indices.Front(), Indices.Size(), UpdateCallback); + UpdateCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadDelete *)param)->Process(); + } +}; + +struct CThreadCreateFolder +{ + CMyComPtr FolderOperations; + UString Name; + CMyComPtr UpdateCallback; + CUpdateCallback100Imp *UpdateCallbackSpec; + HRESULT Result; + + DWORD Process() + { + NCOM::CComInitializer comInitializer; + UpdateCallbackSpec->ProgressDialog.WaitCreating(); + Result = FolderOperations->CreateFolder(Name, UpdateCallback); + UpdateCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadCreateFolder *)param)->Process(); + } +}; + +#ifndef _UNICODE +typedef int (WINAPI * SHFileOperationWP)(LPSHFILEOPSTRUCTW lpFileOp); +#endif + +void CPanel::DeleteItems(bool toRecycleBin) +{ + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CRecordVector indices; + GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + CSelectedState state; + SaveSelectedState(state); + bool useInternalDelete = false; + if (IsFSFolder() && toRecycleBin) + { + #ifndef _UNICODE + if (!g_IsNT) + { + CDynamicBuffer buffer; + size_t size = 0; + for (int i = 0; i < indices.Size(); i++) + { + const AString path = GetSystemString(GetFsPath() + GetItemRelPath(indices[i])); + buffer.EnsureCapacity(size + path.Length() + 1); + memmove(((CHAR *)buffer) + size, (const CHAR *)path, (path.Length() + 1) * sizeof(CHAR)); + size += path.Length() + 1; + } + buffer.EnsureCapacity(size + 1); + ((CHAR *)buffer)[size] = 0; + SHFILEOPSTRUCTA fo; + fo.hwnd = GetParent(); + fo.wFunc = FO_DELETE; + fo.pFrom = (const CHAR *)buffer; + fo.pTo = 0; + fo.fFlags = 0; + if (toRecycleBin) + fo.fFlags |= FOF_ALLOWUNDO; + // fo.fFlags |= FOF_NOCONFIRMATION; + // fo.fFlags |= FOF_NOERRORUI; + // fo.fFlags |= FOF_SILENT; + // fo.fFlags |= FOF_WANTNUKEWARNING; + fo.fAnyOperationsAborted = FALSE; + fo.hNameMappings = 0; + fo.lpszProgressTitle = 0; + /* int res = */ ::SHFileOperationA(&fo); + } + else + #endif + { + CDynamicBuffer buffer; + size_t size = 0; + int maxLen = 0; + for (int i = 0; i < indices.Size(); i++) + { + // L"\\\\?\\") doesn't work here. + const UString path = GetFsPath() + GetItemRelPath(indices[i]); + if (path.Length() > maxLen) + maxLen = path.Length(); + buffer.EnsureCapacity(size + path.Length() + 1); + memmove(((WCHAR *)buffer) + size, (const WCHAR *)path, (path.Length() + 1) * sizeof(WCHAR)); + size += path.Length() + 1; + } + buffer.EnsureCapacity(size + 1); + ((WCHAR *)buffer)[size] = 0; + if (maxLen >= MAX_PATH) + { + if (toRecycleBin) + { + MessageBoxMyError(L"You can't send file with long path to Recycle Bin"); + return; + } + useInternalDelete = true; + } + else + { + SHFILEOPSTRUCTW fo; + fo.hwnd = GetParent(); + fo.wFunc = FO_DELETE; + fo.pFrom = (const WCHAR *)buffer; + fo.pTo = 0; + fo.fFlags = 0; + if (toRecycleBin) + fo.fFlags |= FOF_ALLOWUNDO; + fo.fAnyOperationsAborted = FALSE; + fo.hNameMappings = 0; + fo.lpszProgressTitle = 0; + int res; + #ifdef _UNICODE + res = ::SHFileOperationW(&fo); + #else + SHFileOperationWP shFileOperationW = (SHFileOperationWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHFileOperationW"); + if (shFileOperationW == 0) + return; + res = shFileOperationW(&fo); + #endif + } + } + /* + if (fo.fAnyOperationsAborted) + MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217)); + */ + } + else + useInternalDelete = true; + if (useInternalDelete) + DeleteItemsInternal(indices); + RefreshListCtrl(state); +} + +void CPanel::DeleteItemsInternal(CRecordVector &indices) +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + + UString title; + UString message; + if (indices.Size() == 1) + { + int index = indices[0]; + const UString itemName = GetItemRelPath(index); + if (IsItemFolder(index)) + { + title = LangString(IDS_CONFIRM_FOLDER_DELETE, 0x03020211); + message = MyFormatNew(IDS_WANT_TO_DELETE_FOLDER, 0x03020214, itemName); + } + else + { + title = LangString(IDS_CONFIRM_FILE_DELETE, 0x03020210); + message = MyFormatNew(IDS_WANT_TO_DELETE_FILE, 0x03020213, itemName); + } + } + else + { + title = LangString(IDS_CONFIRM_ITEMS_DELETE, 0x03020212); + message = MyFormatNew(IDS_WANT_TO_DELETE_ITEMS, 0x03020215, + NumberToString(indices.Size())); + } + if (::MessageBoxW(GetParent(), message, title, MB_OKCANCEL | MB_ICONQUESTION) != IDOK) + return; + + CThreadDelete deleter; + deleter.UpdateCallbackSpec = new CUpdateCallback100Imp; + deleter.UpdateCallback = deleter.UpdateCallbackSpec; + deleter.UpdateCallbackSpec->Init(GetParent(), false, L""); + + UString progressTitle = LangString(IDS_DELETING, 0x03020216); + + deleter.UpdateCallbackSpec->ProgressDialog.MainWindow = _mainWindow; + deleter.UpdateCallbackSpec->ProgressDialog.MainTitle = LangString(IDS_APP_TITLE, 0x03000000); + deleter.UpdateCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + UString(L" "); + + deleter.FolderOperations = folderOperations; + deleter.Indices = indices; + + NWindows::CThread thread; + if (thread.Create(CThreadDelete::MyThreadFunction, &deleter) != S_OK) + throw 271824; + deleter.UpdateCallbackSpec->StartProgressDialog(progressTitle); + + HRESULT result = deleter.Result; + if (result != S_OK) + MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217)); +} + +BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh) +{ + int realIndex = GetRealIndex(lpnmh->item); + if (realIndex == kParentIndex) + return TRUE; + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + return TRUE; + return FALSE; +} + +BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh) +{ + if (lpnmh->item.pszText == NULL) + return FALSE; + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBoxMyError(L"Renaming is not supported"); + return FALSE; + } + const UString newName = lpnmh->item.pszText; + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + + SaveSelectedState(_selectedState); + + int realIndex = GetRealIndex(lpnmh->item); + if (realIndex == kParentIndex) + return FALSE; + const UString prefix = GetItemPrefix(realIndex); + HRESULT result = folderOperations->Rename(realIndex, newName, 0); + if (result != S_OK) + { + MessageBoxError(result, LangString(IDS_ERROR_RENAMING, 0x03020221)); + return FALSE; + } + // Can't use RefreshListCtrl here. + // RefreshListCtrlSaveFocused(); + _selectedState.FocusedName = prefix + newName; + _selectedState.SelectFocused = true; + + // We need clear all items to disable GetText before Reload: + // number of items can change. + // _listView.DeleteAllItems(); + // But seems it can still call GetText (maybe for current item) + // so we can't delete items. + + _dontShowMode = true; + + PostMessage(kReLoadMessage); + return TRUE; +} + +void CPanel::CreateFolder() +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CSelectedState state; + SaveSelectedState(state); + CComboDialog comboDialog; + comboDialog.Title = LangString(IDS_CREATE_FOLDER, 0x03020230); + comboDialog.Static = LangString(IDS_CREATE_FOLDER_NAME, 0x03020231); + comboDialog.Value = LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, /*0x03020232*/ (UInt32)-1); + if (comboDialog.Create(GetParent()) == IDCANCEL) + return; + + UString newName = comboDialog.Value; + + // HRESULT result = folderOperations->CreateFolder(newName, 0); + + CThreadCreateFolder upd; + upd.UpdateCallbackSpec = new CUpdateCallback100Imp; + upd.UpdateCallback = upd.UpdateCallbackSpec; + upd.UpdateCallbackSpec->Init(GetParent(), false, L""); + + UString progressTitle = LangString(IDS_CREATE_FOLDER, 0x03020230); + + upd.UpdateCallbackSpec->ProgressDialog.MainWindow = _mainWindow; + upd.UpdateCallbackSpec->ProgressDialog.MainTitle = LangString(IDS_APP_TITLE, 0x03000000); + upd.UpdateCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + UString(L" "); + + upd.FolderOperations = folderOperations; + upd.Name = newName; + + NWindows::CThread thread; + if (thread.Create(CThreadCreateFolder::MyThreadFunction, &upd) != S_OK) + throw 271824; + upd.UpdateCallbackSpec->StartProgressDialog(progressTitle); + + HRESULT result = upd.Result; + + if (result != S_OK) + { + MessageBoxError(result, LangString(IDS_CREATE_FOLDER_ERROR, 0x03020233)); + return; + } + int pos = newName.Find(L'\\'); + if (pos >= 0) + newName = newName.Left(pos); + if (!_mySelectMode) + state.SelectedNames.Clear(); + state.FocusedName = newName; + state.SelectFocused = true; + RefreshListCtrl(state); +} + +void CPanel::CreateFile() +{ + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + CSelectedState state; + SaveSelectedState(state); + CComboDialog comboDialog; + comboDialog.Title = LangString(IDS_CREATE_FILE, 0x03020240); + comboDialog.Static = LangString(IDS_CREATE_FILE_NAME, 0x03020241); + comboDialog.Value = LangString(IDS_CREATE_FILE_DEFAULT_NAME, /*0x03020242*/ (UInt32)-1); + if (comboDialog.Create(GetParent()) == IDCANCEL) + return; + UString newName = comboDialog.Value; + HRESULT result = folderOperations->CreateFile(newName, 0); + if (result != S_OK) + { + MessageBoxError(result, LangString(IDS_CREATE_FILE_ERROR, 0x03020243)); + return; + } + int pos = newName.Find(L'\\'); + if (pos >= 0) + newName = newName.Left(pos); + if (!_mySelectMode) + state.SelectedNames.Clear(); + state.FocusedName = newName; + state.SelectFocused = true; + RefreshListCtrl(state); +} + +void CPanel::RenameFile() +{ + int index = _listView.GetFocusedItem(); + if (index >= 0) + _listView.EditLabel(index); +} + +void CPanel::ChangeComment() +{ + CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + int index = _listView.GetFocusedItem(); + if (index < 0) + return; + int realIndex = GetRealItemIndex(index); + if (realIndex == kParentIndex) + return; + CSelectedState state; + SaveSelectedState(state); + CMyComPtr folderOperations; + if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) + { + MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + + UString comment; + { + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(realIndex, kpidComment, &propVariant) != S_OK) + return; + if (propVariant.vt == VT_BSTR) + comment = propVariant.bstrVal; + else if (propVariant.vt != VT_EMPTY) + return; + } + UString name = GetItemRelPath(realIndex); + CComboDialog comboDialog; + comboDialog.Title = name + L" " + LangString(IDS_COMMENT, 0x03020290); + comboDialog.Value = comment; + comboDialog.Static = LangString(IDS_COMMENT2, 0x03020291); + if (comboDialog.Create(GetParent()) == IDCANCEL) + return; + NCOM::CPropVariant propVariant = comboDialog.Value; + + HRESULT result = folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL); + if (result != S_OK) + { + MessageBoxError(result, L"Set Comment Error"); + } + RefreshListCtrl(state); +} + diff --git a/CPP/7zip/UI/FileManager/PanelSelect.cpp b/CPP/7zip/UI/FileManager/PanelSelect.cpp new file mode 100755 index 00000000..4b726b1e --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelSelect.cpp @@ -0,0 +1,297 @@ +// PanelSelect.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" + +#include "Panel.h" + +#include "ComboDialog.h" + +#include "LangUtils.h" + +void CPanel::OnShiftSelectMessage() +{ + if (!_mySelectMode) + return; + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + if (!_selectionIsDefined) + return; + int startItem = MyMin(focusedItem, _prevFocusedItem); + int finishItem = MyMax(focusedItem, _prevFocusedItem); + for (int i = 0; i < _listView.GetItemCount(); i++) + { + int realIndex = GetRealItemIndex(i); + if (realIndex == kParentIndex) + continue; + if (i >= startItem && i <= finishItem) + if (_selectedStatusVector[realIndex] != _selectMark) + { + _selectedStatusVector[realIndex] = _selectMark; + _listView.RedrawItem(i); + } + } + _prevFocusedItem = focusedItem; +} + +void CPanel::OnArrowWithShift() +{ + if (!_mySelectMode) + return; + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + if (_selectionIsDefined) + { + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = _selectMark; + } + else + { + if (realIndex == kParentIndex) + { + _selectionIsDefined = true; + _selectMark = true; + } + else + { + _selectionIsDefined = true; + _selectMark = !_selectedStatusVector[realIndex]; + _selectedStatusVector[realIndex] = _selectMark; + } + } + _prevFocusedItem = focusedItem; + PostMessage(kShiftSelectMessage); + _listView.RedrawItem(focusedItem); +} + +void CPanel::OnInsert() +{ + /* + const int kState = CDIS_MARKED; // LVIS_DROPHILITED; + UINT state = (_listView.GetItemState(focusedItem, LVIS_CUT) == 0) ? + LVIS_CUT : 0; + _listView.SetItemState(focusedItem, state, LVIS_CUT); + // _listView.SetItemState(focusedItem, LVIS_SELECTED, LVIS_SELECTED); + + */ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + bool isSelected = !_selectedStatusVector[realIndex]; + if (realIndex != kParentIndex) + _selectedStatusVector[realIndex] = isSelected; + + if (!_mySelectMode) + _listView.SetItemState(focusedItem, isSelected ? LVIS_SELECTED: 0, LVIS_SELECTED); + + _listView.RedrawItem(focusedItem); + + int nextIndex = focusedItem + 1; + if (nextIndex < _listView.GetItemCount()) + { + _listView.SetItemState(nextIndex, LVIS_FOCUSED | LVIS_SELECTED, + LVIS_FOCUSED | LVIS_SELECTED); + _listView.EnsureVisible(nextIndex, false); + } +} + +/* +void CPanel::OnUpWithShift() +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int index = GetRealItemIndex(focusedItem); + _selectedStatusVector[index] = !_selectedStatusVector[index]; + _listView.RedrawItem(index); +} + +void CPanel::OnDownWithShift() +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int index = GetRealItemIndex(focusedItem); + _selectedStatusVector[index] = !_selectedStatusVector[index]; + _listView.RedrawItem(index); +} +*/ + +void CPanel::UpdateSelection() +{ + if (!_mySelectMode) + { + bool enableTemp = _enableItemChangeNotify; + _enableItemChangeNotify = false; + int numItems = _listView.GetItemCount(); + for (int i = 0; i < numItems; i++) + { + int realIndex = GetRealItemIndex(i); + if (realIndex != kParentIndex) + { + UINT value = 0; + value = _selectedStatusVector[realIndex] ? LVIS_SELECTED: 0; + _listView.SetItemState(i, value, LVIS_SELECTED); + } + } + _enableItemChangeNotify = enableTemp; + } + _listView.RedrawAllItems(); +} + + +void CPanel::SelectSpec(bool selectMode) +{ + CComboDialog comboDialog; + comboDialog.Title = selectMode ? + LangString(IDS_SELECT, 0x03020250): + LangString(IDS_DESELECT, 0x03020251); + comboDialog.Static = LangString(IDS_SELECT_MASK, 0x03020252); + comboDialog.Value = L"*"; + if (comboDialog.Create(GetParent()) == IDCANCEL) + return; + const UString &mask = comboDialog.Value; + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (CompareWildCardWithName(mask, GetItemName(i))) + _selectedStatusVector[i] = selectMode; + UpdateSelection(); +} + +void CPanel::SelectByType(bool selectMode) +{ + int focusedItem = _listView.GetFocusedItem(); + if (focusedItem < 0) + return; + int realIndex = GetRealItemIndex(focusedItem); + UString name = GetItemName(realIndex); + bool isItemFolder = IsItemFolder(realIndex); + + /* + UINT32 numItems; + _folder->GetNumberOfItems(&numItems); + if ((UInt32)_selectedStatusVector.Size() != numItems) + throw 11111; + */ + + if (isItemFolder) + { + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (IsItemFolder(i) == isItemFolder) + _selectedStatusVector[i] = selectMode; + } + else + { + int pos = name.ReverseFind(L'.'); + if (pos < 0) + { + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (IsItemFolder(i) == isItemFolder && GetItemName(i).ReverseFind(L'.') < 0) + _selectedStatusVector[i] = selectMode; + } + else + { + UString mask = UString(L'*') + name.Mid(pos); + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (IsItemFolder(i) == isItemFolder && CompareWildCardWithName(mask, GetItemName(i))) + _selectedStatusVector[i] = selectMode; + } + } + UpdateSelection(); +} + +void CPanel::SelectAll(bool selectMode) +{ + for (int i = 0; i < _selectedStatusVector.Size(); i++) + _selectedStatusVector[i] = selectMode; + UpdateSelection(); +} + +void CPanel::InvertSelection() +{ + if (!_mySelectMode) + { + int numSelected = 0; + for (int i = 0; i < _selectedStatusVector.Size(); i++) + if (_selectedStatusVector[i]) + numSelected++; + if (numSelected == 1) + { + int focused = _listView.GetFocusedItem(); + if (focused >= 0) + { + int realIndex = GetRealItemIndex(focused); + if (realIndex >= 0) + if (_selectedStatusVector[realIndex]) + _selectedStatusVector[realIndex] = false; + } + } + } + for (int i = 0; i < _selectedStatusVector.Size(); i++) + _selectedStatusVector[i] = !_selectedStatusVector[i]; + UpdateSelection(); +} + +void CPanel::KillSelection() +{ + SelectAll(false); + if (!_mySelectMode) + { + int focused = _listView.GetFocusedItem(); + if (focused >= 0) + _listView.SetItemState(focused, LVIS_SELECTED, LVIS_SELECTED); + } +} + +void CPanel::OnLeftClick(LPNMITEMACTIVATE itemActivate) +{ + if(itemActivate->hdr.hwndFrom != HWND(_listView)) + return; + // It will be work only for Version 4.71 (IE 4); + int indexInList = itemActivate->iItem; + if (indexInList < 0) + return; + if ((itemActivate->uKeyFlags & LVKF_SHIFT) != 0) + { + // int focusedIndex = _listView.GetFocusedItem(); + int focusedIndex = _startGroupSelect; + if (focusedIndex < 0) + return; + int startItem = MyMin(focusedIndex, indexInList); + int finishItem = MyMax(focusedIndex, indexInList); + for (int i = 0; i < _selectedStatusVector.Size(); i++) + { + int realIndex = GetRealItemIndex(i); + if (realIndex == kParentIndex) + continue; + bool selected = (i >= startItem && i <= finishItem); + if (_selectedStatusVector[realIndex] != selected) + { + _selectedStatusVector[realIndex] = selected; + _listView.RedrawItem(i); + } + } + } + else + { + _startGroupSelect = indexInList; + if ((itemActivate->uKeyFlags & LVKF_CONTROL) != 0) + { + int realIndex = GetRealItemIndex(indexInList); + if (realIndex != kParentIndex) + { + _selectedStatusVector[realIndex] = !_selectedStatusVector[realIndex]; + _listView.RedrawItem(indexInList); + } + } + } + return; +} + diff --git a/CPP/7zip/UI/FileManager/PanelSort.cpp b/CPP/7zip/UI/FileManager/PanelSort.cpp new file mode 100755 index 00000000..c5fddcd6 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelSort.cpp @@ -0,0 +1,163 @@ +// PanelSort.cpp + +#include "StdAfx.h" + +#include "Windows/PropVariant.h" + +#include "../../PropID.h" + +#include "Panel.h" + +using namespace NWindows; + +static UString GetExtension(const UString &name) +{ + int dotPos = name.ReverseFind(L'.'); + if (dotPos < 0) + return UString(); + return name.Mid(dotPos); +} + +int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + if(lpData == NULL) + return 0; + CPanel *panel = (CPanel*)lpData; + + switch(panel->_sortID) + { + // if (panel->_sortIndex == 0) + case kpidName: + { + const UString name1 = panel->GetItemName((int)lParam1); + const UString name2 = panel->GetItemName((int)lParam2); + int res = name1.CompareNoCase(name2); + /* + if (res != 0 || !panel->_flatMode) + return res; + const UString prefix1 = panel->GetItemPrefix(lParam1); + const UString prefix2 = panel->GetItemPrefix(lParam2); + return res = prefix1.CompareNoCase(prefix2); + */ + return res; + } + case kpidNoProperty: + { + return MyCompare(lParam1, lParam2); + } + case kpidExtension: + { + const UString ext1 = GetExtension(panel->GetItemName((int)lParam1)); + const UString ext2 = GetExtension(panel->GetItemName((int)lParam2)); + return ext1.CompareNoCase(ext2); + } + } + /* + if (panel->_sortIndex == 1) + return MyCompare(file1.Size, file2.Size); + return ::CompareFileTime(&file1.LastWriteTime, &file2.LastWriteTime); + */ + + // PROPID propID = panel->_properties[panel->_sortIndex].ID; + PROPID propID = panel->_sortID; + + NCOM::CPropVariant propVariant1, propVariant2; + // Name must be first property + panel->_folder->GetProperty((UINT32)lParam1, propID, &propVariant1); + panel->_folder->GetProperty((UINT32)lParam2, propID, &propVariant2); + if(propVariant1.vt != propVariant2.vt) + return 0; // It means some BUG + if (propVariant1.vt == VT_BSTR) + { + return _wcsicmp(propVariant1.bstrVal, propVariant2.bstrVal); + } + return propVariant1.Compare(propVariant2); + // return 0; +} + +int CALLBACK CompareItems(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) +{ + if(lpData == NULL) + return 0; + if (lParam1 == kParentIndex) + return -1; + if (lParam2 == kParentIndex) + return 1; + + CPanel *panel = (CPanel*)lpData; + + bool isDirectory1 = panel->IsItemFolder((int)lParam1); + bool isDirectory2 = panel->IsItemFolder((int)lParam2); + + if(isDirectory1 && (!isDirectory2)) + return -1; + if((!isDirectory1) && isDirectory2) + return 1; + + int result = CompareItems2(lParam1, lParam2, lpData); + return panel->_ascending ? result: (-result); +} + + +/* +void CPanel::SortItems(int index) +{ + if(index == _sortIndex) + _ascending = !_ascending; + else + { + _sortIndex = index; + _ascending = true; + switch (_properties[_sortIndex].ID) + { + case kpidSize: + case kpidPackedSize: + case kpidCreationTime: + case kpidLastAccessTime: + case kpidLastWriteTime: + _ascending = false; + break; + } + } + _listView.SortItems(CompareItems, (LPARAM)this); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} +void CPanel::SortItemsWithPropID(PROPID propID) +{ + int index = _properties.FindItemWithID(propID); + if (index >= 0) + SortItems(index); +} +*/ +void CPanel::SortItemsWithPropID(PROPID propID) +{ + if(propID == _sortID) + _ascending = !_ascending; + else + { + _sortID = propID; + _ascending = true; + switch (propID) + { + case kpidSize: + case kpidPackedSize: + case kpidCreationTime: + case kpidLastAccessTime: + case kpidLastWriteTime: + _ascending = false; + break; + } + } + _listView.SortItems(CompareItems, (LPARAM)this); + _listView.EnsureVisible(_listView.GetFocusedItem(), false); +} + + +void CPanel::OnColumnClick(LPNMLISTVIEW info) +{ + /* + int index = _properties.FindItemWithID(_visibleProperties[info->iSubItem].ID); + SortItems(index); + */ + SortItemsWithPropID(_visibleProperties[info->iSubItem].ID); +} diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp new file mode 100755 index 00000000..b9cce2d8 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp @@ -0,0 +1,481 @@ +// PanelSplitFile.cpp + +#include "StdAfx.h" + +#include "resource.h" + +extern "C" +{ + #include "../../../../C/Alloc.h" +} + +#include "Common/Types.h" +#include "Common/IntToString.h" + +// #include "Windows/COM.h" +#include "Windows/FileIO.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" +#include "ProgressDialog2.h" +#include "SplitDialog.h" +#include "CopyDialog.h" + +#include "../GUI/ExtractRes.h" + +#include "SplitUtils.h" +#include "App.h" +#include "FormatUtils.h" +#include "LangUtils.h" + +using namespace NWindows; + +class CMyBuffer +{ + void *_data; +public: + CMyBuffer(): _data(0) {} + operator void *() { return _data; } + bool Allocate(size_t size) + { + if (_data != 0) + return false; + _data = ::MidAlloc(size); + return _data != 0; + } + ~CMyBuffer() { ::MidFree(_data); } +}; + +struct CVolSeqName +{ + UString UnchangedPart; + UString ChangedPart; + CVolSeqName(): ChangedPart(L"000") {}; + + bool ParseName(const UString &name) + { + if (name.Right(2) != L"01") + return false; + int numLetters = 2; + while (numLetters < name.Length()) + { + if (name[name.Length() - numLetters - 1] != '0') + break; + numLetters++; + } + UnchangedPart = name.Left(name.Length() - numLetters); + ChangedPart = name.Right(numLetters); + return true; + } + + UString GetNextName() + { + UString newName; + int i; + int numLetters = ChangedPart.Length(); + for (i = numLetters - 1; i >= 0; i--) + { + wchar_t c = ChangedPart[i]; + if (c == L'9') + { + c = L'0'; + newName = c + newName; + if (i == 0) + newName = UString(L'1') + newName; + continue; + } + c++; + newName = c + newName; + i--; + for (; i >= 0; i--) + newName = ChangedPart[i] + newName; + break; + } + ChangedPart = newName; + return UnchangedPart + ChangedPart; + } +}; + +static const UInt32 kBufSize = (1 << 20); + +struct CThreadSplit +{ + // HRESULT Result; + // CPanel *Panel; + CProgressDialog *ProgressDialog; + UString FilePath; + UString VolBasePath; + CRecordVector VolumeSizes; + UString Error; + + void Process2() + { + // NCOM::CComInitializer comInitializer; + ProgressDialog->WaitCreating(); + NFile::NIO::CInFile inFile; + if (!inFile.Open(FilePath)) + throw L"Can not open file"; + NFile::NIO::COutFile outFile; + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + throw L"Can not allocate buffer"; + Byte *buffer = (Byte *)(void *)bufferObject; + UInt64 curVolSize = 0; + CVolSeqName seqName; + UInt64 length; + if (!inFile.GetLength(length)) + throw "error"; + + ProgressDialog->ProgressSynch.SetProgress(length, 0); + UInt64 pos = 0; + + int volIndex = 0; + + for (;;) + { + UInt64 volSize; + if (volIndex < VolumeSizes.Size()) + volSize = VolumeSizes[volIndex]; + else + volSize = VolumeSizes.Back(); + + UInt32 needSize = (UInt32)(MyMin((UInt64)kBufSize, volSize - curVolSize)); + UInt32 processedSize; + if (!inFile.Read(buffer, needSize, processedSize)) + throw L"Can not read input file"; + if (processedSize == 0) + break; + needSize = processedSize; + if (curVolSize == 0) + { + UString name = VolBasePath; + name += L"."; + name += seqName.GetNextName(); + if (!outFile.Create(name, false)) + throw L"Can not create output file"; + ProgressDialog->ProgressSynch.SetCurrentFileName(name); + } + if (!outFile.Write(buffer, needSize, processedSize)) + throw L"Can not write output file"; + if (needSize != processedSize) + throw L"Can not write output file"; + curVolSize += processedSize; + if (curVolSize == volSize) + { + outFile.Close(); + if (volIndex < VolumeSizes.Size()) + volIndex++; + curVolSize = 0; + } + pos += processedSize; + HRESULT res = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(pos); + if (res != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(const wchar_t *s) { Error = s; } + catch(...) { Error = L"Error"; } + ProgressDialog->MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadSplit *)param)->Process(); + } +}; + +void CApp::Split() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CRecordVector indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + if (indices.Size() != 1) + { + srcPanel.MessageBox(L"Select one file"); + return; + } + int index = indices[0]; + if (srcPanel.IsItemFolder(index)) + { + srcPanel.MessageBox(L"Select one file"); + return; + } + const UString itemName = srcPanel.GetItemName(index); + + UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); + UString path = srcPath; + int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel._currentFolderPrefix; + CSplitDialog splitDialog; + splitDialog.FilePath = srcPanel.GetItemRelPath(index); + splitDialog.Path = path; + if (splitDialog.Create(srcPanel.GetParent()) == IDCANCEL) + return; + + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(srcPath + itemName, fileInfo)) + { + srcPanel.MessageBoxMyError(L"Can not find file"); + return; + } + if (fileInfo.Size <= splitDialog.VolumeSizes.Front()) + { + srcPanel.MessageBoxMyError(LangString(IDS_SPLIT_VOL_MUST_BE_SMALLER, 0x03020522)); + return; + } + const UInt64 numVolumes = GetNumberOfVolumes(fileInfo.Size, splitDialog.VolumeSizes); + if (numVolumes >= 100) + { + wchar_t s[32]; + ConvertUInt64ToString(numVolumes, s); + if (::MessageBoxW(srcPanel, MyFormatNew(IDS_SPLIT_CONFIRM_MESSAGE, 0x03020521, s), + LangString(IDS_SPLIT_CONFIRM_TITLE, 0x03020520), + MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL) != IDYES) + return; + } + + path = splitDialog.Path; + NFile::NName::NormalizeDirPathPrefix(path); + if (!NFile::NDirectory::CreateComplexDirectory(path)) + { + srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path)); + return; + } + + CThreadSplit spliter; + // spliter.Panel = this; + + CProgressDialog progressDialog; + spliter.ProgressDialog = &progressDialog; + + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + UString title = LangString(IDS_SPLITTING, 0x03020510); + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title + UString(L" "); + progressDialog.ProgressSynch.SetTitleFileName(itemName); + + + spliter.FilePath = srcPath + itemName; + spliter.VolBasePath = path + itemName; + spliter.VolumeSizes = splitDialog.VolumeSizes; + + // if (splitDialog.VolumeSizes.Size() == 0) return; + + // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); + // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); + + NWindows::CThread thread; + if (thread.Create(CThreadSplit::MyThreadFunction, &spliter) != S_OK) + throw 271824; + progressDialog.Create(title, _window); + + if (!spliter.Error.IsEmpty()) + srcPanel.MessageBoxMyError(spliter.Error); + // disableTimerProcessing1.Restore(); + // disableTimerProcessing2.Restore(); + // srcPanel.SetFocusToList(); + // srcPanel.RefreshListCtrlSaveFocused(); +} + + +struct CThreadCombine +{ + CProgressDialog *ProgressDialog; + UString InputDirPrefix; + UString FirstVolumeName; + UString OutputDirPrefix; + UString Error; + + void Process2() + { + // NCOM::CComInitializer comInitializer; + ProgressDialog->WaitCreating(); + + CVolSeqName volSeqName; + if (!volSeqName.ParseName(FirstVolumeName)) + throw L"Can not detect file as splitted file"; + + UString nextName = InputDirPrefix + FirstVolumeName; + UInt64 totalSize = 0; + for (;;) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(nextName, fileInfo)) + break; + if (fileInfo.IsDirectory()) + break; + totalSize += fileInfo.Size; + nextName = InputDirPrefix + volSeqName.GetNextName(); + } + if (totalSize == 0) + throw L"no data"; + ProgressDialog->ProgressSynch.SetProgress(totalSize, 0); + + if (!volSeqName.ParseName(FirstVolumeName)) + throw L"Can not detect file as splitted file"; + + UString outName = volSeqName.UnchangedPart; + while(!outName.IsEmpty()) + { + int lastIndex = outName.Length() - 1; + if (outName[lastIndex] != L'.') + break; + outName.Delete(lastIndex); + } + if (outName.IsEmpty()) + outName = L"file"; + NFile::NIO::COutFile outFile; + if (!outFile.Create(OutputDirPrefix + outName, false)) + throw L"Can create open output file"; + + NFile::NIO::CInFile inFile; + CMyBuffer bufferObject; + if (!bufferObject.Allocate(kBufSize)) + throw L"Can not allocate buffer"; + Byte *buffer = (Byte *)(void *)bufferObject; + UInt64 pos = 0; + nextName = InputDirPrefix + FirstVolumeName; + bool needOpen = true; + for (;;) + { + if (needOpen) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(nextName, fileInfo)) + break; + if (fileInfo.IsDirectory()) + break; + if (!inFile.Open(nextName)) + throw L"Can not open file"; + ProgressDialog->ProgressSynch.SetCurrentFileName(fileInfo.Name); + nextName = InputDirPrefix + volSeqName.GetNextName(); + needOpen = false; + } + UInt32 processedSize; + if (!inFile.Read(buffer, kBufSize, processedSize)) + throw L"Can not read input file"; + if (processedSize == 0) + { + needOpen = true; + continue; + } + UInt32 needSize = processedSize; + if (!outFile.Write(buffer, needSize, processedSize)) + throw L"Can not write output file"; + if (needSize != processedSize) + throw L"Can not write output file"; + pos += processedSize; + HRESULT res = ProgressDialog->ProgressSynch.SetPosAndCheckPaused(pos); + if (res != S_OK) + return; + } + } + DWORD Process() + { + try { Process2(); } + catch(const wchar_t *s) { Error = s; } + catch(...) { Error = L"Error";} + ProgressDialog->MyClose(); + return 0; + } + + static THREAD_FUNC_DECL MyThreadFunction(void *param) + { + return ((CThreadCombine *)param)->Process(); + } +}; + +void CApp::Combine() +{ + int srcPanelIndex = GetFocusedPanelIndex(); + CPanel &srcPanel = Panels[srcPanelIndex]; + if (!srcPanel.IsFSFolder()) + { + srcPanel.MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208)); + return; + } + CRecordVector indices; + srcPanel.GetOperatedItemIndices(indices); + if (indices.IsEmpty()) + return; + int index = indices[0]; + if (indices.Size() != 1 || srcPanel.IsItemFolder(index)) + { + srcPanel.MessageBox(LangString(IDS_COMBINE_SELECT_ONE_FILE, 0x03020620)); + return; + } + const UString itemName = srcPanel.GetItemName(index); + + UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); + UString path = srcPath; + int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); + CPanel &destPanel = Panels[destPanelIndex]; + if (NumPanels > 1) + if (destPanel.IsFSFolder()) + path = destPanel._currentFolderPrefix; + CCopyDialog copyDialog; + copyDialog.Value = path; + copyDialog.Title = LangString(IDS_COMBINE, 0x03020600); + copyDialog.Title += ' '; + copyDialog.Title += srcPanel.GetItemRelPath(index); + + copyDialog.Static = LangString(IDS_COMBINE_TO, 0x03020601);; + if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL) + return; + + CThreadCombine combiner; + // combiner.Panel = this; + + CProgressDialog progressDialog; + combiner.ProgressDialog = &progressDialog; + + UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000); + UString title = LangString(IDS_COMBINING, 0x03020610); + + progressDialog.MainWindow = _window; + progressDialog.MainTitle = progressWindowTitle; + progressDialog.MainAddTitle = title + UString(L" "); + + path = copyDialog.Value; + NFile::NName::NormalizeDirPathPrefix(path); + if (!NFile::NDirectory::CreateComplexDirectory(path)) + { + srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path)); + return; + } + + combiner.InputDirPrefix = srcPath; + combiner.FirstVolumeName = itemName; + combiner.OutputDirPrefix = path; + + // CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel); + // CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel); + + NWindows::CThread thread; + if (thread.Create(CThreadCombine::MyThreadFunction, &combiner) != S_OK) + throw 271824; + progressDialog.Create(title, _window); + + if (!combiner.Error.IsEmpty()) + srcPanel.MessageBoxMyError(combiner.Error); + // disableTimerProcessing1.Restore(); + // disableTimerProcessing2.Restore(); + // srcPanel.SetFocusToList(); + // srcPanel.RefreshListCtrlSaveFocused(); +} diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.cpp b/CPP/7zip/UI/FileManager/PasswordDialog.cpp new file mode 100755 index 00000000..a366a61e --- /dev/null +++ b/CPP/7zip/UI/FileManager/PasswordDialog.cpp @@ -0,0 +1,50 @@ +// PasswordDialog.cpp + +#include "StdAfx.h" +#include "PasswordDialog.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_PASSWORD_HEADER, 0x02000B01 }, + { IDC_CHECK_PASSWORD_SHOW, 0x02000B02 }, + +}; +#endif + + +bool CPasswordDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000B00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _passwordControl.Attach(GetItem(IDC_EDIT_PASSWORD)); + _passwordControl.SetText(Password); + _passwordControl.SetPasswordChar(TEXT('*')); + return CModalDialog::OnInit(); +} + +bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + if (buttonID == IDC_CHECK_PASSWORD_SHOW) + { + _passwordControl.SetPasswordChar((IsButtonChecked( + IDC_CHECK_PASSWORD_SHOW) == BST_CHECKED) ? 0: TEXT('*')); + UString password; + _passwordControl.GetText(password); + _passwordControl.SetText(password); + return true; + } + return CDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CPasswordDialog::OnOK() +{ + _passwordControl.GetText(Password); + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.h b/CPP/7zip/UI/FileManager/PasswordDialog.h new file mode 100755 index 00000000..e5a96073 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PasswordDialog.h @@ -0,0 +1,21 @@ +// PasswordDialog.h + +#ifndef __PASSWORDDIALOG_H +#define __PASSWORDDIALOG_H + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/Edit.h" +#include "PasswordDialogRes.h" + +class CPasswordDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CEdit _passwordControl; + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + UString Password; + INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_PASSWORD, parentWindow); } +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.rc b/CPP/7zip/UI/FileManager/PasswordDialog.rc new file mode 100755 index 00000000..64381aff --- /dev/null +++ b/CPP/7zip/UI/FileManager/PasswordDialog.rc @@ -0,0 +1,26 @@ +#include "PasswordDialogRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 172 +#define ySize2 68 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + +IDD_DIALOG_PASSWORD DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Enter password" +MY_FONT +BEGIN + LTEXT "&Enter password:", IDC_STATIC_PASSWORD_HEADER, marg, marg, xSize2, 8 + EDITTEXT IDC_EDIT_PASSWORD, marg , 19, xSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL + + CONTROL "&Show password", IDC_CHECK_PASSWORD_SHOW, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 41, xSize2, 10 + + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END diff --git a/CPP/7zip/UI/FileManager/PasswordDialogRes.h b/CPP/7zip/UI/FileManager/PasswordDialogRes.h new file mode 100755 index 00000000..e0b42661 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PasswordDialogRes.h @@ -0,0 +1,4 @@ +#define IDD_DIALOG_PASSWORD 501 +#define IDC_STATIC_PASSWORD_HEADER 1000 +#define IDC_EDIT_PASSWORD 1001 +#define IDC_CHECK_PASSWORD_SHOW 1002 diff --git a/CPP/7zip/UI/FileManager/PhysDriveFolder.cpp b/CPP/7zip/UI/FileManager/PhysDriveFolder.cpp new file mode 100755 index 00000000..d611e096 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PhysDriveFolder.cpp @@ -0,0 +1,299 @@ +// PhysDriveFolder.cpp + +#include "StdAfx.h" + +extern "C" +{ + #include "../../../../C/Alloc.h" +} + +#include "PhysDriveFolder.h" +#include "Windows/PropVariant.h" +#include "Windows/FileDevice.h" +#include "Windows/FileSystem.h" + +#include "../../PropID.h" + +using namespace NWindows; + +static const UInt32 kBufferSize = (4 << 20); + +static STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR}, + { NULL, kpidSize, VT_UI8} +}; + +HRESULT CPhysDriveFolder::Init(const UString &path) +{ + _prefix = L"\\\\.\\"; + _path = path; + NFile::NDevice::CInFile inFile; + if (!inFile.Open(GetFullPath())) + return GetLastError(); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::LoadItems() +{ + _driveType = NFile::NSystem::MyGetDriveType(_path + L"\\"); + _name = _path.Left(1); + _name += L'.'; + if (_driveType == DRIVE_CDROM) + _name += L"iso"; + else + _name += L"img"; + Int32 dummy; + WasChanged(&dummy); + return GetLength(_length); +} + +STDMETHODIMP CPhysDriveFolder::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 1; + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + if (itemIndex >= 1) + return E_INVALIDARG; + switch(propID) + { + case kpidIsFolder: + propVariant = false; + break; + case kpidName: + propVariant = _name; + break; + case kpidSize: + propVariant = _length; + break; + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::BindToFolder(UInt32 /* index */, IFolderFolder ** /* resultFolder */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + + +STDMETHODIMP CPhysDriveFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidType: prop = L"PhysDrive"; break; + case kpidPath: prop = (GetFullPath() + L"\\"); break; + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::WasChanged(Int32 *wasChanged) +{ + bool wasChangedMain = false; + *wasChanged = BoolToInt(wasChangedMain); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::Clone(IFolderFolder **resultFolder) +{ + CPhysDriveFolder *folderSpec = new CPhysDriveFolder; + CMyComPtr folderNew = folderSpec; + folderSpec->Init(_path); + *resultFolder = folderNew.Detach(); + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress * /* progress */) +{ + NCOM::CPropVariant propVariant; + if (index >= 1) + return E_INVALIDARG; + UInt64 size = 0; + HRESULT result = GetLength(size); + propVariant = size; + propVariant.Detach(value); + return result; +} + +STDMETHODIMP CPhysDriveFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::Rename(UInt32 /* index */, const wchar_t * /* newName */, IProgress * /* progress */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::Delete(const UInt32 * /* indices */, UInt32 /* numItems */, IProgress * /* progress */) + { return E_NOTIMPL; } + +STDMETHODIMP CPhysDriveFolder::SetProperty(UInt32 index, PROPID /* propID */, + const PROPVARIANT * /* value */, IProgress * /* progress */) +{ + if (index >= 1) + return E_INVALIDARG; + return E_NOTIMPL; +} + +HRESULT CPhysDriveFolder::GetLength(UInt64 &length) const +{ + NFile::NDevice::CInFile inFile; + if (!inFile.Open(GetFullPath())) + return GetLastError(); + if (!inFile.GetLengthSmart(length)) + return GetLastError(); + return S_OK; +} + +struct CPhysTempBuffer +{ + void *buffer; + CPhysTempBuffer(): buffer(0) {} + ~CPhysTempBuffer() { MyFree(buffer); } +}; + +HRESULT CopyFileSpec(LPCWSTR fromPath, LPCWSTR toPath, bool writeToDisk, UInt64 fileSize, UInt32 bufferSize, IProgress *progress) +{ + NFile::NIO::CInFile inFile; + if (!inFile.Open(fromPath)) + return GetLastError(); + if (fileSize == (UInt64)(Int64)-1) + { + if (!inFile.GetLength(fileSize)) + ::GetLastError(); + } + NFile::NIO::COutFile outFile; + if (writeToDisk) + { + if (!outFile.Open(toPath, FILE_SHARE_WRITE, OPEN_EXISTING, 0)) + return GetLastError(); + } + else + if (!outFile.Create(toPath, true)) + return GetLastError(); + CPhysTempBuffer tempBuffer; + tempBuffer.buffer = MyAlloc(bufferSize); + if (tempBuffer.buffer == 0) + return E_OUTOFMEMORY; + + for (UInt64 pos = 0; pos < fileSize;) + { + RINOK(progress->SetCompleted(&pos)); + UInt64 rem = fileSize - pos; + UInt32 curSize = (UInt32)MyMin(rem, (UInt64)bufferSize); + UInt32 processedSize; + if (!inFile.Read(tempBuffer.buffer, curSize, processedSize)) + return GetLastError(); + if (processedSize == 0) + break; + curSize = processedSize; + if (writeToDisk) + { + const UInt32 kMask = 0x1FF; + curSize = (curSize + kMask) & ~kMask; + if (curSize > bufferSize) + return E_FAIL; + } + + if (!outFile.Write(tempBuffer.buffer, curSize, processedSize)) + return GetLastError(); + if (curSize != processedSize) + return E_FAIL; + pos += curSize; + } + return S_OK; +} + +STDMETHODIMP CPhysDriveFolder::CopyTo(const UInt32 * /* indices */, UInt32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback) +{ + if (numItems == 0) + return S_OK; + UString destPath = path; + if (destPath.IsEmpty()) + return E_INVALIDARG; + bool directName = (destPath[destPath.Length() - 1] != L'\\'); + if (directName) + { + if (numItems > 1) + return E_INVALIDARG; + } + else + destPath += _name; + + UInt64 fileSize; + if (GetLength(fileSize) == S_OK) + { + RINOK(callback->SetTotal(fileSize)); + } + + Int32 writeAskResult; + CMyComBSTR destPathResult; + RINOK(callback->AskWrite(GetFullPath(), BoolToInt(false), NULL, &fileSize, + destPath, &destPathResult, &writeAskResult)); + if (!IntToBool(writeAskResult)) + return S_OK; + + RINOK(callback->SetCurrentFilePath(GetFullPathWithName())); + + UInt32 bufferSize = (_driveType == DRIVE_REMOVABLE) ? (18 << 10) * 4 : kBufferSize; + return CopyFileSpec(GetFullPath(), destPathResult, false, fileSize, bufferSize, callback); +} + +///////////////////////////////////////////////// +// Move Operations + +STDMETHODIMP CPhysDriveFolder::MoveTo( + const UInt32 * /* indices */, + UInt32 /* numItems */, + const wchar_t * /* path */, + IFolderOperationsExtractCallback * /* callback */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CPhysDriveFolder::CopyFrom( + const wchar_t * fromFolderPath, + const wchar_t ** itemsPaths, UInt32 numItems, IProgress *callback) +{ + if (numItems == 0) + return S_OK; + if (numItems != 1) + return E_INVALIDARG; + if (_driveType != DRIVE_REMOVABLE /* && _driveType != DRIVE_CDROM */) + return E_NOTIMPL; + UInt32 bufferSize = (_driveType == DRIVE_REMOVABLE) ? (18 << 10) * 4 : kBufferSize; + // MessageBoxW(0, fromFolderPath, itemsPaths[0], 0); + return CopyFileSpec((UString)fromFolderPath + itemsPaths[0], GetFullPath(), true, (UInt64)(Int64)-1, bufferSize, callback); +} diff --git a/CPP/7zip/UI/FileManager/PhysDriveFolder.h b/CPP/7zip/UI/FileManager/PhysDriveFolder.h new file mode 100755 index 00000000..996dda13 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PhysDriveFolder.h @@ -0,0 +1,58 @@ +// PhysDriveFolder.h + +#ifndef __PHYSDRIVEFOLDER_H +#define __PHYSDRIVEFOLDER_H + +#include "Common/MyString.h" +#include "Common/MyCom.h" + +#include "IFolder.h" + +class CPhysDriveFolder: + public IFolderFolder, + public IFolderWasChanged, + public IFolderOperations, + public IFolderGetItemFullSize, + public IFolderClone, + // public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ + UInt64 GetSizeOfItem(int anIndex) const; +public: + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IFolderWasChanged) + MY_QUERYINTERFACE_ENTRY(IFolderOperations) + MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize) + MY_QUERYINTERFACE_ENTRY(IFolderClone) + // MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex) + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + + INTERFACE_FolderFolder(;) + INTERFACE_FolderOperations(;) + + STDMETHOD(WasChanged)(INT32 *wasChanged); + STDMETHOD(Clone)(IFolderFolder **resultFolder); + STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress); + + // STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + +private: + UString _name; + UString _prefix; + UString _path; + UString GetFullPath() const { return _prefix + _path; } + UString GetFullPathWithName() const { return GetFullPath() + L'\\' + _name; } + CMyComPtr _parentFolder; + + UINT _driveType; + DISK_GEOMETRY geom; + UInt64 _length; + +public: + HRESULT Init(const UString &path); + HRESULT GetLength(UInt64 &size) const; +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/PluginInterface.h b/CPP/7zip/UI/FileManager/PluginInterface.h new file mode 100755 index 00000000..7bef6950 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PluginInterface.h @@ -0,0 +1,42 @@ +// PluginInterface.h + +#ifndef __PLUGININTERFACE_H +#define __PLUGININTERFACE_H + +#include "Common/MyString.h" + +// {23170F69-40C1-278D-0000-000100010000} +DEFINE_GUID(IID_IInitContextMenu, +0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278D-0000-000100010000") +IInitContextMenu: public IUnknown +{ +public: + STDMETHOD(InitContextMenu)(const wchar_t *aFolder, const wchar_t **aNames, UINT32 aNumFiles) PURE; + +}; + +// {23170F69-40C1-278D-0000-000100020100} +DEFINE_GUID(IID_IPluginOptionsCallback, +0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278D-0000-000100020000") +IPluginOptionsCallback: public IUnknown +{ +public: + STDMETHOD(GetProgramFolderPath)(BSTR *value) PURE; + STDMETHOD(GetProgramPath)(BSTR *value) PURE; + STDMETHOD(GetRegistryCUPath)(BSTR *value) PURE; +}; + +// {23170F69-40C1-278D-0000-000100020000} +DEFINE_GUID(IID_IPluginOptions, +0x23170F69, 0x40C1, 0x278D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278D-0000-000100020000") +IPluginOptions: public IUnknown +{ +public: + STDMETHOD(PluginOptions)(HWND hWnd, IPluginOptionsCallback *callback) PURE; + // STDMETHOD(GetFileExtensions)(BSTR *extensions) PURE; +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/PluginLoader.h b/CPP/7zip/UI/FileManager/PluginLoader.h new file mode 100755 index 00000000..598a874b --- /dev/null +++ b/CPP/7zip/UI/FileManager/PluginLoader.h @@ -0,0 +1,32 @@ +// PluginLoader.h + +#ifndef __PLUGINLOADER_H +#define __PLUGINLOADER_H + +#include "Windows/DLL.h" + +typedef UINT32 (WINAPI * CreateObjectPointer)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +class CPluginLibrary: public NWindows::NDLL::CLibrary +{ +public: + HRESULT CreateManager(REFGUID clsID, IFolderManager **manager) + { + CreateObjectPointer createObject = (CreateObjectPointer) + GetProcAddress("CreateObject"); + if (createObject == NULL) + return GetLastError(); + return createObject(&clsID, &IID_IFolderManager, (void **)manager); + } + HRESULT LoadAndCreateManager(LPCWSTR filePath, REFGUID clsID, IFolderManager **manager) + { + if (!Load(filePath)) + return GetLastError(); + return CreateManager(clsID, manager); + } +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/PluginsPage.cpp b/CPP/7zip/UI/FileManager/PluginsPage.cpp new file mode 100755 index 00000000..3be15b18 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PluginsPage.cpp @@ -0,0 +1,223 @@ +// PluginsPage.cpp + +#include "StdAfx.h" +#include "PluginsPageRes.h" +#include "PluginsPage.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" + +#include "Windows/Defs.h" +#include "Windows/DLL.h" +#include "Windows/Control/ListView.h" +#include "Windows/FileFind.h" + +#include "RegistryUtils.h" +#include "HelpUtils.h" +#include "LangUtils.h" +#include "ProgramLocation.h" + +#include "PluginInterface.h" + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_PLUGINS_STATIC_PLUGINS, 0x03010101}, + { IDC_PLUGINS_BUTTON_OPTIONS, 0x03010110} +}; + +static LPCWSTR kPluginsTopic = L"FM/options.htm#plugins"; + +bool CPluginsPage::OnInit() +{ + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + _listView.Attach(GetItem(IDC_PLUGINS_LIST)); + + UINT32 newFlags = /*LVS_EX_CHECKBOXES | */ LVS_EX_FULLROWSELECT; + _listView.SetExtendedListViewStyle(newFlags, newFlags); + + UString title = L"Plugins"; + LVCOLUMNW column; + column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM; + column.cx = 160; + column.fmt = LVCFMT_LEFT; + column.pszText = (LPWSTR)(LPCWSTR)title; + column.iSubItem = 0; + _listView.InsertColumn(0, &column); + + ReadFileFolderPluginInfoList(_plugins); + + _listView.SetRedraw(false); + // _listView.DeleteAllItems(); + for(int i = 0; i < _plugins.Size(); i++) + { + const CPluginInfo &p = _plugins[i]; + if (!p.OptionsClassIDDefined) + continue; + LVITEMW item; + item.iItem = i; + item.mask = LVIF_TEXT | LVIF_STATE; + UString pluginName = p.Name; + item.pszText = (WCHAR *)(const WCHAR *)pluginName; + item.state = 0; + item.stateMask = UINT(-1); + item.iSubItem = 0; + _listView.InsertItem(&item); + _listView.SetCheckState(i, true); + } + _listView.SetRedraw(true); + if(_listView.GetItemCount() > 0) + { + UINT state = LVIS_SELECTED | LVIS_FOCUSED; + _listView.SetItemState(0, state, state); + } + + return CPropertyPage::OnInit(); +} + +LONG CPluginsPage::OnApply() +{ + /* + int selectedIndex = m_Lang.GetCurSel(); + int aPathIndex = m_Lang.GetItemData(selectedIndex); + SaveRegLang(m_Paths[aPathIndex]); + ReloadLang(); + */ + return PSNRET_NOERROR; +} + +void CPluginsPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kPluginsTopic); +} + +bool CPluginsPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_PLUGINS_BUTTON_OPTIONS: + OnButtonOptions(); + break; + default: + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); + } + return true; +} + +class CPluginOptionsCallback: + public IPluginOptionsCallback, + public CMyUnknownImp +{ + UString _pluginName; +public: + MY_UNKNOWN_IMP + + STDMETHOD(GetProgramFolderPath)(BSTR *value); + STDMETHOD(GetProgramPath)(BSTR *Value); + STDMETHOD(GetRegistryCUPath)(BSTR *Value); + void Init(const UString &pluginName) + { _pluginName = pluginName; } +}; + +STDMETHODIMP CPluginOptionsCallback::GetProgramFolderPath(BSTR *value) +{ + *value = 0; + UString folder; + if (!::GetProgramFolderPath(folder)) + return E_FAIL; + CMyComBSTR valueTemp = folder; + *value = valueTemp.Detach(); + return S_OK; +} + +static UString GetDefaultProgramName() +{ + return L"7zFM.exe"; +} + +STDMETHODIMP CPluginOptionsCallback::GetProgramPath(BSTR *value) +{ + *value = 0; + UString folder; + if (!::GetProgramFolderPath(folder)) + return E_FAIL; + CMyComBSTR valueTemp = folder + GetDefaultProgramName(); + *value = valueTemp.Detach(); + return S_OK; +} + +STDMETHODIMP CPluginOptionsCallback::GetRegistryCUPath(BSTR *value) +{ + CMyComBSTR valueTemp = UString(L"Software\\7-Zip\\FM\\Plugins\\") + _pluginName; + *value = valueTemp.Detach(); + return S_OK; +} + +void CPluginsPage::OnButtonOptions() +{ + int index = _listView.GetSelectionMark(); + if (index < 0) + return; + + CPluginInfo pluginInfo = _plugins[index]; + if (!pluginInfo.OptionsClassIDDefined) + { + MessageBoxW(HWND(*this), L"There are no options", L"7-Zip", 0); + return; + } + NWindows::NDLL::CLibrary library; + CMyComPtr pluginOptions; + if (!library.Load(pluginInfo.FilePath)) + { + MessageBoxW(HWND(*this), L"Can't load plugin", L"7-Zip", 0); + return; + } + typedef UINT32 (WINAPI * CreateObjectPointer)( + const GUID *clsID, const GUID *interfaceID, void **outObject); + CreateObjectPointer createObject = (CreateObjectPointer) + library.GetProcAddress("CreateObject"); + if (createObject == NULL) + { + MessageBoxW(HWND(*this), L"Incorrect plugin", L"7-Zip", 0); + return; + } + if (createObject(&pluginInfo.OptionsClassID, &IID_IPluginOptions, (void **)&pluginOptions) != S_OK) + { + MessageBoxW(HWND(*this), L"There are no options", L"7-Zip", 0); + return; + } + CPluginOptionsCallback *callbackSpec = new CPluginOptionsCallback; + CMyComPtr callback(callbackSpec); + callbackSpec->Init(pluginInfo.Name); + pluginOptions->PluginOptions(HWND(*this), callback); +} + +bool CPluginsPage::OnNotify(UINT controlID, LPNMHDR lParam) +{ + if (lParam->hwndFrom == HWND(_listView) && lParam->code == LVN_ITEMCHANGED) + { + const NMLISTVIEW *aNMListView = (const NMLISTVIEW *)lParam; + if ((aNMListView->uChanged & LVIF_STATE) != 0) + { + UINT oldState = aNMListView->uOldState & LVIS_STATEIMAGEMASK; + UINT newState = aNMListView->uNewState & LVIS_STATEIMAGEMASK; + if (oldState != newState) + Changed(); + } + return true; + } + return CPropertyPage::OnNotify(controlID, lParam); +} + +/* +bool CPluginsPage::OnCommand(int code, int itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE && itemID == IDC_LANG_COMBO_LANG) + { + Changed(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, lParam); +} + +*/ \ No newline at end of file diff --git a/CPP/7zip/UI/FileManager/PluginsPage.h b/CPP/7zip/UI/FileManager/PluginsPage.h new file mode 100755 index 00000000..1dcd62d2 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PluginsPage.h @@ -0,0 +1,26 @@ +// PluginsPage.h + +#include "Windows/Control/ListView.h" + +#ifndef __PLUGINSPAGE_H +#define __PLUGINSPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/ComboBox.h" + +#include "RegistryPlugins.h" + +class CPluginsPage: public NWindows::NControl::CPropertyPage +{ + NWindows::NControl::CListView _listView; + CObjectVector _plugins; +public: + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnButtonOptions(); + virtual LONG OnApply(); + virtual bool OnNotify(UINT controlID, LPNMHDR lParam); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/PluginsPage.rc b/CPP/7zip/UI/FileManager/PluginsPage.rc new file mode 100755 index 00000000..5a1f48ec --- /dev/null +++ b/CPP/7zip/UI/FileManager/PluginsPage.rc @@ -0,0 +1,19 @@ +#include "PluginsPageRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + + +IDD_PLUGINS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Plugins" +MY_FONT +BEGIN + LTEXT "&Plugins:", IDC_PLUGINS_STATIC_PLUGINS, marg, marg, xSize2, 8 + CONTROL "List1", IDC_PLUGINS_LIST, "SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | + LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP, + marg, 20, xSize2 - bXSize - 12, ySize2 - 12 + PUSHBUTTON "Options...", IDC_PLUGINS_BUTTON_OPTIONS, (xSize - marg - bXSize), 20, bXSize, bYSize +END diff --git a/CPP/7zip/UI/FileManager/PluginsPageRes.h b/CPP/7zip/UI/FileManager/PluginsPageRes.h new file mode 100755 index 00000000..8fc923ee --- /dev/null +++ b/CPP/7zip/UI/FileManager/PluginsPageRes.h @@ -0,0 +1,4 @@ +#define IDD_PLUGINS 901 +#define IDC_PLUGINS_STATIC_PLUGINS 1000 +#define IDC_PLUGINS_LIST 1001 +#define IDC_PLUGINS_BUTTON_OPTIONS 1002 diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.cpp b/CPP/7zip/UI/FileManager/ProgramLocation.cpp new file mode 100755 index 00000000..88c18d5e --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgramLocation.cpp @@ -0,0 +1,24 @@ +// ProgramLocation.h + +#include "StdAfx.h" + +#include "ProgramLocation.h" + +#include "Windows/FileName.h" +#include "Windows/DLL.h" + +using namespace NWindows; + +extern HINSTANCE g_hInstance; + +bool GetProgramFolderPath(UString &folder) +{ + if (!NDLL::MyGetModuleFileName(g_hInstance, folder)) + return false; + int pos = folder.ReverseFind(L'\\'); + if (pos < 0) + return false; + folder = folder.Left(pos + 1); + return true; +} + diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.h b/CPP/7zip/UI/FileManager/ProgramLocation.h new file mode 100755 index 00000000..38317b45 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgramLocation.h @@ -0,0 +1,10 @@ +// ProgramLocation.h + +#ifndef __PROGRAMLOCATION_H +#define __PROGRAMLOCATION_H + +#include "Common/MyString.h" + +bool GetProgramFolderPath(UString &folder); // normalized + +#endif diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/CPP/7zip/UI/FileManager/ProgressDialog.cpp new file mode 100755 index 00000000..b185868b --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog.cpp @@ -0,0 +1,175 @@ +// ProgressDialog.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "ProgressDialog.h" +#include "Common/IntToString.h" +#include "Common/IntToString.h" + +using namespace NWindows; + +static const UINT_PTR kTimerID = 3; +static const UINT kTimerElapse = 50; + +#ifdef LANG +#include "LangUtils.h" +#endif + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDCANCEL, 0x02000711 } +}; +#endif + +#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(-1); + _prevPercentValue = -1; + + #ifdef LANG + // LangSetWindowText(HWND(*this), 0x02000C00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + + m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); + _timer = SetTimer(kTimerID, kTimerElapse); + _dialogCreatedEvent.Set(); + SetText(_title); + return CModalDialog::OnInit(); +} + +void CProgressDialog::OnCancel() +{ + ProgressSynch.SetStopped(true); +} + +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 (ProgressSynch.GetPaused()) + return true; + UINT64 total, completed; + ProgressSynch.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; +} + + +//////////////////// +// CU64ToI32Converter + +static const UINT64 kMaxIntValue = 0x7FFFFFFF; + +void CU64ToI32Converter::Init(UINT64 range) +{ + _numShiftBits = 0; + while(range > kMaxIntValue) + { + range >>= 1; + _numShiftBits++; + } +} + +int CU64ToI32Converter::Count(UINT64 aValue) +{ + return int(aValue >> _numShiftBits); +} + +const UINT CProgressDialog::kCloseMessage = WM_USER + 1; + +bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case kCloseMessage: + { + KillTimer(_timer); + _timer = 0; + End(0); + return true; + } + 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 = ProgressSynch.GetPaused();; + ProgressSynch.SetPaused(true); + int res = ::MessageBoxW(HWND(*this), + L"Are you sure you want to cancel?", + _title, MB_YESNOCANCEL); + ProgressSynch.SetPaused(paused); + if (res == IDCANCEL || res == IDNO) + return true; + break; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.h b/CPP/7zip/UI/FileManager/ProgressDialog.h new file mode 100755 index 00000000..0ef2dc99 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog.h @@ -0,0 +1,132 @@ +// ProgressDialog.h + +#ifndef __PROGRESSDIALOG_H +#define __PROGRESSDIALOG_H + +#include "ProgressDialogRes.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ProgressBar.h" +#include "Windows/Synchronization.h" + +class CProgressSynch +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; + bool _stopped; + bool _paused; + UINT64 _total; + UINT64 _completed; +public: + CProgressSynch(): _stopped(false), _paused(false), _total(1), _completed(0) {} + + bool GetStopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return _stopped; + } + void SetStopped(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _stopped = value; + } + bool GetPaused() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return _paused; + } + void SetPaused(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _paused = value; + } + void SetProgress(UINT64 total, UINT64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _total = total; + _completed = completed; + } + void SetPos(UINT64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _completed = completed; + } + void GetProgress(UINT64 &total, UINT64 &completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + total = _total; + completed = _completed; + } +}; + +class CU64ToI32Converter +{ + UINT64 _numShiftBits; +public: + void Init(UINT64 _range); + int Count(UINT64 aValue); +}; + +// class CProgressDialog: public NWindows::NControl::CModelessDialog + +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 OnTimer(WPARAM timerID, LPARAM callback); + void SetRange(UINT64 range); + void SetPos(UINT64 pos); + virtual bool OnInit(); + virtual void OnCancel(); + NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent; + #ifndef _SFX + void AddToTitle(LPCWSTR string); + #endif + bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + CProgressSynch ProgressSynch; + + #ifndef _SFX + HWND MainWindow; + UString MainTitle; + UString MainAddTitle; + ~CProgressDialog(); + #endif + + CProgressDialog(): _timer(0) + #ifndef _SFX + ,MainWindow(0) + #endif + { + if (_dialogCreatedEvent.Create() != S_OK) + throw 1334987; + } + + void WaitCreating() { _dialogCreatedEvent.Lock(); } + + + INT_PTR Create(const UString &title, HWND wndParent = 0) + { + _title = title; + return CModalDialog::Create(IDD_DIALOG_PROGRESS, wndParent); + } + + static const UINT kCloseMessage; + + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + + void MyClose() + { + PostMessage(kCloseMessage); + }; +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.rc b/CPP/7zip/UI/FileManager/ProgressDialog.rc new file mode 100755 index 00000000..e5cdd7e8 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog.rc @@ -0,0 +1,20 @@ +#include "ProgressDialogRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 172 +#define ySize2 42 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define bXPos (xSize - marg - bXSize) + + +IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Progress" +MY_FONT +BEGIN + PUSHBUTTON "Cancel", IDCANCEL, bXPos, bYPos , bXSize, bYSize + CONTROL "Progress1", IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER, + marg,marg, xSize2, 14 +END diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp new file mode 100755 index 00000000..ae4752ef --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -0,0 +1,483 @@ +// ProgressDialog2.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "ProgressDialog2.h" +#include "Common/IntToString.h" + +using namespace NWindows; + +static const UINT_PTR kTimerID = 3; +static const UINT kTimerElapse = 100; + +#ifdef LANG +#include "LangUtils.h" +#endif + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDCANCEL, 0x02000C00 }, + { IDC_PROGRESS_ELAPSED, 0x02000C01 }, + { IDC_PROGRESS_REMAINING, 0x02000C02 }, + { IDC_PROGRESS_TOTAL, 0x02000C03 }, + { IDC_PROGRESS_SPEED, 0x02000C04 }, + { IDC_PROGRESS_UNPACKED, 0x02000C05 }, + { IDC_PROGRESS_PACKED, 0x02000323 }, + { IDC_PROGRESS_RATIO, 0x02000C06 }, + { IDC_PROGRESS_SPEED, 0x02000C04 }, + { IDC_PROGRESS_FILES, 0x02000320 }, + { IDC_BUTTON_PROGRESS_PRIORITY, 0x02000C10 }, + { IDC_BUTTON_PAUSE, 0x02000C12 }, + { IDCANCEL, 0x02000711 }, +}; +#endif + +HRESULT CProgressSynch::SetPosAndCheckPaused(UInt64 completed) +{ + for (;;) + { + if(GetStopped()) + return E_ABORT; + if(!GetPaused()) + break; + ::Sleep(100); + } + SetPos(completed); + return S_OK; +} + +#ifndef _SFX +CProgressDialog::~CProgressDialog() +{ + AddToTitle(L""); +} +void CProgressDialog::AddToTitle(LPCWSTR s) +{ + if (MainWindow != 0) + { + CWindow window(MainWindow); + window.SetText(s + UString(MainTitle)); + } +} + +static const int kTitleFileNameSizeLimit = 36; +static const int kCurrentFileNameSizeLimit = 68; + +static void ReduceString(UString &s, int size) +{ + if (s.Length() > size) + s = s.Left(size / 2) + UString(L" ... ") + s.Right(size / 2); +} +#endif + +bool CProgressDialog::OnInit() +{ + _range = (UInt64)(Int64)(-1); + _prevPercentValue = UInt32(-1); + _prevElapsedSec = UInt32(-1); + _prevRemainingSec = UInt32(-1); + _prevSpeed = UInt32(-1); + _prevMode = kSpeedBytes; + _prevTime = ::GetTickCount(); + _elapsedTime = 0; + _foreground = true; + + #ifdef LANG + // LangSetWindowText(HWND(*this), 0x02000C00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + + + CWindow window(GetItem(IDC_BUTTON_PROGRESS_PRIORITY)); + window.GetText(backgroundString); + backgroundedString = backgroundString; + backgroundedString.Replace(L"&", L""); + + window = GetItem(IDC_BUTTON_PAUSE); + window.GetText(pauseString); + + foregroundString = LangString(IDS_PROGRESS_FOREGROUND, 0x02000C11); + continueString = LangString(IDS_PROGRESS_CONTINUE, 0x02000C13); + pausedString = LangString(IDS_PROGRESS_PAUSED, 0x02000C20); + + m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); + _timer = SetTimer(kTimerID, kTimerElapse); + _dialogCreatedEvent.Set(); + SetText(_title); + SetPauseText(); + SetPriorityText(); + return CModalDialog::OnInit(); +} + +void CProgressDialog::OnCancel() +{ + ProgressSynch.SetStopped(true); +} + +static void ConvertSizeToString(UInt64 value, wchar_t *s) +{ + const wchar_t *kModif = L" KM"; + for (int i = 0; ; i++) + if (i == 2 || value < (UInt64(10000) << (i * 10))) + { + ConvertUInt64ToString(value >> (i * 10), s); + s += wcslen(s); + *s++ = ' '; + if (i != 0) + *s++ = kModif[i]; + *s++ = L'B'; + *s++ = L'\0'; + return; + } +} + +void CProgressDialog::SetRange(UInt64 range) +{ + _range = range; + _previousPos = (UInt64)(Int64)-1; + _converter.Init(range); + m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100% + + wchar_t s[32]; + ConvertSizeToString(_range, s); + SetItemText(IDC_PROGRESS_TOTAL_VALUE, s); +} + +void CProgressDialog::SetPos(UInt64 pos) +{ + bool redraw = true; + if (pos < _range && pos > _previousPos) + { + if (pos - _previousPos < (_range >> 10)) + redraw = false; + } + if(redraw) + { + m_ProgressBar.SetPos(_converter.Count(pos)); // Test it for 100% + _previousPos = pos; + } +} + +static void GetTimeString(UInt64 timeValue, TCHAR *s) +{ + wsprintf(s, TEXT("%02d:%02d:%02d"), + UInt32(timeValue / 3600), + UInt32((timeValue / 60) % 60), + UInt32(timeValue % 60)); +} + +void CProgressDialog::ShowSize(int id, UInt64 value) +{ + wchar_t s[40]; + s[0] = 0; + if (value != (UInt64)(Int64)-1) + ConvertSizeToString(value, s); + SetItemText(id, s); +} + +bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) +{ + if (ProgressSynch.GetPaused()) + return true; + UInt64 total, completed, totalFiles, completedFiles, inSize, outSize; + ProgressSynch.GetProgress(total, completed, totalFiles, completedFiles, inSize, outSize); + + UInt32 curTime = ::GetTickCount(); + + if (total != _range) + SetRange(total); + if (total == (UInt64)(Int64)-1) + { + SetPos(0); + SetRange(completed); + } + else + SetPos(completed); + + _elapsedTime += (curTime - _prevTime); + _prevTime = curTime; + + UInt32 elapsedSec = _elapsedTime / 1000; + + bool elapsedChanged = false; + if (elapsedSec != _prevElapsedSec) + { + TCHAR s[40]; + GetTimeString(elapsedSec, s); + SetItemText(IDC_PROGRESS_ELAPSED_VALUE, s); + _prevElapsedSec = elapsedSec; + elapsedChanged = true; + } + + if (elapsedChanged) + { + if (completed != 0) + { + + if (total == (UInt64)(Int64)-1) + { + SetItemText(IDC_PROGRESS_REMAINING_VALUE, L""); + } + else + { + UInt64 remainingTime = 0; + if (completed < total) + remainingTime = _elapsedTime * (total - completed) / completed; + UInt64 remainingSec = remainingTime / 1000; + if (remainingSec != _prevRemainingSec) + { + TCHAR s[40]; + GetTimeString(remainingSec, s); + SetItemText(IDC_PROGRESS_REMAINING_VALUE, s); + _prevRemainingSec = remainingSec; + } + } + // if (elapsedChanged) + { + UInt64 speedB = (completed * 1000) / _elapsedTime; + UInt64 speedKB = speedB / 1024; + UInt64 speedMB = speedKB / 1024; + const UInt32 kLimit1 = 10; + TCHAR s[40]; + bool needRedraw = false; + if (speedMB >= kLimit1) + { + if (_prevMode != kSpeedMBytes || speedMB != _prevSpeed) + { + ConvertUInt64ToString(speedMB, s); + lstrcat(s, TEXT(" MB/s")); + _prevMode = kSpeedMBytes; + _prevSpeed = speedMB; + needRedraw = true; + } + } + else if (speedKB >= kLimit1) + { + if (_prevMode != kSpeedKBytes || speedKB != _prevSpeed) + { + ConvertUInt64ToString(speedKB, s); + lstrcat(s, TEXT(" KB/s")); + _prevMode = kSpeedKBytes; + _prevSpeed = speedKB; + needRedraw = true; + } + } + else + { + if (_prevMode != kSpeedBytes || speedB != _prevSpeed) + { + ConvertUInt64ToString(speedB, s); + lstrcat(s, TEXT(" B/s")); + _prevMode = kSpeedBytes; + _prevSpeed = speedB; + needRedraw = true; + } + } + if (needRedraw) + SetItemText(IDC_PROGRESS_SPEED_VALUE, s); + } + } + + if (total == 0) + total = 1; + UInt32 percentValue = (UInt32)(completed * 100 / total); + UString titleName; + ProgressSynch.GetTitleFileName(titleName); + if (percentValue != _prevPercentValue || _prevTitleName != titleName) + { + _prevPercentValue = percentValue; + SetTitleText(); + _prevTitleName = titleName; + } + + TCHAR s[64]; + ConvertUInt64ToString(completedFiles, s); + if (totalFiles != (UInt64)(Int64)-1) + { + lstrcat(s, TEXT(" / ")); + ConvertUInt64ToString(totalFiles, s + lstrlen(s)); + } + + SetItemText(IDC_PROGRESS_FILES_VALUE, s); + + const UInt64 packSize = CompressingMode ? outSize : inSize; + const UInt64 unpackSize = CompressingMode ? inSize : outSize; + + if (unpackSize == (UInt64)(Int64)-1 && packSize == (UInt64)(Int64)-1) + { + ShowSize(IDC_PROGRESS_UNPACKED_VALUE, completed); + SetItemText(IDC_PROGRESS_PACKED_VALUE, L""); + } + else + { + ShowSize(IDC_PROGRESS_UNPACKED_VALUE, unpackSize); + ShowSize(IDC_PROGRESS_PACKED_VALUE, packSize); + + if (packSize != (UInt64)(Int64)-1 && unpackSize != (UInt64)(Int64)-1 && unpackSize != 0) + { + UInt64 ratio = packSize * 100 / unpackSize; + ConvertUInt64ToString(ratio, s); + lstrcat(s, TEXT("%")); + SetItemText(IDC_PROGRESS_RATIO_VALUE, s); + } + } + } + + + UString fileName; + ProgressSynch.GetCurrentFileName(fileName); + if (_prevFileName != fileName) + { + ReduceString(fileName, kCurrentFileNameSizeLimit); + SetItemText(IDC_PROGRESS_FILE_NAME, fileName); + _prevFileName == fileName; + } + + return true; +} + + +//////////////////// +// CU64ToI32Converter + +static const UInt64 kMaxIntValue = 0x7FFFFFFF; + +void CU64ToI32Converter::Init(UInt64 range) +{ + _numShiftBits = 0; + while(range > kMaxIntValue) + { + range >>= 1; + _numShiftBits++; + } +} + +int CU64ToI32Converter::Count(UInt64 aValue) +{ + return int(aValue >> _numShiftBits); +} + +const UINT CProgressDialog::kCloseMessage = WM_USER + 1; + +bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case kCloseMessage: + { + KillTimer(_timer); + _timer = 0; + End(0); + return true; + } + case WM_SETTEXT: + { + if (_timer == 0) + return true; + } + } + return CModalDialog::OnMessage(message, wParam, lParam); +} + +void CProgressDialog::SetTitleText() +{ + UString title; + if (ProgressSynch.GetPaused()) + { + title = pausedString; + title += L" "; + } + if (_prevPercentValue != UInt32(-1)) + { + wchar_t s[64]; + ConvertUInt64ToString(_prevPercentValue, s); + title += s; + title += L"%"; + } + if (!_foreground) + { + title += L" "; + title += backgroundedString; + } + title += L" "; + UString totalTitle = title + _title; + UString fileName; + ProgressSynch.GetTitleFileName(fileName); + if (!fileName.IsEmpty()) + { + ReduceString(fileName, kTitleFileNameSizeLimit); + totalTitle += L" "; + totalTitle += fileName; + } + SetText(totalTitle); + #ifndef _SFX + AddToTitle(title + MainAddTitle); + #endif +} + +void CProgressDialog::SetPauseText() +{ + SetItemText(IDC_BUTTON_PAUSE, ProgressSynch.GetPaused() ? + continueString : pauseString); + SetTitleText(); +} + +void CProgressDialog::OnPauseButton() +{ + bool paused = !ProgressSynch.GetPaused(); + ProgressSynch.SetPaused(paused); + UInt32 curTime = ::GetTickCount(); + if (paused) + _elapsedTime += (curTime - _prevTime); + _prevTime = curTime; + SetPauseText(); +} + +void CProgressDialog::SetPriorityText() +{ + SetItemText(IDC_BUTTON_PROGRESS_PRIORITY, _foreground ? + backgroundString : + foregroundString); + SetTitleText(); +} + +void CProgressDialog::OnPriorityButton() +{ + _foreground = !_foreground; + SetPriorityClass(GetCurrentProcess(), _foreground ? + NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS); + SetPriorityText(); +} + +bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDCANCEL: + { + bool paused = ProgressSynch.GetPaused();; + // ProgressSynch.SetPaused(true); + if (!paused) + OnPauseButton(); + int res = ::MessageBoxW(HWND(*this), + LangString(IDS_PROGRESS_ASK_CANCEL, 0x02000C30), + _title, MB_YESNOCANCEL); + // ProgressSynch.SetPaused(paused); + if (!paused) + OnPauseButton(); + if (res == IDCANCEL || res == IDNO) + return true; + break; + } + case IDC_BUTTON_PAUSE: + OnPauseButton(); + return true; + case IDC_BUTTON_PROGRESS_PRIORITY: + { + OnPriorityButton(); + return true; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h new file mode 100755 index 00000000..9acaf9de --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h @@ -0,0 +1,226 @@ +// ProgressDialog2.h + +#ifndef __PROGRESSDIALOG2_H +#define __PROGRESSDIALOG2_H + +#include "ProgressDialog2Res.h" + +#include "Common/Types.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ProgressBar.h" +#include "Windows/Synchronization.h" + +class CProgressSynch +{ + NWindows::NSynchronization::CCriticalSection _criticalSection; + bool _stopped; + bool _paused; + UInt64 _total; + UInt64 _completed; + UInt64 _inSize; + UInt64 _outSize; + UInt64 _totalFiles; + UInt64 _completedFiles; + UString TitleFileName; + UString CurrentFileName; +public: + CProgressSynch(): + _stopped(false), _paused(false), + _total((UInt64)(Int64)-1), + _completed(0), + _totalFiles((UInt64)(Int64)-1), + _completedFiles(0), + _inSize((UInt64)(Int64)-1), + _outSize((UInt64)(Int64)-1) + {} + + bool GetStopped() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return _stopped; + } + void SetStopped(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _stopped = value; + } + bool GetPaused() + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + return _paused; + } + void SetPaused(bool value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _paused = value; + } + void SetProgress(UInt64 total, UInt64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _total = total; + _completed = completed; + } + void SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + if (inSize) + _inSize = *inSize; + if (outSize) + _outSize = *outSize; + } + void SetPos(UInt64 completed) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _completed = completed; + } + void SetNumFilesTotal(UInt64 value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _totalFiles = value; + } + void SetNumFilesCur(UInt64 value) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + _completedFiles = value; + } + HRESULT SetPosAndCheckPaused(UInt64 completed); + void GetProgress(UInt64 &total, UInt64 &completed, + UInt64 &totalFiles, UInt64 &completedFiles, + UInt64 &inSize, UInt64 &outSize) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + total = _total; + completed = _completed; + totalFiles = _totalFiles; + completedFiles = _completedFiles; + inSize = _inSize; + outSize = _outSize; + } + void SetTitleFileName(const UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + TitleFileName = fileName; + } + void GetTitleFileName(UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + fileName = TitleFileName; + } + void SetCurrentFileName(const UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + CurrentFileName = fileName; + } + void GetCurrentFileName(UString &fileName) + { + NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection); + fileName = CurrentFileName; + } +}; + +class CU64ToI32Converter +{ + UInt64 _numShiftBits; +public: + void Init(UInt64 _range); + int Count(UInt64 aValue); +}; + +// class CProgressDialog: public NWindows::NControl::CModelessDialog + +enum ESpeedMode +{ + kSpeedBytes, + kSpeedKBytes, + kSpeedMBytes +}; + +class CProgressDialog: public NWindows::NControl::CModalDialog +{ + UString _prevFileName; + UString _prevTitleName; +private: + UString backgroundString; + UString backgroundedString; + UString foregroundString; + UString pauseString; + UString continueString; + UString pausedString; + + + + UINT_PTR _timer; + + UString _title; + CU64ToI32Converter _converter; + UInt64 _previousPos; + UInt64 _range; + NWindows::NControl::CProgressBar m_ProgressBar; + + UInt32 _prevPercentValue; + UInt32 _prevTime; + UInt32 _elapsedTime; + UInt32 _prevElapsedSec; + UInt64 _prevRemainingSec; + ESpeedMode _prevMode; + UInt64 _prevSpeed; + + bool _foreground; + + bool OnTimer(WPARAM timerID, LPARAM callback); + void SetRange(UInt64 range); + void SetPos(UInt64 pos); + virtual bool OnInit(); + virtual void OnCancel(); + 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); + + void SetTitleText(); + void ShowSize(int id, UInt64 value); + +public: + CProgressSynch ProgressSynch; + bool CompressingMode; + + #ifndef _SFX + HWND MainWindow; + UString MainTitle; + UString MainAddTitle; + ~CProgressDialog(); + #endif + + CProgressDialog(): _timer(0), CompressingMode(true) + #ifndef _SFX + ,MainWindow(0) + #endif + { + if (_dialogCreatedEvent.Create() != S_OK) + throw 1334987; + } + + void WaitCreating() { _dialogCreatedEvent.Lock(); } + + + INT_PTR Create(const UString &title, HWND wndParent = 0) + { + _title = title; + return CModalDialog::Create(IDD_DIALOG_PROGRESS, wndParent); + } + + static const UINT kCloseMessage; + + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + + void MyClose() { PostMessage(kCloseMessage); }; +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.rc b/CPP/7zip/UI/FileManager/ProgressDialog2.rc new file mode 100755 index 00000000..5818dfb3 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.rc @@ -0,0 +1,77 @@ +#include "ProgressDialog2Res.h" +#include "../../GuiCommon.rc" + +#define xSize2 300 +#define ySize2 98 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) + +#undef bXSize +#define bXSize 72 + +#define bXPos1 (xSize - marg - bXSize) +#define bXPos2 (bXPos1 - 10 - bXSize) +#define bXPos3 (bXPos2 - 10 - bXSize) + +#define x0Size 90 +#define x1 (marg + x0Size) +#define x1Size 40 + +#define x3Size 40 +#define x3 (xSize - marg - x3Size) + +#define x2Size 90 +#define x2 (x3 - x2Size) + +#undef y0 +#undef y1 +#undef y2 +#undef y3 +#define y0 marg +#define y1 (y0 + 11) +#define y2 (y1 + 11) +#define y3 (y2 + 11) + + +IDD_DIALOG_PROGRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX +CAPTION "Progress" +MY_FONT +BEGIN + PUSHBUTTON "&Background", IDC_BUTTON_PROGRESS_PRIORITY, bXPos3, bYPos, bXSize, bYSize + PUSHBUTTON "&Pause", IDC_BUTTON_PAUSE, bXPos2, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, bXPos1, bYPos, bXSize, bYSize + LTEXT "Elapsed time:", IDC_PROGRESS_ELAPSED, marg, y0, x0Size, 8 + LTEXT "Remaining time:", IDC_PROGRESS_REMAINING, marg, y1, x0Size, 8 + LTEXT "Files:", IDC_PROGRESS_FILES, marg, y2, x0Size, 8 + LTEXT "Compression ratio:",IDC_PROGRESS_RATIO, marg, y3, x0Size, 8 + + LTEXT "Total size:", IDC_PROGRESS_TOTAL, x2, y0, x2Size, 8 + LTEXT "Speed:", IDC_PROGRESS_SPEED, x2, y1, x2Size, 8 + LTEXT "Processed:", IDC_PROGRESS_UNPACKED, x2, y2, x2Size, 8 + LTEXT "Compressed size:", IDC_PROGRESS_PACKED, x2, y3, x2Size, 8 + + RTEXT "00:00:00", IDC_PROGRESS_ELAPSED_VALUE, x1, y0, x1Size, 8 + RTEXT "", IDC_PROGRESS_REMAINING_VALUE, x1, y1, x1Size, 8 + RTEXT "", IDC_PROGRESS_FILES_VALUE, x1, y2, x1Size, 8 + RTEXT "", IDC_PROGRESS_RATIO_VALUE, x1, y3, x1Size, 8 + + RTEXT "", IDC_PROGRESS_TOTAL_VALUE, x3, y0, x3Size, 8 + RTEXT "", IDC_PROGRESS_SPEED_VALUE, x3, y1, x3Size, 8 + RTEXT "", IDC_PROGRESS_UNPACKED_VALUE, x3, y2, x3Size, 8 + RTEXT "", IDC_PROGRESS_PACKED_VALUE, x3, y3, x3Size, 8 + + LTEXT "", IDC_PROGRESS_FILE_NAME, marg, bYPos - 30, xSize2, 8, SS_NOPREFIX + CONTROL "Progress1", IDC_PROGRESS1, "msctls_progress32", PBS_SMOOTH | WS_BORDER, marg, bYPos - 20, xSize2, 13 +END + + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PROGRESS_PAUSED "Paused" + IDS_PROGRESS_FOREGROUND "&Foreground" + IDS_PROGRESS_CONTINUE "&Continue" + IDS_PROGRESS_ASK_CANCEL "Are you sure you want to cancel?" +END diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h new file mode 100755 index 00000000..16bf2634 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h @@ -0,0 +1,26 @@ +#define IDC_BUTTON_PAUSE 3 +#define IDC_BUTTON_PROGRESS_PRIORITY 4 +#define IDD_DIALOG_PROGRESS 500 +#define IDS_PROGRESS_PAUSED 700 +#define IDS_PROGRESS_FOREGROUND 701 +#define IDS_PROGRESS_CONTINUE 702 +#define IDS_PROGRESS_ASK_CANCEL 703 +#define IDC_PROGRESS1 1000 +#define IDC_PROGRESS_ELAPSED 1002 +#define IDC_PROGRESS_ELAPSED_VALUE 1003 +#define IDC_PROGRESS_REMAINING 1004 +#define IDC_PROGRESS_REMAINING_VALUE 1005 +#define IDC_PROGRESS_SPEED 1006 +#define IDC_PROGRESS_SPEED_VALUE 1007 +#define IDC_PROGRESS_TOTAL 1008 +#define IDC_PROGRESS_TOTAL_VALUE 1009 +#define IDC_PROGRESS_FILE_NAME 1010 + +#define IDC_PROGRESS_FILES 1012 +#define IDC_PROGRESS_FILES_VALUE 1013 +#define IDC_PROGRESS_RATIO 1014 +#define IDC_PROGRESS_RATIO_VALUE 1015 +#define IDC_PROGRESS_PACKED 1016 +#define IDC_PROGRESS_PACKED_VALUE 1017 +#define IDC_PROGRESS_UNPACKED 1018 +#define IDC_PROGRESS_UNPACKED_VALUE 1019 diff --git a/CPP/7zip/UI/FileManager/ProgressDialogRes.h b/CPP/7zip/UI/FileManager/ProgressDialogRes.h new file mode 100755 index 00000000..97e47228 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ProgressDialogRes.h @@ -0,0 +1,3 @@ +#define IDD_DIALOG_PROGRESS 500 + +#define IDC_PROGRESS1 1000 diff --git a/CPP/7zip/UI/FileManager/PropertyName.cpp b/CPP/7zip/UI/FileManager/PropertyName.cpp new file mode 100755 index 00000000..fb8f707e --- /dev/null +++ b/CPP/7zip/UI/FileManager/PropertyName.cpp @@ -0,0 +1,83 @@ +// PropertyName.cpp + +#include "StdAfx.h" + +#include "../../PropID.h" +#include "Windows/ResourceString.h" +#include "resource.h" +#include "PropertyName.h" +#include "PropertyNameRes.h" +#include "LangUtils.h" + +struct CPropertyIDNamePair +{ + PROPID PropID; + UINT ResourceID; + UINT LangID; +}; + +static CPropertyIDNamePair kPropertyIDNamePairs[] = +{ + { kpidPath, IDS_PROPERTY_PATH, 0x02000203 }, + { kpidName, IDS_PROPERTY_NAME, 0x02000204 }, + // { kpidExtension, L"Extension" }, + { kpidIsFolder, IDS_PROPERTY_IS_FOLDER, 0x02000206}, + { kpidSize, IDS_PROPERTY_SIZE, 0x02000207}, + { kpidPackedSize, IDS_PROPERTY_PACKED_SIZE, 0x02000208 }, + { kpidAttributes, IDS_PROPERTY_ATTRIBUTES, 0x02000209 }, + { kpidCreationTime, IDS_PROPERTY_CREATION_TIME, 0x0200020A }, + { kpidLastAccessTime, IDS_PROPERTY_LAST_ACCESS_TIME, 0x0200020B }, + { kpidLastWriteTime, IDS_PROPERTY_LAST_WRITE_TIME, 0x0200020C }, + { kpidSolid, IDS_PROPERTY_SOLID, 0x0200020D }, + { kpidCommented, IDS_PROPERTY_C0MMENTED, 0x0200020E }, + { kpidEncrypted, IDS_PROPERTY_ENCRYPTED, 0x0200020F }, + { kpidSplitBefore, IDS_PROPERTY_SPLIT_BEFORE, 0x02000210 }, + { kpidSplitAfter, IDS_PROPERTY_SPLIT_AFTER, 0x02000211 }, + { kpidDictionarySize, IDS_PROPERTY_DICTIONARY_SIZE, 0x02000212 }, + { kpidCRC, IDS_PROPERTY_CRC, 0x02000213 }, + { kpidType, IDS_PROPERTY_FILE_TYPE, 0x02000214}, + { kpidIsAnti, IDS_PROPERTY_ANTI, 0x02000215 }, + { kpidMethod, IDS_PROPERTY_METHOD, 0x02000216 }, + { kpidHostOS, IDS_PROPERTY_HOST_OS, 0x02000217 }, + { kpidFileSystem, IDS_PROPERTY_FILE_SYSTEM, 0x02000218}, + { kpidUser, IDS_PROPERTY_USER, 0x02000219}, + { kpidGroup, IDS_PROPERTY_GROUP, 0x0200021A}, + { kpidBlock, IDS_PROPERTY_BLOCK, 0x0200021B }, + { kpidComment, IDS_PROPERTY_COMMENT, 0x0200021C }, + { kpidPosition, IDS_PROPERTY_POSITION, 0x0200021D }, + { kpidPrefix, IDS_PROPERTY_PREFIX, 0x0200021E }, + { kpidNumSubFolders, IDS_PROPERTY_FOLDERS, 0x0200021F }, + { kpidNumSubFiles, IDS_PROPERTY_FILES, 0x02000220 }, + { kpidUnpackVer, IDS_PROPERTY_VERSION, 0x02000221}, + { kpidVolume, IDS_PROPERTY_VOLUME, 0x02000222}, + { kpidIsVolume, IDS_PROPERTY_IS_VOLUME, 0x02000223}, + { kpidOffset, IDS_PROPERTY_OFFSET, 0x02000224}, + { kpidLinks, IDS_PROPERTY_LINKS, 0x02000225}, + { kpidNumBlocks, IDS_PROPERTY_NUM_BLOCKS, 0x02000226}, + { kpidNumVolumes, IDS_PROPERTY_NUM_VOLUMES, 0x02000227}, + + { kpidTotalSize, IDS_PROPERTY_TOTAL_SIZE, 0x03031100 }, + { kpidFreeSpace, IDS_PROPERTY_FREE_SPACE, 0x03031101 }, + { kpidClusterSize, IDS_PROPERTY_CLUSTER_SIZE, 0x03031102}, + { kpidVolumeName, IDS_PROPERTY_VOLUME_NAME, 0x03031103 }, + + { kpidLocalName, IDS_PROPERTY_LOCAL_NAME, 0x03031200 }, + { kpidProvider, IDS_PROPERTY_PROVIDER, 0x03031201 } +}; + +int FindProperty(PROPID propID) +{ + for (int i = 0; i < sizeof(kPropertyIDNamePairs) / sizeof(kPropertyIDNamePairs[0]); i++) + if(kPropertyIDNamePairs[i].PropID == propID) + return i; + return -1; +} + +UString GetNameOfProperty(PROPID propID) +{ + int index = FindProperty(propID); + if (index < 0) + return UString(); + const CPropertyIDNamePair &pair = kPropertyIDNamePairs[index]; + return LangString(pair.ResourceID, pair.LangID); +} diff --git a/CPP/7zip/UI/FileManager/PropertyName.h b/CPP/7zip/UI/FileManager/PropertyName.h new file mode 100755 index 00000000..413d2343 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PropertyName.h @@ -0,0 +1,10 @@ +// PropertyName.h + +#ifndef __PROPERTYNAME_H +#define __PROPERTYNAME_H + +#include "Common/MyString.h" + +UString GetNameOfProperty(PROPID propID); + +#endif diff --git a/CPP/7zip/UI/FileManager/PropertyName.rc b/CPP/7zip/UI/FileManager/PropertyName.rc new file mode 100755 index 00000000..94171ee3 --- /dev/null +++ b/CPP/7zip/UI/FileManager/PropertyName.rc @@ -0,0 +1,45 @@ +#include "PropertyNameRes.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE +BEGIN + IDS_PROPERTY_PATH "Path" + IDS_PROPERTY_NAME "Name" + IDS_PROPERTY_EXTENSION "Extension" + IDS_PROPERTY_IS_FOLDER "Folder" + IDS_PROPERTY_SIZE "Size" + IDS_PROPERTY_PACKED_SIZE "Packed Size" + IDS_PROPERTY_ATTRIBUTES "Attributes" + IDS_PROPERTY_CREATION_TIME "Created" + IDS_PROPERTY_LAST_ACCESS_TIME "Accessed" + IDS_PROPERTY_LAST_WRITE_TIME "Modified" + IDS_PROPERTY_SOLID "Solid" + IDS_PROPERTY_C0MMENTED "Commented" + IDS_PROPERTY_ENCRYPTED "Encrypted" + IDS_PROPERTY_DICTIONARY_SIZE "Dictionary Size" + IDS_PROPERTY_SPLIT_BEFORE "Split Before" + IDS_PROPERTY_SPLIT_AFTER "Split After" + IDS_PROPERTY_CRC "CRC" + IDS_PROPERTY_FILE_TYPE "Type" + IDS_PROPERTY_ANTI "Anti" + IDS_PROPERTY_METHOD "Method" + IDS_PROPERTY_HOST_OS "Host OS" + IDS_PROPERTY_FILE_SYSTEM "File System" + IDS_PROPERTY_USER "User" + IDS_PROPERTY_GROUP "Group" + IDS_PROPERTY_BLOCK "Block" + IDS_PROPERTY_COMMENT "Comment" + IDS_PROPERTY_POSITION "Position" + IDS_PROPERTY_PREFIX "Path Prefix" + IDS_PROPERTY_FOLDERS "Folders" + IDS_PROPERTY_FILES "Files" + IDS_PROPERTY_VERSION "Version" + IDS_PROPERTY_VOLUME "Volume" + IDS_PROPERTY_IS_VOLUME "Multivolume" + IDS_PROPERTY_OFFSET "Offset" + IDS_PROPERTY_LINKS "Links" + IDS_PROPERTY_NUM_BLOCKS "Blocks" + IDS_PROPERTY_NUM_VOLUMES "Volumes" + +END diff --git a/CPP/7zip/UI/FileManager/PropertyNameRes.h b/CPP/7zip/UI/FileManager/PropertyNameRes.h new file mode 100755 index 00000000..80c9637f --- /dev/null +++ b/CPP/7zip/UI/FileManager/PropertyNameRes.h @@ -0,0 +1,37 @@ +#define IDS_PROPERTY_PATH 3 +#define IDS_PROPERTY_NAME 4 +#define IDS_PROPERTY_EXTENSION 5 +#define IDS_PROPERTY_IS_FOLDER 6 +#define IDS_PROPERTY_SIZE 7 +#define IDS_PROPERTY_PACKED_SIZE 8 +#define IDS_PROPERTY_ATTRIBUTES 9 +#define IDS_PROPERTY_CREATION_TIME 10 +#define IDS_PROPERTY_LAST_ACCESS_TIME 11 +#define IDS_PROPERTY_LAST_WRITE_TIME 12 +#define IDS_PROPERTY_SOLID 13 +#define IDS_PROPERTY_C0MMENTED 14 +#define IDS_PROPERTY_ENCRYPTED 15 +#define IDS_PROPERTY_DICTIONARY_SIZE 16 +#define IDS_PROPERTY_SPLIT_BEFORE 17 +#define IDS_PROPERTY_SPLIT_AFTER 18 +#define IDS_PROPERTY_CRC 19 +#define IDS_PROPERTY_FILE_TYPE 20 +#define IDS_PROPERTY_ANTI 21 +#define IDS_PROPERTY_METHOD 22 +#define IDS_PROPERTY_HOST_OS 23 +#define IDS_PROPERTY_FILE_SYSTEM 24 +#define IDS_PROPERTY_USER 25 +#define IDS_PROPERTY_GROUP 26 +#define IDS_PROPERTY_BLOCK 27 +#define IDS_PROPERTY_COMMENT 28 +#define IDS_PROPERTY_POSITION 29 +#define IDS_PROPERTY_PREFIX 30 +#define IDS_PROPERTY_FOLDERS 31 +#define IDS_PROPERTY_FILES 32 +#define IDS_PROPERTY_VERSION 33 +#define IDS_PROPERTY_VOLUME 34 +#define IDS_PROPERTY_IS_VOLUME 35 +#define IDS_PROPERTY_OFFSET 36 +#define IDS_PROPERTY_LINKS 37 +#define IDS_PROPERTY_NUM_BLOCKS 38 +#define IDS_PROPERTY_NUM_VOLUMES 39 diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp new file mode 100755 index 00000000..a03762ef --- /dev/null +++ b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp @@ -0,0 +1,303 @@ +// RegistryAssociations.cpp + +#include "StdAfx.h" + +#include "RegistryAssociations.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/StringToInt.h" + +#include "Windows/Synchronization.h" +#include "Windows/Registry.h" + +#include "Windows/FileName.h" + +#include "StringUtils.h" + +using namespace NWindows; +using namespace NRegistry; + + +namespace NRegistryAssociations { + +static NSynchronization::CCriticalSection g_CriticalSection; + +static const TCHAR *kCUKeyPath = TEXT("Software\\7-ZIP\\FM"); +static const TCHAR *kAssociations = TEXT("Associations"); +static const WCHAR *kExtPlugins = L"Plugins"; +static const TCHAR *kExtEnabled = TEXT("Enabled"); + +static CSysString GetAssociationsPath() +{ + return CSysString(kCUKeyPath) + CSysString('\\') + CSysString(kAssociations); +} + +bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey key; + if(key.Open(HKEY_CURRENT_USER, GetAssociationsPath() + CSysString('\\') + + CSysString(GetSystemString(ext)), KEY_READ) != ERROR_SUCCESS) + return false; + UString pluginsString; + key.QueryValue(kExtPlugins, pluginsString); + SplitString(pluginsString, extInfo.Plugins); + return true; +} + +void ReadInternalAssociations(CObjectVector &items) +{ + items.Clear(); + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey associationsKey; + if(associationsKey.Open(HKEY_CURRENT_USER, GetAssociationsPath(), KEY_READ) != ERROR_SUCCESS) + return; + CSysStringVector extNames; + associationsKey.EnumKeys(extNames); + for(int i = 0; i < extNames.Size(); i++) + { + const CSysString extName = extNames[i]; + CExtInfo extInfo; + // extInfo.Enabled = false; + extInfo.Ext = GetUnicodeString(extName); + CKey key; + if(key.Open(associationsKey, extName, KEY_READ) != ERROR_SUCCESS) + return; + UString pluginsString; + key.QueryValue(kExtPlugins, pluginsString); + SplitString(pluginsString, extInfo.Plugins); + /* + if (key.QueryValue(kExtEnabled, extInfo.Enabled) != ERROR_SUCCESS) + extInfo.Enabled = false; + */ + items.Add(extInfo); + } +} + +void WriteInternalAssociations(const CObjectVector &items) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey mainKey; + mainKey.Create(HKEY_CURRENT_USER, kCUKeyPath); + mainKey.RecurseDeleteKey(kAssociations); + CKey associationsKey; + associationsKey.Create(mainKey, kAssociations); + for(int i = 0; i < items.Size(); i++) + { + const CExtInfo &extInfo = items[i]; + CKey key; + key.Create(associationsKey, GetSystemString(extInfo.Ext)); + key.SetValue(kExtPlugins, JoinStrings(extInfo.Plugins)); + // key.SetValue(kExtEnabled, extInfo.Enabled); + } +} + +/////////////////////////////////// +// External + +static const TCHAR *kShellNewKeyName = TEXT("ShellNew"); +static const TCHAR *kShellNewDataValueName = TEXT("Data"); + +static const TCHAR *kDefaultIconKeyName = TEXT("DefaultIcon"); +static const TCHAR *kShellKeyName = TEXT("shell"); +static const TCHAR *kOpenKeyName = TEXT("open"); +static const TCHAR *kCommandKeyName = TEXT("command"); + +static CSysString GetExtensionKeyName(const CSysString &extension) +{ + return CSysString(TEXT(".")) + extension; +} + +static CSysString GetExtProgramKeyName(const CSysString &extension) +{ + return CSysString(TEXT("7-Zip.")) + extension; +} + +static bool CheckShellExtensionInfo2(const CSysString &extension, UString &iconPath, int &iconIndex) +{ + iconIndex = -1; + iconPath.Empty(); + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey extKey; + if (extKey.Open(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension), KEY_READ) != ERROR_SUCCESS) + return false; + CSysString programNameValue; + if (extKey.QueryValue(NULL, programNameValue) != ERROR_SUCCESS) + return false; + CSysString extProgramKeyName = GetExtProgramKeyName(extension); + if (programNameValue.CompareNoCase(extProgramKeyName) != 0) + return false; + CKey iconKey; + if (extKey.Open(HKEY_CLASSES_ROOT, extProgramKeyName + CSysString(TEXT('\\')) + kDefaultIconKeyName, KEY_READ) != ERROR_SUCCESS) + return false; + UString value; + if (extKey.QueryValue(NULL, value) == ERROR_SUCCESS) + { + int pos = value.ReverseFind(L','); + iconPath = value; + if (pos >= 0) + { + const wchar_t *end; + UInt64 index = ConvertStringToUInt64((const wchar_t *)value + pos + 1, &end); + if (*end == 0) + { + iconIndex = (int)index; + iconPath = value.Left(pos); + } + } + } + return true; +} + +bool CheckShellExtensionInfo(const CSysString &extension, UString &iconPath, int &iconIndex) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + if (!CheckShellExtensionInfo2(extension, iconPath, iconIndex)) + return false; + CKey extProgKey; + return (extProgKey.Open(HKEY_CLASSES_ROOT, GetExtProgramKeyName(extension), KEY_READ) == ERROR_SUCCESS); +} + +static void DeleteShellExtensionKey(const CSysString &extension) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetExtensionKeyName(extension)); + rootKey.Detach(); +} + +static void DeleteShellExtensionProgramKey(const CSysString &extension) +{ + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetExtProgramKeyName(extension)); + rootKey.Detach(); +} + +void DeleteShellExtensionInfo(const CSysString &extension) +{ + UString iconPath; + int iconIndex; + if (CheckShellExtensionInfo2(extension, iconPath, iconIndex)) + DeleteShellExtensionKey(extension); + DeleteShellExtensionProgramKey(extension); +} + +void AddShellExtensionInfo(const CSysString &extension, + const UString &programTitle, + const UString &programOpenCommand, + const UString &iconPath, int iconIndex, + const void *shellNewData, int shellNewDataSize) +{ + DeleteShellExtensionKey(extension); + DeleteShellExtensionProgramKey(extension); + NSynchronization::CCriticalSectionLock lock(g_CriticalSection); + CSysString programKeyName = GetExtProgramKeyName(extension); + { + CKey extKey; + extKey.Create(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension)); + extKey.SetValue(NULL, programKeyName); + if (shellNewData != NULL) + { + CKey shellNewKey; + shellNewKey.Create(extKey, kShellNewKeyName); + shellNewKey.SetValue(kShellNewDataValueName, shellNewData, shellNewDataSize); + } + } + CKey programKey; + programKey.Create(HKEY_CLASSES_ROOT, programKeyName); + programKey.SetValue(NULL, programTitle); + { + CKey iconKey; + iconKey.Create(programKey, kDefaultIconKeyName); + UString iconPathFull = iconPath; + if (iconIndex >= 0) + { + iconPathFull += L","; + wchar_t s[32]; + ConvertUInt64ToString((UInt64)iconIndex, s); + iconPathFull += s; + } + iconKey.SetValue(NULL, iconPathFull); + } + + CKey shellKey; + shellKey.Create(programKey, kShellKeyName); + shellKey.SetValue(NULL, TEXT("")); + + CKey openKey; + openKey.Create(shellKey, kOpenKeyName); + openKey.SetValue(NULL, TEXT("")); + + CKey commandKey; + commandKey.Create(openKey, kCommandKeyName); + + commandKey.SetValue(NULL, programOpenCommand); +} + +/////////////////////////// +// ContextMenu +/* + +static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-ZIP"); +static const TCHAR *kContextMenuHandlerCLASSIDValue = + TEXT("{23170F69-40C1-278A-1000-000100020000}"); +static const TCHAR *kRootKeyNameForFile = TEXT("*"); +static const TCHAR *kRootKeyNameForFolder = TEXT("Folder"); + +static CSysString GetFullContextMenuKeyName(const CSysString &aKeyName) + { return (aKeyName + kContextMenuKeyName); } + +static bool CheckContextMenuHandlerCommon(const CSysString &aKeyName) +{ + NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true); + CKey aKey; + if (aKey.Open(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName), KEY_READ) + != ERROR_SUCCESS) + return false; + CSysString aValue; + if (aKey.QueryValue(NULL, aValue) != ERROR_SUCCESS) + return false; + return (aValue.CompareNoCase(kContextMenuHandlerCLASSIDValue) == 0); +} + +bool CheckContextMenuHandler() +{ + return CheckContextMenuHandlerCommon(kRootKeyNameForFile) && + CheckContextMenuHandlerCommon(kRootKeyNameForFolder); +} + +static void DeleteContextMenuHandlerCommon(const CSysString &aKeyName) +{ + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(aKeyName)); + rootKey.Detach(); +} + +void DeleteContextMenuHandler() +{ + DeleteContextMenuHandlerCommon(kRootKeyNameForFile); + DeleteContextMenuHandlerCommon(kRootKeyNameForFolder); +} + +static void AddContextMenuHandlerCommon(const CSysString &aKeyName) +{ + DeleteContextMenuHandlerCommon(aKeyName); + NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true); + CKey aKey; + aKey.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName)); + aKey.SetValue(NULL, kContextMenuHandlerCLASSIDValue); +} + +void AddContextMenuHandler() +{ + AddContextMenuHandlerCommon(kRootKeyNameForFile); + AddContextMenuHandlerCommon(kRootKeyNameForFolder); +} +*/ + +} diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.h b/CPP/7zip/UI/FileManager/RegistryAssociations.h new file mode 100755 index 00000000..c1a64c96 --- /dev/null +++ b/CPP/7zip/UI/FileManager/RegistryAssociations.h @@ -0,0 +1,44 @@ +// RegistryAssociations.h + +#ifndef __REGISTRYASSOCIATIONS_H +#define __REGISTRYASSOCIATIONS_H + +#include "Common/MyString.h" + +namespace NRegistryAssociations { + + struct CExtInfo + { + UString Ext; + UStringVector Plugins; + // bool Enabled; + }; + bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo); + void ReadInternalAssociations(CObjectVector &items); + void WriteInternalAssociations(const CObjectVector &items); + + bool CheckShellExtensionInfo(const CSysString &extension, UString &iconPath, int &iconIndex); + + // void ReadCompressionInfo(NZipSettings::NCompression::CInfo &anInfo, + void DeleteShellExtensionInfo(const CSysString &extension); + + void AddShellExtensionInfo(const CSysString &extension, + const UString &programTitle, + const UString &programOpenCommand, + const UString &iconPath, int iconIndex, + const void *shellNewData, int shellNewDataSize); + + + /////////////////////////// + // ContextMenu + /* + bool CheckContextMenuHandler(); + void AddContextMenuHandler(); + void DeleteContextMenuHandler(); + */ + +} + +// bool GetProgramDirPrefix(CSysString &aFolder); + +#endif diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.cpp b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp new file mode 100755 index 00000000..771166ca --- /dev/null +++ b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp @@ -0,0 +1,146 @@ +// RegistryPlugins.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +// #include "Windows/Registry.h" +// #include "Windows/Synchronization.h" + +#include "Windows/DLL.h" +#include "Windows/PropVariant.h" +#include "Windows/FileFind.h" + +#include "RegistryPlugins.h" +#include "IFolder.h" + +using namespace NWindows; +using namespace NFile; +// using namespace NRegistry; +// using namespace NCOM; + +/* +static const TCHAR *kLMBasePath = TEXT("Software\\7-Zip\\FM"); + +static const TCHAR *kPluginsKeyName = TEXT("Plugins"); +static const TCHAR *kPluginsOpenClassIDValue = TEXT("CLSID"); +static const TCHAR *kPluginsOptionsClassIDValue = TEXT("Options"); +static const TCHAR *kPluginsTypeValue = TEXT("Type"); + +static CSysString GetFileFolderPluginsKeyName() +{ + return CSysString(kLMBasePath) + CSysString(TEXT('\\')) + + CSysString(kPluginsKeyName); +} + +static NSynchronization::CCriticalSection g_CriticalSection; +*/ +typedef UINT32 (WINAPI * GetPluginPropertyFunc)( + PROPID propID, PROPVARIANT *value); + +static bool ReadPluginInfo(CPluginInfo &pluginInfo) +{ + { + NDLL::CLibrary library; + if (!library.LoadEx(pluginInfo.FilePath, LOAD_LIBRARY_AS_DATAFILE)) + return false; + } + NDLL::CLibrary library; + if (!library.Load(pluginInfo.FilePath)) + return false; + GetPluginPropertyFunc getPluginProperty = (GetPluginPropertyFunc) + library.GetProcAddress("GetPluginProperty"); + if (getPluginProperty == NULL) + return false; + + NCOM::CPropVariant propVariant; + if (getPluginProperty(NPlugin::kName, &propVariant) != S_OK) + return false; + if (propVariant.vt != VT_BSTR) + return false; + pluginInfo.Name = propVariant.bstrVal; + propVariant.Clear(); + + if (getPluginProperty(NPlugin::kClassID, &propVariant) != S_OK) + return false; + if (propVariant.vt == VT_EMPTY) + pluginInfo.ClassIDDefined = false; + else if (propVariant.vt != VT_BSTR) + return false; + else + { + pluginInfo.ClassIDDefined = true; + pluginInfo.ClassID = *(const GUID *)propVariant.bstrVal; + } + propVariant.Clear(); + + if (getPluginProperty(NPlugin::kOptionsClassID, &propVariant) != S_OK) + return false; + if (propVariant.vt == VT_EMPTY) + pluginInfo.OptionsClassIDDefined = false; + else if (propVariant.vt != VT_BSTR) + return false; + else + { + pluginInfo.OptionsClassIDDefined = true; + pluginInfo.OptionsClassID = *(const GUID *)propVariant.bstrVal; + } + propVariant.Clear(); + + if (getPluginProperty(NPlugin::kType, &propVariant) != S_OK) + return false; + if (propVariant.vt == VT_EMPTY) + pluginInfo.Type = kPluginTypeFF; + else if (propVariant.vt == VT_UI4) + pluginInfo.Type = (EPluginType)propVariant.ulVal; + else + return false; + return true; +} + +UString GetProgramFolderPrefix(); + +void ReadPluginInfoList(CObjectVector &plugins) +{ + plugins.Clear(); + + UString baseFolderPrefix = GetProgramFolderPrefix(); + { + CPluginInfo pluginInfo; + pluginInfo.FilePath = baseFolderPrefix + L"7-zip.dll"; + if (::ReadPluginInfo(pluginInfo)) + plugins.Add(pluginInfo); + } + UString folderPath = baseFolderPrefix + L"Plugins\\"; + NFind::CEnumeratorW enumerator(folderPath + L"*"); + NFind::CFileInfoW fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + continue; + CPluginInfo pluginInfo; + pluginInfo.FilePath = folderPath + fileInfo.Name; + if (::ReadPluginInfo(pluginInfo)) + plugins.Add(pluginInfo); + } +} + +void ReadFileFolderPluginInfoList(CObjectVector &plugins) +{ + ReadPluginInfoList(plugins); + for (int i = 0; i < plugins.Size();) + if (plugins[i].Type != kPluginTypeFF) + plugins.Delete(i); + else + i++; + { + CPluginInfo p; + // p.FilePath.Empty(); + p.Type = kPluginTypeFF; + p.Name = L"7-Zip"; + // p.ClassID = CLSID_CAgentArchiveHandler; + p.ClassIDDefined = true; + // p.OptionsClassID; + p.OptionsClassIDDefined = false; + plugins.Add(p); + } +} diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.h b/CPP/7zip/UI/FileManager/RegistryPlugins.h new file mode 100755 index 00000000..90bab7b5 --- /dev/null +++ b/CPP/7zip/UI/FileManager/RegistryPlugins.h @@ -0,0 +1,32 @@ +// RegistryPlugins.h + +#ifndef __REGISTRYPLUGINS_H +#define __REGISTRYPLUGINS_H + +#include "Common/MyString.h" + +enum EPluginType +{ + kPluginTypeFF = 0 +}; + +struct CPluginInfo +{ + UString FilePath; + EPluginType Type; + UString Name; + CLSID ClassID; + CLSID OptionsClassID; + bool ClassIDDefined; + bool OptionsClassIDDefined; + + // CSysString Extension; + // CSysString AddExtension; + // bool UpdateEnabled; + // bool KeepName; +}; + +void ReadPluginInfoList(CObjectVector &plugins); +void ReadFileFolderPluginInfoList(CObjectVector &plugins); + +#endif diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.cpp b/CPP/7zip/UI/FileManager/RegistryUtils.cpp new file mode 100755 index 00000000..e9c13d19 --- /dev/null +++ b/CPP/7zip/UI/FileManager/RegistryUtils.cpp @@ -0,0 +1,150 @@ +// RegistryUtils.cpp + +#include "StdAfx.h" + +#include "RegistryUtils.h" +#include "Windows/Registry.h" + +using namespace NWindows; +using namespace NRegistry; + +static const TCHAR *kCUBasePath = TEXT("Software\\7-ZIP"); +static const TCHAR *kCU_FMPath = TEXT("Software\\7-ZIP\\FM"); +// static const TCHAR *kLM_Path = TEXT("Software\\7-ZIP\\FM"); + +static const WCHAR *kLangValueName = L"Lang"; +static const WCHAR *kEditor = L"Editor"; +static const TCHAR *kShowDots = TEXT("ShowDots"); +static const TCHAR *kShowRealFileIcons = TEXT("ShowRealFileIcons"); +static const TCHAR *kShowSystemMenu = TEXT("ShowSystemMenu"); + +static const TCHAR *kFullRow = TEXT("FullRow"); +static const TCHAR *kShowGrid = TEXT("ShowGrid"); +static const TCHAR *kAlternativeSelection = TEXT("AlternativeSelection"); +// static const TCHAR *kLockMemoryAdd = TEXT("LockMemoryAdd"); +static const TCHAR *kLargePagesEnable = TEXT("LargePages"); +// static const TCHAR *kSingleClick = TEXT("SingleClick"); +// static const TCHAR *kUnderline = TEXT("Underline"); + +void SaveRegLang(const UString &langFile) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(kLangValueName, langFile); +} + +void ReadRegLang(UString &langFile) +{ + langFile.Empty(); + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) + key.QueryValue(kLangValueName, langFile); +} + +void SaveRegEditor(const UString &editorPath) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCU_FMPath); + key.SetValue(kEditor, editorPath); +} + +void ReadRegEditor(UString &editorPath) +{ + editorPath.Empty(); + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS) + key.QueryValue(kEditor, editorPath); +} + +static void Save7ZipOption(const TCHAR *value, bool enabled) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(value, enabled); +} + +static void SaveOption(const TCHAR *value, bool enabled) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCU_FMPath); + key.SetValue(value, enabled); +} + +static bool Read7ZipOption(const TCHAR *value, bool defaultValue) +{ + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) + { + bool enabled; + if (key.QueryValue(value, enabled) == ERROR_SUCCESS) + return enabled; + } + return defaultValue; +} + +static bool ReadOption(const TCHAR *value, bool defaultValue) +{ + CKey key; + if (key.Open(HKEY_CURRENT_USER, kCU_FMPath, KEY_READ) == ERROR_SUCCESS) + { + bool enabled; + if (key.QueryValue(value, enabled) == ERROR_SUCCESS) + return enabled; + } + return defaultValue; +} + +/* +static void SaveLmOption(const TCHAR *value, bool enabled) +{ + CKey key; + key.Create(HKEY_LOCAL_MACHINE, kLM_Path); + key.SetValue(value, enabled); +} + +static bool ReadLmOption(const TCHAR *value, bool defaultValue) +{ + CKey key; + if (key.Open(HKEY_LOCAL_MACHINE, kLM_Path, KEY_READ) == ERROR_SUCCESS) + { + bool enabled; + if (key.QueryValue(value, enabled) == ERROR_SUCCESS) + return enabled; + } + return defaultValue; +} +*/ + +void SaveShowDots(bool showDots) { SaveOption(kShowDots, showDots); } +bool ReadShowDots() { return ReadOption(kShowDots, false); } + +void SaveShowRealFileIcons(bool show) { SaveOption(kShowRealFileIcons, show); } +bool ReadShowRealFileIcons() { return ReadOption(kShowRealFileIcons, false); } + +void SaveShowSystemMenu(bool show) { SaveOption(kShowSystemMenu, show); } +bool ReadShowSystemMenu(){ return ReadOption(kShowSystemMenu, false); } + +void SaveFullRow(bool enable) { SaveOption(kFullRow, enable); } +bool ReadFullRow() { return ReadOption(kFullRow, false); } + +void SaveShowGrid(bool enable) { SaveOption(kShowGrid, enable); } +bool ReadShowGrid(){ return ReadOption(kShowGrid, false); } + +void SaveAlternativeSelection(bool enable) { SaveOption(kAlternativeSelection, enable); } +bool ReadAlternativeSelection(){ return ReadOption(kAlternativeSelection, false); } + +/* +void SaveSingleClick(bool enable) { SaveOption(kSingleClick, enable); } +bool ReadSingleClick(){ return ReadOption(kSingleClick, false); } + +void SaveUnderline(bool enable) { SaveOption(kUnderline, enable); } +bool ReadUnderline(){ return ReadOption(kUnderline, false); } +*/ + +// void SaveLockMemoryAdd(bool enable) { SaveLmOption(kLockMemoryAdd, enable); } +// bool ReadLockMemoryAdd() { return ReadLmOption(kLockMemoryAdd, true); } + +void SaveLockMemoryEnable(bool enable) { Save7ZipOption(kLargePagesEnable, enable); } +bool ReadLockMemoryEnable() { return Read7ZipOption(kLargePagesEnable, false); } + + diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.h b/CPP/7zip/UI/FileManager/RegistryUtils.h new file mode 100755 index 00000000..0fec6f80 --- /dev/null +++ b/CPP/7zip/UI/FileManager/RegistryUtils.h @@ -0,0 +1,46 @@ +// RegistryUtils.h + +#include "Common/StringConvert.h" + +#ifndef __REGISTRYUTILS_H +#define __REGISTRYUTILS_H + +void SaveRegLang(const UString &langFile); +void ReadRegLang(UString &langFile); + +void SaveRegEditor(const UString &editorPath); +void ReadRegEditor(UString &editorPath); + +void SaveShowDots(bool showDots); +bool ReadShowDots(); + +void SaveShowRealFileIcons(bool show); +bool ReadShowRealFileIcons(); + +void SaveShowSystemMenu(bool showSystemMenu); +bool ReadShowSystemMenu(); + +void SaveFullRow(bool enable); +bool ReadFullRow(); + +void SaveShowGrid(bool enable); +bool ReadShowGrid(); + +void SaveAlternativeSelection(bool enable); +bool ReadAlternativeSelection(); + +// void SaveLockMemoryAdd(bool enable); +// bool ReadLockMemoryAdd(); + +bool ReadLockMemoryEnable(); +void SaveLockMemoryEnable(bool enable); + +/* +void SaveSingleClick(bool enable); +bool ReadSingleClick(); + +void SaveUnderline(bool enable); +bool ReadUnderline(); +*/ + +#endif diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp new file mode 100755 index 00000000..5c8e0e28 --- /dev/null +++ b/CPP/7zip/UI/FileManager/RootFolder.cpp @@ -0,0 +1,197 @@ +// RootFolder.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "RootFolder.h" + +#include "Common/StringConvert.h" +#include "../../PropID.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "FSDrives.h" +#include "PhysDriveFolder.h" +#include "NetFolder.h" +#include "SysIconUtils.h" +#include "LangUtils.h" + +using namespace NWindows; + + +static const STATPROPSTG kProperties[] = +{ + { NULL, kpidName, VT_BSTR} +}; + +// static const wchar_t *kMyComputerTitle = L"Computer"; +// static const wchar_t *kMyNetworkTitle = L"Network"; + +void CRootFolder::Init() +{ + _computerName = LangString(IDS_COMPUTER, 0x03020300); + _networkName = LangString(IDS_NETWORK, 0x03020301); +}; + +STDMETHODIMP CRootFolder::LoadItems() +{ + Init(); + return S_OK; +} + +STDMETHODIMP CRootFolder::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = 2; + return S_OK; +} + +STDMETHODIMP CRootFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + if (itemIndex == 0) + propVariant = _computerName; + else if (itemIndex == 1) + propVariant = _networkName; + break; + } + propVariant.Detach(value); + return S_OK; +} + +STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) +{ + if (index == 0) + { + CFSDrives *fsDrivesSpec = new CFSDrives; + CMyComPtr subFolder = fsDrivesSpec; + fsDrivesSpec->Init(); + *resultFolder = subFolder.Detach(); + } + else if (index == 1) + { + CNetFolder *netFolderSpec = new CNetFolder; + CMyComPtr subFolder = netFolderSpec; + netFolderSpec->Init(0, 0, _networkName + L'\\'); + *resultFolder = subFolder.Detach(); + } + else + return E_INVALIDARG; + return S_OK; +} + +STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + *resultFolder = 0; + UString name2 = name; + name2.Trim(); + if (name2.IsEmpty()) + { + CRootFolder *rootFolderSpec = new CRootFolder; + CMyComPtr rootFolder = rootFolderSpec; + rootFolderSpec->Init(); + *resultFolder = rootFolder.Detach(); + return S_OK; + } + if (name2 == _computerName || + name2 == (_computerName + UString(L'\\'))) + return BindToFolder(UInt32(0), resultFolder); + if (name2 == _networkName || + name2 == (_networkName + UString(L'\\'))) + return BindToFolder(UInt32(1), resultFolder); + if (name2 == UString(L'\\')) + { + CMyComPtr subFolder = this; + *resultFolder = subFolder.Detach(); + return S_OK; + } + + if (name2.Length () < 2) + return E_INVALIDARG; + + CMyComPtr subFolder; + + if (name2.Left(4) == L"\\\\.\\") + { + CPhysDriveFolder *folderSpec = new CPhysDriveFolder; + subFolder = folderSpec; + RINOK(folderSpec->Init(name2.Mid(4, 2))); + } + else + { + if (name2[name2.Length () - 1] != L'\\') + name2 += L'\\'; + NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder; + subFolder = fsFolderSpec; + if (fsFolderSpec->Init(name2, 0) != S_OK) + { + if (name2[0] == L'\\') + { + CNetFolder *netFolderSpec = new CNetFolder; + subFolder = netFolderSpec; + netFolderSpec->Init(name2); + } + else + return E_INVALIDARG; + } + } + *resultFolder = subFolder.Detach(); + return S_OK; +} + +STDMETHODIMP CRootFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + *resultFolder = 0; + return S_OK; +} + +STDMETHODIMP CRootFolder::GetNumberOfProperties(UInt32 *numProperties) +{ + *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + return S_OK; +} + +STDMETHODIMP CRootFolder::GetPropertyInfo(UInt32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + if (index >= sizeof(kProperties) / sizeof(kProperties[0])) + return E_INVALIDARG; + const STATPROPSTG &prop = kProperties[index]; + *propID = prop.propid; + *varType = prop.vt; + *name = 0; + return S_OK; +} + +STDMETHODIMP CRootFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant prop; + switch(propID) + { + case kpidType: prop = L"RootFolder"; break; + case kpidPath: prop = L""; break; + } + prop.Detach(value); + return S_OK; +} + +STDMETHODIMP CRootFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) +{ + int aCSIDL; + if (index == 0) + aCSIDL = CSIDL_DRIVES; + else + aCSIDL = CSIDL_NETWORK; + *iconIndex = GetIconIndexForCSIDL(aCSIDL); + return S_OK; +} + + + + diff --git a/CPP/7zip/UI/FileManager/RootFolder.h b/CPP/7zip/UI/FileManager/RootFolder.h new file mode 100755 index 00000000..7dad969d --- /dev/null +++ b/CPP/7zip/UI/FileManager/RootFolder.h @@ -0,0 +1,32 @@ +// RootFolder.h + +#ifndef __ROOTFOLDER_H +#define __ROOTFOLDER_H + +#include "Common/MyString.h" + +#include "Windows/PropVariant.h" + +#include "FSFolder.h" + +class CRootFolder: + public IFolderFolder, + public IFolderGetSystemIconIndex, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1( + IFolderGetSystemIconIndex + ) + + INTERFACE_FolderFolder(;) + + STDMETHOD(GetSystemIconIndex)(UInt32 index, INT32 *iconIndex); + + void Init(); +private: + UString _computerName; + UString _networkName; +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/SettingsPage.cpp b/CPP/7zip/UI/FileManager/SettingsPage.cpp new file mode 100755 index 00000000..4ce2919d --- /dev/null +++ b/CPP/7zip/UI/FileManager/SettingsPage.cpp @@ -0,0 +1,113 @@ +// SettingsPage.cpp + +#include "StdAfx.h" +#include "SettingsPageRes.h" +#include "SettingsPage.h" + +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" +#include "Windows/MemoryLock.h" + +#include "RegistryUtils.h" +#include "HelpUtils.h" +#include "LangUtils.h" +#include "ProgramLocation.h" + +using namespace NWindows; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_SETTINGS_SHOW_DOTS, 0x03010401}, + { IDC_SETTINGS_SHOW_REAL_FILE_ICONS, 0x03010402}, + { IDC_SETTINGS_SHOW_SYSTEM_MENU, 0x03010410}, + { IDC_SETTINGS_FULL_ROW, 0x03010420}, + { IDC_SETTINGS_SHOW_GRID, 0x03010421}, + { IDC_SETTINGS_ALTERNATIVE_SELECTION, 0x03010430}, + { IDC_SETTINGS_LARGE_PAGES, 0x03010440} + // { IDC_SETTINGS_SINGLE_CLICK, 0x03010422}, + // { IDC_SETTINGS_UNDERLINE, 0x03010423} +}; + +static LPCWSTR kEditTopic = L"FM/options.htm#settings"; + +extern bool IsLargePageSupported(); + +bool CSettingsPage::OnInit() +{ + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + CheckButton(IDC_SETTINGS_SHOW_DOTS, ReadShowDots()); + CheckButton(IDC_SETTINGS_SHOW_SYSTEM_MENU, ReadShowSystemMenu()); + CheckButton(IDC_SETTINGS_SHOW_REAL_FILE_ICONS, ReadShowRealFileIcons()); + + CheckButton(IDC_SETTINGS_FULL_ROW, ReadFullRow()); + CheckButton(IDC_SETTINGS_SHOW_GRID, ReadShowGrid()); + CheckButton(IDC_SETTINGS_ALTERNATIVE_SELECTION, ReadAlternativeSelection()); + if (IsLargePageSupported()) + CheckButton(IDC_SETTINGS_LARGE_PAGES, ReadLockMemoryEnable()); + else + EnableItem(IDC_SETTINGS_LARGE_PAGES, false); + // CheckButton(IDC_SETTINGS_SINGLE_CLICK, ReadSingleClick()); + // CheckButton(IDC_SETTINGS_UNDERLINE, ReadUnderline()); + + // EnableSubItems(); + + return CPropertyPage::OnInit(); +} + +/* +void CSettingsPage::EnableSubItems() +{ + EnableItem(IDC_SETTINGS_UNDERLINE, IsButtonCheckedBool(IDC_SETTINGS_SINGLE_CLICK)); +} +*/ + +LONG CSettingsPage::OnApply() +{ + SaveShowDots(IsButtonCheckedBool(IDC_SETTINGS_SHOW_DOTS)); + SaveShowSystemMenu(IsButtonCheckedBool(IDC_SETTINGS_SHOW_SYSTEM_MENU)); + SaveShowRealFileIcons(IsButtonCheckedBool(IDC_SETTINGS_SHOW_REAL_FILE_ICONS)); + + SaveFullRow(IsButtonCheckedBool(IDC_SETTINGS_FULL_ROW)); + SaveShowGrid(IsButtonCheckedBool(IDC_SETTINGS_SHOW_GRID)); + SaveAlternativeSelection(IsButtonCheckedBool(IDC_SETTINGS_ALTERNATIVE_SELECTION)); + if (IsLargePageSupported()) + { + bool enable = IsButtonCheckedBool(IDC_SETTINGS_LARGE_PAGES); + NSecurity::EnableLockMemoryPrivilege(enable); + SaveLockMemoryEnable(enable); + } + + // SaveSingleClick(IsButtonCheckedBool(IDC_SETTINGS_SINGLE_CLICK)); + // SaveUnderline(IsButtonCheckedBool(IDC_SETTINGS_UNDERLINE)); + + return PSNRET_NOERROR; +} + +void CSettingsPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kEditTopic); // change it +} + +bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + /* + case IDC_SETTINGS_SINGLE_CLICK: + EnableSubItems(); + break; + */ + case IDC_SETTINGS_SHOW_DOTS: + case IDC_SETTINGS_SHOW_SYSTEM_MENU: + case IDC_SETTINGS_SHOW_REAL_FILE_ICONS: + case IDC_SETTINGS_FULL_ROW: + case IDC_SETTINGS_SHOW_GRID: + case IDC_SETTINGS_ALTERNATIVE_SELECTION: + case IDC_SETTINGS_LARGE_PAGES: + Changed(); + return true; + } + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); +} diff --git a/CPP/7zip/UI/FileManager/SettingsPage.h b/CPP/7zip/UI/FileManager/SettingsPage.h new file mode 100755 index 00000000..e5fe6e67 --- /dev/null +++ b/CPP/7zip/UI/FileManager/SettingsPage.h @@ -0,0 +1,19 @@ +// SettingsPage.h + +#ifndef __SETTINGSPAGE_H +#define __SETTINGSPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/Edit.h" + +class CSettingsPage: public NWindows::NControl::CPropertyPage +{ + // void EnableSubItems(); + bool OnButtonClicked(int buttonID, HWND buttonHWND); +public: + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual LONG OnApply(); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/SettingsPage.rc b/CPP/7zip/UI/FileManager/SettingsPage.rc new file mode 100755 index 00000000..ddd0911b --- /dev/null +++ b/CPP/7zip/UI/FileManager/SettingsPage.rc @@ -0,0 +1,35 @@ +#include "SettingsPageRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + + +IDD_SETTINGS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Settings" +MY_FONT +BEGIN + CONTROL "Show "".."" item", IDC_SETTINGS_SHOW_DOTS, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, marg, xSize2, 10 + CONTROL "Show real file &icons", IDC_SETTINGS_SHOW_REAL_FILE_ICONS, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 21, xSize2, 10 + CONTROL "Show system &menu", IDC_SETTINGS_SHOW_SYSTEM_MENU, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 35, xSize2, 10 + CONTROL "&Full row select", IDC_SETTINGS_FULL_ROW, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 63, xSize2, 10 + CONTROL "Show &grid lines", IDC_SETTINGS_SHOW_GRID, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 77, xSize2, 10 + CONTROL "&Single-click to open an item", IDC_SETTINGS_SINGLE_CLICK, "Button", BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP, + marg, 91, xSize2, 10 + CONTROL "&Underline current name", IDC_SETTINGS_UNDERLINE, "Button", BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP, + marg + 12, 105, xSize2 - 12, 10 + + CONTROL "&Alternative selection mode", IDC_SETTINGS_ALTERNATIVE_SELECTION, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 122, xSize2, 10 + + CONTROL "Use &large memory pages", IDC_SETTINGS_LARGE_PAGES, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 142, xSize2, 10 + +END diff --git a/CPP/7zip/UI/FileManager/SettingsPageRes.h b/CPP/7zip/UI/FileManager/SettingsPageRes.h new file mode 100755 index 00000000..8932dc0e --- /dev/null +++ b/CPP/7zip/UI/FileManager/SettingsPageRes.h @@ -0,0 +1,11 @@ +#define IDD_SETTINGS 904 +#define IDC_SETTINGS_SHOW_DOTS 1000 +#define IDC_SETTINGS_SHOW_REAL_FILE_ICONS 1001 + +#define IDC_SETTINGS_SHOW_SYSTEM_MENU 1010 +#define IDC_SETTINGS_FULL_ROW 1011 +#define IDC_SETTINGS_SHOW_GRID 1013 +#define IDC_SETTINGS_SINGLE_CLICK 1014 +#define IDC_SETTINGS_UNDERLINE 1015 +#define IDC_SETTINGS_ALTERNATIVE_SELECTION 1016 +#define IDC_SETTINGS_LARGE_PAGES 1017 diff --git a/CPP/7zip/UI/FileManager/SplitDialog.cpp b/CPP/7zip/UI/FileManager/SplitDialog.cpp new file mode 100755 index 00000000..1a3770ee --- /dev/null +++ b/CPP/7zip/UI/FileManager/SplitDialog.cpp @@ -0,0 +1,89 @@ +// SplitDialog.cpp + +#include "StdAfx.h" +#include "SplitDialog.h" + +#include "Common/StringToInt.h" +#include "Windows/Shell.h" +#include "Windows/FileName.h" + +#include "SplitUtils.h" +#ifdef LANG +#include "LangUtils.h" +#endif + +#include "CopyDialogRes.h" + +using namespace NWindows; + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_SPLIT_PATH, 0x03020501 }, + { IDC_STATIC_SPLIT_VOLUME, 0x02000D40 }, +}; +#endif + + +bool CSplitDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x03020500); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + _pathCombo.Attach(GetItem(IDC_COMBO_SPLIT_PATH)); + _volumeCombo.Attach(GetItem(IDC_COMBO_SPLIT_VOLUME)); + + if (!FilePath.IsEmpty()) + { + UString title; + GetText(title); + title += L' '; + title += FilePath; + SetText(title); + } + _pathCombo.SetText(Path); + AddVolumeItems(_volumeCombo); + _volumeCombo.SetCurSel(0); + return CModalDialog::OnInit(); +} + +bool CSplitDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_BUTTON_SPLIT_PATH: + OnButtonSetPath(); + return true; + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CSplitDialog::OnButtonSetPath() +{ + UString currentPath; + _pathCombo.GetText(currentPath); + // UString title = L"Specify a location for output folder"; + UString title = LangStringSpec(IDS_SET_FOLDER, 0x03020209); + + UString resultPath; + if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + return; + NFile::NName::NormalizeDirPathPrefix(resultPath); + _pathCombo.SetCurSel(-1); + _pathCombo.SetText(resultPath); +} + +void CSplitDialog::OnOK() +{ + _pathCombo.GetText(Path); + UString volumeString; + _volumeCombo.GetText(volumeString); + volumeString.Trim(); + if (!ParseVolumeSizes(volumeString, VolumeSizes) || VolumeSizes.Size() == 0) + { + ::MessageBoxW(*this, LangString(IDS_COMPRESS_INCORRECT_VOLUME_SIZE, 0x02000D41), L"7-Zip", 0); + return; + } + CModalDialog::OnOK(); +} diff --git a/CPP/7zip/UI/FileManager/SplitDialog.h b/CPP/7zip/UI/FileManager/SplitDialog.h new file mode 100755 index 00000000..607a3daf --- /dev/null +++ b/CPP/7zip/UI/FileManager/SplitDialog.h @@ -0,0 +1,27 @@ +// SplitDialog.h + +#ifndef __SPLITDIALOG_H +#define __SPLITDIALOG_H + +#include "Common/Types.h" +#include "Windows/Control/Dialog.h" +#include "Windows/Control/ComboBox.h" +#include "SplitDialogRes.h" + +class CSplitDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox _pathCombo; + NWindows::NControl::CComboBox _volumeCombo; + virtual void OnOK(); + virtual bool OnInit(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + void OnButtonSetPath(); +public: + UString FilePath; + UString Path; + CRecordVector VolumeSizes; + INT_PTR Create(HWND parentWindow = 0) + { return CModalDialog::Create(IDD_DIALOG_SPLIT, parentWindow); } +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/SplitDialog.rc b/CPP/7zip/UI/FileManager/SplitDialog.rc new file mode 100755 index 00000000..7e78daaf --- /dev/null +++ b/CPP/7zip/UI/FileManager/SplitDialog.rc @@ -0,0 +1,32 @@ +#include "SplitDialogRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 223 +#define ySize2 89 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define bYPos (ySize - marg - bYSize) +#define b1XPos (xSize - marg - bXSize) +#define b2XPos (b1XPos - 10 - bXSize) + + + +IDD_DIALOG_SPLIT DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Split File" +MY_FONT +BEGIN + LTEXT "&Split to:", IDC_STATIC_SPLIT_PATH, marg, marg, xSize2, 8 + COMBOBOX IDC_COMBO_SPLIT_PATH, marg, 18, xSize2 - bDotsSize - 12, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...", IDC_BUTTON_SPLIT_PATH, xSize - marg - bDotsSize, 17, bDotsSize, bYSize, WS_GROUP + LTEXT "Split to &volumes, bytes:", IDC_STATIC_SPLIT_VOLUME, marg, 38, xSize2, 8 + COMBOBOX IDC_COMBO_SPLIT_VOLUME, marg, 50, 120, 52, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK", IDOK, b2XPos, bYPos, bXSize, bYSize + PUSHBUTTON "Cancel", IDCANCEL, b1XPos, bYPos, bXSize, bYSize +END + +STRINGTABLE +BEGIN + IDS_COMPRESS_INCORRECT_VOLUME_SIZE "Incorrect volume size" +END diff --git a/CPP/7zip/UI/FileManager/SplitDialogRes.h b/CPP/7zip/UI/FileManager/SplitDialogRes.h new file mode 100755 index 00000000..019b7029 --- /dev/null +++ b/CPP/7zip/UI/FileManager/SplitDialogRes.h @@ -0,0 +1,8 @@ +#define IDD_DIALOG_SPLIT 504 +#define IDC_STATIC_SPLIT_PATH 1000 +#define IDC_COMBO_SPLIT_PATH 1001 +#define IDC_BUTTON_SPLIT_PATH 1002 +#define IDC_STATIC_SPLIT_VOLUME 1010 +#define IDC_COMBO_SPLIT_VOLUME 1011 + +#define IDS_COMPRESS_INCORRECT_VOLUME_SIZE 95 diff --git a/CPP/7zip/UI/FileManager/SplitUtils.cpp b/CPP/7zip/UI/FileManager/SplitUtils.cpp new file mode 100755 index 00000000..3a7635fa --- /dev/null +++ b/CPP/7zip/UI/FileManager/SplitUtils.cpp @@ -0,0 +1,85 @@ +// SplitUtils.cpp + +#include "StdAfx.h" + +#include "Common/StringToInt.h" + +#include "SplitUtils.h" +#include "StringUtils.h" + +bool ParseVolumeSizes(const UString &s, CRecordVector &values) +{ + values.Clear(); + UStringVector destStrings; + SplitString(s, destStrings); + bool prevIsNumber = false; + for (int i = 0; i < destStrings.Size(); i++) + { + UString subString = destStrings[i]; + subString.MakeUpper(); + if (subString.IsEmpty()) + return false; + if (subString == L"-") + return true; + if (prevIsNumber) + { + wchar_t c = subString[0]; + UInt64 &value = values.Back(); + prevIsNumber = false; + switch(c) + { + case L'B': + continue; + case L'K': + value <<= 10; + continue; + case L'M': + value <<= 20; + continue; + case L'G': + value <<= 30; + continue; + } + } + const wchar_t *start = subString; + const wchar_t *end; + UInt64 value = ConvertStringToUInt64(start, &end); + if (start == end) + return false; + if (value == 0) + return false; + values.Add(value); + prevIsNumber = true; + UString rem = subString.Mid((int)(end - start)); + if (!rem.IsEmpty()) + destStrings.Insert(i + 1, rem); + } + return true; +} + +void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo) +{ + volumeCombo.AddString(TEXT("1457664 - 3.5\" floppy")); + volumeCombo.AddString(TEXT("650M - CD")); + volumeCombo.AddString(TEXT("700M - CD")); + volumeCombo.AddString(TEXT("4480M - DVD")); +} + +UInt64 GetNumberOfVolumes(UInt64 size, CRecordVector &volSizes) +{ + if (size == 0 || volSizes.Size() == 0) + return 1; + UInt64 numVolumes = 0; + for (int i = 0; i < volSizes.Size(); i++) + { + UInt64 volSize = volSizes[i]; + numVolumes++; + if (volSize >= size) + return numVolumes; + size -= volSize; + } + UInt64 volSize = volSizes.Back(); + if (volSize == 0) + return (UInt64)(Int64)-1; + return numVolumes + (size - 1) / volSize + 1; +} diff --git a/CPP/7zip/UI/FileManager/SplitUtils.h b/CPP/7zip/UI/FileManager/SplitUtils.h new file mode 100755 index 00000000..755c707c --- /dev/null +++ b/CPP/7zip/UI/FileManager/SplitUtils.h @@ -0,0 +1,15 @@ +// SplitUtils.h + +#ifndef __SPLITUTILS_H +#define __SPLITUTILS_H + +#include "Common/MyString.h" +#include "Common/Types.h" +#include "Windows/Control/ComboBox.h" + +bool ParseVolumeSizes(const UString &s, CRecordVector &values); +void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo); + +UInt64 GetNumberOfVolumes(UInt64 size, CRecordVector &volSizes); + +#endif diff --git a/CPP/7zip/UI/FileManager/StdAfx.cpp b/CPP/7zip/UI/FileManager/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/FileManager/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/FileManager/StdAfx.h b/CPP/7zip/UI/FileManager/StdAfx.h new file mode 100755 index 00000000..b09de592 --- /dev/null +++ b/CPP/7zip/UI/FileManager/StdAfx.h @@ -0,0 +1,23 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 + +// it's for Windows NT supporting (MENUITEMINFOW) +#define WINVER 0x0400 + +#include +#include +#include +#include +#include +#include +#include + +// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/FileManager/StringUtils.cpp b/CPP/7zip/UI/FileManager/StringUtils.cpp new file mode 100755 index 00000000..63eebdba --- /dev/null +++ b/CPP/7zip/UI/FileManager/StringUtils.cpp @@ -0,0 +1,68 @@ +// StringUtils.cpp + +#include "StdAfx.h" + +#include "StringUtils.h" + +void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2) +{ + dest1.Empty(); + dest2.Empty(); + bool quoteMode = false; + int i; + for (i = 0; i < src.Length(); i++) + { + wchar_t c = src[i]; + if (c == L'\"') + quoteMode = !quoteMode; + else if (c == L' ' && !quoteMode) + { + if (!quoteMode) + { + i++; + break; + } + } + else + dest1 += c; + } + dest2 = src.Mid(i); +} + +void SplitString(const UString &srcString, UStringVector &destStrings) +{ + destStrings.Clear(); + UString string; + int len = srcString.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L' ') + { + if (!string.IsEmpty()) + { + destStrings.Add(string); + string.Empty(); + } + } + else + string += c; + } + if (!string.IsEmpty()) + destStrings.Add(string); +} + +UString JoinStrings(const UStringVector &srcStrings) +{ + UString destString; + for (int i = 0; i < srcStrings.Size(); i++) + { + if (i != 0) + destString += L' '; + destString += srcStrings[i]; + } + return destString; +} + diff --git a/CPP/7zip/UI/FileManager/StringUtils.h b/CPP/7zip/UI/FileManager/StringUtils.h new file mode 100755 index 00000000..7f72b764 --- /dev/null +++ b/CPP/7zip/UI/FileManager/StringUtils.h @@ -0,0 +1,13 @@ +// StringUtils.h + +#ifndef __STRINGUTILS_H +#define __STRINGUTILS_H + +#include "Common/MyString.h" + +void SplitStringToTwoStrings(const UString &src, UString &dest1, UString &dest2); + +void SplitString(const UString &srcString, UStringVector &destStrings); +UString JoinStrings(const UStringVector &srcStrings); + +#endif diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/CPP/7zip/UI/FileManager/SysIconUtils.cpp new file mode 100755 index 00000000..0d337550 --- /dev/null +++ b/CPP/7zip/UI/FileManager/SysIconUtils.cpp @@ -0,0 +1,157 @@ +// SysIconUtils.h + +#include "StdAfx.h" + +#include "SysIconUtils.h" +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +int GetIconIndexForCSIDL(int aCSIDL) +{ + LPITEMIDLIST pidlMyComputer = 0; + SHGetSpecialFolderLocation(NULL, aCSIDL, &pidlMyComputer); + if (pidlMyComputer) + { + SHFILEINFO shellInfo; + SHGetFileInfo(LPCTSTR(pidlMyComputer), FILE_ATTRIBUTE_NORMAL, + &shellInfo, sizeof(shellInfo), + SHGFI_PIDL | SHGFI_SYSICONINDEX); + IMalloc *pMalloc; + SHGetMalloc(&pMalloc); + if(pMalloc) + { + pMalloc->Free(pidlMyComputer); + pMalloc->Release(); + } + return shellInfo.iIcon; + } + return 0; +} + +DWORD_PTR GetRealIconIndex(LPCTSTR path, UINT32 attributes, int &iconIndex) +{ + SHFILEINFO shellInfo; + DWORD_PTR res = ::SHGetFileInfo(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + iconIndex = shellInfo.iIcon; + return res; +} + + +#ifndef _UNICODE +typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags); + +struct CSHGetFileInfoInit +{ + SHGetFileInfoWP shGetFileInfoW; + CSHGetFileInfoInit() + { + shGetFileInfoW = (SHGetFileInfoWP) + ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHGetFileInfoW"); + } +} g_SHGetFileInfoInit; +#endif + +DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags) +{ + #ifdef _UNICODE + return SHGetFileInfoW( + #else + if (g_SHGetFileInfoInit.shGetFileInfoW == 0) + return 0; + return g_SHGetFileInfoInit.shGetFileInfoW( + #endif + pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags); +} + +#ifndef _UNICODE +// static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } +DWORD_PTR GetRealIconIndex(LPCWSTR path, UINT32 attributes, int &iconIndex) +{ + if(g_IsNT) + { + SHFILEINFOW shellInfo; + DWORD_PTR res = ::MySHGetFileInfoW(path, FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + iconIndex = shellInfo.iIcon; + return res; + } + else + return GetRealIconIndex(UnicodeStringToMultiByte(path), attributes, iconIndex); +} +#endif + +DWORD_PTR GetRealIconIndex(const UString &fileName, UINT32 attributes, + int &iconIndex, UString &typeName) +{ + #ifndef _UNICODE + if(!g_IsNT) + { + SHFILEINFO shellInfo; + shellInfo.szTypeName[0] = 0; + DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_NORMAL | attributes, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX + | SHGFI_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 | attributes, &shellInfo, + sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX + | SHGFI_TYPENAME); + typeName = shellInfo.szTypeName; + iconIndex = shellInfo.iIcon; + return res; + } +} + +int CExtToIconMap::GetIconIndex(UINT32 attributes, const UString &fileNameSpec, UString &typeName) +{ + UString fileName = fileNameSpec; + if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + { + fileName = L"__Fldr__"; + if (_dirIconIndex < 0) + GetRealIconIndex(fileName, attributes, _dirIconIndex, _dirTypeName); + typeName = _dirTypeName; + return _dirIconIndex; + } + int dotPos = fileName.ReverseFind('.'); + if (dotPos < 0) + { + fileName = L"__File__"; + if (_noExtIconIndex < 0) + { + int iconIndexTemp; + GetRealIconIndex(fileName, attributes, iconIndexTemp, _noExtTypeName); + } + typeName = _noExtTypeName; + return _noExtIconIndex; + } + CExtIconPair extIconPair; + extIconPair.Ext = fileName.Mid(dotPos + 1); + int anIndex = _map.FindInSorted(extIconPair); + if (anIndex >= 0) + return _map[anIndex].IconIndex; + fileName = fileName.Mid(dotPos); + GetRealIconIndex(fileName, attributes, extIconPair.IconIndex, extIconPair.TypeName); + _map.AddToSorted(extIconPair); + typeName = extIconPair.TypeName; + return extIconPair.IconIndex; +} + +int CExtToIconMap::GetIconIndex(UINT32 attributes, const UString &fileName) +{ + UString typeName; + return GetIconIndex(attributes, fileName, typeName); +} diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.h b/CPP/7zip/UI/FileManager/SysIconUtils.h new file mode 100755 index 00000000..3b6c6c2e --- /dev/null +++ b/CPP/7zip/UI/FileManager/SysIconUtils.h @@ -0,0 +1,51 @@ +// SysIconUtils.h + +#ifndef __SYSICONUTILS_H +#define __SYSICONUTILS_H + +#include "Common/MyString.h" + +struct CExtIconPair +{ + UString Ext; + int IconIndex; + UString TypeName; + +}; + +inline bool operator==(const CExtIconPair &a1, const CExtIconPair &a2) +{ + return (a1.Ext == a2.Ext); +} + +inline bool operator<(const CExtIconPair &a1, const CExtIconPair &a2) +{ + return (a1.Ext < a2.Ext); +} + +class CExtToIconMap +{ + int _dirIconIndex; + UString _dirTypeName; + int _noExtIconIndex; + UString _noExtTypeName; + CObjectVector _map; +public: + CExtToIconMap(): _dirIconIndex(-1), _noExtIconIndex(-1) {} + void Clear() + { + _dirIconIndex = -1; + _noExtIconIndex = -1; + _map.Clear(); + } + int GetIconIndex(UINT32 attributes, const UString &fileName, UString &typeName); + int GetIconIndex(UINT32 attributes, const UString &fileName); +}; + +DWORD_PTR GetRealIconIndex(LPCTSTR path, UINT32 attributes, int &iconIndex); +#ifndef _UNICODE +DWORD_PTR GetRealIconIndex(LPCWSTR path, UINT32 attributes, int &iconIndex); +#endif +int GetIconIndexForCSIDL(int aCSIDL); + +#endif diff --git a/CPP/7zip/UI/FileManager/SystemPage.cpp b/CPP/7zip/UI/FileManager/SystemPage.cpp new file mode 100755 index 00000000..40da5cb3 --- /dev/null +++ b/CPP/7zip/UI/FileManager/SystemPage.cpp @@ -0,0 +1,437 @@ +// SystemPage.cpp + +#include "StdAfx.h" +#include "SystemPageRes.h" +#include "SystemPage.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" + +#include "Windows/Defs.h" +#include "Windows/Control/ListView.h" +#include "Windows/FileFind.h" + +#include "IFolder.h" +#include "HelpUtils.h" +#include "LangUtils.h" +#include "PluginLoader.h" +#include "ProgramLocation.h" +#include "StringUtils.h" + +#include "PropertyNameRes.h" +#include "../Agent/Agent.h" + +using namespace NRegistryAssociations; + +const int kRefreshpluginsListMessage = WM_USER + 1; +const int kUpdateDatabase = kRefreshpluginsListMessage + 1; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_SYSTEM_STATIC_ASSOCIATE, 0x03010302}, + { IDC_SYSTEM_SELECT_ALL, 0x03000330} +}; + +static LPCWSTR kSystemTopic = L"FM/options.htm#system"; + + +bool CSystemPage::OnInit() +{ + _initMode = true; + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + _listViewExt.Attach(GetItem(IDC_SYSTEM_LIST_ASSOCIATE)); + _listViewPlugins.Attach(GetItem(IDC_SYSTEM_LIST_PLUGINS)); + + /* + CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, + NRegistryAssociations::CheckContextMenuHandler()); + */ + + UINT32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT; + _listViewExt.SetExtendedListViewStyle(newFlags, newFlags); + _listViewPlugins.SetExtendedListViewStyle(newFlags, newFlags); + + UString s = LangString(IDS_PROPERTY_EXTENSION, 0x02000205); + LVCOLUMNW column; + column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM; + column.cx = 70; + column.fmt = LVCFMT_LEFT; + column.pszText = (LPWSTR)(LPCWSTR)s; + column.iSubItem = 0; + _listViewExt.InsertColumn(0, &column); + + s = LangString(IDS_PLUGIN, 0x03010310); + column.cx = 70; + column.pszText = (LPWSTR)(LPCWSTR)s; + column.iSubItem = 1; + _listViewExt.InsertColumn(1, &column); + + s = LangString(IDS_PLUGIN, 0x03010310); + column.cx = 70; + column.pszText = (LPWSTR)(LPCWSTR)s; + column.iSubItem = 0; + _listViewPlugins.InsertColumn(0, &column); + + _extDatabase.Read(); + + for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++) + { + CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i]; + + LVITEMW item; + item.iItem = i; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.lParam = i; + item.pszText = (LPWSTR)(LPCWSTR)extInfo.Ext; + item.iSubItem = 0; + int itemIndex = _listViewExt.InsertItem(&item); + + UString iconPath; + int iconIndex; + extInfo.Associated = NRegistryAssociations::CheckShellExtensionInfo(GetSystemString(extInfo.Ext), iconPath, iconIndex); + if (extInfo.Associated && !NWindows::NFile::NFind::DoesFileExist(iconPath)) + extInfo.Associated = false; + _listViewExt.SetCheckState(itemIndex, extInfo.Associated); + + SetMainPluginText(itemIndex, i); + } + // _listViewExt.SortItems(); + + if(_listViewExt.GetItemCount() > 0) + { + UINT state = LVIS_SELECTED | LVIS_FOCUSED; + _listViewExt.SetItemState(0, state, state); + } + RefreshPluginsList(-1); + _initMode = false; + + return CPropertyPage::OnInit(); +} + +void CSystemPage::SetMainPluginText(int itemIndex, int indexInDatabase) +{ + LVITEMW item; + item.iItem = itemIndex; + item.mask = LVIF_TEXT; + UString mainPlugin = _extDatabase.GetMainPluginNameForExtItem(indexInDatabase); + item.pszText = (WCHAR *)(const WCHAR *)mainPlugin; + item.iSubItem = 1; + _listViewExt.SetItem(&item); +} + +static UString GetProgramCommand() +{ + UString path = L"\""; + UString folder; + if (GetProgramFolderPath(folder)) + path += folder; + path += L"7zFM.exe\" \"%1\""; + return path; +} + +static UString GetIconPath(const UString &filePath, + const CLSID &clsID, const UString &extension, Int32 &iconIndex) +{ + CPluginLibrary library; + CMyComPtr folderManager; + CMyComPtr folder; + if (filePath.IsEmpty()) + folderManager = new CArchiveFolderManager; + else if (library.LoadAndCreateManager(filePath, clsID, &folderManager) != S_OK) + return UString(); + CMyComBSTR extBSTR; + if (folderManager->GetExtensions(&extBSTR) != S_OK) + return UString(); + const UString ext2 = (const wchar_t *)extBSTR; + UStringVector exts; + SplitString(ext2, exts); + for (int i = 0; i < exts.Size(); i++) + { + const UString &plugExt = exts[i]; + if (extension.CompareNoCase((const wchar_t *)plugExt) == 0) + { + CMyComBSTR iconPathTemp; + if (folderManager->GetIconPath(plugExt, &iconPathTemp, &iconIndex) != S_OK) + break; + if (iconPathTemp != 0) + return (const wchar_t *)iconPathTemp; + } + } + return UString(); +} + +LONG CSystemPage::OnApply() +{ + UpdateDatabase(); + _extDatabase.Save(); + UString command = GetProgramCommand(); + + for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++) + { + const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i]; + if (extInfo.Associated) + { + UString title = extInfo.Ext + UString(L" Archive"); + UString command = GetProgramCommand(); + UString iconPath; + Int32 iconIndex = -1; + if (!extInfo.PluginsPairs.IsEmpty()) + { + const CPluginInfo &plugin = _extDatabase.Plugins[extInfo.PluginsPairs[0].Index]; + iconPath = GetIconPath(plugin.FilePath, plugin.ClassID, extInfo.Ext, iconIndex); + } + NRegistryAssociations::AddShellExtensionInfo(GetSystemString(extInfo.Ext), + title, command, iconPath, iconIndex, NULL, 0); + } + else + NRegistryAssociations::DeleteShellExtensionInfo(GetSystemString(extInfo.Ext)); + } + /* + if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU)) + NRegistryAssociations::AddContextMenuHandler(); + else + NRegistryAssociations::DeleteContextMenuHandler(); + */ + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); + return PSNRET_NOERROR; +} + +void CSystemPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kSystemTopic); +} + +void CSystemPage::SelectAll() +{ + int count = _listViewExt.GetItemCount(); + for (int i = 0; i < count; i++) + _listViewExt.SetCheckState(i, true); + UpdateDatabase(); +} + +bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_SYSTEM_SELECT_ALL: + { + SelectAll(); + Changed(); + return true; + } + } + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); +} + +bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam) +{ + if (lParam->hwndFrom == HWND(_listViewExt)) + { + switch(lParam->code) + { + case (LVN_ITEMCHANGED): + return OnItemChanged((const NMLISTVIEW *)lParam); + case NM_RCLICK: + case NM_DBLCLK: + case LVN_KEYDOWN: + case NM_CLICK: + case LVN_BEGINRDRAG: + PostMessage(kRefreshpluginsListMessage, 0); + PostMessage(kUpdateDatabase, 0); + break; + } + } + else if (lParam->hwndFrom == HWND(_listViewPlugins)) + { + switch(lParam->code) + { + case NM_RCLICK: + case NM_DBLCLK: + // case LVN_KEYDOWN: + case NM_CLICK: + case LVN_BEGINRDRAG: + PostMessage(kUpdateDatabase, 0); + break; + + case (LVN_ITEMCHANGED): + { + OnItemChanged((const NMLISTVIEW *)lParam); + PostMessage(kUpdateDatabase, 0); + break; + } + case LVN_KEYDOWN: + { + OnPluginsKeyDown((LPNMLVKEYDOWN)lParam); + PostMessage(kUpdateDatabase, 0); + break; + } + } + } + return CPropertyPage::OnNotify(controlID, lParam); +} + +bool CSystemPage::OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo) +{ + bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0; + // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; + switch(keyDownInfo->wVKey) + { + case VK_UP: + { + if (alt) + MovePlugin(true); + return true; + } + case VK_DOWN: + { + if (alt) + MovePlugin(false); + return true; + } + } + return false; +} + +void CSystemPage::MovePlugin(bool upDirection) +{ + int selectedPlugin = _listViewPlugins.GetSelectionMark(); + if (selectedPlugin < 0) + return; + int newIndex = selectedPlugin + (upDirection ? -1: 1); + if (newIndex < 0 || newIndex >= _listViewPlugins.GetItemCount()) + return; + int selectedExtIndex = GetSelectedExtIndex(); + if (selectedExtIndex < 0) + return; + CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; + CPluginEnabledPair pluginPairTemp = extInfo.PluginsPairs[newIndex]; + extInfo.PluginsPairs[newIndex] = extInfo.PluginsPairs[selectedPlugin]; + extInfo.PluginsPairs[selectedPlugin] = pluginPairTemp; + + SetMainPluginText(_listViewExt.GetSelectionMark(), selectedExtIndex); + RefreshPluginsList(newIndex); + + Changed(); +} + +bool CSystemPage::OnItemChanged(const NMLISTVIEW *info) +{ + if (_initMode) + return true; + if ((info->uChanged & LVIF_STATE) != 0) + { + UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK; + UINT newState = info->uNewState & LVIS_STATEIMAGEMASK; + if (oldState != newState) + Changed(); + } + // PostMessage(kRefreshpluginsListMessage, 0); + // RefreshPluginsList(); + return true; +} + +bool CSystemPage::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) + { + case kRefreshpluginsListMessage: + RefreshPluginsList(-1); + return true; + case kUpdateDatabase: + UpdateDatabase(); + return true; + } + return CPropertyPage::OnMessage(message, wParam, lParam); +} + +void CSystemPage::UpdateDatabase() +{ + int i; + for (i = 0; i < _listViewExt.GetItemCount(); i++) + { + LPARAM param; + if (!_listViewExt.GetItemParam(i, param)) + return; + CExtInfoBig &extInfo = _extDatabase.ExtBigItems[(int)param]; + extInfo.Associated = _listViewExt.GetCheckState(i); + } + + int selectedExtIndex = GetSelectedExtIndex(); + if (selectedExtIndex < 0) + return; + + CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; + for (i = 0; i < _listViewPlugins.GetItemCount(); i++) + { + extInfo.PluginsPairs[i].Enabled = _listViewPlugins.GetCheckState(i); + } +} + + + +int CSystemPage::GetSelectedExtIndex() +{ + int selectedIndex = _listViewExt.GetSelectionMark(); + if (selectedIndex < 0) + return -1; + LPARAM param; + if (!_listViewExt.GetItemParam(selectedIndex, param)) + return -1; + return (int)param; +} + + +void CSystemPage::RefreshPluginsList(int selectIndex) +{ + _listViewPlugins.DeleteAllItems(); + int selectedExtIndex = GetSelectedExtIndex(); + if (selectedExtIndex < 0) + return; + const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex]; + + _initMode = true; + for (int i = 0; i < extInfo.PluginsPairs.Size(); i++) + { + CPluginEnabledPair pluginPair = extInfo.PluginsPairs[i]; + UString pluginName = _extDatabase.Plugins[pluginPair.Index].Name; + LVITEMW item; + item.iItem = i; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.lParam = i; + item.pszText = (LPWSTR)(LPCWSTR)pluginName; + item.iSubItem = 0; + int itemIndex = _listViewPlugins.InsertItem(&item); + _listViewPlugins.SetCheckState(itemIndex, pluginPair.Enabled); + } + if(_listViewPlugins.GetItemCount() > 0) + { + if (selectIndex < 0) + selectIndex = 0; + UINT state = LVIS_SELECTED | LVIS_FOCUSED; + _listViewPlugins.SetItemState(selectIndex, state, state); + } + _initMode = false; +} + + + +/* +static BYTE kZipShellNewData[] = + { 0x50-1, 0x4B, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0 }; + +static BYTE kRarShellNewData[] = + { 0x52-1, 0x61, 0x72, 0x21, 0x1A, 7, 0, 0xCF, 0x90, 0x73, 0, 0, 0x0D, 0, 0, 0, 0, 0, 0, 0}; + +class CSignatureMaker +{ +public: + CSignatureMaker() + { + kZipShellNewData[0]++; + kRarShellNewData[0]++; + }; +}; + +static CSignatureMaker g_SignatureMaker; +*/ diff --git a/CPP/7zip/UI/FileManager/SystemPage.h b/CPP/7zip/UI/FileManager/SystemPage.h new file mode 100755 index 00000000..1b5891f6 --- /dev/null +++ b/CPP/7zip/UI/FileManager/SystemPage.h @@ -0,0 +1,40 @@ +// SystemPage.h + +#ifndef __SYSTEMPAGE_H +#define __SYSTEMPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/ListView.h" + +#include "FilePlugins.h" + +class CSystemPage: public NWindows::NControl::CPropertyPage +{ + bool _initMode; + CExtDatabase _extDatabase; + + // CObjectVector m_Archivers; + NWindows::NControl::CListView _listViewExt; + NWindows::NControl::CListView _listViewPlugins; + + void SetMainPluginText(int itemIndex, int indexInDatabase); + + int GetSelectedExtIndex(); + void RefreshPluginsList(int selectIndex); + void MovePlugin(bool upDirection); + void UpdateDatabase(); + void SelectAll(); + +public: + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnNotify(UINT controlID, LPNMHDR lParam); + virtual bool OnItemChanged(const NMLISTVIEW *info); + + virtual LONG OnApply(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + bool OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/SystemPage.rc b/CPP/7zip/UI/FileManager/SystemPage.rc new file mode 100755 index 00000000..f881f612 --- /dev/null +++ b/CPP/7zip/UI/FileManager/SystemPage.rc @@ -0,0 +1,28 @@ +#include "SystemPageRes.h" +#include "../../GuiCommon.rc" + +#define xSize2 238 +#define ySize2 214 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) +#define gSpace 30 +#define g0Size 160 +#define gYSize (ySize2 - 20 - bYSize) + + +IDD_SYSTEM DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "System" +MY_FONT +BEGIN + LTEXT "Associate 7-Zip with:", IDC_SYSTEM_STATIC_ASSOCIATE, marg, marg, xSize2, 8 + CONTROL "List1", IDC_SYSTEM_LIST_ASSOCIATE, "SysListView32", + LVS_LIST | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP, + marg, 20, g0Size, gYSize + PUSHBUTTON "Select all", IDC_SYSTEM_SELECT_ALL, marg, (ySize - marg - bYSize), 90, bYSize + +END + +STRINGTABLE +BEGIN + IDS_PLUGIN "Plugin" +END diff --git a/CPP/7zip/UI/FileManager/SystemPageRes.h b/CPP/7zip/UI/FileManager/SystemPageRes.h new file mode 100755 index 00000000..8dce778b --- /dev/null +++ b/CPP/7zip/UI/FileManager/SystemPageRes.h @@ -0,0 +1,7 @@ +#define IDD_SYSTEM 902 +#define IDS_PLUGIN 990 +// #define IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 1010 +#define IDC_SYSTEM_STATIC_ASSOCIATE 1020 +#define IDC_SYSTEM_LIST_ASSOCIATE 1021 +#define IDC_SYSTEM_LIST_PLUGINS 1022 +#define IDC_SYSTEM_SELECT_ALL 1023 diff --git a/CPP/7zip/UI/FileManager/Test.bmp b/CPP/7zip/UI/FileManager/Test.bmp new file mode 100755 index 00000000..ef85ba23 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Test.bmp differ diff --git a/CPP/7zip/UI/FileManager/Test2.bmp b/CPP/7zip/UI/FileManager/Test2.bmp new file mode 100755 index 00000000..99b7dbf0 Binary files /dev/null and b/CPP/7zip/UI/FileManager/Test2.bmp differ diff --git a/CPP/7zip/UI/FileManager/TextPairs.cpp b/CPP/7zip/UI/FileManager/TextPairs.cpp new file mode 100755 index 00000000..76c97b8c --- /dev/null +++ b/CPP/7zip/UI/FileManager/TextPairs.cpp @@ -0,0 +1,216 @@ +// Common/TextPairs.cpp + +#include "StdAfx.h" + +#include "TextPairs.h" + +#include "Common/Defs.h" +#include "Common/UTFConvert.h" + +static const wchar_t kNewLineChar = '\n'; + +static const wchar_t kSpaceChar = ' '; +static const wchar_t kTabChar = '\t'; + +static const wchar_t kQuoteChar = '\"'; +static const wchar_t kEndOfLine = '\0'; + +static const wchar_t kBOM = wchar_t(0xFEFF); + +static bool IsSeparatorChar(wchar_t c) +{ + return (c == kSpaceChar || c == kTabChar); +} + +static UString GetIDString(const wchar_t *srcString, int &finishPos) +{ + UString result; + bool quotes = false; + for (finishPos = 0;;) + { + wchar_t c = srcString[finishPos]; + if (c == kEndOfLine) + break; + finishPos++; + bool isSeparatorChar = IsSeparatorChar(c); + if (c == kNewLineChar || (isSeparatorChar && !quotes) + || (c == kQuoteChar && quotes)) + break; + else if (c == kQuoteChar) + quotes = true; + else + result += c; + } + result.Trim(); + return result; +} + +static UString GetValueString(const wchar_t *srcString, int &finishPos) +{ + UString result; + for (finishPos = 0;;) + { + wchar_t c = srcString[finishPos]; + if (c == kEndOfLine) + break; + finishPos++; + if (c == kNewLineChar) + break; + result += c; + } + result.Trim(); + return result; +} + +static bool GetTextPairs(const UString &srcString, CObjectVector &pairs) +{ + pairs.Clear(); + UString srcString2 = srcString; + srcString2.Replace(L"\x0D", L""); + + pairs.Clear(); + int pos = 0; + + ///////////////////// + // read strings + + if (srcString2.Length() > 0) + { + if (srcString2[0] == kBOM) + pos++; + } + while (pos < srcString2.Length()) + { + int finishPos; + UString id = GetIDString((const wchar_t *)srcString2 + pos, finishPos); + pos += finishPos; + if (id.IsEmpty()) + continue; + UString value = GetValueString((const wchar_t *)srcString2 + pos, finishPos); + pos += finishPos; + if (!id.IsEmpty()) + { + CTextPair pair; + pair.ID = id; + pair.Value = value; + pairs.Add(pair); + } + } + return true; +} + +int FindItem(const CObjectVector &pairs, const UString &id) +{ + for (int i = 0; i < pairs.Size(); i++) + if (pairs[i].ID.CompareNoCase(id) == 0) + return i; + return -1; +} + +UString GetTextConfigValue(const CObjectVector &pairs, const UString &id) +{ + int index = FindItem(pairs, id); + if (index < 0) + return UString(); + return pairs[index].Value; +} + +static int ComparePairIDs(const UString &s1, const UString &s2) + { return s1.CompareNoCase(s2); } +static int ComparePairItems(const CTextPair &p1, const CTextPair &p2) + { return ComparePairIDs(p1.ID, p2.ID); } + +// typedef void* MY_PVOID; + +// static int ComparePairItems(const MY_PVOID *a1, const MY_PVOID *a2, void *param) +static int ComparePairItems(void *const *a1, void *const *a2, void * /* param */) + { return ComparePairItems(**(const CTextPair **)a1, **(const CTextPair **)a2); } + +void CPairsStorage::Sort() + { Pairs.Sort(ComparePairItems, 0); } + +int CPairsStorage::FindID(const UString &id, int &insertPos) +{ + int left = 0, right = Pairs.Size(); + while (left != right) + { + UINT32 mid = (left + right) / 2; + int compResult = ComparePairIDs(id, Pairs[mid].ID); + if (compResult == 0) + return mid; + if (compResult < 0) + right = mid; + else + left = mid + 1; + } + insertPos = left; + return -1; +} + +int CPairsStorage::FindID(const UString &id) +{ + int pos; + return FindID(id, pos); +} + +void CPairsStorage::AddPair(const CTextPair &pair) +{ + int insertPos; + int pos = FindID(pair.ID, insertPos); + if (pos >= 0) + Pairs[pos] = pair; + else + Pairs.Insert(insertPos, pair); +} + +void CPairsStorage::DeletePair(const UString &id) +{ + int pos = FindID(id); + if (pos >= 0) + Pairs.Delete(pos); +} + +bool CPairsStorage::GetValue(const UString &id, UString &value) +{ + value.Empty(); + int pos = FindID(id); + if (pos < 0) + return false; + value = Pairs[pos].Value; + return true; +} + +UString CPairsStorage::GetValue(const UString &id) +{ + int pos = FindID(id); + if (pos < 0) + return UString(); + return Pairs[pos].Value; +} + +bool CPairsStorage::ReadFromString(const UString &text) +{ + bool result = ::GetTextPairs(text, Pairs); + if (result) + Sort(); + else + Pairs.Clear(); + return result; +} + +void CPairsStorage::SaveToString(UString &text) +{ + for (int i = 0; i < Pairs.Size(); i++) + { + const CTextPair &pair = Pairs[i]; + bool multiWord = (pair.ID.Find(L' ') >= 0); + if (multiWord) + text += L'\"'; + text += pair.ID; + if (multiWord) + text += L'\"'; + text += L' '; + text += pair.Value; + text += L'\n'; + } +} diff --git a/CPP/7zip/UI/FileManager/TextPairs.h b/CPP/7zip/UI/FileManager/TextPairs.h new file mode 100755 index 00000000..b75d9c72 --- /dev/null +++ b/CPP/7zip/UI/FileManager/TextPairs.h @@ -0,0 +1,31 @@ +// Common/TextPairs.h + +#ifndef __COMMON_TEXTPAIRS_H +#define __COMMON_TEXTPAIRS_H + +#include "Common/MyString.h" + +struct CTextPair +{ + UString ID; + UString Value; +}; + +class CPairsStorage +{ + CObjectVector Pairs; + int FindID(const UString &id, int &insertPos); + int FindID(const UString &id); + void Sort(); +public: + void Clear() { Pairs.Clear(); }; + bool ReadFromString(const UString &text); + void SaveToString(UString &text); + + bool GetValue(const UString &id, UString &value); + UString GetValue(const UString &id); + void AddPair(const CTextPair &pair); + void DeletePair(const UString &id); +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.cpp b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp new file mode 100755 index 00000000..927d3cd5 --- /dev/null +++ b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp @@ -0,0 +1,106 @@ +// UpdateCallback.h + +#include "StdAfx.h" + +#include "Common/StringConvert.h" + +#include "UpdateCallback100.h" +// #include "Windows/ProcessMessages.h" +// #include "Resource/PasswordDialog/PasswordDialog.h" +#include "MessagesDialog.h" + +#include "Common/Defs.h" + +using namespace NWindows; + +CUpdateCallback100Imp::~CUpdateCallback100Imp() +{ + if (ShowMessages && !Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &Messages; + messagesDialog.Create(_parentWindow); + } +} + +void CUpdateCallback100Imp::AddErrorMessage(LPCWSTR message) +{ + Messages.Add(message); +} + +STDMETHODIMP CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles) +{ + ProgressDialog.ProgressSynch.SetNumFilesTotal(numFiles); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::SetTotal(UInt64 size) +{ + ProgressDialog.ProgressSynch.SetProgress(size, 0); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UInt64 *completeValue) +{ + for (;;) + { + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + if(!ProgressDialog.ProgressSynch.GetPaused()) + break; + ::Sleep(100); + } + if (completeValue != NULL) + ProgressDialog.ProgressSynch.SetPos(*completeValue); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) +{ + ProgressDialog.ProgressSynch.SetRatioInfo(inSize, outSize); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *name) +{ + ProgressDialog.ProgressSynch.SetCurrentFileName(name); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t * /* name */) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::OperationResult(Int32 /* operationResult */) +{ + NumFiles++; + ProgressDialog.ProgressSynch.SetNumFilesCur(NumFiles); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message) +{ + AddErrorMessage(message); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + *passwordIsDefined = BoolToInt(_passwordIsDefined); + if (!_passwordIsDefined) + { + return S_OK; + /* + CPasswordDialog dialog; + if (dialog.Create(_parentWindow) == IDCANCEL) + return E_ABORT; + _password = dialog._password; + _passwordIsDefined = true; + */ + } + *passwordIsDefined = BoolToInt(_passwordIsDefined); + CMyComBSTR tempName = _password; + *password = tempName.Detach(); + return S_OK; +} diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.h b/CPP/7zip/UI/FileManager/UpdateCallback100.h new file mode 100755 index 00000000..fd75bf2f --- /dev/null +++ b/CPP/7zip/UI/FileManager/UpdateCallback100.h @@ -0,0 +1,74 @@ +// UpdateCallback100.h + +#ifndef __UPDATE_CALLBACK100_H +#define __UPDATE_CALLBACK100_H + +#include "Common/MyCom.h" +#include "Common/MyString.h" + +#include "../Agent/IFolderArchive.h" +#include "ProgressDialog2.h" +#include "../../IPassword.h" + +#ifdef LANG +#include "LangUtils.h" +#endif + +class CUpdateCallback100Imp: + public IFolderArchiveUpdateCallback, + public ICryptoGetTextPassword2, + public ICompressProgressInfo, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP3( + IFolderArchiveUpdateCallback, + ICryptoGetTextPassword2, + ICompressProgressInfo) + + // IProgress + + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); + + // IUpdateCallBack + STDMETHOD(CompressOperation)(const wchar_t *name); + STDMETHOD(DeleteOperation)(const wchar_t *name); + STDMETHOD(OperationResult)(Int32 operationResult); + STDMETHOD(UpdateErrorMessage)(const wchar_t *message); + STDMETHOD(SetNumFiles)(UInt64 numFiles); + + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); +private: + bool _passwordIsDefined; + UString _password; + + void AddErrorMessage(LPCWSTR message); + bool ShowMessages; + +public: + CUpdateCallback100Imp(): ShowMessages(true) {} + ~CUpdateCallback100Imp(); + CProgressDialog ProgressDialog; + HWND _parentWindow; + UStringVector Messages; + UInt64 NumFolders; + UInt64 NumFiles; + + void Init(HWND parentWindow, + bool passwordIsDefined, const UString &password) + { + _passwordIsDefined = passwordIsDefined; + _password = password; + _parentWindow = parentWindow; + NumFolders = NumFiles = 0; + } + void StartProgressDialog(const UString &title) + { + ProgressDialog.Create(title, _parentWindow); + } + +}; + +#endif diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp new file mode 100755 index 00000000..9102cc4e --- /dev/null +++ b/CPP/7zip/UI/FileManager/ViewSettings.cpp @@ -0,0 +1,429 @@ +// ViewSettings.h + +#include "StdAfx.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "ViewSettings.h" +#include "Windows/Registry.h" +#include "Windows/Synchronization.h" + +using namespace NWindows; +using namespace NRegistry; + +static const TCHAR *kCUBasePath = TEXT("Software\\7-Zip\\FM"); + +static const TCHAR *kCulumnsKeyName = TEXT("Columns"); + +static const TCHAR *kPositionValueName = TEXT("Position"); +static const TCHAR *kPanelsInfoValueName = TEXT("Panels"); +static const TCHAR *kToolbars = TEXT("Toolbars"); + +static const WCHAR *kPanelPathValueName = L"PanelPath"; +static const TCHAR *kListMode = TEXT("ListMode"); +static const TCHAR *kFolderHistoryValueName = TEXT("FolderHistory"); +static const TCHAR *kFastFoldersValueName = TEXT("FolderShortcuts"); +static const TCHAR *kCopyHistoryValueName = TEXT("CopyHistory"); + +/* +class CColumnInfoSpec +{ + UInt32 PropID; + Byte IsVisible; + UInt32 Width; +}; + +struct CColumnHeader +{ + UInt32 Version; + UInt32 SortID; + Byte Ascending; +}; +*/ + +static const UInt32 kColumnInfoSpecHeader = 12; +static const UInt32 kColumnHeaderSize = 12; + +static const UInt32 kColumnInfoVersion = 1; + +static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; + +class CTempOutBufferSpec +{ + CByteBuffer Buffer; + UInt32 Size; + UInt32 Pos; +public: + operator const Byte *() const { return (const Byte *)Buffer; } + void Init(UInt32 dataSize) + { + Buffer.SetCapacity(dataSize); + Size = dataSize; + Pos = 0; + } + void WriteByte(Byte value) + { + if (Pos >= Size) + throw "overflow"; + ((Byte *)Buffer)[Pos++] = value; + } + void WriteUInt32(UInt32 value) + { + for (int i = 0; i < 4; i++) + { + WriteByte((Byte)value); + value >>= 8; + } + } + void WriteBool(bool value) + { + WriteUInt32(value ? 1 : 0); + } +}; + +class CTempInBufferSpec +{ +public: + Byte *Buffer; + UInt32 Size; + UInt32 Pos; + Byte ReadByte() + { + if (Pos >= Size) + throw "overflow"; + return Buffer[Pos++]; + } + UInt32 ReadUInt32() + { + UInt32 value = 0; + for (int i = 0; i < 4; i++) + value |= (((UInt32)ReadByte()) << (8 * i)); + return value; + } + bool ReadBool() + { + return (ReadUInt32() != 0); + } +}; + +void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo) +{ + const CObjectVector &columns = viewInfo.Columns; + CTempOutBufferSpec buffer; + UInt32 dataSize = kColumnHeaderSize + kColumnInfoSpecHeader * columns.Size(); + buffer.Init(dataSize); + + buffer.WriteUInt32(kColumnInfoVersion); + buffer.WriteUInt32(viewInfo.SortID); + buffer.WriteBool(viewInfo.Ascending); + for(int i = 0; i < columns.Size(); i++) + { + const CColumnInfo &column = columns[i]; + buffer.WriteUInt32(column.PropID); + buffer.WriteBool(column.IsVisible); + buffer.WriteUInt32(column.Width); + } + { + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CSysString keyName = kCUBasePath; + keyName += kKeyNameDelimiter; + keyName += kCulumnsKeyName; + CKey key; + key.Create(HKEY_CURRENT_USER, keyName); + key.SetValue(GetSystemString(id), (const Byte *)buffer, dataSize); + } +} + +void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo) +{ + viewInfo.Clear(); + CObjectVector &columns = viewInfo.Columns; + CByteBuffer buffer; + UInt32 size; + { + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CSysString keyName = kCUBasePath; + keyName += kKeyNameDelimiter; + keyName += kCulumnsKeyName; + CKey key; + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return; + if (key.QueryValue(GetSystemString(id), buffer, size) != ERROR_SUCCESS) + return; + } + if (size < kColumnHeaderSize) + return; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + + + UInt32 version = inBuffer.ReadUInt32(); + if (version != kColumnInfoVersion) + return; + viewInfo.SortID = inBuffer.ReadUInt32(); + viewInfo.Ascending = inBuffer.ReadBool(); + + size -= kColumnHeaderSize; + if (size % kColumnInfoSpecHeader != 0) + return; + int numItems = size / kColumnInfoSpecHeader; + columns.Reserve(numItems); + for(int i = 0; i < numItems; i++) + { + CColumnInfo columnInfo; + columnInfo.PropID = inBuffer.ReadUInt32(); + columnInfo.IsVisible = inBuffer.ReadBool(); + columnInfo.Width = inBuffer.ReadUInt32(); + columns.Add(columnInfo); + } +} + +static const UInt32 kWindowPositionHeaderSize = 5 * 4; +static const UInt32 kPanelsInfoHeaderSize = 3 * 4; + +/* +struct CWindowPosition +{ + RECT Rect; + UInt32 Maximized; +}; + +struct CPanelsInfo +{ + UInt32 NumPanels; + UInt32 CurrentPanel; + UInt32 SplitterPos; +}; +*/ + +void SaveWindowSize(const RECT &rect, bool maximized) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, keyName); + // CWindowPosition position; + CTempOutBufferSpec buffer; + buffer.Init(kWindowPositionHeaderSize); + buffer.WriteUInt32(rect.left); + buffer.WriteUInt32(rect.top); + buffer.WriteUInt32(rect.right); + buffer.WriteUInt32(rect.bottom); + buffer.WriteBool(maximized); + key.SetValue(kPositionValueName, (const Byte *)buffer, kWindowPositionHeaderSize); +} + +bool ReadWindowSize(RECT &rect, bool &maximized) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return false; + CByteBuffer buffer; + UInt32 size; + if (key.QueryValue(kPositionValueName, buffer, size) != ERROR_SUCCESS) + return false; + if (size != kWindowPositionHeaderSize) + return false; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + rect.left = inBuffer.ReadUInt32(); + rect.top = inBuffer.ReadUInt32(); + rect.right = inBuffer.ReadUInt32(); + rect.bottom = inBuffer.ReadUInt32(); + maximized = inBuffer.ReadBool(); + return true; +} + +void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, keyName); + + CTempOutBufferSpec buffer; + buffer.Init(kPanelsInfoHeaderSize); + buffer.WriteUInt32(numPanels); + buffer.WriteUInt32(currentPanel); + buffer.WriteUInt32(splitterPos); + key.SetValue(kPanelsInfoValueName, (const Byte *)buffer, kPanelsInfoHeaderSize); +} + +bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos) +{ + CSysString keyName = kCUBasePath; + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, keyName, KEY_READ) != ERROR_SUCCESS) + return false; + CByteBuffer buffer; + UInt32 size; + if (key.QueryValue(kPanelsInfoValueName, buffer, size) != ERROR_SUCCESS) + return false; + if (size != kPanelsInfoHeaderSize) + return false; + CTempInBufferSpec inBuffer; + inBuffer.Size = size; + inBuffer.Buffer = (Byte *)buffer; + inBuffer.Pos = 0; + numPanels = inBuffer.ReadUInt32(); + currentPanel = inBuffer.ReadUInt32(); + splitterPos = inBuffer.ReadUInt32(); + return true; +} + +void SaveToolbarsMask(UInt32 toolbarMask) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(kToolbars, toolbarMask); +} + +static const UInt32 kDefaultToolbarMask = 8 | 4 | 1; + +UInt32 ReadToolbarsMask() +{ + CKey key; + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return kDefaultToolbarMask; + UInt32 mask; + if (key.QueryValue(kToolbars, mask) != ERROR_SUCCESS) + return kDefaultToolbarMask; + return mask; +} + + +static UString GetPanelPathName(UInt32 panelIndex) +{ + WCHAR panelString[32]; + ConvertUInt64ToString(panelIndex, panelString); + return UString(kPanelPathValueName) + panelString; +} + + +void SavePanelPath(UInt32 panel, const UString &path) +{ + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(GetPanelPathName(panel), path); +} + +bool ReadPanelPath(UInt32 panel, UString &path) +{ + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return false; + return (key.QueryValue(GetPanelPathName(panel), path) == ERROR_SUCCESS); +} + +void SaveListMode(const CListMode &listMode) +{ + CKey key; + key.Create(HKEY_CURRENT_USER, kCUBasePath); + UInt32 t = 0; + for (int i = 0; i < 2; i++) + t |= ((listMode.Panels[i]) & 0xFF) << (i * 8); + key.SetValue(kListMode, t); +} + +void ReadListMode(CListMode &listMode) +{ + CKey key; + listMode.Init(); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return; + UInt32 t; + if (key.QueryValue(kListMode, t) != ERROR_SUCCESS) + return; + for (int i = 0; i < 2; i++) + { + listMode.Panels[i] = (t & 0xFF); + t >>= 8; + } +} + + +void SaveStringList(LPCTSTR valueName, const UStringVector &folders) +{ + UInt32 sizeInChars = 0; + int i; + for (i = 0; i < folders.Size(); i++) + sizeInChars += folders[i].Length() + 1; + CBuffer buffer; + buffer.SetCapacity(sizeInChars); + int pos = 0; + for (i = 0; i < folders.Size(); i++) + { + MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)folders[i]); + pos += folders[i].Length() + 1; + } + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + key.Create(HKEY_CURRENT_USER, kCUBasePath); + key.SetValue(valueName, buffer, sizeInChars * sizeof(wchar_t)); +} + +void ReadStringList(LPCTSTR valueName, UStringVector &folders) +{ + folders.Clear(); + CKey key; + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + if(key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) + return; + CByteBuffer buffer; + UInt32 dataSize; + if (key.QueryValue(valueName, buffer, dataSize) != ERROR_SUCCESS) + return; + if (dataSize % sizeof(wchar_t) != 0) + return; + const wchar_t *data = (const wchar_t *)(const Byte *)buffer; + int sizeInChars = dataSize / sizeof(wchar_t); + UString string; + for (int i = 0; i < sizeInChars; i++) + { + wchar_t c = data[i]; + if (c == L'\0') + { + folders.Add(string); + string.Empty(); + } + else + string += c; + } +} + +void SaveFolderHistory(const UStringVector &folders) + { SaveStringList(kFolderHistoryValueName, folders); } +void ReadFolderHistory(UStringVector &folders) + { ReadStringList(kFolderHistoryValueName, folders); } + +void SaveFastFolders(const UStringVector &folders) + { SaveStringList(kFastFoldersValueName, folders); } +void ReadFastFolders(UStringVector &folders) + { ReadStringList(kFastFoldersValueName, folders); } + +void SaveCopyHistory(const UStringVector &folders) + { SaveStringList(kCopyHistoryValueName, folders); } +void ReadCopyHistory(UStringVector &folders) + { ReadStringList(kCopyHistoryValueName, folders); } + +void AddUniqueStringToHeadOfList(UStringVector &list, + const UString &string) +{ + for(int i = 0; i < list.Size();) + if (string.CompareNoCase(list[i]) == 0) + list.Delete(i); + else + i++; + list.Insert(0, string); +} + diff --git a/CPP/7zip/UI/FileManager/ViewSettings.h b/CPP/7zip/UI/FileManager/ViewSettings.h new file mode 100755 index 00000000..4af0b991 --- /dev/null +++ b/CPP/7zip/UI/FileManager/ViewSettings.h @@ -0,0 +1,98 @@ +// ViewSettings.h + +#ifndef __VIEWSETTINGS_H +#define __VIEWSETTINGS_H + +#include "Common/MyString.h" + +struct CColumnInfo +{ + PROPID PropID; + bool IsVisible; + UInt32 Width; +}; + +inline bool operator==(const CColumnInfo &a1, const CColumnInfo &a2) +{ + return (a1.PropID == a2.PropID) && + (a1.IsVisible == a2.IsVisible) && (a1.Width == a2.Width); +} + +inline bool operator!=(const CColumnInfo &a1, const CColumnInfo &a2) +{ + return !(a1 == a2); +} + +struct CListViewInfo +{ + CObjectVector Columns; + PROPID SortID; + bool Ascending; + + void Clear() + { + SortID = 0; + Ascending = true; + Columns.Clear(); + } + + int FindColumnWithID(PROPID propID) const + { + for (int i = 0; i < Columns.Size(); i++) + if (Columns[i].PropID == propID) + return i; + return -1; + } + + bool IsEqual(const CListViewInfo &aNewInfo) const + { + if (Columns.Size() != aNewInfo.Columns.Size() || + // SortIndex != aNewInfo.SortIndex || + SortID != aNewInfo.SortID || + Ascending != aNewInfo.Ascending) + return false; + for (int i = 0; i < Columns.Size(); i++) + if (Columns[i] != aNewInfo.Columns[i]) + return false; + return true; + } +}; + +void SaveListViewInfo(const UString &id, const CListViewInfo &viewInfo); +void ReadListViewInfo(const UString &id, CListViewInfo &viewInfo); + +void SaveWindowSize(const RECT &rect, bool maximized); +bool ReadWindowSize(RECT &rect, bool &maximized); + +void SavePanelsInfo(UInt32 numPanels, UInt32 currentPanel, UInt32 splitterPos); +bool ReadPanelsInfo(UInt32 &numPanels, UInt32 ¤tPanel, UInt32 &splitterPos); + +void SaveToolbarsMask(UInt32 toolbarMask); +UInt32 ReadToolbarsMask(); + +void SavePanelPath(UInt32 panel, const UString &path); +bool ReadPanelPath(UInt32 panel, UString &path); + +struct CListMode +{ + UInt32 Panels[2]; + void Init() { Panels[0] = Panels[1] = 3; } + CListMode() { Init(); } +}; + +void SaveListMode(const CListMode &listMode); +void ReadListMode(CListMode &listMode); + +void SaveFolderHistory(const UStringVector &folders); +void ReadFolderHistory(UStringVector &folders); + +void SaveFastFolders(const UStringVector &folders); +void ReadFastFolders(UStringVector &folders); + +void SaveCopyHistory(const UStringVector &folders); +void ReadCopyHistory(UStringVector &folders); + +void AddUniqueStringToHeadOfList(UStringVector &list, + const UString &string); + +#endif diff --git a/CPP/7zip/UI/FileManager/makefile b/CPP/7zip/UI/FileManager/makefile new file mode 100755 index 00000000..68723921 --- /dev/null +++ b/CPP/7zip/UI/FileManager/makefile @@ -0,0 +1,194 @@ +PROG = 7zFM.exe +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib shell32.lib ole32.lib comctl32.lib htmlhelp.lib Mpr.lib Gdi32.lib comdlg32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DLANG \ + -DWIN_LONG_PATH \ + -DNEW_FOLDER_INTERFACE \ + -DEXTERNAL_CODECS \ + +FM_OBJS = \ + $O\App.obj \ + $O\ClassDefs.obj \ + $O\EnumFormatEtc.obj \ + $O\ExtractCallback.obj \ + $O\FileFolderPluginOpen.obj \ + $O\FilePlugins.obj \ + $O\FM.obj \ + $O\FormatUtils.obj \ + $O\FSDrives.obj \ + $O\FSFolder.obj \ + $O\FSFolderCopy.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\MyLoadMenu.obj \ + $O\NetFolder.obj \ + $O\OpenCallback.obj \ + $O\OptionsDialog.obj \ + $O\Panel.obj \ + $O\PanelCopy.obj \ + $O\PanelCrc.obj \ + $O\PanelDrag.obj \ + $O\PanelFolderChange.obj \ + $O\PanelItemOpen.obj \ + $O\PanelItems.obj \ + $O\PanelKey.obj \ + $O\PanelListNotify.obj \ + $O\PanelMenu.obj \ + $O\PanelOperations.obj \ + $O\PanelSelect.obj \ + $O\PanelSort.obj \ + $O\PanelSplitFile.obj \ + $O\PhysDriveFolder.obj \ + $O\ProgramLocation.obj \ + $O\PropertyName.obj \ + $O\RegistryAssociations.obj \ + $O\RegistryPlugins.obj \ + $O\RegistryUtils.obj \ + $O\RootFolder.obj \ + $O\SplitUtils.obj \ + $O\StringUtils.obj \ + $O\SysIconUtils.obj \ + $O\TextPairs.obj \ + $O\UpdateCallback100.obj \ + $O\ViewSettings.obj \ + $O\AboutDialog.obj \ + $O\ComboDialog.obj \ + $O\CopyDialog.obj \ + $O\EditPage.obj \ + $O\LangPage.obj \ + $O\ListViewDialog.obj \ + $O\MessagesDialog.obj \ + $O\OverwriteDialog.obj \ + $O\PasswordDialog.obj \ + $O\PluginsPage.obj \ + $O\ProgressDialog2.obj \ + $O\SettingsPage.obj \ + $O\SplitDialog.obj \ + $O\SystemPage.obj \ + +COMMON_OBJS = \ + $O\CRC.obj \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\Random.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\MyString.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\TextConfig.obj \ + $O\UTFConvert.obj \ + $O\MyVector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\CommonDialog.obj \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDevice.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\FileSystem.obj \ + $O\Memory.obj \ + $O\MemoryLock.obj \ + $O\Menu.obj \ + $O\Net.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Security.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\ComboBox.obj \ + $O\Dialog.obj \ + $O\ListView.obj \ + $O\PropertyPage.obj \ + $O\Window2.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\ProgressUtils.obj \ + $O\StreamObjects.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveName.obj \ + $O\ArchiveOpenCallback.obj \ + $O\CompressCall.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\ExtractingFilePath.obj \ + $O\LoadCodecs.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SortUtils.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +AGENT_OBJS = \ + $O\Agent.obj \ + $O\AgentOut.obj \ + $O\AgentProxy.obj \ + $O\ArchiveFolder.obj \ + $O\ArchiveFolderOpen.obj \ + $O\ArchiveFolderOut.obj \ + $O\UpdateCallbackAgent.obj \ + +C_OBJS = \ + $O\Alloc.obj \ + $O\Sort.obj \ + $O\Threads.obj \ + +!include "../../Crc2.mak" + +OBJS = \ + $O\StdAfx.obj \ + $(FM_OBJS)\ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AGENT_OBJS) \ + $O\CopyCoder.obj \ + $(CRC_OBJS) \ + $(C_OBJS) \ + $O\resource.res \ + +!include "../../../Build.mak" + +$(FM_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(AGENT_OBJS): ../Agent/$(*B).cpp + $(COMPL) + +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) + +!include "../../Crc.mak" diff --git a/CPP/7zip/UI/FileManager/resource.h b/CPP/7zip/UI/FileManager/resource.h new file mode 100755 index 00000000..864c066b --- /dev/null +++ b/CPP/7zip/UI/FileManager/resource.h @@ -0,0 +1,159 @@ +#define IDI_FAM 101 +#define IDI_FM 101 +#define IDR_MENUBAR1 103 +#define IDM_MENU 103 +#define IDR_ACCELERATOR1 209 +#define IDM_FILE_OPEN 210 +#define IDM_FILE_OPEN_INSIDE 211 +#define IDM_FILE_OPEN_OUTSIDE 212 +#define IDM_FILE_VIEW 220 +#define IDM_FILE_EDIT 221 +#define IDM_RENAME 230 +#define IDM_COPY_TO 231 +#define IDM_MOVE_TO 232 +#define IDM_DELETE 233 +#define IDM_FILE_SPLIT 238 +#define IDM_FILE_COMBINE 239 +#define IDM_FILE_PROPERTIES 240 +#define IDM_FILE_COMMENT 241 +#define IDM_FILE_CRC 242 +#define IDM_CREATE_FOLDER 250 +#define IDM_CREATE_FILE 251 +#define IDM_EDIT_CUT 320 +#define IDM_EDIT_COPY 321 +#define IDM_EDIT_PASTE 322 +#define IDM_SELECT_ALL 330 +#define IDM_DESELECT_ALL 331 +#define IDM_INVERT_SELECTION 332 +#define IDM_SELECT 333 +#define IDM_DESELECT 334 +#define IDM_SELECT_BY_TYPE 335 +#define IDM_DESELECT_BY_TYPE 336 +#define IDM_VIEW_LARGE_ICONS 410 +#define IDM_VIEW_SMALL_ICONS 411 +#define IDM_VIEW_LIST 412 +#define IDM_VIEW_DETAILS 413 +#define IDM_VIEW_ARANGE_BY_NAME 420 +#define IDM_VIEW_ARANGE_BY_TYPE 421 +#define IDM_VIEW_ARANGE_BY_DATE 422 +#define IDM_VIEW_ARANGE_BY_SIZE 423 +#define IDM_VIEW_ARANGE_NO_SORT 424 +#define IDM_OPEN_ROOT_FOLDER 430 +#define IDM_OPEN_PARENT_FOLDER 431 +#define IDM_FOLDERS_HISTORY 432 +#define IDM_VIEW_REFRESH 440 +#define IDM_VIEW_FLAT_VIEW 449 +#define IDM_VIEW_TWO_PANELS 450 +#define IDM_VIEW_TOOLBARS 451 +#define IDM_VIEW_STANDARD_TOOLBAR 460 +#define IDM_VIEW_ARCHIVE_TOOLBAR 461 +#define IDM_VIEW_TOOLBARS_LARGE_BUTTONS 462 +#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 463 +#define IDM_OPTIONS 510 +#define IDM_BENCHMARK 511 +#define IDM_HELP_CONTENTS 610 +#define IDM_ABOUT 620 +#define IDS_BOOKMARK 720 +#define IDB_ADD 2002 +#define IDB_EXTRACT 2003 +#define IDB_TEST 2004 +#define IDB_COPY 2010 +#define IDB_MOVE 2011 +#define IDB_DELETE 2012 +#define IDB_INFO 2013 +#define IDB_ADD2 2082 +#define IDB_EXTRACT2 2083 +#define IDB_TEST2 2084 +#define IDB_COPY2 2090 +#define IDB_MOVE2 2091 +#define IDB_DELETE2 2092 +#define IDB_INFO2 2093 +#define IDS_APP_TITLE 2200 +#define IDS_COPY 2201 +#define IDS_MOVE 2202 +#define IDS_COPY_TO 2203 +#define IDS_MOVE_TO 2204 +#define IDS_COPYING 2205 +#define IDS_MOVING 2206 +#define IDS_CANNOT_COPY 2207 +#define IDS_OPERATION_IS_NOT_SUPPORTED 2208 + +#define IDS_CONFIRM_FILE_DELETE 2210 +#define IDS_CONFIRM_FOLDER_DELETE 2211 +#define IDS_CONFIRM_ITEMS_DELETE 2212 +#define IDS_WANT_TO_DELETE_FILE 2213 +#define IDS_WANT_TO_DELETE_FOLDER 2214 +#define IDS_WANT_TO_DELETE_ITEMS 2215 +#define IDS_DELETING 2216 +#define IDS_ERROR_DELETING 2217 + +#define IDS_RENAMING 2220 +#define IDS_ERROR_RENAMING 2221 +#define IDS_CONFIRM_FILE_COPY 2222 +#define IDS_WANT_TO_COPY_FILES 2223 + + +#define IDS_CREATE_FOLDER 2230 +#define IDS_CREATE_FOLDER_NAME 2231 +#define IDS_CREATE_FOLDER_DEFAULT_NAME 2232 +#define IDS_CREATE_FOLDER_ERROR 2233 +#define IDS_CREATE_FILE 2240 +#define IDS_CREATE_FILE_NAME 2241 +#define IDS_CREATE_FOLDER_DEFAULT_FILE_NAME 2242 +#define IDS_CREATE_FILE_DEFAULT_NAME 2242 +#define IDS_CREATE_FILE_ERROR 2243 +#define IDS_SELECT 2250 +#define IDS_DESELECT 2251 +#define IDS_SELECT_MASK 2252 +#define IDS_FOLDERS_HISTORY 2260 +#define IDS_N_SELECTED_ITEMS 2270 +#define IDS_FILES_COLON 2274 +#define IDS_FOLDERS_COLON 2275 +#define IDS_SIZE_COLON 2276 + +#define IDS_TOO_MANY_ITEMS 2279 +#define IDS_WANT_UPDATE_MODIFIED_FILE 2280 +#define IDS_CANNOT_UPDATE_FILE 2281 +#define IDS_CANNOT_START_EDITOR 2282 +#define IDS_OPENNING 2283 +#define IDS_COMPUTER 2300 +#define IDS_NETWORK 2301 +#define IDS_ADD 2400 +#define IDS_EXTRACT 2401 +#define IDS_TEST 2402 +#define IDS_BUTTON_COPY 2420 +#define IDS_BUTTON_MOVE 2421 +#define IDS_BUTTON_DELETE 2422 +#define IDS_BUTTON_INFO 2423 +#define IDS_PROPERTY_TOTAL_SIZE 3100 +#define IDS_PROPERTY_FREE_SPACE 3101 +#define IDS_PROPERTY_CLUSTER_SIZE 3102 +#define IDS_PROPERTY_VOLUME_NAME 3103 +#define IDS_PROPERTY_LOCAL_NAME 3200 +#define IDS_PROPERTY_PROVIDER 3201 +#define IDS_OPTIONS 4000 +#define IDS_COMMENT 4001 +#define IDS_COMMENT2 4002 +#define IDS_SYSTEM 4010 + +#define IDS_SPLITTING 4020 +#define IDS_SPLIT_CONFIRM_TITLE 4021 +#define IDS_SPLIT_CONFIRM_MESSAGE 4022 +#define IDS_SPLIT_VOL_MUST_BE_SMALLER 4023 + +#define IDS_COMBINE 4030 +#define IDS_COMBINE_TO 4031 +#define IDS_COMBINING 4032 +#define IDS_COMBINE_SELECT_ONE_FILE 4033 + +#define IDS_CHECKSUM_CALCULATING 4040 +#define IDS_CHECKSUM_INFORMATION 4041 +#define IDS_CHECKSUM_CRC_DATA 4042 +#define IDS_CHECKSUM_CRC_DATA_NAMES 4043 + +#define IDS_SCANNING 4050 +#define IDS_PROPERTIES 4060 + +#define IDS_PROGRESS_TESTING 4100 +#define IDS_MESSAGE_NO_ERRORS 4200 + diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc new file mode 100755 index 00000000..b8664cbe --- /dev/null +++ b/CPP/7zip/UI/FileManager/resource.rc @@ -0,0 +1,237 @@ +#include "../../MyVersionInfo.rc" +#include "../../GuiCommon.rc" +#include "resource.h" + +MY_VERSION_INFO_APP("7-Zip File Manager", "7zFM") + + +IDR_ACCELERATOR1 ACCELERATORS +BEGIN + "N", IDM_CREATE_FILE, VIRTKEY, CONTROL, NOINVERT + VK_F1, IDM_HELP_CONTENTS, VIRTKEY, NOINVERT + VK_F12, IDM_FOLDERS_HISTORY, VIRTKEY, ALT, NOINVERT + VK_F7, IDM_CREATE_FOLDER, VIRTKEY, NOINVERT +END + + +IDM_MENU MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open\tEnter", IDM_FILE_OPEN + MENUITEM "Open &Inside\tCtrl+PgDn", IDM_FILE_OPEN_INSIDE + MENUITEM "Open O&utside\tShift+Enter", IDM_FILE_OPEN_OUTSIDE + MENUITEM "&Edit\tF4", IDM_FILE_EDIT + MENUITEM SEPARATOR + MENUITEM "Rena&me\tF2", IDM_RENAME + MENUITEM "&Copy To...\tF5", IDM_COPY_TO + MENUITEM "&Move To...\tF6", IDM_MOVE_TO + MENUITEM "&Delete\tDel", IDM_DELETE + MENUITEM SEPARATOR + MENUITEM "&Split file...", IDM_FILE_SPLIT + MENUITEM "Com&bine files...", IDM_FILE_COMBINE + MENUITEM SEPARATOR + MENUITEM "P&roperties\tAlt+Enter", IDM_FILE_PROPERTIES + MENUITEM "Comme&nt\tCtrl+Z", IDM_FILE_COMMENT + MENUITEM "Calculate checksum", IDM_FILE_CRC + MENUITEM SEPARATOR + MENUITEM "Create Folder\tF7", IDM_CREATE_FOLDER + MENUITEM "Create File\tCtrl+N", IDM_CREATE_FILE + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", IDCLOSE + END + POPUP "&Edit" + BEGIN + MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT, GRAYED + MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY, GRAYED + MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE, GRAYED + MENUITEM SEPARATOR + MENUITEM "Select &All\tShift+[Grey +]", IDM_SELECT_ALL + MENUITEM "Deselect All\tShift+[Grey -]", IDM_DESELECT_ALL + MENUITEM "&Invert Selection\tGrey *", IDM_INVERT_SELECTION + MENUITEM "Select...\tGrey +", IDM_SELECT + MENUITEM "Deselect...\tGrey -", IDM_DESELECT + MENUITEM "Select by Type\tAlt+[Grey+]", IDM_SELECT_BY_TYPE + MENUITEM "Deselect by Type\tAlt+[Grey -]", IDM_DESELECT_BY_TYPE + END + POPUP "&View" + BEGIN + MENUITEM "Lar&ge Icons\tCtrl+1", IDM_VIEW_LARGE_ICONS + MENUITEM "S&mall Icons\tCtrl+2", IDM_VIEW_SMALL_ICONS + MENUITEM "&List\tCtrl+3", IDM_VIEW_LIST + MENUITEM "&Details\tCtrl+4", IDM_VIEW_DETAILS, CHECKED + MENUITEM SEPARATOR + MENUITEM "Name\tCtrl+F3", IDM_VIEW_ARANGE_BY_NAME + MENUITEM "Type\tCtrl+F4", IDM_VIEW_ARANGE_BY_TYPE + MENUITEM "Date\tCtrl+F5", IDM_VIEW_ARANGE_BY_DATE + MENUITEM "Size\tCtrl+F6", IDM_VIEW_ARANGE_BY_SIZE + MENUITEM "Unsorted\tCtrl+F7", IDM_VIEW_ARANGE_NO_SORT + MENUITEM SEPARATOR + MENUITEM "Flat View", IDM_VIEW_FLAT_VIEW + MENUITEM "&2 Panels\tF9", IDM_VIEW_TWO_PANELS + POPUP "Toolbars" + BEGIN + MENUITEM "Archive Toolbar", IDM_VIEW_ARCHIVE_TOOLBAR + MENUITEM "Standard Toolbar", IDM_VIEW_STANDARD_TOOLBAR + MENUITEM SEPARATOR + MENUITEM "Large Buttons", IDM_VIEW_TOOLBARS_LARGE_BUTTONS + MENUITEM "Show Buttons Text", IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT + END + MENUITEM SEPARATOR + MENUITEM "Open Root Folder\t\\", IDM_OPEN_ROOT_FOLDER + MENUITEM "Up One Level\tBackspace", IDM_OPEN_PARENT_FOLDER + MENUITEM "Folders History...\tAlt+F12", IDM_FOLDERS_HISTORY + MENUITEM SEPARATOR + MENUITEM "&Refresh\tCtrl+R", IDM_VIEW_REFRESH + END + POPUP "F&avorites" + BEGIN + POPUP "&Add folder to Favorites as" + BEGIN + MENUITEM SEPARATOR + END + MENUITEM SEPARATOR + END + POPUP "&Tools" + BEGIN + MENUITEM "&Options...", IDM_OPTIONS + MENUITEM "&Benchmark", IDM_BENCHMARK + END + POPUP "&Help" + BEGIN + MENUITEM "&Contents...\tF1", IDM_HELP_CONTENTS + MENUITEM SEPARATOR + MENUITEM "&About 7-Zip...", IDM_ABOUT + END +END + + +IDI_FM ICON "FM.ico" + +1 24 MOVEABLE PURE "7zFM.exe.manifest" + +IDB_ADD BITMAP "Add.bmp" +IDB_EXTRACT BITMAP "Extract.bmp" +IDB_TEST BITMAP "Test.bmp" +IDB_COPY BITMAP "Copy.bmp" +IDB_MOVE BITMAP "Move.bmp" +IDB_DELETE BITMAP "Delete.bmp" +IDB_INFO BITMAP "Info.bmp" +IDB_ADD2 BITMAP "Add2.bmp" +IDB_EXTRACT2 BITMAP "Extract2.bmp" +IDB_TEST2 BITMAP "Test2.bmp" +IDB_COPY2 BITMAP "Copy2.bmp" +IDB_MOVE2 BITMAP "Move2.bmp" +IDB_DELETE2 BITMAP "Delete2.bmp" +IDB_INFO2 BITMAP "Info2.bmp" + + +STRINGTABLE +BEGIN + IDS_APP_TITLE "7-Zip File Manager" + IDS_COPY "Copy" + IDS_MOVE "Move" + IDS_COPY_TO "Copy to:" + IDS_MOVE_TO "Move to:" + IDS_COPYING "Copying..." + IDS_MOVING "Moving..." + IDS_CANNOT_COPY "You cannot move or copy items for such folders." + IDS_SPLITTING "Splitting..." + IDS_SPLIT_CONFIRM_TITLE "Confirm Splitting" + IDS_SPLIT_CONFIRM_MESSAGE "Are you sure you want to split file into {0} volumes?" + IDS_SPLIT_VOL_MUST_BE_SMALLER "Volume size must be smaller than size of original file" + + IDS_COMBINE "Combine Files" + IDS_COMBINE_TO "&Combine to:" + IDS_COMBINING "Combining..." + IDS_COMBINE_SELECT_ONE_FILE "Select only first file" + + IDS_CHECKSUM_CALCULATING "Checksum calculating..." + IDS_CHECKSUM_INFORMATION "Checksum information" + IDS_CHECKSUM_CRC_DATA "CRC checksum for data:" + IDS_CHECKSUM_CRC_DATA_NAMES "CRC checksum for data and names:" + + IDS_SCANNING "Scanning..." + + IDS_PROPERTIES "Properties" + + IDS_OPERATION_IS_NOT_SUPPORTED "Operation is not supported." + + IDS_CONFIRM_FILE_DELETE "Confirm File Delete" + IDS_CONFIRM_FOLDER_DELETE "Confirm Folder Delete" + IDS_CONFIRM_ITEMS_DELETE "Confirm Multiple File Delete" + IDS_WANT_TO_DELETE_FILE "Are you sure you want to delete '{0}'?" + IDS_WANT_TO_DELETE_FOLDER "Are you sure you want to delete the folder '{0}' and all its contents?" + IDS_WANT_TO_DELETE_ITEMS "Are you sure you want to delete these {0} items?" + IDS_DELETING "Deleting..." + IDS_ERROR_DELETING "Error Deleting File or Folder" + IDS_RENAMING "Renaming..." + IDS_ERROR_RENAMING "Error Renaming File or Folder" + IDS_CONFIRM_FILE_COPY "Confirm File Copy" + IDS_WANT_TO_COPY_FILES "Are you sure you want to copy files to archive" + + IDS_CREATE_FOLDER "Create Folder" + IDS_CREATE_FOLDER_NAME "Folder name:" + IDS_CREATE_FOLDER_DEFAULT_NAME "New Folder" + IDS_CREATE_FOLDER_ERROR "Error Creating Folder" + IDS_CREATE_FILE "Create File" + IDS_CREATE_FILE_NAME "File Name:" + IDS_CREATE_FILE_DEFAULT_NAME "New File" + IDS_CREATE_FILE_ERROR "Error Creating File" + IDS_SELECT "Select" + IDS_DESELECT "Deselect" + IDS_SELECT_MASK "Mask:" + IDS_FOLDERS_HISTORY "Folders History" + IDS_N_SELECTED_ITEMS "{0} object(s) selected" + IDS_FILES_COLON "Files:" + IDS_FOLDERS_COLON "Folders:" + IDS_SIZE_COLON "Size:" + + IDS_PROPERTY_TOTAL_SIZE "Total Size" + IDS_PROPERTY_FREE_SPACE "Free Space" + IDS_PROPERTY_CLUSTER_SIZE "Cluster Size" + IDS_PROPERTY_VOLUME_NAME "Label" + IDS_PROPERTY_LOCAL_NAME "Local Name" + IDS_PROPERTY_PROVIDER "Provider" + IDS_OPTIONS "Options" + IDS_COMMENT "Comment" + IDS_COMMENT2 "&Comment:" + IDS_SYSTEM "System" + IDS_TOO_MANY_ITEMS "Too many items" + IDS_WANT_UPDATE_MODIFIED_FILE "File '{0}' was modified.\nDo you want to update it in the archive?" + IDS_CANNOT_UPDATE_FILE "Can not update file\n'{0}'" + IDS_CANNOT_START_EDITOR "Cannot start editor." + IDS_OPENNING "Opening..." + IDS_ADD "Add" + IDS_EXTRACT "Extract" + IDS_TEST "Test" + IDS_BUTTON_COPY "Copy" + IDS_BUTTON_MOVE "Move" + IDS_BUTTON_DELETE "Delete" + IDS_BUTTON_INFO "Info" + IDS_BOOKMARK "Bookmark" + IDS_COMPUTER "Computer" + IDS_NETWORK "Network" + + IDS_PROGRESS_TESTING "Testing" + IDS_MESSAGE_NO_ERRORS "There are no errors" +END + + +#include "ComboDialog.rc" +#include "CopyDialog.rc" +#include "ListViewDialog.rc" +#include "PropertyName.rc" +#include "MessagesDialog.rc" +#include "OverwriteDialog.rc" +#include "PasswordDialog.rc" +#include "SplitDialog.rc" +#include "ProgressDialog2.rc" +#include "AboutDialog.rc" +#include "LangPage.rc" +#include "PluginsPage.rc" +#include "SystemPage.rc" +#include "EditPage.rc" +#include "SettingsPage.rc" +#include "../GUI/ExtractDialog.rc" +#include "../GUI/Extract.rc" -- cgit v1.2.3