mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 08:07:09 -06:00
4.23
This commit is contained in:
committed by
Kornel Lesiński
parent
3c510ba80b
commit
ac2b563958
@@ -16,7 +16,6 @@
|
||||
#include "Resource/CopyDialog/CopyDialog.h"
|
||||
|
||||
#include "ExtractCallback.h"
|
||||
#include "UpdateCallback100.h"
|
||||
#include "ViewSettings.h"
|
||||
#include "RegistryUtils.h"
|
||||
|
||||
@@ -27,6 +26,8 @@ using namespace NFind;
|
||||
extern DWORD g_ComCtl32Version;
|
||||
extern HINSTANCE g_hInstance;
|
||||
|
||||
static LPCWSTR kTempDirPrefix = L"7zE";
|
||||
|
||||
void CPanelCallbackImp::OnTab()
|
||||
{
|
||||
if (g_App.NumPanels != 1)
|
||||
@@ -42,8 +43,8 @@ void CPanelCallbackImp::SetFocusToPath(int index)
|
||||
}
|
||||
|
||||
|
||||
void CPanelCallbackImp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame)
|
||||
{ _app->OnCopy(externalNames, move, copyToSame, _index); }
|
||||
void CPanelCallbackImp::OnCopy(bool move, bool copyToSame)
|
||||
{ _app->OnCopy(move, copyToSame, _index); }
|
||||
|
||||
void CPanelCallbackImp::OnSetSameFolder()
|
||||
{ _app->OnSetSameFolder(_index); }
|
||||
@@ -52,9 +53,13 @@ void CPanelCallbackImp::OnSetSubFolder()
|
||||
{ _app->OnSetSubFolder(_index); }
|
||||
|
||||
void CPanelCallbackImp::PanelWasFocused()
|
||||
{
|
||||
_app->LastFocusedPanel = _index;
|
||||
}
|
||||
{ _app->SetFocusedPanel(_index); }
|
||||
|
||||
void CPanelCallbackImp::DragBegin()
|
||||
{ _app->DragBegin(_index); }
|
||||
|
||||
void CPanelCallbackImp::DragEnd()
|
||||
{ _app->DragEnd(); }
|
||||
|
||||
void CApp::SetListSettings()
|
||||
{
|
||||
@@ -350,6 +355,7 @@ void CApp::Create(HWND hwnd, const UString &mainPath, int xSizes[2])
|
||||
Panels[i]._xSize = xSizes[0] + xSizes[1];
|
||||
CreateOnePanel(i, (i == LastFocusedPanel) ? mainPath : L"");
|
||||
}
|
||||
SetFocusedPanel(LastFocusedPanel);
|
||||
Panels[LastFocusedPanel].SetFocusToList();
|
||||
}
|
||||
|
||||
@@ -398,111 +404,55 @@ void CApp::Release()
|
||||
Panels[i].Release();
|
||||
}
|
||||
|
||||
class CWindowDisable
|
||||
static bool IsThereFolderOfPath(const UString &path)
|
||||
{
|
||||
bool _wasEnabled;
|
||||
CWindow _window;
|
||||
public:
|
||||
CWindowDisable(HWND window): _window(window)
|
||||
{
|
||||
_wasEnabled = _window.IsEnabled();
|
||||
if (_wasEnabled)
|
||||
_window.Enable(false);
|
||||
}
|
||||
~CWindowDisable()
|
||||
{
|
||||
if (_wasEnabled)
|
||||
_window.Enable(true);
|
||||
}
|
||||
};
|
||||
CFileInfoW fileInfo;
|
||||
if (!FindFile(path, fileInfo))
|
||||
return false;
|
||||
return fileInfo.IsDirectory();
|
||||
}
|
||||
|
||||
struct CThreadExtract
|
||||
// reduces path to part that exists on disk
|
||||
static void ReducePathToRealFileSystemPath(UString &path)
|
||||
{
|
||||
bool Move;
|
||||
CMyComPtr<IFolderOperations> FolderOperations;
|
||||
CRecordVector<UINT32> Indices;
|
||||
UString DestPath;
|
||||
CExtractCallbackImp *ExtractCallbackSpec;
|
||||
CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
|
||||
HRESULT Result;
|
||||
|
||||
DWORD Extract()
|
||||
while(!path.IsEmpty())
|
||||
{
|
||||
NCOM::CComInitializer comInitializer;
|
||||
ExtractCallbackSpec->ProgressDialog.WaitCreating();
|
||||
if (Move)
|
||||
if (IsThereFolderOfPath(path))
|
||||
{
|
||||
Result = FolderOperations->MoveTo(
|
||||
&Indices.Front(), Indices.Size(),
|
||||
DestPath, ExtractCallback);
|
||||
// ExtractCallbackSpec->DestroyWindows();
|
||||
NName::NormalizeDirPathPrefix(path);
|
||||
break;
|
||||
}
|
||||
int pos = path.ReverseFind('\\');
|
||||
if (pos < 0)
|
||||
path.Empty();
|
||||
else
|
||||
{
|
||||
Result = FolderOperations->CopyTo(
|
||||
&Indices.Front(), Indices.Size(),
|
||||
DestPath, ExtractCallback);
|
||||
// ExtractCallbackSpec->DestroyWindows();
|
||||
path = path.Left(pos + 1);
|
||||
if (path.Length() == 3 && path[1] == L':')
|
||||
break;
|
||||
path = path.Left(pos);
|
||||
}
|
||||
ExtractCallbackSpec->ProgressDialog.MyClose();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD WINAPI MyThreadFunction(void *param)
|
||||
{
|
||||
return ((CThreadExtract *)param)->Extract();
|
||||
}
|
||||
};
|
||||
|
||||
struct CThreadUpdate
|
||||
// return true for dir\, if dir exist
|
||||
static bool CheckFolderPath(const UString &path)
|
||||
{
|
||||
bool Move;
|
||||
CMyComPtr<IFolderOperations> FolderOperations;
|
||||
UString SrcFolderPrefix;
|
||||
UStringVector FileNames;
|
||||
CRecordVector<const wchar_t *> FileNamePointers;
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;
|
||||
CUpdateCallback100Imp *UpdateCallbackSpec;
|
||||
HRESULT Result;
|
||||
|
||||
DWORD Process()
|
||||
{
|
||||
NCOM::CComInitializer comInitializer;
|
||||
UpdateCallbackSpec->ProgressDialog.WaitCreating();
|
||||
if (Move)
|
||||
{
|
||||
{
|
||||
throw 1;
|
||||
// srcPanel.MessageBoxMyError(L"Move is not supported");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = FolderOperations->CopyFrom(
|
||||
SrcFolderPrefix,
|
||||
&FileNamePointers.Front(),
|
||||
FileNamePointers.Size(),
|
||||
UpdateCallback);
|
||||
}
|
||||
UpdateCallbackSpec->ProgressDialog.MyClose();
|
||||
return 0;
|
||||
}
|
||||
UString pathReduced = path;
|
||||
ReducePathToRealFileSystemPath(pathReduced);
|
||||
return (pathReduced == path);
|
||||
}
|
||||
|
||||
static DWORD WINAPI MyThreadFunction(void *param)
|
||||
{
|
||||
return ((CThreadUpdate *)param)->Process();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int srcPanelIndex)
|
||||
static bool IsPathAbsolute(const UString &path)
|
||||
{
|
||||
bool external = (externalNames.Size() > 0);
|
||||
if (external)
|
||||
copyToSame = true;
|
||||
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];
|
||||
@@ -510,220 +460,162 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int
|
||||
CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel);
|
||||
CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel);
|
||||
|
||||
bool useSrcPanel = true;
|
||||
if (!external)
|
||||
if (NumPanels != 1)
|
||||
{
|
||||
if (!srcPanel.IsFSFolder() && !destPanel.IsFSFolder())
|
||||
{
|
||||
srcPanel.MessageBox(LangLoadStringW(IDS_CANNOT_COPY, 0x03020207));
|
||||
return;
|
||||
}
|
||||
useSrcPanel = copyToSame || destPanel.IsFSFolder();
|
||||
if (move && !useSrcPanel)
|
||||
{
|
||||
srcPanel.MessageBoxMyError(L"Move is not supported");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!srcPanel.DoesItSupportOperations())
|
||||
{
|
||||
srcPanel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
|
||||
return;
|
||||
}
|
||||
|
||||
CPanel &panel = useSrcPanel ? srcPanel : destPanel;
|
||||
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
|
||||
// if (move)
|
||||
if (panel._folder.QueryInterface(IID_IFolderOperations,
|
||||
&folderOperations) != S_OK)
|
||||
{
|
||||
panel.MessageBox(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
|
||||
return;
|
||||
}
|
||||
|
||||
CRecordVector<UINT32> indices;
|
||||
CRecordVector<UInt32> indices;
|
||||
UString destPath;
|
||||
bool useDestPanel = false;
|
||||
|
||||
if (external)
|
||||
{
|
||||
UString message = L"Are you sure you want to copy files to archive \'";
|
||||
message += srcPanel._currentFolderPrefix;
|
||||
message += L"\'?";
|
||||
int res = MessageBoxW(_window, message, L"Confirm File Copy",
|
||||
MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL);
|
||||
if (res != IDYES)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCopyDialog copyDialog;
|
||||
|
||||
UStringVector copyFolders;
|
||||
ReadCopyHistory(copyFolders);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < copyFolders.Size(); i++)
|
||||
copyDialog.Strings.Add(GetSystemString(copyFolders[i]));
|
||||
|
||||
if (copyToSame)
|
||||
{
|
||||
int focusedItem = srcPanel._listView.GetFocusedItem();
|
||||
if (focusedItem < 0)
|
||||
return;
|
||||
int realIndex = srcPanel.GetRealItemIndex(focusedItem);
|
||||
if (realIndex == -1)
|
||||
return;
|
||||
indices.Add(realIndex);
|
||||
copyDialog.Value = srcPanel.GetItemName(realIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
srcPanel.GetOperatedItemIndices(indices);
|
||||
if (indices.Size() == 0)
|
||||
return;
|
||||
UString destPath = destPanel._currentFolderPrefix;
|
||||
if (NumPanels == 1)
|
||||
if (copyToSame)
|
||||
{
|
||||
while(!destPath.IsEmpty())
|
||||
{
|
||||
CFileInfoW fileInfo;
|
||||
if (FindFile(destPath, fileInfo))
|
||||
{
|
||||
if (fileInfo.IsDirectory())
|
||||
{
|
||||
destPath += L'\\';
|
||||
break;
|
||||
}
|
||||
}
|
||||
int pos = destPath.ReverseFind('\\');
|
||||
if (pos < 0)
|
||||
destPath.Empty();
|
||||
else
|
||||
{
|
||||
destPath = destPath.Left(pos + 1);
|
||||
if (destPath.Length() == 3 && destPath[1] == L':')
|
||||
break;
|
||||
destPath = destPath.Left(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
copyDialog.Value = destPath;
|
||||
}
|
||||
copyDialog.Title = move ?
|
||||
LangLoadStringW(IDS_MOVE, 0x03020202):
|
||||
LangLoadStringW(IDS_COPY, 0x03020201);
|
||||
copyDialog.Static = move ?
|
||||
LangLoadStringW(IDS_MOVE_TO, 0x03020204):
|
||||
LangLoadStringW(IDS_COPY_TO, 0x03020203);
|
||||
if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL)
|
||||
return;
|
||||
|
||||
AddUniqueStringToHeadOfList(copyFolders, GetUnicodeString(
|
||||
copyDialog.Value));
|
||||
while (copyFolders.Size() > 20)
|
||||
copyFolders.DeleteBack();
|
||||
|
||||
SaveCopyHistory(copyFolders);
|
||||
|
||||
/// ?????
|
||||
SetCurrentDirectory(GetSystemString(srcPanel._currentFolderPrefix));
|
||||
|
||||
if (!NDirectory::MyGetFullPathName(copyDialog.Value, destPath))
|
||||
{
|
||||
srcPanel.MessageBoxLastError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (destPath.Length() > 0 && destPath.ReverseFind('\\') == destPath.Length() - 1)
|
||||
NDirectory::CreateComplexDirectory(destPath);
|
||||
}
|
||||
|
||||
UString title = move ?
|
||||
LangLoadStringW(IDS_MOVING, 0x03020206):
|
||||
LangLoadStringW(IDS_COPYING, 0x03020205);
|
||||
UString progressWindowTitle = LangLoadStringW(IDS_APP_TITLE, 0x03000000);
|
||||
|
||||
CSelectedState srcSelState;
|
||||
CSelectedState destSelState;
|
||||
if (copyToSame || move)
|
||||
srcPanel.SaveSelectedState(srcSelState);
|
||||
if (!copyToSame)
|
||||
destPanel.SaveSelectedState(destSelState);
|
||||
|
||||
HRESULT result;
|
||||
if (useSrcPanel && !external)
|
||||
{
|
||||
CThreadExtract extracter;
|
||||
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
|
||||
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
|
||||
extracter.ExtractCallbackSpec->ParentWindow = _window;
|
||||
|
||||
extracter.ExtractCallbackSpec->ProgressDialog.MainWindow = _window;
|
||||
extracter.ExtractCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
|
||||
extracter.ExtractCallbackSpec->ProgressDialog.MainAddTitle = title + L" ";
|
||||
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
|
||||
|
||||
extracter.ExtractCallbackSpec->Init();
|
||||
extracter.Move = move;
|
||||
extracter.FolderOperations = folderOperations;
|
||||
extracter.Indices = indices;;
|
||||
extracter.DestPath = GetUnicodeString(destPath);
|
||||
CThread thread;
|
||||
if (!thread.Create(CThreadExtract::MyThreadFunction, &extracter))
|
||||
throw 271824;
|
||||
extracter.ExtractCallbackSpec->StartProgressDialog(title);
|
||||
result = extracter.Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
CThreadUpdate updater;
|
||||
updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
|
||||
updater.UpdateCallback = updater.UpdateCallbackSpec;
|
||||
|
||||
updater.UpdateCallbackSpec->ProgressDialog.MainWindow = _window;
|
||||
updater.UpdateCallbackSpec->ProgressDialog.MainTitle = progressWindowTitle;
|
||||
updater.UpdateCallbackSpec->ProgressDialog.MainAddTitle = title + UString(L" ");
|
||||
|
||||
updater.UpdateCallbackSpec->Init(_window, false, L"");
|
||||
updater.Move = move;
|
||||
updater.FolderOperations = folderOperations;
|
||||
if (external)
|
||||
{
|
||||
updater.FileNames.Reserve(externalNames.Size());
|
||||
for(int i = 0; i < externalNames.Size(); i++)
|
||||
updater.FileNames.Add(externalNames[i]);
|
||||
int focusedItem = srcPanel._listView.GetFocusedItem();
|
||||
if (focusedItem < 0)
|
||||
return;
|
||||
int realIndex = srcPanel.GetRealItemIndex(focusedItem);
|
||||
if (realIndex == -1)
|
||||
return;
|
||||
indices.Add(realIndex);
|
||||
destPath = srcPanel.GetItemName(realIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
updater.SrcFolderPrefix = srcPanel._currentFolderPrefix;
|
||||
updater.FileNames.Reserve(indices.Size());
|
||||
for(int i = 0; i < indices.Size(); i++)
|
||||
updater.FileNames.Add(srcPanel.GetItemName(indices[i]));
|
||||
srcPanel.GetOperatedItemIndices(indices);
|
||||
if (indices.Size() == 0)
|
||||
return;
|
||||
destPath = destPanel._currentFolderPrefix;
|
||||
if (NumPanels == 1)
|
||||
ReducePathToRealFileSystemPath(destPath);
|
||||
}
|
||||
updater.FileNamePointers.Reserve(updater.FileNames.Size());
|
||||
int i;
|
||||
for(i = 0; i < updater.FileNames.Size(); i++)
|
||||
updater.FileNamePointers.Add(updater.FileNames[i]);
|
||||
CThread thread;
|
||||
if (!thread.Create(CThreadUpdate::MyThreadFunction, &updater))
|
||||
throw 271824;
|
||||
updater.UpdateCallbackSpec->StartProgressDialog(title);
|
||||
result = updater.Result;
|
||||
|
||||
CCopyDialog copyDialog;
|
||||
UStringVector copyFolders;
|
||||
ReadCopyHistory(copyFolders);
|
||||
|
||||
copyDialog.Strings = copyFolders;
|
||||
copyDialog.Value = destPath;
|
||||
|
||||
copyDialog.Title = move ?
|
||||
LangLoadStringW(IDS_MOVE, 0x03020202):
|
||||
LangLoadStringW(IDS_COPY, 0x03020201);
|
||||
copyDialog.Static = move ?
|
||||
LangLoadStringW(IDS_MOVE_TO, 0x03020204):
|
||||
LangLoadStringW(IDS_COPY_TO, 0x03020203);
|
||||
|
||||
if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL)
|
||||
return;
|
||||
|
||||
destPath = copyDialog.Value;
|
||||
|
||||
if (!IsPathAbsolute(destPath))
|
||||
{
|
||||
if (!srcPanel.IsFSFolder())
|
||||
{
|
||||
srcPanel.MessageBox(LangLoadStringW(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(LangLoadStringW(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(LangLoadStringW(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddUniqueStringToHeadOfList(copyFolders, destPath);
|
||||
while (copyFolders.Size() > 20)
|
||||
copyFolders.DeleteBack();
|
||||
SaveCopyHistory(copyFolders);
|
||||
}
|
||||
|
||||
/*
|
||||
if (useSrcPanel)
|
||||
extractCallbackSpec->DestroyWindows();
|
||||
*/
|
||||
|
||||
if (result != S_OK)
|
||||
bool useSrcPanel = (!useDestPanel || !srcPanel.IsFSFolder() || destPanel.IsFSFolder());
|
||||
bool useTemp = useSrcPanel && useDestPanel;
|
||||
NFile::NDirectory::CTempDirectoryW tempDirectory;
|
||||
UString tempDirPrefix;
|
||||
if (useTemp)
|
||||
{
|
||||
disableTimerProcessing1.Restore();
|
||||
disableTimerProcessing2.Restore();
|
||||
// For Password:
|
||||
srcPanel.SetFocusToList();
|
||||
if (result != E_ABORT)
|
||||
srcPanel.MessageBoxError(result, L"Error");
|
||||
return;
|
||||
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.GetItemName(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);
|
||||
@@ -738,7 +630,6 @@ void CApp::OnCopy(UStringVector &externalNames, bool move, bool copyToSame, int
|
||||
srcPanel.SetFocusToList();
|
||||
}
|
||||
|
||||
|
||||
void CApp::OnSetSameFolder(int srcPanelIndex)
|
||||
{
|
||||
if (NumPanels <= 1)
|
||||
|
||||
@@ -35,16 +35,69 @@ public:
|
||||
}
|
||||
virtual void OnTab();
|
||||
virtual void SetFocusToPath(int index);
|
||||
virtual void OnCopy(UStringVector &externalNames, bool move, bool copyToSame);
|
||||
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;
|
||||
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).
|
||||
|
||||
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) {}
|
||||
|
||||
CApp *App;
|
||||
int SrcPanelIndex; // index of D&D source_panel
|
||||
int TargetPanelIndex; // what panel to use as target_panel of Application
|
||||
};
|
||||
|
||||
class CApp
|
||||
{
|
||||
NWindows::CWindow _window;
|
||||
public:
|
||||
NWindows::CWindow _window;
|
||||
bool ShowSystemMenu;
|
||||
int NumPanels;
|
||||
int LastFocusedPanel;
|
||||
@@ -65,9 +118,37 @@ public:
|
||||
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(UStringVector &externalNames,
|
||||
bool move, bool copyToSame, int srcPanelIndex);
|
||||
void OnCopy(bool move, bool copyToSame, int srcPanelIndex);
|
||||
void OnSetSameFolder(int srcPanelIndex);
|
||||
void OnSetSubFolder(int srcPanelIndex);
|
||||
|
||||
@@ -87,6 +168,8 @@ public:
|
||||
|
||||
int GetFocusedPanelIndex() const { return LastFocusedPanel; }
|
||||
|
||||
bool IsPanelVisible(int index) const { return (NumPanels > 1 || index == LastFocusedPanel); }
|
||||
|
||||
/*
|
||||
void SetCurrentIndex()
|
||||
{ CurrentPanel = GetFocusedPanelIndex(); }
|
||||
@@ -108,9 +191,9 @@ public:
|
||||
void Rename()
|
||||
{ GetFocusedPanel().RenameFile(); }
|
||||
void CopyTo()
|
||||
{ OnCopy(UStringVector(), false, false, GetFocusedPanelIndex()); }
|
||||
{ OnCopy(false, false, GetFocusedPanelIndex()); }
|
||||
void MoveTo()
|
||||
{ OnCopy(UStringVector(), true, false, GetFocusedPanelIndex()); }
|
||||
{ OnCopy(true, false, GetFocusedPanelIndex()); }
|
||||
void Delete()
|
||||
{ GetFocusedPanel().DeleteItems(); }
|
||||
void Split();
|
||||
|
||||
@@ -2,28 +2,14 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
// #define INITGUID
|
||||
#include <initguid.h>
|
||||
|
||||
#include "IFolder.h"
|
||||
#include "../IPassword.h"
|
||||
// #include "../Archiver/Format/Common/ArchiveInterface.h"
|
||||
#include "PluginInterface.h"
|
||||
#include "ExtractCallback.h"
|
||||
#include "../ICoder.h"
|
||||
|
||||
/*
|
||||
// {23170F69-40C1-278A-1000-000100030000}
|
||||
DEFINE_GUID(CLSID_CAgentArchiveHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00);
|
||||
*/
|
||||
|
||||
// {23170F69-40C1-278A-1000-000100020000}
|
||||
DEFINE_GUID(CLSID_CZipContextMenu,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00);
|
||||
|
||||
/*
|
||||
// {23170F69-40C1-278F-1000-000110050000}
|
||||
DEFINE_GUID(CLSID_CTest,
|
||||
0x23170F69, 0x40C1, 0x278F, 0x10, 0x00, 0x00, 0x01, 0x10, 0x05, 0x00, 0x00);
|
||||
*/
|
||||
|
||||
108
7zip/FileManager/EnumFormatEtc.cpp
Executable file
108
7zip/FileManager/EnumFormatEtc.cpp
Executable file
@@ -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(int 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;
|
||||
}
|
||||
10
7zip/FileManager/EnumFormatEtc.h
Executable file
10
7zip/FileManager/EnumFormatEtc.h
Executable file
@@ -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
|
||||
@@ -27,7 +27,7 @@ using namespace NFind;
|
||||
|
||||
CExtractCallbackImp::~CExtractCallbackImp()
|
||||
{
|
||||
if (!Messages.IsEmpty())
|
||||
if (ShowMessages && !Messages.IsEmpty())
|
||||
{
|
||||
CMessagesDialog messagesDialog;
|
||||
messagesDialog.Messages = &Messages;
|
||||
@@ -43,7 +43,7 @@ void CExtractCallbackImp::Init()
|
||||
|
||||
void CExtractCallbackImp::AddErrorMessage(LPCWSTR message)
|
||||
{
|
||||
Messages.Add(GetSystemString(message));
|
||||
Messages.Add(message);
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetTotal(UInt64 total)
|
||||
|
||||
@@ -95,7 +95,8 @@ private:
|
||||
void AddErrorMessage(LPCWSTR message);
|
||||
public:
|
||||
CProgressDialog ProgressDialog;
|
||||
CSysStringVector Messages;
|
||||
UStringVector Messages;
|
||||
bool ShowMessages;
|
||||
HWND ParentWindow;
|
||||
INT_PTR StartProgressDialog(const UString &title)
|
||||
{
|
||||
@@ -114,7 +115,8 @@ public:
|
||||
PasswordIsDefined(false),
|
||||
#endif
|
||||
OverwriteMode(NExtract::NOverwriteMode::kAskBefore),
|
||||
ParentWindow(0)
|
||||
ParentWindow(0),
|
||||
ShowMessages(true)
|
||||
{}
|
||||
|
||||
~CExtractCallbackImp();
|
||||
|
||||
@@ -304,7 +304,10 @@ int WINAPI WinMain( HINSTANCE hInstance,
|
||||
|
||||
g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
|
||||
|
||||
NCOM::CComInitializer comInitializer;
|
||||
// OleInitialize is required for drag and drop.
|
||||
OleInitialize(NULL);
|
||||
// Maybe needs CoInitializeEx also ?
|
||||
// NCOM::CComInitializer comInitializer;
|
||||
|
||||
UString programString, commandsString;
|
||||
// MessageBoxW(0, GetCommandLineW(), L"", 0);
|
||||
@@ -343,6 +346,7 @@ int WINAPI WinMain( HINSTANCE hInstance,
|
||||
}
|
||||
|
||||
g_HWND = 0;
|
||||
OleUninitialize();
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
@@ -459,15 +463,22 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
xSizes[1] = xSize - kSplitterWidth - xSizes[0];
|
||||
if (xSizes[1] < 0)
|
||||
xSizes[1] = 0;
|
||||
|
||||
g_App.CreateDragTarget();
|
||||
g_App.Create(hWnd, g_MainPath, xSizes);
|
||||
// g_SplitterPos = 0;
|
||||
|
||||
DragAcceptFiles(hWnd, TRUE);
|
||||
// ::DragAcceptFiles(hWnd, TRUE);
|
||||
RegisterDragDrop(hWnd, g_App._dropTarget);
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_DESTROY:
|
||||
{
|
||||
::DragAcceptFiles(hWnd, FALSE);
|
||||
// ::DragAcceptFiles(hWnd, FALSE);
|
||||
RevokeDragDrop(hWnd);
|
||||
g_App._dropTarget.Release();
|
||||
|
||||
g_App.Save();
|
||||
g_App.Release();
|
||||
SaveWindowInfo(hWnd);
|
||||
@@ -559,11 +570,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
g_App.OnNotify(wParam, (LPNMHDR)lParam);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
case WM_DROPFILES:
|
||||
{
|
||||
g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam);
|
||||
return 0 ;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
@@ -319,6 +319,14 @@ 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
|
||||
@@ -335,6 +343,14 @@ SOURCE=.\Panel.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\PanelCopy.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
|
||||
@@ -788,6 +804,14 @@ 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\Menu.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -1126,6 +1150,10 @@ 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
|
||||
|
||||
42
7zip/FileManager/MyCom2.h
Executable file
42
7zip/FileManager/MyCom2.h
Executable file
@@ -0,0 +1,42 @@
|
||||
// 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) \
|
||||
)
|
||||
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Windows/Error.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Shell.h"
|
||||
|
||||
#include "../PropID.h"
|
||||
|
||||
@@ -60,6 +59,7 @@ LRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
|
||||
_processTimer = true;
|
||||
_processNotify = true;
|
||||
|
||||
|
||||
_panelCallback = panelCallback;
|
||||
_appState = appState;
|
||||
// _index = index;
|
||||
@@ -107,9 +107,11 @@ LRESULT CPanel::OnMessage(UINT message, UINT wParam, LPARAM lParam)
|
||||
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);
|
||||
}
|
||||
@@ -488,13 +490,12 @@ bool CPanel::OnCreate(CREATESTRUCT *createStruct)
|
||||
// InitListCtrl();
|
||||
RefreshListCtrl();
|
||||
RefreshStatusBar();
|
||||
::DragAcceptFiles(HWND(*this), TRUE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPanel::OnDestroy()
|
||||
{
|
||||
::DragAcceptFiles(HWND(*this), FALSE);
|
||||
SaveListViewInfo();
|
||||
CWindow2::OnDestroy();
|
||||
}
|
||||
@@ -651,6 +652,17 @@ bool CPanel::IsFSFolder() const
|
||||
return (GetFolderTypeID() == L"FSFolder");
|
||||
}
|
||||
|
||||
bool CPanel::IsFSDrivesFolder() const
|
||||
{
|
||||
return (GetFolderTypeID() == L"FSDrives");
|
||||
}
|
||||
|
||||
bool CPanel::DoesItSupportOperations() const
|
||||
{
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
return _folder.QueryInterface(IID_IFolderOperations, &folderOperations) == S_OK;
|
||||
}
|
||||
|
||||
void CPanel::SetListViewMode(UINT32 index)
|
||||
{
|
||||
if (index >= 4)
|
||||
@@ -668,37 +680,6 @@ void CPanel::RefreshStatusBar()
|
||||
PostMessage(kRefreshStatusBar);
|
||||
}
|
||||
|
||||
void CPanel::CompressDropFiles(HDROP dr)
|
||||
{
|
||||
NShell::CDrop drop(true);
|
||||
drop.Attach(dr);
|
||||
CSysStringVector fileNames;
|
||||
drop.QueryFileNames(fileNames);
|
||||
if (fileNames.Size() == 0)
|
||||
return;
|
||||
UStringVector fileNamesUnicode;
|
||||
for (int i = 0; i < fileNames.Size(); i++)
|
||||
fileNamesUnicode.Add(GetUnicodeString(fileNames[i]));
|
||||
const UString archiveName = CreateArchiveName(
|
||||
fileNamesUnicode.Front(), (fileNamesUnicode.Size() > 1), false);
|
||||
UString currentDirectory;
|
||||
if (IsFSFolder())
|
||||
{
|
||||
CompressFiles(_currentFolderPrefix, archiveName, fileNamesUnicode,
|
||||
false, // email
|
||||
true // showDialog
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
_panelCallback->OnCopy(fileNamesUnicode, false, true);
|
||||
/*
|
||||
if (!NFile::NDirectory::GetOnlyDirPrefix(fileNames.Front(), currentDirectory))
|
||||
return;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void CPanel::AddToArchive()
|
||||
{
|
||||
CRecordVector<UINT32> indices;
|
||||
@@ -722,7 +703,7 @@ void CPanel::AddToArchive()
|
||||
const UString archiveName = CreateArchiveName(
|
||||
names.Front(), (names.Size() > 1), false);
|
||||
CompressFiles(_currentFolderPrefix, archiveName,
|
||||
names, false, true);
|
||||
names, false, true, false);
|
||||
KillSelection();
|
||||
}
|
||||
|
||||
@@ -730,7 +711,7 @@ void CPanel::ExtractArchives()
|
||||
{
|
||||
if (_parentFolders.Size() > 0)
|
||||
{
|
||||
_panelCallback->OnCopy(UStringVector(), false, false);
|
||||
_panelCallback->OnCopy(false, false);
|
||||
return;
|
||||
}
|
||||
CRecordVector<UINT32> indices;
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
#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"
|
||||
@@ -12,21 +20,11 @@
|
||||
#include "Windows/Control/Window2.h"
|
||||
#include "Windows/Control/StatusBar.h"
|
||||
|
||||
#include "Windows/DLL.h"
|
||||
#include "Windows/FileFind.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/Synchronization.h"
|
||||
#include "Windows/Handle.h"
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "SysIconUtils.h"
|
||||
|
||||
#include "IFolder.h"
|
||||
|
||||
#include "ViewSettings.h"
|
||||
|
||||
#include "AppState.h"
|
||||
#include "MyCom2.h"
|
||||
|
||||
const int kParentFolderID = 100;
|
||||
const int kPluginMenuStartID = 1000;
|
||||
@@ -37,10 +35,12 @@ class CPanelCallback
|
||||
public:
|
||||
virtual void OnTab() = 0;
|
||||
virtual void SetFocusToPath(int index) = 0;
|
||||
virtual void OnCopy(UStringVector &externalNames, bool move, bool copyToSame) = 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();
|
||||
@@ -76,13 +76,13 @@ public:
|
||||
struct CTempFileInfo
|
||||
{
|
||||
UString ItemName;
|
||||
CSysString FolderPath;
|
||||
CSysString FilePath;
|
||||
NWindows::NFile::NFind::CFileInfo FileInfo;
|
||||
UString FolderPath;
|
||||
UString FilePath;
|
||||
NWindows::NFile::NFind::CFileInfoW FileInfo;
|
||||
void DeleteDirAndFile()
|
||||
{
|
||||
NWindows::NFile::NDirectory::DeleteFileAlways(FilePath);
|
||||
::RemoveDirectory(FolderPath);
|
||||
NWindows::NFile::NDirectory::MyRemoveDirectory(FolderPath);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -90,7 +90,6 @@ struct CFolderLink: public CTempFileInfo
|
||||
{
|
||||
NWindows::NDLL::CLibrary Library;
|
||||
CMyComPtr<IFolderFolder> ParentFolder;
|
||||
// CSysString RealPath;
|
||||
};
|
||||
|
||||
enum MyMessages
|
||||
@@ -144,7 +143,6 @@ class CPanel:public NWindows::NControl::CWindow2
|
||||
HWND _mainWindow;
|
||||
|
||||
CExtToIconMap _extToIconMap;
|
||||
// int _index;
|
||||
UINT _baseID;
|
||||
int _comboBoxID;
|
||||
UINT _statusBarID;
|
||||
@@ -162,7 +160,7 @@ class CPanel:public NWindows::NControl::CWindow2
|
||||
bool OnNotifyReBar(LPNMHDR lParam, LRESULT &result);
|
||||
bool OnNotifyComboBox(LPNMHDR lParam, LRESULT &result);
|
||||
bool OnNotifyList(LPNMHDR lParam, LRESULT &result);
|
||||
// void OnDrag(LPNMLISTVIEW nmListView);
|
||||
void OnDrag(LPNMLISTVIEW nmListView);
|
||||
bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result);
|
||||
BOOL OnBeginLabelEdit(LV_DISPINFO * lpnmh);
|
||||
BOOL OnEndLabelEdit(LV_DISPINFO * lpnmh);
|
||||
@@ -176,8 +174,6 @@ public:
|
||||
void CreateFolder();
|
||||
void CreateFile();
|
||||
|
||||
// void Split();
|
||||
|
||||
private:
|
||||
|
||||
void ChangeWindowSize(int xSize, int ySize);
|
||||
@@ -222,8 +218,8 @@ public:
|
||||
bool _showDots;
|
||||
bool _showRealFileIcons;
|
||||
// bool _virtualMode;
|
||||
// CUIntVector _realIndices;
|
||||
CBoolVector _selectedStatusVector;
|
||||
CUIntVector _realIndices;
|
||||
|
||||
UInt32 GetRealIndex(const LVITEM &item) const
|
||||
{
|
||||
@@ -375,11 +371,15 @@ public:
|
||||
|
||||
void GetSelectedItemsIndices(CRecordVector<UInt32> &indices) const;
|
||||
void GetOperatedItemIndices(CRecordVector<UInt32> &indices) const;
|
||||
// void GetOperatedListViewIndices(CRecordVector<UInt32> &indices) const;
|
||||
void KillSelection();
|
||||
|
||||
UString GetFolderTypeID() const;
|
||||
bool IsRootFolder() const;
|
||||
bool IsFSFolder() const;
|
||||
bool IsFSDrivesFolder() const;
|
||||
|
||||
bool DoesItSupportOperations() const;
|
||||
|
||||
bool _processTimer;
|
||||
bool _processNotify;
|
||||
@@ -430,14 +430,13 @@ public:
|
||||
void OpenFolder(int index);
|
||||
HRESULT OpenParentArchiveFolder();
|
||||
HRESULT OpenItemAsArchive(const UString &name,
|
||||
const CSysString &folderPath,
|
||||
const CSysString &filePath);
|
||||
const UString &folderPath,
|
||||
const UString &filePath);
|
||||
HRESULT OpenItemAsArchive(const UString &aName);
|
||||
HRESULT OpenItemAsArchive(int index);
|
||||
// void OpenItem(int index, CSysString realPath);
|
||||
void OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
|
||||
bool editMode);
|
||||
LRESULT OnOpenItemChanged(const CSysString &folderPath, const UString &itemName);
|
||||
LRESULT OnOpenItemChanged(const UString &folderPath, const UString &itemName);
|
||||
LRESULT OnOpenItemChanged(LPARAM lParam);
|
||||
|
||||
void OpenItem(int index, bool tryInternal, bool tryExternal);
|
||||
@@ -453,11 +452,23 @@ public:
|
||||
void RefreshStatusBar();
|
||||
void OnRefreshStatusBar();
|
||||
|
||||
void CompressDropFiles(HDROP dr);
|
||||
|
||||
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
|
||||
|
||||
@@ -1,10 +1,209 @@
|
||||
// PanelCopy.cpp
|
||||
// PanelExtract.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "App.h"
|
||||
#include "Windows/COM.h"
|
||||
|
||||
void CApp::PanelCopyItems()
|
||||
#include "Panel.h"
|
||||
#include "resource.h"
|
||||
#include "LangUtils.h"
|
||||
#include "ExtractCallback.h"
|
||||
#include "Windows/Thread.h"
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "..\UI\Resource\Extract\resource.h"
|
||||
|
||||
#include "UpdateCallback100.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
struct CThreadExtractInArchive2
|
||||
{
|
||||
return;
|
||||
}
|
||||
CMyComPtr<IFolderOperations> FolderOperations;
|
||||
CRecordVector<UInt32> Indices;
|
||||
UString DestPath;
|
||||
CExtractCallbackImp *ExtractCallbackSpec;
|
||||
CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
|
||||
HRESULT Result;
|
||||
bool MoveMode;
|
||||
|
||||
CThreadExtractInArchive2(): MoveMode(false) {}
|
||||
|
||||
DWORD Extract()
|
||||
{
|
||||
// NCOM::CComInitializer comInitializer;
|
||||
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 DWORD WINAPI 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 = LangLoadStringW(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;
|
||||
|
||||
UString title = moveMode ?
|
||||
LangLoadStringW(IDS_MOVING, 0x03020206):
|
||||
LangLoadStringW(IDS_COPYING, 0x03020205);
|
||||
UString progressWindowTitle = LangLoadStringW(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;
|
||||
|
||||
CThread extractThread;
|
||||
if (!extractThread.Create(CThreadExtractInArchive2::MyThreadFunction, &extracter))
|
||||
throw 271824;
|
||||
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()
|
||||
{
|
||||
NCOM::CComInitializer comInitializer;
|
||||
UpdateCallbackSpec->ProgressDialog.WaitCreating();
|
||||
Result = FolderOperations->CopyFrom(
|
||||
FolderPrefix,
|
||||
&FileNamePointers.Front(),
|
||||
FileNamePointers.Size(),
|
||||
UpdateCallback);
|
||||
UpdateCallbackSpec->ProgressDialog.MyClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD WINAPI 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 = LangLoadStringW(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 = LangLoadStringW(IDS_COPYING, 0x03020205);
|
||||
UString progressWindowTitle = LangLoadStringW(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]);
|
||||
|
||||
CThread thread;
|
||||
if (!thread.Create(CThreadUpdate::MyThreadFunction, &updater))
|
||||
throw 271824;
|
||||
updater.UpdateCallbackSpec->StartProgressDialog(title);
|
||||
|
||||
if (messages != 0)
|
||||
*messages = updater.UpdateCallbackSpec->Messages;
|
||||
|
||||
return updater.Result;
|
||||
}
|
||||
|
||||
void CPanel::CopyFrom(const UStringVector &filePaths)
|
||||
{
|
||||
UString message = L"Are you sure you want to copy files to archive\n\'";
|
||||
message += _currentFolderPrefix;
|
||||
message += L"\' ?";
|
||||
int res = ::MessageBoxW(*(this), message, L"Confirm File Copy",
|
||||
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, L"Error");
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshListCtrl(srcSelState);
|
||||
|
||||
disableTimerProcessing.Restore();
|
||||
SetFocusToList();
|
||||
}
|
||||
|
||||
|
||||
704
7zip/FileManager/PanelDrag.cpp
Executable file
704
7zip/FileManager/PanelDrag.cpp
Executable file
@@ -0,0 +1,704 @@
|
||||
// PanelDrag.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/Memory.h"
|
||||
#include "Windows/FileDir.h"
|
||||
#include "Windows/Shell.h"
|
||||
#include "Common/StringConvert.h"
|
||||
|
||||
#include "../UI/Common/ArchiveName.h"
|
||||
#include "../UI/Common/CompressCall.h"
|
||||
|
||||
#include "Resource/MessagesDialog/MessagesDialog.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
#include "App.h"
|
||||
#include "EnumFormatEtc.h"
|
||||
|
||||
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
|
||||
{
|
||||
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) {}
|
||||
};
|
||||
|
||||
STDMETHODIMP CDropSource::QueryContinueDrag(BOOL escapePressed, DWORD keyState)
|
||||
{
|
||||
if(escapePressed == TRUE)
|
||||
return DRAGDROP_S_CANCEL;
|
||||
if((keyState & MK_LBUTTON) == 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return DRAGDROP_S_USEDEFAULTCURSORS;
|
||||
}
|
||||
|
||||
static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const CSysStringVector &names)
|
||||
{
|
||||
size_t totalLength = 1;
|
||||
int i;
|
||||
for (i = 0; i < names.Size(); i++)
|
||||
totalLength += names[i].Length() + 1;
|
||||
|
||||
if (!hgDrop.Alloc(GHND | GMEM_SHARE, totalLength * sizeof(TCHAR) + 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);
|
||||
#ifdef _UNICODE
|
||||
dropFiles->fWide = TRUE;
|
||||
#else
|
||||
dropFiles->fWide = FALSE;
|
||||
#endif
|
||||
TCHAR *p = (TCHAR *)((BYTE *)dropFiles + sizeof(DROPFILES));
|
||||
for (i = 0; i < names.Size(); i++)
|
||||
{
|
||||
const CSysString &s = names[i];
|
||||
int fullLength = s.Length() + 1;
|
||||
if (fullLength > totalLength)
|
||||
return false; // error: name was changed!
|
||||
lstrcpy(p, s);
|
||||
p += fullLength;
|
||||
totalLength -= fullLength;
|
||||
}
|
||||
if (totalLength == 0)
|
||||
return false;
|
||||
*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;
|
||||
|
||||
{
|
||||
CSysStringVector names;
|
||||
for (int i = 0; i < indices.Size(); i++)
|
||||
names.Add(GetSystemString(dirPrefix + GetItemName(indices[i])));
|
||||
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, L"7-Zip");
|
||||
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, L"7-Zip");
|
||||
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 == -1)
|
||||
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;
|
||||
}
|
||||
|
||||
DWORD CDropTarget::GetEffect(DWORD keyState, POINTL pt, DWORD allowedEffect)
|
||||
{
|
||||
if (!m_DropIsAllowed || !m_PanelDropIsAllowed)
|
||||
return DROPEFFECT_NONE;
|
||||
|
||||
if (!IsFsFolderPath())
|
||||
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) 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 = { 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;
|
||||
}
|
||||
wcscpy(dest, path);
|
||||
GlobalUnlock(medium.hGlobal);
|
||||
bool res = m_DataObject->SetData(&etc, &medium, FALSE) == S_OK;
|
||||
GlobalFree(medium.hGlobal);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CDropTarget::SetPath()
|
||||
{
|
||||
return SetPath(m_DropIsAllowed && m_PanelDropIsAllowed && IsFsFolderPath());
|
||||
}
|
||||
|
||||
STDMETHODIMP CDropTarget::DragEnter(IDataObject * dataObject, DWORD keyState,
|
||||
POINTL pt, DWORD *effect)
|
||||
{
|
||||
QueryGetData(dataObject);
|
||||
m_DataObject = dataObject;
|
||||
return DragOver(keyState, pt, effect);
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CDropTarget::DragOver(DWORD keyState, POINTL pt, DWORD *effect)
|
||||
{
|
||||
PositionCursor(pt);
|
||||
*effect = GetEffect(keyState, pt, *effect);
|
||||
SetPath();
|
||||
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);
|
||||
*effect = GetEffect(keyState, pt, *effect);
|
||||
m_DataObject = dataObject;
|
||||
if(m_DropIsAllowed && m_PanelDropIsAllowed)
|
||||
{
|
||||
bool needDrop = true;
|
||||
if (IsFsFolderPath())
|
||||
needDrop = !SetPath();
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void CPanel::DropObject(IDataObject *dataObject, const UString &folderPath)
|
||||
{
|
||||
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;
|
||||
UStringVector names;
|
||||
{
|
||||
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);
|
||||
}
|
||||
CompressDropFiles(names, folderPath);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void CPanel::CompressDropFiles(HDROP dr)
|
||||
{
|
||||
CSysStringVector fileNames;
|
||||
{
|
||||
NShell::CDrop drop(true);
|
||||
drop.Attach(dr);
|
||||
drop.QueryFileNames(fileNames);
|
||||
}
|
||||
UStringVector fileNamesUnicode;
|
||||
for (int i = 0; i < fileNames.Size(); i++)
|
||||
fileNamesUnicode.Add(GetUnicodeString(fileNames[i]));
|
||||
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, fileNames,
|
||||
false, // email
|
||||
true, // showDialog
|
||||
AreThereNamesFromTemp(fileNames) // waitFinish
|
||||
);
|
||||
}
|
||||
else
|
||||
CopyFrom(fileNames);
|
||||
}
|
||||
208
7zip/FileManager/PanelExtract.cpp
Executable file
208
7zip/FileManager/PanelExtract.cpp
Executable file
@@ -0,0 +1,208 @@
|
||||
// PanelExtract.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Windows/COM.h"
|
||||
|
||||
#include "Panel.h"
|
||||
#include "resource.h"
|
||||
#include "LangUtils.h"
|
||||
#include "ExtractCallback.h"
|
||||
#include "Windows/Thread.h"
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "..\UI\Resource\Extract\resource.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()
|
||||
{
|
||||
// NCOM::CComInitializer comInitializer;
|
||||
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 DWORD WINAPI 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 = LangLoadStringW(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;
|
||||
|
||||
UString title = moveMode ?
|
||||
LangLoadStringW(IDS_MOVING, 0x03020206):
|
||||
LangLoadStringW(IDS_COPYING, 0x03020205);
|
||||
UString progressWindowTitle = LangLoadStringW(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;
|
||||
|
||||
CThread extractThread;
|
||||
if (!extractThread.Create(CThreadExtractInArchive2::MyThreadFunction, &extracter))
|
||||
throw 271824;
|
||||
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()
|
||||
{
|
||||
NCOM::CComInitializer comInitializer;
|
||||
UpdateCallbackSpec->ProgressDialog.WaitCreating();
|
||||
Result = FolderOperations->CopyFrom(
|
||||
FolderPrefix,
|
||||
&FileNamePointers.Front(),
|
||||
FileNamePointers.Size(),
|
||||
UpdateCallback);
|
||||
UpdateCallbackSpec->ProgressDialog.MyClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD WINAPI 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 = LangLoadStringW(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 = LangLoadStringW(IDS_COPYING, 0x03020205);
|
||||
UString progressWindowTitle = LangLoadStringW(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]);
|
||||
|
||||
CThread thread;
|
||||
if (!thread.Create(CThreadUpdate::MyThreadFunction, &updater))
|
||||
throw 271824;
|
||||
updater.UpdateCallbackSpec->StartProgressDialog(title);
|
||||
|
||||
if (messages != 0)
|
||||
*messages = updater.UpdateCallbackSpec->Messages;
|
||||
|
||||
return updater.Result;
|
||||
}
|
||||
|
||||
void CPanel::CopyFrom(const UStringVector &filePaths)
|
||||
{
|
||||
UString message = L"Are you sure you want to copy files to archive\n\'";
|
||||
message += _currentFolderPrefix;
|
||||
message += L"\' ?";
|
||||
int res = ::MessageBoxW(*(this), message, L"Confirm File Copy",
|
||||
MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL);
|
||||
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, L"Error");
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshListCtrl(srcSelState);
|
||||
|
||||
disableTimerProcessing.Restore();
|
||||
SetFocusToList();
|
||||
}
|
||||
@@ -31,20 +31,20 @@ HRESULT CPanel::BindToPath(const UString &fullPath)
|
||||
{
|
||||
CDisableTimerProcessing disableTimerProcessing1(*this);
|
||||
CloseOpenFolders();
|
||||
CSysString sysPath = GetSystemString(fullPath);
|
||||
CFileInfo fileInfo;
|
||||
UString sysPath = fullPath;
|
||||
CFileInfoW fileInfo;
|
||||
UStringVector reducedParts;
|
||||
while(!sysPath.IsEmpty())
|
||||
{
|
||||
if (FindFile(sysPath, fileInfo))
|
||||
break;
|
||||
int pos = sysPath.ReverseFind('\\');
|
||||
int pos = sysPath.ReverseFind(L'\\');
|
||||
if (pos < 0)
|
||||
sysPath.Empty();
|
||||
else
|
||||
{
|
||||
if (reducedParts.Size() > 0 || pos < sysPath.Length() - 1)
|
||||
reducedParts.Add(GetUnicodeString(sysPath.Mid(pos + 1)));
|
||||
reducedParts.Add(sysPath.Mid(pos + 1));
|
||||
sysPath = sysPath.Left(pos);
|
||||
}
|
||||
}
|
||||
@@ -58,24 +58,23 @@ HRESULT CPanel::BindToPath(const UString &fullPath)
|
||||
else if (fileInfo.IsDirectory())
|
||||
{
|
||||
NName::NormalizeDirPathPrefix(sysPath);
|
||||
if (_folder->BindToFolder(GetUnicodeString(sysPath), &newFolder) == S_OK)
|
||||
if (_folder->BindToFolder(sysPath, &newFolder) == S_OK)
|
||||
_folder = newFolder;
|
||||
}
|
||||
else
|
||||
{
|
||||
CSysString dirPrefix;
|
||||
UString dirPrefix;
|
||||
if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix))
|
||||
dirPrefix.Empty();
|
||||
if (_folder->BindToFolder(GetUnicodeString(dirPrefix), &newFolder) == S_OK)
|
||||
if (_folder->BindToFolder(dirPrefix, &newFolder) == S_OK)
|
||||
{
|
||||
_folder = newFolder;
|
||||
LoadFullPath();
|
||||
CSysString fileName;
|
||||
UString fileName;
|
||||
if (NDirectory::GetOnlyName(sysPath, fileName))
|
||||
{
|
||||
if (OpenItemAsArchive(GetUnicodeString(fileName),
|
||||
GetSystemString(_currentFolderPrefix),
|
||||
GetSystemString(_currentFolderPrefix) + fileName) == S_OK)
|
||||
if (OpenItemAsArchive(fileName, _currentFolderPrefix,
|
||||
_currentFolderPrefix + fileName) == S_OK)
|
||||
{
|
||||
for (int i = reducedParts.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ extern HWND g_HWND;
|
||||
static inline UINT GetCurrentFileCodePage()
|
||||
{ return AreFileApisANSI() ? CP_ACP : CP_OEMCP;}
|
||||
|
||||
static LPCTSTR kTempDirPrefix = TEXT("7zO");
|
||||
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";
|
||||
|
||||
@@ -63,8 +63,7 @@ public:
|
||||
};
|
||||
|
||||
HRESULT CPanel::OpenItemAsArchive(const UString &name,
|
||||
const CSysString &folderPath,
|
||||
const CSysString &filePath)
|
||||
const UString &folderPath, const UString &filePath)
|
||||
{
|
||||
CFolderLink folderLink;
|
||||
if (!NFile::NFind::FindFile(filePath, folderLink.FileInfo))
|
||||
@@ -99,8 +98,7 @@ HRESULT CPanel::OpenItemAsArchive(const UString &name,
|
||||
|
||||
HRESULT CPanel::OpenItemAsArchive(const UString &name)
|
||||
{
|
||||
return OpenItemAsArchive(name, GetSystemString(_currentFolderPrefix),
|
||||
GetSystemString(_currentFolderPrefix + name));
|
||||
return OpenItemAsArchive(name, _currentFolderPrefix, _currentFolderPrefix + name);
|
||||
}
|
||||
|
||||
HRESULT CPanel::OpenItemAsArchive(int index)
|
||||
@@ -117,7 +115,7 @@ HRESULT CPanel::OpenParentArchiveFolder()
|
||||
if (_parentFolders.Size() < 2)
|
||||
return S_OK;
|
||||
CFolderLink &folderLink = _parentFolders.Back();
|
||||
NFind::CFileInfo newFileInfo;
|
||||
NFind::CFileInfoW newFileInfo;
|
||||
if (NFind::FindFile(folderLink.FilePath, newFileInfo))
|
||||
{
|
||||
if (newFileInfo.Size != folderLink.FileInfo.Size ||
|
||||
@@ -150,7 +148,7 @@ static bool DoItemAlwaysStart(const UString &name)
|
||||
return (ext == UString(L"exe") || ext == UString(L"bat") || ext == UString(L"com"));
|
||||
}
|
||||
|
||||
static HANDLE StartEditApplication(CSysString &path, HWND window)
|
||||
static HANDLE StartEditApplication(const UString &path, HWND window)
|
||||
{
|
||||
CSysString command;
|
||||
ReadRegEditor(command);
|
||||
@@ -163,7 +161,7 @@ static HANDLE StartEditApplication(CSysString &path, HWND window)
|
||||
}
|
||||
command = CSysString(TEXT("\"")) + command + CSysString(TEXT("\""));
|
||||
command += TEXT(" \"");
|
||||
command += path;
|
||||
command += GetSystemString(path);
|
||||
command += TEXT("\"");
|
||||
|
||||
STARTUPINFO startupInfo;
|
||||
@@ -188,14 +186,15 @@ static HANDLE StartEditApplication(CSysString &path, HWND window)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HANDLE StartApplication(CSysString &path, HWND window)
|
||||
static HANDLE StartApplication(const UString &path, HWND window)
|
||||
{
|
||||
SHELLEXECUTEINFO execInfo;
|
||||
execInfo.cbSize = sizeof(execInfo);
|
||||
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
|
||||
execInfo.hwnd = NULL;
|
||||
execInfo.lpVerb = NULL;
|
||||
execInfo.lpFile = path;
|
||||
const CSysString sysPath = GetSystemString(path);
|
||||
execInfo.lpFile = sysPath;
|
||||
execInfo.lpParameters = NULL;
|
||||
execInfo.lpDirectory = NULL;
|
||||
execInfo.nShow = SW_SHOWNORMAL;
|
||||
@@ -223,18 +222,14 @@ void CPanel::EditItem(int index)
|
||||
OpenItemInArchive(index, false, true, true);
|
||||
return;
|
||||
}
|
||||
CSysString fullPath = GetSystemString((_currentFolderPrefix +
|
||||
GetItemName(index)), GetCurrentFileCodePage());
|
||||
HANDLE hProcess = StartEditApplication(fullPath, (HWND)*this);
|
||||
HANDLE hProcess = StartEditApplication(_currentFolderPrefix + GetItemName(index), (HWND)*this);
|
||||
if (hProcess != 0)
|
||||
::CloseHandle(hProcess);
|
||||
}
|
||||
|
||||
void CPanel::OpenFolderExternal(int index)
|
||||
{
|
||||
CSysString fullPath = GetSystemString((_currentFolderPrefix +
|
||||
GetItemName(index)), GetCurrentFileCodePage());
|
||||
HANDLE hProcess = StartApplication(fullPath, (HWND)*this);
|
||||
HANDLE hProcess = StartApplication(_currentFolderPrefix + GetItemName(index), (HWND)*this);
|
||||
if (hProcess != 0)
|
||||
::CloseHandle(hProcess);
|
||||
}
|
||||
@@ -253,22 +248,21 @@ void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal)
|
||||
MessageBoxMyError(virusMessage);
|
||||
return;
|
||||
}
|
||||
CSysString fullPath = GetSystemString((_currentFolderPrefix + name),
|
||||
GetCurrentFileCodePage());
|
||||
UString fullPath = _currentFolderPrefix + name;
|
||||
if (tryInternal)
|
||||
if (!tryExternal || !DoItemAlwaysStart(GetItemName(index)))
|
||||
if (!tryExternal || !DoItemAlwaysStart(name))
|
||||
if (OpenItemAsArchive(index) == S_OK)
|
||||
return;
|
||||
if (tryExternal)
|
||||
{
|
||||
::SetCurrentDirectory(GetSystemString(_currentFolderPrefix));
|
||||
NDirectory::MySetCurrentDirectory(_currentFolderPrefix);
|
||||
HANDLE hProcess = StartApplication(fullPath, (HWND)*this);
|
||||
if (hProcess != 0)
|
||||
::CloseHandle(hProcess);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CPanel::OnOpenItemChanged(const CSysString &folderPath, const UString &itemName)
|
||||
HRESULT CPanel::OnOpenItemChanged(const UString &folderPath, const UString &itemName)
|
||||
{
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
@@ -281,14 +275,9 @@ HRESULT CPanel::OnOpenItemChanged(const CSysString &folderPath, const UString &i
|
||||
fileNames.Add(itemName);
|
||||
fileNamePointers.Add(fileNames[0]);
|
||||
|
||||
// SetCurrentDirectory(tmpProcessInfo.FolderPath);
|
||||
CSysString pathPrefix = folderPath;
|
||||
UString pathPrefix = folderPath;
|
||||
NName::NormalizeDirPathPrefix(pathPrefix);
|
||||
return folderOperations->CopyFrom(
|
||||
GetUnicodeString(pathPrefix),
|
||||
&fileNamePointers.Front(),
|
||||
fileNamePointers.Size(),
|
||||
NULL);
|
||||
return folderOperations->CopyFrom(pathPrefix, &fileNamePointers.Front(),fileNamePointers.Size(), NULL);
|
||||
}
|
||||
|
||||
LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
|
||||
@@ -337,7 +326,7 @@ static DWORD WINAPI MyThreadFunction(void *param)
|
||||
if (waitResult != WAIT_OBJECT_0 + 1)
|
||||
return 1;
|
||||
Sleep(200);
|
||||
NFind::CFileInfo newFileInfo;
|
||||
NFind::CFileInfoW newFileInfo;
|
||||
if (NFind::FindFile(tmpProcessInfo->FilePath, newFileInfo))
|
||||
{
|
||||
if (newFileInfo.Size != tmpProcessInfo->FileInfo.Size ||
|
||||
@@ -361,35 +350,6 @@ static DWORD WINAPI MyThreadFunction(void *param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CCriticalSection g_CriticalSection;
|
||||
|
||||
struct CThreadExtractInArchive
|
||||
{
|
||||
CMyComPtr<IFolderOperations> FolderOperations;
|
||||
CRecordVector<UINT32> Indices;
|
||||
UString DestPath;
|
||||
CExtractCallbackImp *ExtractCallbackSpec;
|
||||
CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;
|
||||
HRESULT Result;
|
||||
|
||||
DWORD Extract()
|
||||
{
|
||||
NCOM::CComInitializer comInitializer;
|
||||
ExtractCallbackSpec->ProgressDialog.WaitCreating();
|
||||
Result = FolderOperations->CopyTo(
|
||||
&Indices.Front(), Indices.Size(),
|
||||
DestPath, ExtractCallback);
|
||||
// ExtractCallbackSpec->DestroyWindows();
|
||||
ExtractCallbackSpec->ProgressDialog.MyClose();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD WINAPI MyThreadFunction(void *param)
|
||||
{
|
||||
return ((CThreadExtractInArchive *)param)->Extract();
|
||||
}
|
||||
};
|
||||
|
||||
void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
|
||||
bool editMode)
|
||||
{
|
||||
@@ -400,7 +360,6 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
{
|
||||
@@ -408,56 +367,35 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
|
||||
return;
|
||||
}
|
||||
|
||||
CSysString tempDir;
|
||||
if (!CreateTempDirectory(kTempDirPrefix, tempDir))
|
||||
return;
|
||||
NFile::NDirectory::CTempDirectoryW tempDirectory;
|
||||
tempDirectory.Create(kTempDirPrefix);
|
||||
UString tempDir = tempDirectory.GetPath();
|
||||
UString tempDirNorm = tempDir;
|
||||
NFile::NName::NormalizeDirPathPrefix(tempDirNorm);
|
||||
|
||||
CThreadExtractInArchive extracter;
|
||||
CRecordVector<UInt32> indices;
|
||||
indices.Add(index);
|
||||
|
||||
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
|
||||
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
|
||||
extracter.ExtractCallbackSpec->ParentWindow = GetParent();
|
||||
|
||||
// extracter.ExtractCallbackSpec->_appTitle.Window = extracter.ExtractCallbackSpec->_parentWindow;
|
||||
// extracter.ExtractCallbackSpec->_appTitle.Title = progressWindowTitle;
|
||||
// extracter.ExtractCallbackSpec->_appTitle.AddTitle = title + CSysString(TEXT(" "));
|
||||
HRESULT result = CopyTo(indices, tempDirNorm, false, true, 0);
|
||||
|
||||
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt;
|
||||
extracter.ExtractCallbackSpec->Init();
|
||||
extracter.Indices.Add(index);
|
||||
extracter.DestPath = GetUnicodeString(tempDir + NFile::NName::kDirDelimiter);
|
||||
extracter.FolderOperations = folderOperations;
|
||||
|
||||
CThread extractThread;
|
||||
if (!extractThread.Create(CThreadExtractInArchive::MyThreadFunction, &extracter))
|
||||
throw 271824;
|
||||
extracter.ExtractCallbackSpec->StartProgressDialog(LangLoadStringW(IDS_OPENNING, 0x03020283));
|
||||
|
||||
if (extracter.Result != S_OK || extracter.ExtractCallbackSpec->Messages.Size() != 0)
|
||||
if ((result != S_OK && result != E_ABORT))
|
||||
{
|
||||
if (extracter.Result != S_OK)
|
||||
if (extracter.Result != E_ABORT)
|
||||
{
|
||||
// MessageBox(L"Can not extract item");
|
||||
// NError::MyFormatMessage(systemError.ErrorCode, message);
|
||||
MessageBoxError(extracter.Result, L"7-Zip");
|
||||
}
|
||||
MessageBoxError(result, L"7-Zip");
|
||||
return;
|
||||
}
|
||||
|
||||
CSysString tempFileName = tempDir + NFile::NName::kDirDelimiter +
|
||||
GetSystemString(name);
|
||||
UString tempFilePath = tempDirNorm + name;
|
||||
|
||||
std::auto_ptr<CTmpProcessInfo> tmpProcessInfo(new CTmpProcessInfo());
|
||||
tmpProcessInfo->FolderPath = tempDir;
|
||||
tmpProcessInfo->FilePath = tempFileName;
|
||||
if (!NFind::FindFile(tempFileName, tmpProcessInfo->FileInfo))
|
||||
tmpProcessInfo->FilePath = tempFilePath;
|
||||
if (!NFind::FindFile(tempFilePath, tmpProcessInfo->FileInfo))
|
||||
return;
|
||||
|
||||
if (tryInternal)
|
||||
{
|
||||
if (!tryExternal || !DoItemAlwaysStart(name))
|
||||
if (OpenItemAsArchive(name, tempDir, tempFileName) == S_OK)
|
||||
if (OpenItemAsArchive(name, tempDir, tempFilePath) == S_OK)
|
||||
{
|
||||
RefreshListCtrl();
|
||||
return;
|
||||
@@ -471,9 +409,9 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
|
||||
|
||||
HANDLE hProcess;
|
||||
if (editMode)
|
||||
hProcess = StartEditApplication(tempFileName, (HWND)*this);
|
||||
hProcess = StartEditApplication(tempFilePath, (HWND)*this);
|
||||
else
|
||||
hProcess = StartApplication(tempFileName, (HWND)*this);
|
||||
hProcess = StartApplication(tempFilePath, (HWND)*this);
|
||||
|
||||
if (hProcess == 0)
|
||||
return;
|
||||
@@ -482,10 +420,11 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
|
||||
tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix;
|
||||
tmpProcessInfo->ItemName = name;
|
||||
tmpProcessInfo->ProcessHandle = hProcess;
|
||||
|
||||
|
||||
CThread thread;
|
||||
if (!thread.Create(MyThreadFunction, tmpProcessInfo.get()))
|
||||
throw 271824;
|
||||
tempDirectory.DisableDeleting();
|
||||
tmpProcessInfo.release();
|
||||
tmpProcessInfoRelease._needDelete = false;
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos,
|
||||
|
||||
_listView.DeleteAllItems();
|
||||
_selectedStatusVector.Clear();
|
||||
_realIndices.Clear();
|
||||
// _realIndices.Clear();
|
||||
_startGroupSelect = 0;
|
||||
|
||||
_selectionIsDefined = false;
|
||||
@@ -511,6 +511,27 @@ void CPanel::GetOperatedItemIndices(CRecordVector<UINT32> &indices) const
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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();
|
||||
|
||||
@@ -125,7 +125,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result)
|
||||
{
|
||||
if (!alt && !ctrl)
|
||||
{
|
||||
_panelCallback->OnCopy(UStringVector(), false, shift);
|
||||
_panelCallback->OnCopy(false, shift);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@@ -134,7 +134,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result)
|
||||
{
|
||||
if (!alt && !ctrl)
|
||||
{
|
||||
_panelCallback->OnCopy(UStringVector(), true, shift);
|
||||
_panelCallback->OnCopy(true, shift);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -230,12 +230,6 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
|
||||
|
||||
// TODO : Handler default action...
|
||||
return 0;
|
||||
case LVN_BEGINDRAG:
|
||||
case LVN_BEGINRDRAG:
|
||||
{
|
||||
SendRefreshStatusBarMessage();
|
||||
return 0;
|
||||
}
|
||||
case LVN_ITEMCHANGED:
|
||||
{
|
||||
NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh;
|
||||
@@ -268,7 +262,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
|
||||
case LVN_BEGINDRAG:
|
||||
case LVN_BEGINRDRAG:
|
||||
{
|
||||
// OnDrag((LPNMLISTVIEW)header);
|
||||
OnDrag((LPNMLISTVIEW)header);
|
||||
RefreshStatusBar();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ BEGIN
|
||||
PUSHBUTTON "Support",IDC_ABOUT_BUTTON_EMAIL,136,30,94,14
|
||||
PUSHBUTTON "Register",IDC_ABOUT_BUTTON_REGISTER,136,53,94,14
|
||||
ICON IDI_LOGO,IDC_STATIC,7,7,20,20,SS_REALSIZEIMAGE
|
||||
LTEXT "7-Zip 4.20",IDC_STATIC,7,54,119,9
|
||||
LTEXT "7-Zip 4.23",IDC_STATIC,7,54,119,9
|
||||
LTEXT "Copyright (c) 1999-2005 Igor Pavlov",IDC_STATIC,7,67,
|
||||
119,17
|
||||
LTEXT "7-Zip is free software. However, you can support development of 7-Zip by registering.",
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "StdAfx.h"
|
||||
#include "CopyDialog.h"
|
||||
|
||||
#include "Common/StringConvert.h"
|
||||
|
||||
#include "Windows/Control/Static.h"
|
||||
#include "Windows/Shell.h"
|
||||
#include "Windows/FileName.h"
|
||||
@@ -33,7 +35,7 @@ bool CCopyDialog::OnInit()
|
||||
staticContol.Attach(GetItem(IDC_COPY_STATIC));
|
||||
staticContol.SetText(Static);
|
||||
for(int i = 0; i < Strings.Size(); i++)
|
||||
_path.AddString(Strings[i]);
|
||||
_path.AddString(GetSystemString(Strings[i]));
|
||||
_path.SetText(Value);
|
||||
return CModalDialog::OnInit();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
UString Title;
|
||||
UString Static;
|
||||
UString Value;
|
||||
CSysStringVector Strings;
|
||||
UStringVector Strings;
|
||||
|
||||
INT_PTR Create(HWND parentWindow = 0)
|
||||
{ return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_COPY), parentWindow); }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "MessagesDialog.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Windows/ResourceString.h"
|
||||
|
||||
#ifdef LANG
|
||||
@@ -39,18 +40,18 @@ void CMessagesDialog::AddMessageDirect(LPCTSTR message)
|
||||
_messageList.SetItem(&item);
|
||||
}
|
||||
|
||||
void CMessagesDialog::AddMessage(LPCTSTR message)
|
||||
void CMessagesDialog::AddMessage(LPCWSTR message)
|
||||
{
|
||||
CSysString s = message;
|
||||
UString s = message;
|
||||
while (!s.IsEmpty())
|
||||
{
|
||||
int pos = s.Find(TEXT('\n'));
|
||||
int pos = s.Find(L'\n');
|
||||
if (pos < 0)
|
||||
break;
|
||||
AddMessageDirect(s.Left(pos));
|
||||
AddMessageDirect(GetSystemString(s.Left(pos)));
|
||||
s.Delete(0, pos + 1);
|
||||
}
|
||||
AddMessageDirect(s);
|
||||
AddMessageDirect(GetSystemString(s));
|
||||
}
|
||||
|
||||
bool CMessagesDialog::OnInit()
|
||||
|
||||
@@ -12,10 +12,10 @@ class CMessagesDialog: public NWindows::NControl::CModalDialog
|
||||
{
|
||||
NWindows::NControl::CListView _messageList;
|
||||
void AddMessageDirect(LPCTSTR message);
|
||||
void AddMessage(LPCTSTR message);
|
||||
void AddMessage(LPCWSTR message);
|
||||
virtual bool OnInit();
|
||||
public:
|
||||
const CSysStringVector *Messages;
|
||||
const UStringVector *Messages;
|
||||
INT_PTR Create(HWND parentWindow = 0)
|
||||
{ return CModalDialog::Create(MAKEINTRESOURCE(IDD_DIALOG_MESSAGES), parentWindow); }
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ using namespace NWindows;
|
||||
|
||||
CUpdateCallback100Imp::~CUpdateCallback100Imp()
|
||||
{
|
||||
if (!Messages.IsEmpty())
|
||||
if (ShowMessages && !Messages.IsEmpty())
|
||||
{
|
||||
CMessagesDialog messagesDialog;
|
||||
messagesDialog.Messages = &Messages;
|
||||
@@ -25,7 +25,7 @@ CUpdateCallback100Imp::~CUpdateCallback100Imp()
|
||||
|
||||
void CUpdateCallback100Imp::AddErrorMessage(LPCWSTR message)
|
||||
{
|
||||
Messages.Add(GetSystemString(message));
|
||||
Messages.Add(message);
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 size)
|
||||
|
||||
@@ -41,18 +41,21 @@ private:
|
||||
UString _password;
|
||||
|
||||
void AddErrorMessage(LPCWSTR message);
|
||||
CSysStringVector Messages;
|
||||
bool ShowMessages;
|
||||
|
||||
public:
|
||||
CUpdateCallback100Imp(): ShowMessages(true) {}
|
||||
~CUpdateCallback100Imp();
|
||||
CProgressDialog ProgressDialog;
|
||||
HWND _parentWindow;
|
||||
UStringVector Messages;
|
||||
|
||||
void Init(HWND parentWindow,
|
||||
bool passwordIsDefined, const UString &password)
|
||||
{
|
||||
_passwordIsDefined = passwordIsDefined;
|
||||
_password = password;
|
||||
_parentWindow = parentWindow;
|
||||
|
||||
}
|
||||
void StartProgressDialog(const UString &title)
|
||||
{
|
||||
|
||||
@@ -82,8 +82,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,20,0,0
|
||||
PRODUCTVERSION 4,20,0,0
|
||||
FILEVERSION 4,23,0,0
|
||||
PRODUCTVERSION 4,23,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -101,14 +101,14 @@ BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "Igor Pavlov\0"
|
||||
VALUE "FileDescription", "7-Zip File Manager\0"
|
||||
VALUE "FileVersion", "4, 20, 0, 0\0"
|
||||
VALUE "FileVersion", "4, 23, 0, 0\0"
|
||||
VALUE "InternalName", "7zFM\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "7zFM.exe\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "7-Zip\0"
|
||||
VALUE "ProductVersion", "4, 20, 0, 0\0"
|
||||
VALUE "ProductVersion", "4, 23, 0, 0\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user