summaryrefslogtreecommitdiffstats
path: root/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelOperations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelOperations.cpp')
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelOperations.cpp470
1 files changed, 470 insertions, 0 deletions
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelOperations.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelOperations.cpp
new file mode 100644
index 000000000..5a0d052c4
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/PanelOperations.cpp
@@ -0,0 +1,470 @@
+// PanelOperations.cpp
+
+#include "StdAfx.h"
+
+#include "resource.h"
+
+#include "Panel.h"
+
+#include "Common/StringConvert.h"
+#include "Common/DynamicBuffer.h"
+#include "Windows/FileDir.h"
+#include "Windows/ResourceString.h"
+#include "Windows/Thread.h"
+#include "Windows/COM.h"
+
+#include "ComboDialog.h"
+
+#include "FSFolder.h"
+#include "LangUtils.h"
+#include "FormatUtils.h"
+
+#include "UpdateCallback100.h"
+
+using namespace NWindows;
+using namespace NFile;
+
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
+enum EFolderOpType
+{
+ FOLDER_TYPE_CREATE_FOLDER = 0,
+ FOLDER_TYPE_DELETE = 1,
+ FOLDER_TYPE_RENAME = 2
+};
+
+struct CThreadFolderOperations
+{
+ EFolderOpType OpType;
+ UString Name;
+ UInt32 Index;
+ CRecordVector<UInt32> Indices;
+
+ CMyComPtr<IFolderOperations> FolderOperations;
+ CMyComPtr<IProgress> UpdateCallback;
+ CUpdateCallback100Imp *UpdateCallbackSpec;
+ HRESULT Result;
+
+ CThreadFolderOperations(EFolderOpType opType);
+
+ void Process()
+ {
+#ifdef _WIN32
+ NCOM::CComInitializer comInitializer;
+#endif
+ UpdateCallbackSpec->ProgressDialog.WaitCreating();
+
+ switch(OpType)
+ {
+ case FOLDER_TYPE_CREATE_FOLDER:
+ Result = FolderOperations->CreateFolder(Name, UpdateCallback);
+ break;
+ case FOLDER_TYPE_DELETE:
+ Result = FolderOperations->Delete(&Indices.Front(), Indices.Size(), UpdateCallback);
+ break;
+ case FOLDER_TYPE_RENAME:
+ Result = FolderOperations->Rename(Index, Name, UpdateCallback);
+ break;
+ default:
+ Result = E_FAIL;
+ }
+ UpdateCallbackSpec->ProgressDialog.MyClose();
+ }
+
+ static THREAD_FUNC_DECL MyThreadFunction(void *param)
+ {
+ ((CThreadFolderOperations *)param)->Process();
+ return 0;
+ }
+};
+
+CThreadFolderOperations::CThreadFolderOperations(EFolderOpType opType): OpType(opType) {};
+
+static void DoOperation(CThreadFolderOperations &op, CPanel &panel, const UString &progressTitle)
+{
+ op.UpdateCallbackSpec = new CUpdateCallback100Imp;
+ op.UpdateCallback = op.UpdateCallbackSpec;
+
+ bool usePassword = false;
+ UString password;
+ if (panel._parentFolders.Size() > 0)
+ {
+ const CFolderLink &fl = panel._parentFolders.Back();
+ usePassword = fl.UsePassword;
+ password = fl.Password;
+ }
+
+ op.UpdateCallbackSpec->Init(panel.GetParent(), usePassword, password);
+
+ op.UpdateCallbackSpec->ProgressDialog.MainWindow = panel._mainWindow;
+ op.UpdateCallbackSpec->ProgressDialog.MainTitle = LangString(IDS_APP_TITLE, 0x03000000);
+ op.UpdateCallbackSpec->ProgressDialog.MainAddTitle = progressTitle + UString(L" ");
+
+ // op.FolderOperations = folderOperations;
+ // op.Index = realIndex;
+ // op.Name = newName;
+ // HRESULT result = folderOperations->Rename(realIndex, newName, 0);
+
+ NWindows::CThread thread;
+ if (thread.Create(CThreadFolderOperations::MyThreadFunction, &op) != S_OK)
+ throw 271824;
+ op.UpdateCallbackSpec->StartProgressDialog(progressTitle);
+}
+
+#ifndef _UNICODE
+typedef int (WINAPI * SHFileOperationWP)(LPSHFILEOPSTRUCTW lpFileOp);
+#endif
+
+void CPanel::DeleteItems(bool toRecycleBin)
+{
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ CRecordVector<UInt32> indices;
+ GetOperatedItemIndices(indices);
+ if (indices.IsEmpty())
+ return;
+ CSelectedState state;
+ SaveSelectedState(state);
+ bool useInternalDelete = false;
+ if (IsFSFolder() && toRecycleBin)
+ {
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ CDynamicBuffer<CHAR> buffer;
+ size_t size = 0;
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ const AString path = GetSystemString(GetFsPath() + GetItemRelPath(indices[i]));
+ buffer.EnsureCapacity(size + path.Length() + 1);
+ memmove(((CHAR *)buffer) + size, (const CHAR *)path, (path.Length() + 1) * sizeof(CHAR));
+ size += path.Length() + 1;
+ }
+ buffer.EnsureCapacity(size + 1);
+ ((CHAR *)buffer)[size] = 0;
+ SHFILEOPSTRUCTA fo;
+ fo.hwnd = GetParent();
+ fo.wFunc = FO_DELETE;
+ fo.pFrom = (const CHAR *)buffer;
+ fo.pTo = 0;
+ fo.fFlags = 0;
+ if (toRecycleBin)
+ fo.fFlags |= FOF_ALLOWUNDO;
+ // fo.fFlags |= FOF_NOCONFIRMATION;
+ // fo.fFlags |= FOF_NOERRORUI;
+ // fo.fFlags |= FOF_SILENT;
+ // fo.fFlags |= FOF_WANTNUKEWARNING;
+ fo.fAnyOperationsAborted = FALSE;
+ fo.hNameMappings = 0;
+ fo.lpszProgressTitle = 0;
+ /* int res = */ ::SHFileOperationA(&fo);
+ }
+ else
+ #endif
+ {
+ CDynamicBuffer<WCHAR> buffer;
+ size_t size = 0;
+ int maxLen = 0;
+ for (int i = 0; i < indices.Size(); i++)
+ {
+ // L"\\\\?\\") doesn't work here.
+ const UString path = GetFsPath() + GetItemRelPath(indices[i]);
+ if (path.Length() > maxLen)
+ maxLen = path.Length();
+ buffer.EnsureCapacity(size + path.Length() + 1);
+ memmove(((WCHAR *)buffer) + size, (const WCHAR *)path, (path.Length() + 1) * sizeof(WCHAR));
+ size += path.Length() + 1;
+ }
+ buffer.EnsureCapacity(size + 1);
+ ((WCHAR *)buffer)[size] = 0;
+#ifdef _WIN32
+ if (maxLen >= MAX_PATH)
+ {
+ if (toRecycleBin)
+ {
+ MessageBoxErrorLang(IDS_ERROR_LONG_PATH_TO_RECYCLE, 0x03020218);
+ return;
+ }
+ useInternalDelete = true;
+ }
+ else
+ {
+ SHFILEOPSTRUCTW fo;
+ fo.hwnd = GetParent();
+ fo.wFunc = FO_DELETE;
+ fo.pFrom = (const WCHAR *)buffer;
+ fo.pTo = 0;
+ fo.fFlags = 0;
+ if (toRecycleBin)
+ fo.fFlags |= FOF_ALLOWUNDO;
+ fo.fAnyOperationsAborted = FALSE;
+ fo.hNameMappings = 0;
+ fo.lpszProgressTitle = 0;
+ int res;
+ #ifdef _UNICODE
+ res = ::SHFileOperationW(&fo);
+ #else
+ SHFileOperationWP shFileOperationW = (SHFileOperationWP)
+ ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "SHFileOperationW");
+ if (shFileOperationW == 0)
+ return;
+ res = shFileOperationW(&fo);
+ #endif
+ }
+#else
+ // FIXME - how to use the recycle bin undex Gnome or KDE ?
+ useInternalDelete = true;
+#endif
+ }
+ /*
+ if (fo.fAnyOperationsAborted)
+ MessageBoxError(result, LangString(IDS_ERROR_DELETING, 0x03020217));
+ */
+ }
+ else
+ useInternalDelete = true;
+ if (useInternalDelete)
+ DeleteItemsInternal(indices);
+ RefreshListCtrl(state);
+}
+
+void CPanel::DeleteItemsInternal(CRecordVector<UInt32> &indices)
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
+ return;
+ }
+
+ UString title;
+ UString message;
+ if (indices.Size() == 1)
+ {
+ int index = indices[0];
+ const UString itemName = GetItemRelPath(index);
+ if (IsItemFolder(index))
+ {
+ title = LangString(IDS_CONFIRM_FOLDER_DELETE, 0x03020211);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_FOLDER, 0x03020214, itemName);
+ }
+ else
+ {
+ title = LangString(IDS_CONFIRM_FILE_DELETE, 0x03020210);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_FILE, 0x03020213, itemName);
+ }
+ }
+ else
+ {
+ title = LangString(IDS_CONFIRM_ITEMS_DELETE, 0x03020212);
+ message = MyFormatNew(IDS_WANT_TO_DELETE_ITEMS, 0x03020215,
+ NumberToString(indices.Size()));
+ }
+ if (::MessageBoxW(GetParent(), message, title, MB_OKCANCEL | MB_ICONQUESTION) != IDOK)
+ return;
+
+ {
+ CThreadFolderOperations op(FOLDER_TYPE_DELETE);
+ op.FolderOperations = folderOperations;
+ op.Indices = indices;
+ DoOperation(op, *this, LangString(IDS_DELETING, 0x03020216));
+ if (op.Result != S_OK)
+ MessageBoxError(op.Result, LangString(IDS_ERROR_DELETING, 0x03020217));
+ }
+ RefreshTitleAlways();
+}
+
+#ifdef _WIN32
+BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh)
+{
+ int realIndex = GetRealIndex(lpnmh->item);
+ if (realIndex == kParentIndex)
+ return TRUE;
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ return TRUE;
+ return FALSE;
+}
+
+BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
+{
+ if (lpnmh->item.pszText == NULL)
+ return FALSE;
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
+ return FALSE;
+ }
+ const UString newName = lpnmh->item.pszText;
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+
+ SaveSelectedState(_selectedState);
+
+ int realIndex = GetRealIndex(lpnmh->item);
+ if (realIndex == kParentIndex)
+ return FALSE;
+ const UString prefix = GetItemPrefix(realIndex);
+
+
+ {
+ CThreadFolderOperations op(FOLDER_TYPE_RENAME);
+ op.FolderOperations = folderOperations;
+ op.Index = realIndex;
+ op.Name = newName;
+ DoOperation(op, *this, LangString(IDS_RENAMING, 0x03020220));
+ if (op.Result != S_OK)
+ {
+ MessageBoxError(op.Result, LangString(IDS_ERROR_RENAMING, 0x03020221));
+ return FALSE;
+ }
+ }
+
+ // Can't use RefreshListCtrl here.
+ // RefreshListCtrlSaveFocused();
+ _selectedState.FocusedName = prefix + newName;
+ _selectedState.SelectFocused = true;
+
+ // We need clear all items to disable GetText before Reload:
+ // number of items can change.
+ // _listView.DeleteAllItems();
+ // But seems it can still call GetText (maybe for current item)
+ // so we can't delete items.
+
+ _dontShowMode = true;
+
+ PostMessage(kReLoadMessage);
+ return TRUE;
+}
+#endif
+
+void CPanel::CreateFolder()
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
+ return;
+ }
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ CSelectedState state;
+ SaveSelectedState(state);
+ CComboDialog comboDialog;
+ comboDialog.Title = LangString(IDS_CREATE_FOLDER, 0x03020230);
+ comboDialog.Static = LangString(IDS_CREATE_FOLDER_NAME, 0x03020231);
+ comboDialog.Value = LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, /*0x03020232*/ (UInt32)-1);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+
+ UString newName = comboDialog.Value;
+
+ {
+ CThreadFolderOperations op(FOLDER_TYPE_CREATE_FOLDER);
+ op.FolderOperations = folderOperations;
+ op.Name = newName;
+ DoOperation(op, *this, LangString(IDS_CREATE_FOLDER, 0x03020230));
+
+ if (op.Result != S_OK)
+ {
+ MessageBoxError(op.Result, LangString(IDS_CREATE_FOLDER_ERROR, 0x03020233));
+ return;
+ }
+ }
+ int pos = newName.Find(L'\\');
+ if (pos >= 0)
+ newName = newName.Left(pos);
+ if (!_mySelectMode)
+ state.SelectedNames.Clear();
+ state.FocusedName = newName;
+ state.SelectFocused = true;
+ RefreshTitleAlways();
+ RefreshListCtrl(state);
+}
+
+void CPanel::CreateFile()
+{
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
+ return;
+ }
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ CSelectedState state;
+ SaveSelectedState(state);
+ CComboDialog comboDialog;
+ comboDialog.Title = LangString(IDS_CREATE_FILE, 0x03020240);
+ comboDialog.Static = LangString(IDS_CREATE_FILE_NAME, 0x03020241);
+ comboDialog.Value = LangString(IDS_CREATE_FILE_DEFAULT_NAME, /*0x03020242*/ (UInt32)-1);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ UString newName = comboDialog.Value;
+ HRESULT result = folderOperations->CreateFile(newName, 0);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, LangString(IDS_CREATE_FILE_ERROR, 0x03020243));
+ return;
+ }
+ int pos = newName.Find(L'\\');
+ if (pos >= 0)
+ newName = newName.Left(pos);
+ if (!_mySelectMode)
+ state.SelectedNames.Clear();
+ state.FocusedName = newName;
+ state.SelectFocused = true;
+ RefreshListCtrl(state);
+}
+
+void CPanel::RenameFile()
+{
+ int index = _listView.GetFocusedItem();
+ if (index >= 0)
+ _listView.EditLabel(index);
+}
+
+void CPanel::ChangeComment()
+{
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
+ int index = _listView.GetFocusedItem();
+ if (index < 0)
+ return;
+ int realIndex = GetRealItemIndex(index);
+ if (realIndex == kParentIndex)
+ return;
+ CSelectedState state;
+ SaveSelectedState(state);
+ CMyComPtr<IFolderOperations> folderOperations;
+ if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
+ {
+ MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
+ return;
+ }
+
+ UString comment;
+ {
+ NCOM::CPropVariant propVariant;
+ if (_folder->GetProperty(realIndex, kpidComment, &propVariant) != S_OK)
+ return;
+ if (propVariant.vt == VT_BSTR)
+ comment = propVariant.bstrVal;
+ else if (propVariant.vt != VT_EMPTY)
+ return;
+ }
+ UString name = GetItemRelPath(realIndex);
+ CComboDialog comboDialog;
+ comboDialog.Title = name + L" " + LangString(IDS_COMMENT, 0x03020290);
+ comboDialog.Value = comment;
+ comboDialog.Static = LangString(IDS_COMMENT2, 0x03020291);
+ if (comboDialog.Create(GetParent()) == IDCANCEL)
+ return;
+ NCOM::CPropVariant propVariant(comboDialog.Value);
+
+ HRESULT result = folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);
+ if (result != S_OK)
+ {
+ MessageBoxError(result, L"Set Comment Error");
+ }
+ RefreshListCtrl(state);
+}
+