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

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2018-01-12 00:16:32 +0300
committerKornel <kornel@geekhood.net>2018-01-12 00:16:32 +0300
commitda28077952faf9e716ed7987b842d31617a10125 (patch)
tree5903be6aa5f1405d54028cec42432c46df818af5 /CPP/7zip/UI/FileManager
parentb5dc853b2496447f0a54b3b25cb2659b575c56ef (diff)
18.0018.00
Diffstat (limited to 'CPP/7zip/UI/FileManager')
-rw-r--r--CPP/7zip/UI/FileManager/LinkDialog.cpp6
-rw-r--r--CPP/7zip/UI/FileManager/PanelFolderChange.cpp3
-rw-r--r--CPP/7zip/UI/FileManager/PanelListNotify.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/PanelMenu.cpp119
-rw-r--r--CPP/7zip/UI/FileManager/PanelSelect.cpp3
-rw-r--r--CPP/7zip/UI/FileManager/PanelSplitFile.cpp113
6 files changed, 180 insertions, 66 deletions
diff --git a/CPP/7zip/UI/FileManager/LinkDialog.cpp b/CPP/7zip/UI/FileManager/LinkDialog.cpp
index 70b0ba65..ddef365c 100644
--- a/CPP/7zip/UI/FileManager/LinkDialog.cpp
+++ b/CPP/7zip/UI/FileManager/LinkDialog.cpp
@@ -55,7 +55,8 @@ static bool GetSymLink(CFSTR path, CReparseAttr &attr)
if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize))
return false;
- if (!attr.Parse(buf, returnedSize))
+ DWORD errorCode = 0;
+ if (!attr.Parse(buf, returnedSize, errorCode))
return false;
CByteBuffer data2;
@@ -291,7 +292,8 @@ void CLinkDialog::OnButton_Link()
}
CReparseAttr attr;
- if (!attr.Parse(data, data.Size()))
+ DWORD errorCode = 0;
+ if (!attr.Parse(data, data.Size(), errorCode))
{
ShowError(L"Internal conversion error");
return;
diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
index 6e1e434f..1f93f862 100644
--- a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
+++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
@@ -827,7 +827,8 @@ void CPanel::OpenFolder(int index)
SetNewFolder(newFolder);
LoadFullPath();
RefreshListCtrl();
- _listView.SetItemState_Selected(_listView.GetFocusedItem());
+ // 17.02: fixed : now we don't select first item
+ // _listView.SetItemState_Selected(_listView.GetFocusedItem());
_listView.EnsureVisible(_listView.GetFocusedItem(), false);
}
diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
index d7785d12..9061e585 100644
--- a/CPP/7zip/UI/FileManager/PanelListNotify.cpp
+++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
@@ -702,6 +702,8 @@ void CPanel::Refresh_StatusBar()
wchar_t temp[32];
ConvertUInt32ToString(indices.Size(), temp);
+ wcscat(temp, L" / ");
+ ConvertUInt32ToString(_selectedStatusVector.Size(), temp + wcslen(temp));
// UString s1 = MyFormatNew(g_App.LangString_N_SELECTED_ITEMS, NumberToString(indices.Size()));
// UString s1 = MyFormatNew(IDS_N_SELECTED_ITEMS, NumberToString(indices.Size()));
diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp
index 945a41f8..3db65be4 100644
--- a/CPP/7zip/UI/FileManager/PanelMenu.cpp
+++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp
@@ -403,82 +403,117 @@ void CPanel::EditPaste()
// InvokeSystemCommand("paste");
}
+
+
+struct CFolderPidls
+{
+ LPITEMIDLIST parent;
+ CRecordVector<LPITEMIDLIST> items;
+
+ CFolderPidls(): parent(NULL) {}
+ ~CFolderPidls()
+ {
+ FOR_VECTOR (i, items)
+ CoTaskMemFree(items[i]);
+ CoTaskMemFree(parent);
+ }
+};
+
+
HRESULT CPanel::CreateShellContextMenu(
const CRecordVector<UInt32> &operatedIndices,
CMyComPtr<IContextMenu> &systemContextMenu)
{
systemContextMenu.Release();
- UString folderPath = GetFsPath();
+ const UString folderPath = GetFsPath();
CMyComPtr<IShellFolder> desktopFolder;
RINOK(::SHGetDesktopFolder(&desktopFolder));
if (!desktopFolder)
{
- // ShowMessage("Failed to get Desktop folder.");
+ // ShowMessage("Failed to get Desktop folder");
return E_FAIL;
}
- // Separate the file from the folder.
-
-
- // Get a pidl for the folder the file
- // is located in.
- LPITEMIDLIST parentPidl;
+ CFolderPidls pidls;
DWORD eaten;
+
+ // if (folderPath.IsEmpty()), then ParseDisplayName returns pidls of "My Computer"
RINOK(desktopFolder->ParseDisplayName(
- GetParent(), 0, (wchar_t *)(const wchar_t *)folderPath,
- &eaten, &parentPidl, 0));
+ GetParent(), NULL, (wchar_t *)(const wchar_t *)folderPath,
+ &eaten, &pidls.parent, NULL));
+
+ /*
+ STRRET pName;
+ res = desktopFolder->GetDisplayNameOf(pidls.parent, SHGDN_NORMAL, &pName);
+ WCHAR dir[MAX_PATH];
+ if (!SHGetPathFromIDListW(pidls.parent, dir))
+ dir[0] = 0;
+ */
+
+ if (!pidls.parent)
+ return E_FAIL;
+
+ if (operatedIndices.IsEmpty())
+ {
+ // how to get IContextMenu, if there are no selected files?
+ return E_FAIL;
+
+ /*
+ xp64 :
+ 1) we can't use GetUIObjectOf() with (numItems == 0), it throws exception
+ 2) we can't use desktopFolder->GetUIObjectOf() with absolute pidls of folder
+ context menu items are different in that case:
+ "Open / Explorer" for folder
+ "Delete" for "My Computer" icon
+ "Preperties" for "System"
+ */
+ /*
+ parentFolder = desktopFolder;
+ pidls.items.AddInReserved(pidls.parent);
+ pidls.parent = NULL;
+ */
+
+ // CreateViewObject() doesn't show all context menu items
+ /*
+ HRESULT res = parentFolder->CreateViewObject(
+ GetParent(), IID_IContextMenu, (void**)&systemContextMenu);
+ */
+ }
- // Get an IShellFolder for the folder
- // the file is located in.
CMyComPtr<IShellFolder> parentFolder;
- RINOK(desktopFolder->BindToObject(parentPidl,
- 0, IID_IShellFolder, (void**)&parentFolder));
+ RINOK(desktopFolder->BindToObject(pidls.parent,
+ NULL, IID_IShellFolder, (void**)&parentFolder));
if (!parentFolder)
{
- // ShowMessage("Invalid file name.");
+ // ShowMessage("Invalid file name");
return E_FAIL;
}
- // Get a pidl for the file itself.
- CRecordVector<LPITEMIDLIST> pidls;
- pidls.ClearAndReserve(operatedIndices.Size());
+ pidls.items.ClearAndReserve(operatedIndices.Size());
FOR_VECTOR (i, operatedIndices)
{
LPITEMIDLIST pidl;
- UString fileName = GetItemRelPath2(operatedIndices[i]);
+ const UString fileName = GetItemRelPath2(operatedIndices[i]);
RINOK(parentFolder->ParseDisplayName(GetParent(), 0,
- (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0));
- pidls.AddInReserved(pidl);
- }
-
- ITEMIDLIST temp;
- if (pidls.Size() == 0)
- {
- temp.mkid.cb = 0;
- /*
- LPITEMIDLIST pidl;
- HRESULT result = parentFolder->ParseDisplayName(GetParent(), 0,
- L"." WSTRING_PATH_SEPARATOR, &eaten, &pidl, 0);
- if (result != NOERROR)
- return;
- */
- pidls.Add(&temp);
+ (wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0));
+ pidls.items.AddInReserved(pidl);
}
+
+ // Get IContextMenu for items
- // Get the IContextMenu for the file.
- CMyComPtr<IContextMenu> cm;
- RINOK( parentFolder->GetUIObjectOf(GetParent(), pidls.Size(),
- (LPCITEMIDLIST *)&pidls.Front(), IID_IContextMenu, 0, (void**)&cm));
- if (!cm)
+ RINOK(parentFolder->GetUIObjectOf(GetParent(), pidls.items.Size(),
+ (LPCITEMIDLIST *)&pidls.items.Front(), IID_IContextMenu, 0, (void**)&systemContextMenu));
+
+ if (!systemContextMenu)
{
- // ShowMessage("Unable to get context menu interface.");
+ // ShowMessage("Unable to get context menu interface");
return E_FAIL;
}
- systemContextMenu = cm;
return S_OK;
}
+
void CPanel::CreateSystemMenu(HMENU menuSpec,
const CRecordVector<UInt32> &operatedIndices,
CMyComPtr<IContextMenu> &systemContextMenu)
diff --git a/CPP/7zip/UI/FileManager/PanelSelect.cpp b/CPP/7zip/UI/FileManager/PanelSelect.cpp
index 268b64af..8cfb23f4 100644
--- a/CPP/7zip/UI/FileManager/PanelSelect.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSelect.cpp
@@ -218,6 +218,8 @@ void CPanel::InvertSelection()
FOR_VECTOR (i, _selectedStatusVector)
if (_selectedStatusVector[i])
numSelected++;
+ // 17.02: fixed : now we invert item even, if single item is selected
+ /*
if (numSelected == 1)
{
int focused = _listView.GetFocusedItem();
@@ -229,6 +231,7 @@ void CPanel::InvertSelection()
_selectedStatusVector[realIndex] = false;
}
}
+ */
}
FOR_VECTOR (i, _selectedStatusVector)
_selectedStatusVector[i] = !_selectedStatusVector[i];
diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
index 3f7111a1..7cab2cf9 100644
--- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
@@ -77,8 +77,6 @@ UString CVolSeqName::GetNextName()
return UnchangedPart + ChangedPart;
}
-static const UInt32 kBufSize = (1 << 20);
-
class CThreadSplit: public CProgressThreadVirt
{
HRESULT ProcessVirt();
@@ -89,30 +87,84 @@ public:
CRecordVector<UInt64> VolumeSizes;
};
+
+class CPreAllocOutFile
+{
+ UInt64 _preAllocSize;
+public:
+ NIO::COutFile File;
+ UInt64 Written;
+
+ CPreAllocOutFile(): _preAllocSize(0), Written(0) {}
+
+ ~CPreAllocOutFile()
+ {
+ SetCorrectFileLength();
+ }
+
+ void PreAlloc(UInt64 preAllocSize)
+ {
+ _preAllocSize = 0;
+ if (File.SetLength(preAllocSize))
+ _preAllocSize = preAllocSize;
+ File.SeekToBegin();
+ }
+
+ bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw()
+ {
+ bool res = File.Write(data, size, processedSize);
+ Written += processedSize;
+ return res;
+ }
+
+ void Close()
+ {
+ SetCorrectFileLength();
+ Written = 0;
+ _preAllocSize = 0;
+ File.Close();
+ }
+
+ void SetCorrectFileLength()
+ {
+ if (Written < _preAllocSize)
+ {
+ File.SetLength(Written);
+ _preAllocSize = 0;
+ }
+ }
+};
+
+
+static const UInt32 kBufSize = (1 << 20);
+
HRESULT CThreadSplit::ProcessVirt()
{
NIO::CInFile inFile;
if (!inFile.Open(FilePath))
return GetLastError();
- NIO::COutFile outFile;
- CMyBuffer bufferObject;
- if (!bufferObject.Allocate(kBufSize))
+
+ CPreAllocOutFile outFile;
+
+ CMyBuffer buffer;
+ if (!buffer.Allocate(kBufSize))
return E_OUTOFMEMORY;
- Byte *buffer = (Byte *)(void *)bufferObject;
- UInt64 curVolSize = 0;
+
CVolSeqName seqName;
seqName.SetNumDigits(NumVolumes);
+
UInt64 length;
if (!inFile.GetLength(length))
return GetLastError();
CProgressSync &sync = ProgressDialog.Sync;
sync.Set_NumBytesTotal(length);
- UInt64 pos = 0;
+ UInt64 pos = 0;
+ UInt64 prev = 0;
UInt64 numFiles = 0;
unsigned volIndex = 0;
-
+
for (;;)
{
UInt64 volSize;
@@ -121,46 +173,65 @@ HRESULT CThreadSplit::ProcessVirt()
else
volSize = VolumeSizes.Back();
- UInt32 needSize = (UInt32)(MyMin((UInt64)kBufSize, volSize - curVolSize));
+ UInt32 needSize = kBufSize;
+ {
+ const UInt64 rem = volSize - outFile.Written;
+ if (needSize > rem)
+ needSize = (UInt32)rem;
+ }
UInt32 processedSize;
if (!inFile.Read(buffer, needSize, processedSize))
return GetLastError();
if (processedSize == 0)
- break;
+ return S_OK;
needSize = processedSize;
- if (curVolSize == 0)
+
+ if (outFile.Written == 0)
{
FString name = VolBasePath;
name += '.';
name += us2fs(seqName.GetNextName());
sync.Set_FilePath(fs2us(name));
- sync.Set_NumFilesCur(numFiles++);
- if (!outFile.Create(name, false))
+ if (!outFile.File.Create(name, false))
{
HRESULT res = GetLastError();
AddErrorPath(name);
return res;
}
+ UInt64 expectSize = volSize;
+ if (pos < length)
+ {
+ const UInt64 rem = length - pos;
+ if (expectSize > rem)
+ expectSize = rem;
+ }
+ outFile.PreAlloc(expectSize);
}
+
if (!outFile.Write(buffer, needSize, processedSize))
return GetLastError();
if (needSize != processedSize)
throw g_Message_FileWriteError;
- curVolSize += processedSize;
- if (curVolSize == volSize)
+
+ pos += processedSize;
+
+ if (outFile.Written == volSize)
{
outFile.Close();
+ sync.Set_NumFilesCur(++numFiles);
if (volIndex < VolumeSizes.Size())
volIndex++;
- curVolSize = 0;
}
- pos += processedSize;
- RINOK(sync.Set_NumBytesCur(pos));
+
+ if (pos - prev >= ((UInt32)1 << 22) || outFile.Written == 0)
+ {
+ RINOK(sync.Set_NumBytesCur(pos));
+ prev = pos;
+ }
}
- sync.Set_NumFilesCur(numFiles);
- return S_OK;
}
+
void CApp::Split()
{
int srcPanelIndex = GetFocusedPanelIndex();