Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2007-08-27 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:54 +0300
commit051769bbc577aeede90558b6ab5c9be187940ca0 (patch)
treee6330cb80f2d4a526d8aa27812528e053b0cda90 /CPP/7zip/UI/FileManager
parent33ccab7e728a996800e166d849fe1e92a17e1afe (diff)
4.53 beta
Diffstat (limited to 'CPP/7zip/UI/FileManager')
-rwxr-xr-xCPP/7zip/UI/FileManager/7zFM.exe.manifest1
-rwxr-xr-xCPP/7zip/UI/FileManager/7zipLogo.icobin0 -> 9150 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/AboutDialog.cpp60
-rwxr-xr-xCPP/7zip/UI/FileManager/AboutDialog.h18
-rwxr-xr-xCPP/7zip/UI/FileManager/AboutDialog.rc41
-rwxr-xr-xCPP/7zip/UI/FileManager/AboutDialogRes.h6
-rwxr-xr-xCPP/7zip/UI/FileManager/Add.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/Add2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/App.cpp759
-rwxr-xr-xCPP/7zip/UI/FileManager/App.h332
-rwxr-xr-xCPP/7zip/UI/FileManager/AppState.h114
-rwxr-xr-xCPP/7zip/UI/FileManager/ClassDefs.cpp17
-rwxr-xr-xCPP/7zip/UI/FileManager/ComboDialog.cpp53
-rwxr-xr-xCPP/7zip/UI/FileManager/ComboDialog.h25
-rwxr-xr-xCPP/7zip/UI/FileManager/ComboDialog.rc24
-rwxr-xr-xCPP/7zip/UI/FileManager/ComboDialogRes.h4
-rwxr-xr-xCPP/7zip/UI/FileManager/Copy.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/Copy2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/CopyDialog.cpp81
-rwxr-xr-xCPP/7zip/UI/FileManager/CopyDialog.h26
-rwxr-xr-xCPP/7zip/UI/FileManager/CopyDialog.rc28
-rwxr-xr-xCPP/7zip/UI/FileManager/CopyDialogRes.h7
-rwxr-xr-xCPP/7zip/UI/FileManager/Delete.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/Delete2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/EditPage.cpp91
-rwxr-xr-xCPP/7zip/UI/FileManager/EditPage.h21
-rwxr-xr-xCPP/7zip/UI/FileManager/EditPage.rc16
-rwxr-xr-xCPP/7zip/UI/FileManager/EditPageRes.h4
-rwxr-xr-xCPP/7zip/UI/FileManager/EnumFormatEtc.cpp108
-rwxr-xr-xCPP/7zip/UI/FileManager/EnumFormatEtc.h10
-rwxr-xr-xCPP/7zip/UI/FileManager/Extract.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/Extract2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/ExtractCallback.cpp440
-rwxr-xr-xCPP/7zip/UI/FileManager/ExtractCallback.h147
-rwxr-xr-xCPP/7zip/UI/FileManager/FM.cpp803
-rwxr-xr-xCPP/7zip/UI/FileManager/FM.dsp1486
-rwxr-xr-xCPP/7zip/UI/FileManager/FM.dsw29
-rwxr-xr-xCPP/7zip/UI/FileManager/FM.icobin0 -> 4846 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/FSDrives.cpp236
-rwxr-xr-xCPP/7zip/UI/FileManager/FSDrives.h49
-rwxr-xr-xCPP/7zip/UI/FileManager/FSFolder.cpp682
-rwxr-xr-xCPP/7zip/UI/FileManager/FSFolder.h118
-rwxr-xr-xCPP/7zip/UI/FileManager/FSFolderCopy.cpp475
-rwxr-xr-xCPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp114
-rwxr-xr-xCPP/7zip/UI/FileManager/FileFolderPluginOpen.h9
-rwxr-xr-xCPP/7zip/UI/FileManager/FilePlugins.cpp112
-rwxr-xr-xCPP/7zip/UI/FileManager/FilePlugins.h54
-rwxr-xr-xCPP/7zip/UI/FileManager/FormatUtils.cpp40
-rwxr-xr-xCPP/7zip/UI/FileManager/FormatUtils.h18
-rwxr-xr-xCPP/7zip/UI/FileManager/HelpUtils.cpp23
-rwxr-xr-xCPP/7zip/UI/FileManager/HelpUtils.h10
-rwxr-xr-xCPP/7zip/UI/FileManager/IFolder.h145
-rwxr-xr-xCPP/7zip/UI/FileManager/Info.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/Info2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/LangPage.cpp90
-rwxr-xr-xCPP/7zip/UI/FileManager/LangPage.h21
-rwxr-xr-xCPP/7zip/UI/FileManager/LangPage.rc21
-rwxr-xr-xCPP/7zip/UI/FileManager/LangPageRes.h6
-rwxr-xr-xCPP/7zip/UI/FileManager/LangUtils.cpp207
-rwxr-xr-xCPP/7zip/UI/FileManager/LangUtils.h41
-rwxr-xr-xCPP/7zip/UI/FileManager/ListViewDialog.cpp100
-rwxr-xr-xCPP/7zip/UI/FileManager/ListViewDialog.h30
-rwxr-xr-xCPP/7zip/UI/FileManager/ListViewDialog.rc26
-rwxr-xr-xCPP/7zip/UI/FileManager/ListViewDialogRes.h3
-rwxr-xr-xCPP/7zip/UI/FileManager/MessagesDialog.cpp100
-rwxr-xr-xCPP/7zip/UI/FileManager/MessagesDialog.h22
-rwxr-xr-xCPP/7zip/UI/FileManager/MessagesDialog.rc25
-rwxr-xr-xCPP/7zip/UI/FileManager/MessagesDialogRes.h3
-rwxr-xr-xCPP/7zip/UI/FileManager/Move.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/Move2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/MyCom2.h48
-rwxr-xr-xCPP/7zip/UI/FileManager/MyLoadMenu.cpp694
-rwxr-xr-xCPP/7zip/UI/FileManager/MyLoadMenu.h16
-rwxr-xr-xCPP/7zip/UI/FileManager/NetFolder.cpp302
-rwxr-xr-xCPP/7zip/UI/FileManager/NetFolder.h49
-rwxr-xr-xCPP/7zip/UI/FileManager/OpenCallback.cpp115
-rwxr-xr-xCPP/7zip/UI/FileManager/OpenCallback.h85
-rwxr-xr-xCPP/7zip/UI/FileManager/OptionsDialog.cpp65
-rwxr-xr-xCPP/7zip/UI/FileManager/OverwriteDialog.cpp124
-rwxr-xr-xCPP/7zip/UI/FileManager/OverwriteDialog.h34
-rwxr-xr-xCPP/7zip/UI/FileManager/OverwriteDialog.rc47
-rwxr-xr-xCPP/7zip/UI/FileManager/OverwriteDialogRes.h19
-rwxr-xr-xCPP/7zip/UI/FileManager/Panel.cpp967
-rwxr-xr-xCPP/7zip/UI/FileManager/Panel.h511
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelCopy.cpp203
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelCrc.cpp365
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelDrag.cpp796
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelFolderChange.cpp413
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelItemOpen.cpp546
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelItems.cpp807
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelKey.cpp297
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelListNotify.cpp392
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelMenu.cpp558
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelOperations.cpp443
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelSelect.cpp297
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelSort.cpp163
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelSplitFile.cpp481
-rwxr-xr-xCPP/7zip/UI/FileManager/PasswordDialog.cpp50
-rwxr-xr-xCPP/7zip/UI/FileManager/PasswordDialog.h21
-rwxr-xr-xCPP/7zip/UI/FileManager/PasswordDialog.rc26
-rwxr-xr-xCPP/7zip/UI/FileManager/PasswordDialogRes.h4
-rwxr-xr-xCPP/7zip/UI/FileManager/PhysDriveFolder.cpp299
-rwxr-xr-xCPP/7zip/UI/FileManager/PhysDriveFolder.h58
-rwxr-xr-xCPP/7zip/UI/FileManager/PluginInterface.h42
-rwxr-xr-xCPP/7zip/UI/FileManager/PluginLoader.h32
-rwxr-xr-xCPP/7zip/UI/FileManager/PluginsPage.cpp223
-rwxr-xr-xCPP/7zip/UI/FileManager/PluginsPage.h26
-rwxr-xr-xCPP/7zip/UI/FileManager/PluginsPage.rc19
-rwxr-xr-xCPP/7zip/UI/FileManager/PluginsPageRes.h4
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgramLocation.cpp24
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgramLocation.h10
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog.cpp175
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog.h132
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog.rc20
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog2.cpp483
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog2.h226
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog2.rc77
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog2Res.h26
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialogRes.h3
-rwxr-xr-xCPP/7zip/UI/FileManager/PropertyName.cpp83
-rwxr-xr-xCPP/7zip/UI/FileManager/PropertyName.h10
-rwxr-xr-xCPP/7zip/UI/FileManager/PropertyName.rc45
-rwxr-xr-xCPP/7zip/UI/FileManager/PropertyNameRes.h37
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryAssociations.cpp303
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryAssociations.h44
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryPlugins.cpp146
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryPlugins.h32
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryUtils.cpp150
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryUtils.h46
-rwxr-xr-xCPP/7zip/UI/FileManager/RootFolder.cpp197
-rwxr-xr-xCPP/7zip/UI/FileManager/RootFolder.h32
-rwxr-xr-xCPP/7zip/UI/FileManager/SettingsPage.cpp113
-rwxr-xr-xCPP/7zip/UI/FileManager/SettingsPage.h19
-rwxr-xr-xCPP/7zip/UI/FileManager/SettingsPage.rc35
-rwxr-xr-xCPP/7zip/UI/FileManager/SettingsPageRes.h11
-rwxr-xr-xCPP/7zip/UI/FileManager/SplitDialog.cpp89
-rwxr-xr-xCPP/7zip/UI/FileManager/SplitDialog.h27
-rwxr-xr-xCPP/7zip/UI/FileManager/SplitDialog.rc32
-rwxr-xr-xCPP/7zip/UI/FileManager/SplitDialogRes.h8
-rwxr-xr-xCPP/7zip/UI/FileManager/SplitUtils.cpp85
-rwxr-xr-xCPP/7zip/UI/FileManager/SplitUtils.h15
-rwxr-xr-xCPP/7zip/UI/FileManager/StdAfx.cpp3
-rwxr-xr-xCPP/7zip/UI/FileManager/StdAfx.h23
-rwxr-xr-xCPP/7zip/UI/FileManager/StringUtils.cpp68
-rwxr-xr-xCPP/7zip/UI/FileManager/StringUtils.h13
-rwxr-xr-xCPP/7zip/UI/FileManager/SysIconUtils.cpp157
-rwxr-xr-xCPP/7zip/UI/FileManager/SysIconUtils.h51
-rwxr-xr-xCPP/7zip/UI/FileManager/SystemPage.cpp437
-rwxr-xr-xCPP/7zip/UI/FileManager/SystemPage.h40
-rwxr-xr-xCPP/7zip/UI/FileManager/SystemPage.rc28
-rwxr-xr-xCPP/7zip/UI/FileManager/SystemPageRes.h7
-rwxr-xr-xCPP/7zip/UI/FileManager/Test.bmpbin0 -> 982 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/Test2.bmpbin0 -> 406 bytes
-rwxr-xr-xCPP/7zip/UI/FileManager/TextPairs.cpp216
-rwxr-xr-xCPP/7zip/UI/FileManager/TextPairs.h31
-rwxr-xr-xCPP/7zip/UI/FileManager/UpdateCallback100.cpp106
-rwxr-xr-xCPP/7zip/UI/FileManager/UpdateCallback100.h74
-rwxr-xr-xCPP/7zip/UI/FileManager/ViewSettings.cpp429
-rwxr-xr-xCPP/7zip/UI/FileManager/ViewSettings.h98
-rwxr-xr-xCPP/7zip/UI/FileManager/makefile194
-rwxr-xr-xCPP/7zip/UI/FileManager/resource.h159
-rwxr-xr-xCPP/7zip/UI/FileManager/resource.rc237
162 files changed, 22278 insertions, 0 deletions
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 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7-Zip.7-Zip.7zFM" type="win32"/><description>7-Zip File manager.</description><dependency> <dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency></assembly>
diff --git a/CPP/7zip/UI/FileManager/7zipLogo.ico b/CPP/7zip/UI/FileManager/7zipLogo.ico
new file mode 100755
index 00000000..973241c8
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/7zipLogo.ico
Binary files 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
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Add.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Add2.bmp b/CPP/7zip/UI/FileManager/Add2.bmp
new file mode 100755
index 00000000..252fc253
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Add2.bmp
Binary files 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<UInt32> 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<IFolderFolder> 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<IDataObject> 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<IDropTarget> _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 <initguid.h>
+
+#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
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Copy.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Copy2.bmp b/CPP/7zip/UI/FileManager/Copy2.bmp
new file mode 100755
index 00000000..ba88ded0
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Copy2.bmp
Binary files 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
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Delete.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Delete2.bmp b/CPP/7zip/UI/FileManager/Delete2.bmp
new file mode 100755
index 00000000..60e08c6a
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Delete2.bmp
Binary files 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 <windows.h>
+
+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
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Extract.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Extract2.bmp b/CPP/7zip/UI/FileManager/Extract2.bmp
new file mode 100755
index 00000000..a7e57753
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Extract2.bmp
Binary files 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
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/FM.ico
Binary files 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<IFolderFolder> 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<IFolderFolder> 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<CDriveInfo> _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<IFolderFolder> 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<IFolderFolder> 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<IFolderFolder> 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<IFolderFolder> netFolder = netFolderSpec;
+ netFolderSpec->Init(parentPath);
+ *resultFolder = netFolder.Detach();
+ return S_OK;
+ }
+ CFSFolder *parentFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> 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<IFolderFolder> 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<IFolderFolder> subFolder;
+ RINOK(BindToFolder(index, &subFolder));
+ CMyComPtr<IFolderReload> aFolderReload;
+ subFolder.QueryInterface(&aFolderReload);
+ aFolderReload->Reload();
+ UInt32 numItems;
+ RINOK(subFolder->GetNumberOfItems(&numItems));
+ CMyComPtr<IFolderGetItemFullSize> 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<CDirItem> 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<CDirItem *> _refs;
+
+ CMyComPtr<IFolderFolder> _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 <Winbase.h>
+
+#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<CPluginInfo> &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<CPluginInfo> 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<IFolderManager> folderManager;
+ CMyComPtr<IFolderFolder> 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<IProgress> 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<CExtInfo> 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<IFolderManager> 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<CExtInfo> 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<CPluginEnabledPair> 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<CExtInfoBig> ExtBigItems;
+ CObjectVector<CPluginInfo> 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 <HtmlHelp.h>
+
+#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
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Info.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Info2.bmp b/CPP/7zip/UI/FileManager/Info2.bmp
new file mode 100755
index 00000000..af724d27
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Info2.bmp
Binary files 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<CLangEx> 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<CLangEx> &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<CLangEx> 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<CLangEx> &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
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Move.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Move2.bmp b/CPP/7zip/UI/FileManager/Move2.bmp
new file mode 100755
index 00000000..58679eff
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Move2.bmp
Binary files 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<IFolderFolder> subFolder = fsFolderSpec;
+ RINOK(fsFolderSpec->Init(resource.RemoteName + L'\\', this));
+ *resultFolder = subFolder.Detach();
+ }
+ else
+ {
+ CNetFolder *netFolder = new CNetFolder;
+ CMyComPtr<IFolderFolder> 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<IFolderFolder> 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<IFolderFolder> 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<CResourceEx> _items;
+
+ CMyComPtr<IFolderFolder> _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<IInStream> 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<NControl::CPageInfo> 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 <Windowsx.h>
+
+#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 &currentFolderPrefix, 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<IFolderOperations> 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<UInt32> 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<UInt32> 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<UInt32> Indices;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IFolderArchiveExtractCallback> ExtractCallback;
+ CMyComPtr<IArchiveFolder> 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<UInt32> indices;
+ GetOperatedItemIndices(indices);
+ CMyComPtr<IArchiveFolder> 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<CItemProperty>
+{
+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<IFolderFolder> 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<UInt32> &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<PROPID> 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<CFolderLink> _parentFolders;
+ NWindows::NDLL::CLibrary _library;
+ CMyComPtr<IFolderFolder> _folder;
+ // CMyComPtr<IFolderGetSystemIconIndex> _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 &currentFolderPrefix,
+ 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<IContextMenu> _sevenZipContextMenu;
+ CMyComPtr<IContextMenu> _systemContextMenu;
+ HRESULT CreateShellContextMenu(
+ const CRecordVector<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &systemContextMenu);
+ void CreateSystemMenu(HMENU menu,
+ const CRecordVector<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &systemContextMenu);
+ void CreateSevenZipMenu(HMENU menu,
+ const CRecordVector<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &sevenZipContextMenu);
+ void CreateFileMenu(HMENU menu,
+ CMyComPtr<IContextMenu> &sevenZipContextMenu,
+ CMyComPtr<IContextMenu> &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<UInt32> &indices) const;
+ void GetOperatedItemIndices(CRecordVector<UInt32> &indices) const;
+ void GetAllItemIndices(CRecordVector<UInt32> &indices) const;
+ // void GetOperatedListViewIndices(CRecordVector<UInt32> &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<UInt32> &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<IFolderOperations> FolderOperations;
+ CRecordVector<UInt32> Indices;
+ UString DestPath;
+ CExtractCallbackImp *ExtractCallbackSpec;
+ CMyComPtr<IFolderOperationsExtractCallback> 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<UInt32> &indices, const UString &folder,
+ bool moveMode, bool showErrorMessages, UStringVector *messages)
+{
+ CMyComPtr<IFolderOperations> 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<IFolderOperations> FolderOperations;
+ UString FolderPrefix;
+ UStringVector FileNames;
+ CRecordVector<const wchar_t *> FileNamePointers;
+ CMyComPtr<IFolderArchiveUpdateCallback> 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<IFolderOperations> 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<NFind::CEnumeratorW> 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<UInt32> 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<UInt32> Indices;
+ UString Folder;
+ CDataObject *DataObjectSpec;
+ CMyComPtr<IDataObject> 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<UInt32> 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<IDataObject> 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<IDropSource> 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<IFolderFolder> 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<IFolderFolder> 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<IFolderFolder> rootFolder = rootFolderSpec;
+ rootFolderSpec->Init();
+ CMyComPtr<IFolderFolder> 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<IFolderFolder> 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<IFolderFolder> 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<IFolderFolder> 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<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBox(LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
+ return E_FAIL;
+ }
+ UStringVector fileNames;
+ CRecordVector<const wchar_t *> 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<CTmpProcessInfo> _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<CTmpProcessInfo> 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<IFolderOperations> 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<UInt32> 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<CTmpProcessInfo> 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 *)&currentFileTime))
+ 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<UInt32> 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<IFolderSetFlatMode> 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<IFolderGetSystemIconIndex> 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<UInt32> &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<UInt32> &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<UInt32> &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<UInt32> &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<UInt32> 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<IFolderWasChanged> 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<IFolderGetSystemIconIndex> 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<IFolderGetItemFullSize> 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<UINT32> 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<UInt32> operatedIndices;
+ GetOperatedItemIndices(operatedIndices);
+ if (operatedIndices.IsEmpty())
+ return;
+ CMyComPtr<IContextMenu> 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<IGetFolderArchiveProperties> getFolderArchiveProperties;
+ _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties);
+ if (!getFolderArchiveProperties)
+ {
+ InvokeSystemCommand("properties");
+ return;
+ }
+
+ {
+ UString message;
+
+ CRecordVector<UInt32> 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<IFolderProperties> 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<IGetFolderArchiveProperties> getFolderArchiveProperties;
+ _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties);
+ if (getFolderArchiveProperties)
+ {
+ CMyComPtr<IFolderArchiveProperties> 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<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &systemContextMenu)
+{
+ systemContextMenu.Release();
+ UString folderPath = GetFsPath();
+
+ CMyComPtr<IShellFolder> 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<IShellFolder> 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<LPITEMIDLIST> 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<IContextMenu> 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<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &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<UInt32> &operatedIndices,
+ CMyComPtr<IContextMenu> &sevenZipContextMenu)
+{
+ sevenZipContextMenu.Release();
+
+ CMenu menu;
+ menu.Attach(menuSpec);
+ // CMenuDestroyer menuDestroyer(menu);
+ // menu.CreatePopup();
+
+ bool sevenZipMenuCreated = false;
+
+ CMyComPtr<IContextMenu> contextMenu;
+ if (contextMenu.CoCreateInstance(CLSID_CZipContextMenu, IID_IContextMenu) == S_OK)
+ {
+ CMyComPtr<IInitContextMenu> 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<const wchar_t *> 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<IContextMenu> &sevenZipContextMenu,
+ CMyComPtr<IContextMenu> &systemContextMenu,
+ bool programMenu)
+{
+ sevenZipContextMenu.Release();
+ systemContextMenu.Release();
+
+ CRecordVector<UInt32> 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<UInt32> 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<IContextMenu> sevenZipContextMenu;
+ CMyComPtr<IContextMenu> 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<IFolderOperations> FolderOperations;
+ CRecordVector<UInt32> Indices;
+ CMyComPtr<IProgress> 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<IFolderOperations> FolderOperations;
+ UString Name;
+ CMyComPtr<IProgress> 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<UInt32> indices;
+ GetOperatedItemIndices(indices);
+ if (indices.IsEmpty())
+ return;
+ CSelectedState state;
+ SaveSelectedState(state);
+ bool useInternalDelete = false;
+ if (IsFSFolder() && toRecycleBin)
+ {
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ CDynamicBuffer<CHAR> 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<WCHAR> 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<UInt32> &indices)
+{
+ CMyComPtr<IFolderOperations> 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<IFolderOperations> 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<IFolderOperations> 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<IFolderOperations> 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<IFolderOperations> 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<IFolderOperations> 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<UInt64> 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<UInt32> 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<UInt32> 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<IFolderFolder> 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<IFolderFolder> _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<IPluginOptions> 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<IPluginOptionsCallback> 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<CPluginInfo> _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<CExtInfo> &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<CExtInfo> &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<CExtInfo> &items);
+ void WriteInternalAssociations(const CObjectVector<CExtInfo> &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<CPluginInfo> &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<CPluginInfo> &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<CPluginInfo> &plugins);
+void ReadFileFolderPluginInfoList(CObjectVector<CPluginInfo> &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<IFolderFolder> subFolder = fsDrivesSpec;
+ fsDrivesSpec->Init();
+ *resultFolder = subFolder.Detach();
+ }
+ else if (index == 1)
+ {
+ CNetFolder *netFolderSpec = new CNetFolder;
+ CMyComPtr<IFolderFolder> 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<IFolderFolder> 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<IFolderFolder> subFolder = this;
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+ }
+
+ if (name2.Length () < 2)
+ return E_INVALIDARG;
+
+ CMyComPtr<IFolderFolder> 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<UInt64> 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<UInt64> &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<UInt64> &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<UInt64> &values);
+void AddVolumeItems(NWindows::NControl::CComboBox &volumeCombo);
+
+UInt64 GetNumberOfVolumes(UInt64 size, CRecordVector<UInt64> &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 <windows.h>
+#include <stdio.h>
+#include <commctrl.h>
+#include <ShlObj.h>
+#include <limits.h>
+#include <tchar.h>
+#include <shlwapi.h>
+
+// #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<CExtIconPair> _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<IFolderManager> folderManager;
+ CMyComPtr<IFolderFolder> 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<NZipRootRegistry::CArchiverInfo> 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
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Test.bmp
Binary files differ
diff --git a/CPP/7zip/UI/FileManager/Test2.bmp b/CPP/7zip/UI/FileManager/Test2.bmp
new file mode 100755
index 00000000..99b7dbf0
--- /dev/null
+++ b/CPP/7zip/UI/FileManager/Test2.bmp
Binary files 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<CTextPair> &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<CTextPair> &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<CTextPair> &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<CTextPair> 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<CColumnInfo> &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<CColumnInfo> &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 &currentPanel, 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<wchar_t> 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<CColumnInfo> 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 &currentPanel, 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"