diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2006-03-19 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:47 +0300 |
commit | cb9eea7264409202d974b41b08d976ddbca6d203 (patch) | |
tree | 2e0332b50a46eb1d9c49f1500be9167eb03e82ca | |
parent | 8304895f29dcbf005fe291a69fc1d32a1828eb43 (diff) |
4.37 beta
44 files changed, 690 insertions, 169 deletions
diff --git a/7zip/Archive/Iso/DllExports.cpp b/7zip/Archive/Iso/DllExports.cpp index 0e6ee9b1..3bc48470 100755 --- a/7zip/Archive/Iso/DllExports.cpp +++ b/7zip/Archive/Iso/DllExports.cpp @@ -70,7 +70,7 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value) propVariant = L"iso"; break; case NArchive::kUpdate: - propVariant = true; + propVariant = false; break; case NArchive::kKeepName: propVariant = false; diff --git a/7zip/Archive/Iso/IsoHandler.cpp b/7zip/Archive/Iso/IsoHandler.cpp index 2c961ad0..18bb2ddf 100755 --- a/7zip/Archive/Iso/IsoHandler.cpp +++ b/7zip/Archive/Iso/IsoHandler.cpp @@ -128,7 +128,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidSize: case kpidPackedSize: { - propVariant = (UInt64)be.GetSize(); + propVariant = (UInt64)_archive.GetBootItemSize(index); break; } } @@ -146,7 +146,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val if (_archive.IsJoliet()) s = item.GetPathU(); else - s = MultiByteToUnicodeString(item.GetPath(), CP_OEMCP); + s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP); int pos = s.ReverseFind(L';'); if (pos >= 0 && pos == s.Length() - 2) @@ -210,8 +210,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } else { - const CBootInitialEntry &be = _archive.BootEntries[index - _archive.Refs.Size()]; - totalSize += be.GetSize(); + totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size()); } } extractCallback->SetTotal(totalSize); @@ -248,8 +247,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems, } else { - const CBootInitialEntry &be = _archive.BootEntries[index - _archive.Refs.Size()]; - currentItemSize = be.GetSize(); + int bootIndex = index - _archive.Refs.Size(); + const CBootInitialEntry &be = _archive.BootEntries[bootIndex]; + currentItemSize = _archive.GetBootItemSize(bootIndex); blockIndex = be.LoadRBA; } diff --git a/7zip/Archive/Iso/IsoIn.cpp b/7zip/Archive/Iso/IsoIn.cpp index 5a504955..8501802c 100755 --- a/7zip/Archive/Iso/IsoIn.cpp +++ b/7zip/Archive/Iso/IsoIn.cpp @@ -253,6 +253,7 @@ void CInArchive::ReadDir(CDir &d, int level) SeekToBlock(d.ExtentLocation); UInt64 startPos = _position; + bool firstItem = true; while(true) { UInt64 offset = _position - startPos; @@ -263,8 +264,13 @@ void CInArchive::ReadDir(CDir &d, int level) continue; CDir subItem; ReadDirRecord2(subItem, len); + if (firstItem && level == 0) + IsSusp = subItem.CheckSusp(SuspSkipSize); + if (!subItem.IsSystemItem()) d._subItems.Add(subItem); + + firstItem = false; } for (int i = 0; i < d._subItems.Size(); i++) ReadDir(d._subItems[i], level + 1); @@ -404,6 +410,10 @@ HRESULT CInArchive::Open2() HRESULT CInArchive::Open(IInStream *inStream) { _stream = inStream; + UInt64 pos; + RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &pos)); + RINOK(_stream->Seek(0, STREAM_SEEK_END, &_archiveSize)); + RINOK(_stream->Seek(pos, STREAM_SEEK_SET, &_position)); HRESULT res = S_FALSE; try { res = Open2(); } catch(...) { Clear(); res = S_FALSE; } @@ -418,6 +428,8 @@ void CInArchive::Clear() VolDescs.Clear(); _bootIsDefined = false; BootEntries.Clear(); + SuspSkipSize = 0; + IsSusp = false; } }} diff --git a/7zip/Archive/Iso/IsoIn.h b/7zip/Archive/Iso/IsoIn.h index e91d7812..fe85343f 100755 --- a/7zip/Archive/Iso/IsoIn.h +++ b/7zip/Archive/Iso/IsoIn.h @@ -25,12 +25,12 @@ struct CDir: public CDirRecord _subItems.Clear(); } - int GetLength() const + int GetLength(bool checkSusp, int skipSize) const { - int len = FileId.GetCapacity(); + int len = GetLengthCur(checkSusp, skipSize); if (Parent != 0) if (Parent->Parent != 0) - len += 1 + Parent->GetLength(); + len += 1 + Parent->GetLength(checkSusp, skipSize); return len; } @@ -43,19 +43,19 @@ struct CDir: public CDirRecord return len; } - AString GetPath() const + AString GetPath(bool checkSusp, int skipSize) const { AString s; - int len = GetLength(); + int len = GetLength(checkSusp, skipSize); char *p = s.GetBuffer(len + 1); p += len; *p = 0; const CDir *cur = this; while(true) { - int curLen = cur->FileId.GetCapacity(); + int curLen = cur->GetLengthCur(checkSusp, skipSize); p -= curLen; - memmove(p, (const char *)(const Byte *)cur->FileId, curLen); + memmove(p, (const char *)(const Byte *)cur->GetNameCur(checkSusp, skipSize), curLen); cur = cur->Parent; if (cur == 0) break; @@ -262,13 +262,38 @@ public: HRESULT Open(IInStream *inStream); void Clear(); - CObjectVector<CRef> Refs; + UInt64 _archiveSize; + + CRecordVector<CRef> Refs; CObjectVector<CVolumeDescriptor> VolDescs; int MainVolDescIndex; UInt32 BlockSize; CObjectVector<CBootInitialEntry> BootEntries; + bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); } + + UInt64 GetBootItemSize(int index) const + { + const CBootInitialEntry &be = BootEntries[index]; + UInt64 size = be.GetSize(); + if (be.BootMediaType == NBootMediaType::k1d2Floppy) + size = (1200 << 10); + else if (be.BootMediaType == NBootMediaType::k1d44Floppy) + size = (1440 << 10); + else if (be.BootMediaType == NBootMediaType::k2d88Floppy) + size = (2880 << 10); + UInt64 startPos = be.LoadRBA * BlockSize; + if (startPos < _archiveSize) + { + if (_archiveSize - startPos < size) + size = _archiveSize - startPos; + } + return size; + } + + bool IsSusp; + int SuspSkipSize; }; }} diff --git a/7zip/Archive/Iso/IsoItem.h b/7zip/Archive/Iso/IsoItem.h index dd3377c7..d874ab74 100755 --- a/7zip/Archive/Iso/IsoItem.h +++ b/7zip/Archive/Iso/IsoItem.h @@ -64,6 +64,80 @@ struct CDirRecord Byte b = *(const Byte *)FileId; return (b == 0 || b == 1); } + + const Byte* FindSuspName(int skipSize, int &lenRes) const + { + lenRes = 0; + const Byte *p = (const Byte *)SystemUse + skipSize; + int length = SystemUse.GetCapacity() - skipSize; + while (length >= 5) + { + int len = p[2]; + if (p[0] == 'N' && p[1] == 'M' && p[3] == 1) + { + lenRes = len - 5; + return p + 5; + } + p += len; + length -= len; + } + return 0; + } + + int GetLengthCur(bool checkSusp, int skipSize) const + { + if (checkSusp) + { + int len; + const Byte *res = FindSuspName(skipSize, len); + if (res != 0) + return len; + } + return FileId.GetCapacity(); + } + + const Byte* GetNameCur(bool checkSusp, int skipSize) const + { + if (checkSusp) + { + int len; + const Byte *res = FindSuspName(skipSize, len); + if (res != 0) + return res; + } + return (const Byte *)FileId; + } + + + bool CheckSusp(const Byte *p, int &startPos) const + { + if (p[0] == 'S' && + p[1] == 'P' && + p[2] == 0x7 && + p[3] == 0x1 && + p[4] == 0xBE && + p[5] == 0xEF) + { + startPos = p[6]; + return true; + } + return false; + } + + bool CheckSusp(int &startPos) const + { + const Byte *p = (const Byte *)SystemUse; + int length = SystemUse.GetCapacity(); + const int kMinLen = 7; + if (length < kMinLen) + return false; + if (CheckSusp(p, startPos)) + return true; + const int kOffset2 = 14; + if (length < kOffset2 + kMinLen) + return false; + return CheckSusp(p + kOffset2, startPos); + } }; }} diff --git a/7zip/Compress/LZ/MT/MT.cpp b/7zip/Compress/LZ/MT/MT.cpp index 2c28a287..a96e924f 100755 --- a/7zip/Compress/LZ/MT/MT.cpp +++ b/7zip/Compress/LZ/MT/MT.cpp @@ -110,7 +110,7 @@ STDMETHODIMP_(UInt32) CMatchFinderMT::GetMatchLen(Int32 index, UInt32 distance, distance++; const Byte *pby = m_DataCurrentPos + index; UInt32 i; - for(i = 0; i < limit && pby[i] == pby[i - distance]; i++); + for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++); return i; } diff --git a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp index ef977036..17943a90 100755 --- a/7zip/Compress/LZMA_Alone/LzmaAlone.cpp +++ b/7zip/Compress/LZMA_Alone/LzmaAlone.cpp @@ -152,7 +152,7 @@ int main2(int n, const char *args[]) g_IsNT = IsItWindowsNT(); #endif - fprintf(stderr, "\nLZMA 4.35 Copyright (c) 1999-2006 Igor Pavlov 2006-03-03\n"); + fprintf(stderr, "\nLZMA 4.37 Copyright (c) 1999-2006 Igor Pavlov 2006-03-18\n"); if (n == 1) { diff --git a/7zip/FileManager/App.cpp b/7zip/FileManager/App.cpp index 9d78c300..5f5ca09c 100755 --- a/7zip/FileManager/App.cpp +++ b/7zip/FileManager/App.cpp @@ -612,7 +612,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex) folderPrefix = srcPanel._currentFolderPrefix; filePaths.Reserve(indices.Size()); for(int i = 0; i < indices.Size(); i++) - filePaths.Add(srcPanel.GetItemName(indices[i])); + filePaths.Add(srcPanel.GetItemRelPath(indices[i])); result = destPanel.CopyFrom(folderPrefix, filePaths, true, 0); diff --git a/7zip/FileManager/App.h b/7zip/FileManager/App.h index ecb5345e..d0ffbd98 100755 --- a/7zip/FileManager/App.h +++ b/7zip/FileManager/App.h @@ -262,6 +262,8 @@ public: void SetListSettings(); void SetShowSystemMenu(); void SwitchOnOffOnePanel(); + bool GetFlatMode() { return Panels[LastFocusedPanel].GetFlatMode(); } + void ChangeFlatMode() { Panels[LastFocusedPanel].ChangeFlatMode(); } void OpenBookmark(int index) { GetFocusedPanel().OpenBookmark(index); } diff --git a/7zip/FileManager/FSFolder.cpp b/7zip/FileManager/FSFolder.cpp index 667eee72..f0eb49dc 100755 --- a/7zip/FileManager/FSFolder.cpp +++ b/7zip/FileManager/FSFolder.cpp @@ -34,7 +34,8 @@ static STATPROPSTG kProperties[] = { NULL, kpidLastAccessTime, VT_FILETIME}, { NULL, kpidAttributes, VT_UI4}, { NULL, kpidPackedSize, VT_UI8}, - { NULL, kpidComment, VT_BSTR} + { NULL, kpidComment, VT_BSTR}, + { NULL, kpidPrefix, VT_BSTR} }; HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder) @@ -42,6 +43,8 @@ HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder) _parentFolder = parentFolder; _path = path; + _findChangeNotificationDefined = false; + if (_findChangeNotification.FindFirst(_path, false, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | @@ -77,8 +80,7 @@ static HRESULT GetFolderSize(const UString &path, UInt64 &size, IProgress *progr if (fileInfo.IsDirectory()) { UInt64 subSize; - RINOK(GetFolderSize(path + UString(L"\\") + fileInfo.Name, - subSize, progress)); + RINOK(GetFolderSize(path + UString(L"\\") + fileInfo.Name, subSize, progress)); size += subSize; } else @@ -87,29 +89,67 @@ static HRESULT GetFolderSize(const UString &path, UInt64 &size, IProgress *progr return S_OK; } -STDMETHODIMP CFSFolder::LoadItems() +HRESULT CFSFolder::LoadSubItems(CDirItem &dirItem, const UString &path) { - // OutputDebugString(TEXT("Start\n")); - INT32 dummy; - WasChanged(&dummy); - _files.Clear(); - CEnumeratorW enumerator(_path + L"*"); - CFileInfoEx fileInfo; - while (enumerator.Next(fileInfo)) { - fileInfo.CompressedSizeIsDefined = false; - /* - if (!GetCompressedFileSize(_path + fileInfo.Name, - fileInfo.CompressedSize)) - fileInfo.CompressedSize = fileInfo.Size; - */ - if (fileInfo.IsDirectory()) + CEnumeratorW enumerator(path + L"*"); + CDirItem fileInfo; + while (enumerator.Next(fileInfo)) { - // fileInfo.Size = GetFolderSize(_path + fileInfo.Name); - fileInfo.Size = 0; + fileInfo.CompressedSizeIsDefined = false; + /* + if (!GetCompressedFileSize(_path + fileInfo.Name, + fileInfo.CompressedSize)) + fileInfo.CompressedSize = fileInfo.Size; + */ + if (fileInfo.IsDirectory()) + { + // fileInfo.Size = GetFolderSize(_path + fileInfo.Name); + fileInfo.Size = 0; + } + dirItem.Files.Add(fileInfo); } - _files.Add(fileInfo); } + if (!_flatMode) + return S_OK; + + for (int i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + if (item.IsDirectory()) + LoadSubItems(item, path + item.Name + L'\\'); + } + return S_OK; +} + +void CFSFolder::AddRefs(CDirItem &dirItem) +{ + int i; + for (i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + item.Parent = &dirItem; + _refs.Add(&item); + } + if (!_flatMode) + return; + for (i = 0; i < dirItem.Files.Size(); i++) + { + CDirItem &item = dirItem.Files[i]; + if (item.IsDirectory()) + AddRefs(item); + } +} + +STDMETHODIMP CFSFolder::LoadItems() +{ + // OutputDebugString(TEXT("Start\n")); + INT32 dummy; + WasChanged(&dummy); + Clear(); + RINOK(LoadSubItems(_root, _path)); + AddRefs(_root); + // OutputDebugString(TEXT("Finish\n")); _commentsAreLoaded = false; return S_OK; @@ -178,7 +218,7 @@ bool CFSFolder::SaveComments() STDMETHODIMP CFSFolder::GetNumberOfItems(UInt32 *numItems) { - *numItems = _files.Size(); + *numItems = _refs.Size(); return S_OK; } @@ -197,9 +237,9 @@ STDMETHODIMP CFSFolder::GetNumberOfSubFolders(UInt32 *numSubFolders) STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) { NCOM::CPropVariant propVariant; - if (itemIndex >= (UInt32)_files.Size()) + if (itemIndex >= (UInt32)_refs.Size()) return E_INVALIDARG; - CFileInfoEx &fileInfo = _files[itemIndex]; + CDirItem &fileInfo = *_refs[itemIndex]; switch(propID) { case kpidIsFolder: @@ -216,8 +256,7 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT { fileInfo.CompressedSizeIsDefined = true; if (fileInfo.IsDirectory () || - !MyGetCompressedFileSizeW(_path + fileInfo.Name, - fileInfo.CompressedSize)) + !MyGetCompressedFileSizeW(_path + GetRelPath(fileInfo), fileInfo.CompressedSize)) fileInfo.CompressedSize = fileInfo.Size; } propVariant = fileInfo.CompressedSize; @@ -235,11 +274,21 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT propVariant = fileInfo.LastWriteTime; break; case kpidComment: + { LoadComments(); UString comment; - if (_comments.GetValue(fileInfo.Name, comment)) + if (_comments.GetValue(GetRelPath(fileInfo), comment)) propVariant = comment; break; + } + case kpidPrefix: + { + if (_flatMode) + { + propVariant = GetPrefix(fileInfo); + } + break; + } } propVariant.Detach(value); return S_OK; @@ -250,19 +299,35 @@ HRESULT CFSFolder::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultF *resultFolder = 0; CFSFolder *folderSpec = new CFSFolder; CMyComPtr<IFolderFolder> subFolder = folderSpec; - RINOK(folderSpec ->Init(_path + name + UString(L'\\'), 0)); + RINOK(folderSpec->Init(_path + name + UString(L'\\'), 0)); *resultFolder = subFolder.Detach(); return S_OK; } +UString CFSFolder::GetPrefix(const CDirItem &item) const +{ + UString path; + CDirItem *cur = item.Parent; + while (cur->Parent != 0) + { + path = cur->Name + UString('\\') + path; + cur = cur->Parent; + } + return path; +} + +UString CFSFolder::GetRelPath(const CDirItem &item) const +{ + return GetPrefix(item) + item.Name; +} STDMETHODIMP CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder) { *resultFolder = 0; - const NFind::CFileInfoW &fileInfo = _files[index]; + const CDirItem &fileInfo = *_refs[index]; if (!fileInfo.IsDirectory()) return E_INVALIDARG; - return BindToFolderSpec(fileInfo.Name, resultFolder); + return BindToFolderSpec(GetRelPath(fileInfo), resultFolder); } STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) @@ -328,6 +393,8 @@ STDMETHODIMP CFSFolder::GetName(BSTR *name) STDMETHODIMP CFSFolder::GetNumberOfProperties(UInt32 *numProperties) { *numProperties = sizeof(kProperties) / sizeof(kProperties[0]); + if (!_flatMode) + (*numProperties)--; return S_OK; } @@ -395,7 +462,7 @@ STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder) HRESULT CFSFolder::GetItemFullSize(int index, UInt64 &size, IProgress *progress) { - const CFileInfoW &fileInfo = _files[index]; + const CDirItem &fileInfo = *_refs[index]; if (fileInfo.IsDirectory()) { /* @@ -415,7 +482,7 @@ HRESULT CFSFolder::GetItemFullSize(int index, UInt64 &size, IProgress *progress) *totalSize += size; } */ - return GetFolderSize(_path + fileInfo.Name, size, progress); + return GetFolderSize(_path + GetRelPath(fileInfo), size, progress); } size = fileInfo.Size; return S_OK; @@ -424,7 +491,7 @@ HRESULT CFSFolder::GetItemFullSize(int index, UInt64 &size, IProgress *progress) STDMETHODIMP CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress) { NCOM::CPropVariant propVariant; - if (index >= (UInt32)_files.Size()) + if (index >= (UInt32)_refs.Size()) return E_INVALIDARG; UInt64 size = 0; HRESULT result = GetItemFullSize(index, size, progress); @@ -476,8 +543,9 @@ STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress *progress) STDMETHODIMP CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress) { - const CFileInfoW &fileInfo = _files[index]; - if (!NDirectory::MyMoveFile(_path + fileInfo.Name, _path + newName)) + const CDirItem &fileInfo = *_refs[index]; + const UString fullPrefix = _path + GetPrefix(fileInfo); + if (!NDirectory::MyMoveFile(fullPrefix + fileInfo.Name, fullPrefix + newName)) return GetLastError(); return S_OK; } @@ -489,8 +557,8 @@ STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems, for (UInt32 i = 0; i < numItems; i++) { int index = indices[i]; - const CFileInfoW &fileInfo = _files[indices[i]]; - const UString fullPath = _path + fileInfo.Name; + const CDirItem &fileInfo = *_refs[indices[i]]; + const UString fullPath = _path + GetRelPath(fileInfo); bool result; if (fileInfo.IsDirectory()) result = NDirectory::RemoveDirectoryWithSubItems(fullPath); @@ -507,9 +575,11 @@ STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems, STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) { - if (index >= (UInt32)_files.Size()) + if (index >= (UInt32)_refs.Size()) return E_INVALIDARG; - CFileInfoEx &fileInfo = _files[index]; + CDirItem &fileInfo = *_refs[index]; + if (fileInfo.Parent->Parent != 0) + return E_NOTIMPL; switch(propID) { case kpidComment: @@ -543,12 +613,12 @@ STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID, STDMETHODIMP CFSFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) { - if (index >= (UInt32)_files.Size()) + if (index >= (UInt32)_refs.Size()) return E_INVALIDARG; - const CFileInfoEx &fileInfo = _files[index]; + const CDirItem &fileInfo = *_refs[index]; *iconIndex = 0; int iconIndexTemp; - if (GetRealIconIndex(_path + fileInfo.Name, fileInfo.Attributes, iconIndexTemp) != 0) + if (GetRealIconIndex(_path + GetRelPath(fileInfo), fileInfo.Attributes, iconIndexTemp) != 0) { *iconIndex = iconIndexTemp; return S_OK; @@ -556,5 +626,11 @@ STDMETHODIMP CFSFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex) return GetLastError(); } +STDMETHODIMP CFSFolder::SetFlatMode(Int32 flatMode) +{ + _flatMode = IntToBool(flatMode); + return S_OK; +} + // static const LPCTSTR kInvalidFileChars = TEXT("\\/:*?\"<>|"); diff --git a/7zip/FileManager/FSFolder.h b/7zip/FileManager/FSFolder.h index cbe9cf59..58d920b1 100755 --- a/7zip/FileManager/FSFolder.h +++ b/7zip/FileManager/FSFolder.h @@ -20,6 +20,20 @@ struct CFileInfoEx: public NWindows::NFile::NFind::CFileInfoW UInt64 CompressedSize; }; +struct CDirItem; + +struct CDirItem: public CFileInfoEx +{ + CDirItem *Parent; + CObjectVector<CDirItem> Files; + + CDirItem(): Parent(0) {} + void Clear() + { + Files.Clear(); + Parent = 0; + } +}; class CFSFolder: public IFolderFolder, @@ -32,6 +46,7 @@ class CFSFolder: public IFolderGetItemFullSize, public IFolderClone, public IFolderGetSystemIconIndex, + public IFolderSetFlatMode, public CMyUnknownImp { UInt64 GetSizeOfItem(int anIndex) const; @@ -46,6 +61,7 @@ public: MY_QUERYINTERFACE_ENTRY(IFolderGetItemFullSize) MY_QUERYINTERFACE_ENTRY(IFolderClone) MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex) + MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) MY_QUERYINTERFACE_END MY_ADDREF_RELEASE @@ -67,6 +83,8 @@ public: STDMETHOD(Clone)(IFolderFolder **resultFolder); STDMETHOD(GetItemFullSize)(UInt32 index, PROPVARIANT *value, IProgress *progress); + STDMETHOD(SetFlatMode)(Int32 flatMode); + // IFolderOperations STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress); @@ -84,7 +102,9 @@ public: private: UString _path; - CObjectVector<CFileInfoEx> _files; + CDirItem _root; + CRecordVector<CDirItem *> _refs; + CMyComPtr<IFolderFolder> _parentFolder; bool _findChangeNotificationDefined; @@ -92,6 +112,8 @@ private: bool _commentsAreLoaded; CPairsStorage _comments; + bool _flatMode; + NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification; HRESULT GetItemFullSize(int index, UInt64 &size, IProgress *progress); @@ -100,8 +122,22 @@ private: bool LoadComments(); bool SaveComments(); + HRESULT LoadSubItems(CDirItem &dirItem, const UString &path); + void AddRefs(CDirItem &dirItem); public: HRESULT Init(const UString &path, IFolderFolder *parentFolder); + + CFSFolder() : _flatMode(false) {} + + UString GetPrefix(const CDirItem &item) const; + UString GetRelPath(const CDirItem &item) const; + UString GetRelPath(UInt32 index) const { return GetRelPath(*_refs[index]); } + + void Clear() + { + _root.Clear(); + _refs.Clear(); + } }; #endif diff --git a/7zip/FileManager/FSFolderCopy.cpp b/7zip/FileManager/FSFolderCopy.cpp index f46ee7b0..bba8b3f3 100755 --- a/7zip/FileManager/FSFolderCopy.cpp +++ b/7zip/FileManager/FSFolderCopy.cpp @@ -252,7 +252,7 @@ STDMETHODIMP CFSFolder::CopyTo(const UInt32 *indices, UInt32 numItems, for (i = 0; i < numItems; i++) { int index = indices[i]; - if (index >= _files.Size()) + if (index >= _refs.Size()) return E_INVALIDARG; UINT64 size; RINOK(GetItemFullSize(indices[i], size, callback)); @@ -286,11 +286,11 @@ STDMETHODIMP CFSFolder::CopyTo(const UInt32 *indices, UInt32 numItems, RINOK(callback->SetCompleted(&completedSize)); for (i = 0; i < numItems; i++) { - const CFileInfoW &fileInfo = _files[indices[i]]; + const CDirItem &fileInfo = *_refs[indices[i]]; UString destPath2 = destPath; if (!directName) destPath2 += fileInfo.Name; - UString srcPath = _path + fileInfo.Name; + UString srcPath = _path + GetPrefix(fileInfo) + fileInfo.Name; if (fileInfo.IsDirectory()) { RINOK(CopyFolder(srcPath, destPath2, callback, completedSize)); @@ -415,7 +415,7 @@ STDMETHODIMP CFSFolder::MoveTo( for (i = 0; i < numItems; i++) { int index = indices[i]; - if (index >= _files.Size()) + if (index >= _refs.Size()) return E_INVALIDARG; UINT64 size; RINOK(GetItemFullSize(indices[i], size, callback)); @@ -445,11 +445,11 @@ STDMETHODIMP CFSFolder::MoveTo( RINOK(callback->SetCompleted(&completedSize)); for (i = 0; i < numItems; i++) { - const CFileInfoW &fileInfo = _files[indices[i]]; + const CDirItem &fileInfo = *_refs[indices[i]]; UString destPath2 = destPath; if (!directName) destPath2 += fileInfo.Name; - UString srcPath = _path + fileInfo.Name; + UString srcPath = _path + GetPrefix(fileInfo) + fileInfo.Name; if (fileInfo.IsDirectory()) { RINOK(MyMoveFolder(srcPath, destPath2, callback, completedSize)); diff --git a/7zip/FileManager/IFolder.h b/7zip/FileManager/IFolder.h index 72c96cc5..aa50a39d 100755 --- a/7zip/FileManager/IFolder.h +++ b/7zip/FileManager/IFolder.h @@ -133,8 +133,13 @@ FOLDER_INTERFACE(IFolderClone, 0x09) STDMETHOD(Clone)(IFolderFolder **resultFolder) PURE; }; +FOLDER_INTERFACE(IFolderSetFlatMode, 0x0A) +{ + STDMETHOD(SetFlatMode)(Int32 flatMode) PURE; +}; + /* -FOLDER_INTERFACE(IFolderOpen, 0x0A) +FOLDER_INTERFACE(IFolderOpen, 0x10) { STDMETHOD(FolderOpen)( const wchar_t *aFileName, diff --git a/7zip/FileManager/MyLoadMenu.cpp b/7zip/FileManager/MyLoadMenu.cpp index 9670fc9c..740b2520 100755 --- a/7zip/FileManager/MyLoadMenu.cpp +++ b/7zip/FileManager/MyLoadMenu.cpp @@ -114,6 +114,7 @@ static CIDLangPair kIDLangPairs[] = { IDM_VIEW_REFRESH, 0x03000440 }, + { IDM_VIEW_FLAT_VIEW, 0x03000449 }, { IDM_VIEW_TWO_PANELS, 0x03000450 }, { IDM_VIEW_ARCHIVE_TOOLBAR, 0x03000460 }, { IDM_VIEW_STANDARD_TOOLBAR, 0x03000461 }, @@ -331,6 +332,8 @@ void OnMenuActivating(HWND hWnd, HMENU hMenu, int position) IDM_VIEW_LARGE_ICONS + g_App.GetListViewMode(), MF_BYCOMMAND); menu.CheckItem(IDM_VIEW_TWO_PANELS, MF_BYCOMMAND | ((g_App.NumPanels == 2) ? MF_CHECKED : MF_UNCHECKED)); + menu.CheckItem(IDM_VIEW_FLAT_VIEW, MF_BYCOMMAND | + ((g_App.GetFlatMode()) ? MF_CHECKED : MF_UNCHECKED)); menu.CheckItem(IDM_VIEW_ARCHIVE_TOOLBAR, MF_BYCOMMAND | (g_App.ShowArchiveToolbar ? MF_CHECKED : MF_UNCHECKED)); menu.CheckItem(IDM_VIEW_STANDARD_TOOLBAR, MF_BYCOMMAND | @@ -635,10 +638,12 @@ bool OnMenuCommand(HWND hWnd, int id) case IDM_VIEW_REFRESH: g_App.RefreshView(); break; + case IDM_VIEW_FLAT_VIEW: + g_App.ChangeFlatMode(); + break; case IDM_VIEW_TWO_PANELS: g_App.SwitchOnOffOnePanel(); break; - case IDM_VIEW_STANDARD_TOOLBAR: g_App.SwitchStandardToolbar(); break; diff --git a/7zip/FileManager/Panel.cpp b/7zip/FileManager/Panel.cpp index b54b7cd7..e37b3f59 100755 --- a/7zip/FileManager/Panel.cpp +++ b/7zip/FileManager/Panel.cpp @@ -93,7 +93,7 @@ LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) OnShiftSelectMessage(); return 0; case kReLoadMessage: - OnReload(); + RefreshListCtrl(_selectedState); return 0; case kSetFocusToListView: _listView.SetFocus(); @@ -736,6 +736,13 @@ void CPanel::SetListViewMode(UINT32 index) // RefreshListCtrlSaveFocused(); } +void CPanel::ChangeFlatMode() +{ + _flatMode = !_flatMode; + RefreshListCtrlSaveFocused(); +} + + void CPanel::RefreshStatusBar() { PostMessage(kRefreshStatusBar); @@ -759,7 +766,7 @@ void CPanel::AddToArchive() for (int i = 0; i < indices.Size(); i++) { int index = indices[i]; - names.Add(_currentFolderPrefix + GetItemName(index)); + names.Add(_currentFolderPrefix + GetItemRelPath(index)); } const UString archiveName = CreateArchiveName( names.Front(), (names.Size() > 1), false); @@ -791,7 +798,7 @@ void CPanel::ExtractArchives() MessageBox(kSelectOneFile); return; } - paths.Add(_currentFolderPrefix + GetItemName(index)); + paths.Add(_currentFolderPrefix + GetItemRelPath(index)); } ::ExtractArchives(paths, _currentFolderPrefix, true); } @@ -819,7 +826,7 @@ void CPanel::TestArchives() MessageBox(kSelectOneFile); return; } - paths.Add(_currentFolderPrefix + GetItemName(index)); + paths.Add(_currentFolderPrefix + GetItemRelPath(index)); } ::TestArchives(paths); } diff --git a/7zip/FileManager/Panel.h b/7zip/FileManager/Panel.h index 50002b24..a94cb868 100755 --- a/7zip/FileManager/Panel.h +++ b/7zip/FileManager/Panel.h @@ -232,7 +232,7 @@ public: bool _mySelectMode; CBoolVector _selectedStatusVector; - UString _focusedName; + CSelectedState _selectedState; UInt32 GetRealIndex(const LVITEMW &item) const { @@ -257,6 +257,10 @@ public: UInt32 _ListViewMode; int _xSize; + bool _flatMode; + + bool _dontShowMode; + UString _currentFolderPrefix; @@ -273,6 +277,8 @@ public: void RefreshListCtrlSaveFocused(); UString GetItemName(int itemIndex) const; + UString GetItemPrefix(int itemIndex) const; + UString GetItemRelPath(int itemIndex) const; bool IsItemFolder(int itemIndex) const; UInt64 GetItemSize(int itemIndex) const; @@ -316,10 +322,12 @@ public: _startGroupSelect(0), _selectionIsDefined(false), _ListViewMode(3), + _flatMode(false), _xSize(300), _mySelectMode(false), - _enableItemChangeNotify(true) - {} + _enableItemChangeNotify(true), + _dontShowMode(false) + {} void SetExtendedStyle() { @@ -471,6 +479,9 @@ public: void SetListViewMode(UInt32 index); UInt32 GetListViewMode() const { return _ListViewMode; }; + void ChangeFlatMode(); + bool GetFlatMode() const { return _flatMode; }; + void RefreshStatusBar(); void OnRefreshStatusBar(); diff --git a/7zip/FileManager/PanelCrc.cpp b/7zip/FileManager/PanelCrc.cpp index 998a0468..cc5d1eb2 100755 --- a/7zip/FileManager/PanelCrc.cpp +++ b/7zip/FileManager/PanelCrc.cpp @@ -30,6 +30,7 @@ static const UInt32 kBufSize = (1 << 15); struct CDirEnumerator { + bool FlatMode; UString BasePrefix; UStringVector FileNames; @@ -38,6 +39,8 @@ struct CDirEnumerator int Index; bool GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &fullPath, DWORD &errorCode); void Init(); + + CDirEnumerator(): FlatMode(false) {}; }; void CDirEnumerator::Init() @@ -57,6 +60,10 @@ bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UStr if (Index >= FileNames.Size()) return true; const UString &path = FileNames[Index]; + int pos = path.ReverseFind('\\'); + resPath.Empty(); + if (pos >= 0) + resPath = path.Left(pos + 1); if (!NFind::FindFile(BasePrefix + path, fileInfo)) { errorCode = ::GetLastError(); @@ -64,7 +71,6 @@ bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UStr return false; } Index++; - resPath.Empty(); break; } bool found; @@ -83,7 +89,7 @@ bool CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UStr Prefixes.DeleteBack(); } resPath += fileInfo.Name; - if (fileInfo.IsDirectory()) + if (!FlatMode && fileInfo.IsDirectory()) { UString prefix = resPath + (UString)(wchar_t)kDirDelimiter; Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)kAnyStringWildcard)); @@ -276,8 +282,9 @@ void CApp::CalculateCrc() CThreadCrc combiner; for (int i = 0; i < indices.Size(); i++) - combiner.DirEnumerator.FileNames.Add(srcPanel.GetItemName(indices[i])); + combiner.DirEnumerator.FileNames.Add(srcPanel.GetItemRelPath(indices[i])); combiner.DirEnumerator.BasePrefix = srcPanel._currentFolderPrefix; + combiner.DirEnumerator.FlatMode = GetFlatMode(); CProgressDialog progressDialog; combiner.ProgressDialog = &progressDialog; diff --git a/7zip/FileManager/PanelDrag.cpp b/7zip/FileManager/PanelDrag.cpp index 4de6d95f..494bca79 100755 --- a/7zip/FileManager/PanelDrag.cpp +++ b/7zip/FileManager/PanelDrag.cpp @@ -319,7 +319,15 @@ void CPanel::OnDrag(LPNMLISTVIEW nmListView) { UStringVector names; for (int i = 0; i < indices.Size(); i++) - names.Add(dirPrefix + GetItemName(indices[i])); + { + UInt32 index = indices[i]; + UString s; + if (isFSFolder) + s = GetItemRelPath(index); + else + s = GetItemName(index); + names.Add(dirPrefix + s); + } if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names)) return; } diff --git a/7zip/FileManager/PanelItemOpen.cpp b/7zip/FileManager/PanelItemOpen.cpp index 19cb28ad..fa6ce849 100755 --- a/7zip/FileManager/PanelItemOpen.cpp +++ b/7zip/FileManager/PanelItemOpen.cpp @@ -104,7 +104,7 @@ HRESULT CPanel::OpenItemAsArchive(const UString &name) HRESULT CPanel::OpenItemAsArchive(int index) { CDisableTimerProcessing disableTimerProcessing1(*this); - RINOK(OpenItemAsArchive(GetItemName(index))); + RINOK(OpenItemAsArchive(GetItemRelPath(index))); RefreshListCtrl(); return S_OK; } @@ -279,14 +279,14 @@ void CPanel::EditItem(int index) OpenItemInArchive(index, false, true, true); return; } - HANDLE hProcess = StartEditApplication(_currentFolderPrefix + GetItemName(index), (HWND)*this); + HANDLE hProcess = StartEditApplication(_currentFolderPrefix + GetItemRelPath(index), (HWND)*this); if (hProcess != 0) ::CloseHandle(hProcess); } void CPanel::OpenFolderExternal(int index) { - HANDLE hProcess = StartApplication(GetFsPath() + GetItemName(index), (HWND)*this); + HANDLE hProcess = StartApplication(GetFsPath() + GetItemRelPath(index), (HWND)*this); if (hProcess != 0) ::CloseHandle(hProcess); } @@ -299,7 +299,7 @@ void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal) OpenItemInArchive(index, tryInternal, tryExternal, false); return; } - UString name = GetItemName(index); + UString name = GetItemRelPath(index); if (IsNameVirus(name)) { MessageBoxMyError(virusMessage); @@ -411,7 +411,7 @@ static DWORD WINAPI MyThreadFunction(void *param) void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bool editMode) { - UString name = GetItemName(index); + const UString name = GetItemName(index); if (IsNameVirus(name)) { MessageBoxMyError(virusMessage); diff --git a/7zip/FileManager/PanelItems.cpp b/7zip/FileManager/PanelItems.cpp index 7e926226..12ade3cf 100755 --- a/7zip/FileManager/PanelItems.cpp +++ b/7zip/FileManager/PanelItems.cpp @@ -215,7 +215,7 @@ void CPanel::GetSelectedNames(UStringVector &selectedNames) GetSelectedItemsIndices(indices); selectedNames.Reserve(indices.Size()); for (int i = 0; i < indices.Size(); i++) - selectedNames.Add(GetItemName(indices[i])); + selectedNames.Add(GetItemRelPath(indices[i])); /* for (int i = 0; i < _listView.GetItemCount(); i++) @@ -245,19 +245,12 @@ void CPanel::SaveSelectedState(CSelectedState &s) s.FocusedName.Empty(); s.SelectedNames.Clear(); s.FocusedItem = _listView.GetFocusedItem(); - if (!_focusedName.IsEmpty()) - { - s.FocusedName = _focusedName; - s.SelectFocused = true; - _focusedName.Empty(); - } - else { if (s.FocusedItem >= 0) { int realIndex = GetRealItemIndex(s.FocusedItem); if (realIndex != kParentIndex) - s.FocusedName = GetItemName(realIndex); + s.FocusedName = GetItemRelPath(realIndex); /* const int kSize = 1024; WCHAR name[kSize + 1]; @@ -307,6 +300,7 @@ void CPanel::SetFocusedSelectedItem(int index, bool select) void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, const UStringVector &selectedNames) { + _dontShowMode = false; LoadFullPathAndShow(); // OutputDebugStringA("=======\n"); // OutputDebugStringA("s1 \n"); @@ -340,6 +334,11 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool se bool isRoot = IsRootFolder(); _headerToolBar.EnableButton(kParentFolderID, !IsRootFolder()); + CMyComPtr<IFolderSetFlatMode> folderSetFlatMode; + _folder.QueryInterface(IID_IFolderSetFlatMode, &folderSetFlatMode); + if (folderSetFlatMode) + folderSetFlatMode->SetFlatMode(BoolToInt(_flatMode)); + if (_folder->LoadItems() != S_OK) return; @@ -385,10 +384,11 @@ void CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool se for(UInt32 i = 0; i < numItems; i++) { UString itemName = GetItemName(i); - if (itemName.CompareNoCase(focusedName) == 0) + const UString relPath = GetItemRelPath(i); + if (relPath.CompareNoCase(focusedName) == 0) cursorIndex = _listView.GetItemCount(); bool selected = false; - if (selectedNames.FindInSorted(itemName) >= 0) + if (selectedNames.FindInSorted(relPath) >= 0) selected = true; _selectedStatusVector.Add(selected); @@ -623,6 +623,24 @@ UString CPanel::GetItemName(int itemIndex) const return (propVariant.bstrVal); } +UString CPanel::GetItemPrefix(int itemIndex) const +{ + if (itemIndex == kParentIndex) + return UString(); + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidPrefix, &propVariant) != S_OK) + throw 2723400; + UString prefix; + if (propVariant.vt == VT_BSTR) + prefix = propVariant.bstrVal; + return prefix; +} + +UString CPanel::GetItemRelPath(int itemIndex) const +{ + return GetItemPrefix(itemIndex) + GetItemName(itemIndex); +} + bool CPanel::IsItemFolder(int itemIndex) const { diff --git a/7zip/FileManager/PanelListNotify.cpp b/7zip/FileManager/PanelListNotify.cpp index 831a7d3e..abc86029 100755 --- a/7zip/FileManager/PanelListNotify.cpp +++ b/7zip/FileManager/PanelListNotify.cpp @@ -43,6 +43,9 @@ static UString ConvertSizeToString(UINT64 value) LRESULT CPanel::SetItemText(LVITEMW &item) { + if (_dontShowMode) + return 0; + UINT32 realIndex = GetRealIndex(item); /* if ((item.mask & LVIF_IMAGE) != 0) diff --git a/7zip/FileManager/PanelMenu.cpp b/7zip/FileManager/PanelMenu.cpp index 3766a7ea..878478c0 100755 --- a/7zip/FileManager/PanelMenu.cpp +++ b/7zip/FileManager/PanelMenu.cpp @@ -102,7 +102,7 @@ HRESULT CPanel::CreateShellContextMenu( for (int i = 0; i < operatedIndices.Size(); i++) { LPITEMIDLIST pidl; - UString fileName = GetItemName(operatedIndices[i]); + UString fileName = GetItemRelPath(operatedIndices[i]); if (IsFSDrivesFolder()) fileName += L'\\'; RINOK(parentFolder->ParseDisplayName(GetParent(), 0, @@ -263,7 +263,7 @@ void CPanel::CreateSevenZipMenu(HMENU menuSpec, UStringVector names; int i; for(i = 0; i < operatedIndices.Size(); i++) - names.Add(currentFolderUnicode + GetItemName(operatedIndices[i])); + names.Add(currentFolderUnicode + GetItemRelPath(operatedIndices[i])); CRecordVector<const wchar_t *> namePointers; for(i = 0; i < operatedIndices.Size(); i++) namePointers.Add(names[i]); diff --git a/7zip/FileManager/PanelOperations.cpp b/7zip/FileManager/PanelOperations.cpp index 0aa207d9..8f1f28e4 100755 --- a/7zip/FileManager/PanelOperations.cpp +++ b/7zip/FileManager/PanelOperations.cpp @@ -73,7 +73,7 @@ void CPanel::DeleteItems(bool toRecycleBin) size_t size = 0; for (int i = 0; i < indices.Size(); i++) { - const AString path = GetSystemString(GetFsPath() + GetItemName(indices[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; @@ -104,7 +104,7 @@ void CPanel::DeleteItems(bool toRecycleBin) size_t size = 0; for (int i = 0; i < indices.Size(); i++) { - const UString path = GetFsPath() + GetItemName(indices[i]); + const UString path = GetFsPath() + GetItemRelPath(indices[i]); buffer.EnsureCapacity(size + path.Length() + 1); memmove(((WCHAR *)buffer) + size, (const WCHAR *)path, (path.Length() + 1) * sizeof(WCHAR)); size += path.Length() + 1; @@ -159,7 +159,7 @@ void CPanel::DeleteItems(bool toRecycleBin) if (indices.Size() == 1) { int index = indices[0]; - const UString itemName = GetItemName(index); + const UString itemName = GetItemRelPath(index); if (IsItemFolder(index)) { title = LangString(IDS_CONFIRM_FOLDER_DELETE, 0x03020211); @@ -228,12 +228,15 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh) MessageBoxMyError(L"Renaming is not supported"); return FALSE; } - UString newName = lpnmh->item.pszText; + const UString newName = lpnmh->item.pszText; CPanel::CDisableTimerProcessing disableTimerProcessing2(*this); + SaveSelectedState(_selectedState); + int realIndex = GetRealIndex(lpnmh->item); if (realIndex == kParentIndex) return FALSE; + const UString prefix = GetItemPrefix(realIndex); HRESULT result = folderOperations->Rename(realIndex, newName, 0); if (result != S_OK) { @@ -242,11 +245,16 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh) } // Can't use RefreshListCtrl here. // RefreshListCtrlSaveFocused(); - _focusedName = newName; + _selectedState.FocusedName = prefix + newName; + _selectedState.SelectFocused = true; // We need clear all items to disable GetText before Reload: // number of items can change. - _listView.DeleteAllItems(); + // _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; @@ -355,7 +363,7 @@ void CPanel::ChangeComment() else if (propVariant.vt != VT_EMPTY) return; } - UString name = GetItemName(realIndex); + UString name = GetItemRelPath(realIndex); CComboDialog comboDialog; comboDialog.Title = name + L" " + LangString(IDS_COMMENT, 0x03020290); comboDialog.Value = comment; diff --git a/7zip/FileManager/PanelSort.cpp b/7zip/FileManager/PanelSort.cpp index 02ba2e38..79a36ceb 100755 --- a/7zip/FileManager/PanelSort.cpp +++ b/7zip/FileManager/PanelSort.cpp @@ -29,9 +29,17 @@ int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) // if (panel->_sortIndex == 0) case kpidName: { - UString &name1 = panel->GetItemName(lParam1); - UString &name2 = panel->GetItemName(lParam2); - return name1.CompareNoCase(name2); + const UString &name1 = panel->GetItemName(lParam1); + const UString &name2 = panel->GetItemName(lParam2); + int res = name1.CompareNoCase(name2); + /* + if (res != 0 || !panel->_flatMode) + return res; + const UString &prefix1 = panel->GetItemPrefix(lParam1); + const UString &prefix2 = panel->GetItemPrefix(lParam2); + return res = prefix1.CompareNoCase(prefix2); + */ + return res; } case kpidNoProperty: { @@ -39,8 +47,8 @@ int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) } case kpidExtension: { - UString &ext1 = GetExtension(panel->GetItemName(lParam1)); - UString &ext2 = GetExtension(panel->GetItemName(lParam2)); + const UString &ext1 = GetExtension(panel->GetItemName(lParam1)); + const UString &ext2 = GetExtension(panel->GetItemName(lParam2)); return ext1.CompareNoCase(ext2); } } diff --git a/7zip/FileManager/PanelSplitFile.cpp b/7zip/FileManager/PanelSplitFile.cpp index be732a85..d1d9f408 100755 --- a/7zip/FileManager/PanelSplitFile.cpp +++ b/7zip/FileManager/PanelSplitFile.cpp @@ -204,7 +204,7 @@ void CApp::Split() } const UString itemName = srcPanel.GetItemName(index); - UString srcPath = srcPanel._currentFolderPrefix; + UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); UString path = srcPath; int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &destPanel = Panels[destPanelIndex]; @@ -212,7 +212,7 @@ void CApp::Split() if (destPanel.IsFSFolder()) path = destPanel._currentFolderPrefix; CSplitDialog splitDialog; - splitDialog.FilePath = itemName; + splitDialog.FilePath = srcPanel.GetItemRelPath(index); splitDialog.Path = path; if (splitDialog.Create(srcPanel.GetParent()) == IDCANCEL) return; @@ -412,7 +412,7 @@ void CApp::Combine() } const UString itemName = srcPanel.GetItemName(index); - UString srcPath = srcPanel._currentFolderPrefix; + UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index); UString path = srcPath; int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex); CPanel &destPanel = Panels[destPanelIndex]; @@ -423,7 +423,7 @@ void CApp::Combine() copyDialog.Value = path; copyDialog.Title = LangString(IDS_COMBINE, 0x03020600); copyDialog.Title += ' '; - copyDialog.Title += itemName; + copyDialog.Title += srcPanel.GetItemRelPath(index); copyDialog.Static = LangString(IDS_COMBINE_TO, 0x03020601);; if (copyDialog.Create(srcPanel.GetParent()) == IDCANCEL) diff --git a/7zip/FileManager/PropertyName.cpp b/7zip/FileManager/PropertyName.cpp index d6c5bac4..848a8855 100755 --- a/7zip/FileManager/PropertyName.cpp +++ b/7zip/FileManager/PropertyName.cpp @@ -45,6 +45,7 @@ static CPropertyIDNamePair kPropertyIDNamePairs[] = { kpidBlock, IDS_PROPERTY_BLOCK, 0x0200021B }, { kpidComment, IDS_PROPERTY_COMMENT, 0x0200021C }, { kpidPosition, IDS_PROPERTY_POSITION, 0x0200021D }, + { kpidPrefix, IDS_PROPERTY_PREFIX, 0x0200021E }, { kpidTotalSize, IDS_PROPERTY_TOTAL_SIZE, 0x03031100 }, { kpidFreeSpace, IDS_PROPERTY_FREE_SPACE, 0x03031101 }, diff --git a/7zip/FileManager/Resource/PropertyName/resource.h b/7zip/FileManager/Resource/PropertyName/resource.h index 5730560f..f3d56ef3 100755 --- a/7zip/FileManager/Resource/PropertyName/resource.h +++ b/7zip/FileManager/Resource/PropertyName/resource.h @@ -25,3 +25,4 @@ #define IDS_PROPERTY_BLOCK 27 #define IDS_PROPERTY_COMMENT 28 #define IDS_PROPERTY_POSITION 29 +#define IDS_PROPERTY_PREFIX 30 diff --git a/7zip/FileManager/Resource/PropertyName/resource.rc b/7zip/FileManager/Resource/PropertyName/resource.rc index db04e236..3f517aff 100755 --- a/7zip/FileManager/Resource/PropertyName/resource.rc +++ b/7zip/FileManager/Resource/PropertyName/resource.rc @@ -31,4 +31,5 @@ BEGIN IDS_PROPERTY_BLOCK "Block" IDS_PROPERTY_COMMENT "Comment" IDS_PROPERTY_POSITION "Position" + IDS_PROPERTY_PREFIX "Path Prefix" END diff --git a/7zip/FileManager/resource.h b/7zip/FileManager/resource.h index 0b3d1d50..78673475 100755 --- a/7zip/FileManager/resource.h +++ b/7zip/FileManager/resource.h @@ -42,6 +42,7 @@ #define IDM_OPEN_PARENT_FOLDER 431 #define IDM_FOLDERS_HISTORY 432 #define IDM_VIEW_REFRESH 440 +#define IDM_VIEW_FLAT_VIEW 449 #define IDM_VIEW_TWO_PANELS 450 #define IDM_VIEW_TOOLBARS 451 #define IDM_VIEW_STANDARD_TOOLBAR 460 diff --git a/7zip/FileManager/resource.rc b/7zip/FileManager/resource.rc index d5a7ee64..b6e79eb1 100755 --- a/7zip/FileManager/resource.rc +++ b/7zip/FileManager/resource.rc @@ -67,6 +67,7 @@ BEGIN MENUITEM "Size\tCtrl+F6", IDM_VIEW_ARANGE_BY_SIZE MENUITEM "Unsorted\tCtrl+F7", IDM_VIEW_ARANGE_NO_SORT MENUITEM SEPARATOR + MENUITEM "Flat View", IDM_VIEW_FLAT_VIEW MENUITEM "&2 Panels\tF9", IDM_VIEW_TWO_PANELS POPUP "Toolbars" BEGIN diff --git a/7zip/Guid.txt b/7zip/Guid.txt index 7544f42f..4acc9147 100755 --- a/7zip/Guid.txt +++ b/7zip/Guid.txt @@ -91,7 +91,7 @@ A0 IOutArchive 07 IFolderGetSystemIconIndex 08 IFolderGetItemFullSize 09 IFolderClone -0A IFolderOpen // +0A IFolderSetFlatMode 000900000000} FolderInterface.h::IFolderManager 000900010000} FolderInterface.h::IFolderManagerGetIconPath diff --git a/7zip/MyVersion.h b/7zip/MyVersion.h index b8ae159a..72af8bae 100755 --- a/7zip/MyVersion.h +++ b/7zip/MyVersion.h @@ -1,7 +1,7 @@ #define MY_VER_MAJOR 4 -#define MY_VER_MINOR 36 -#define MY_VERSION "4.36 beta" -#define MY_7ZIP_VERSION "7-Zip 4.36 beta" -#define MY_DATE "2006-03-12" +#define MY_VER_MINOR 37 +#define MY_VERSION "4.37 beta" +#define MY_7ZIP_VERSION "7-Zip 4.37 beta" +#define MY_DATE "2006-03-18" #define MY_COPYRIGHT "Copyright (c) 1999-2006 Igor Pavlov" #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE diff --git a/7zip/PropID.h b/7zip/PropID.h index 9dafc4b6..79f82452 100755 --- a/7zip/PropID.h +++ b/7zip/PropID.h @@ -35,6 +35,7 @@ enum kpidBlock, kpidComment, kpidPosition, + kpidPrefix, kpidTotalSize = 0x1100, kpidFreeSpace, diff --git a/7zip/UI/Agent/Agent.cpp b/7zip/UI/Agent/Agent.cpp index 3f0be7d2..9c573414 100755 --- a/7zip/UI/Agent/Agent.cpp +++ b/7zip/UI/Agent/Agent.cpp @@ -25,15 +25,40 @@ STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder) return S_OK; } +void CAgentFolder::LoadFolder(CProxyFolder *folder) +{ + int i; + CProxyItem item; + item.Folder = folder; + for (i = 0; i < folder->Folders.Size(); i++) + { + item.Index = i; + _items.Add(item); + LoadFolder(&folder->Folders[i]); + } + int start = folder->Folders.Size(); + for (i = 0; i < folder->Files.Size(); i++) + { + item.Index = start + i; + _items.Add(item); + } +} + + STDMETHODIMP CAgentFolder::LoadItems() { + _items.Clear(); + if (_flatMode) + LoadFolder(_proxyFolderItem); return S_OK; } STDMETHODIMP CAgentFolder::GetNumberOfItems(UINT32 *numItems) { - *numItems = _proxyFolderItem->Folders.Size() + - _proxyFolderItem->Files.Size(); + if (_flatMode) + *numItems = _items.Size(); + else + *numItems = _proxyFolderItem->Folders.Size() +_proxyFolderItem->Files.Size(); return S_OK; } @@ -45,12 +70,75 @@ STDMETHODIMP CAgentFolder::GetNumberOfSubFolders(UINT32 *aNumSubFolders) } */ +UString CAgentFolder::GetName(UInt32 index) const +{ + UInt32 realIndex; + const CProxyFolder *folder; + if (_flatMode) + { + const CProxyItem &item = _items[index]; + folder = item.Folder; + realIndex = item.Index; + } + else + { + folder = _proxyFolderItem; + realIndex = index; + } + + if (realIndex < (UINT32)folder->Folders.Size()) + return folder->Folders[realIndex].Name; + return folder->Files[realIndex - folder->Folders.Size()].Name; +} + +UString CAgentFolder::GetPrefix(UInt32 index) const +{ + if (!_flatMode) + return UString(); + const CProxyItem &item = _items[index]; + const CProxyFolder *folder = item.Folder; + UString path; + while(folder != _proxyFolderItem) + { + path = folder->Name + UString(L"\\") + path; + folder = folder->Parent; + } + return path; +} + +UString CAgentFolder::GetFullPathPrefixPlusPrefix(UInt32 index) const +{ + return _proxyFolderItem->GetFullPathPrefix() + GetPrefix(index); +} + +void CAgentFolder::GetPrefixIfAny(UInt32 index, NCOM::CPropVariant &propVariant) const +{ + if (!_flatMode) + return; + propVariant = GetPrefix(index); +} + + STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARIANT *value) { NCOM::CPropVariant propVariant; - if (itemIndex < (UINT32)_proxyFolderItem->Folders.Size()) + const CProxyFolder *folder; + UInt32 realIndex; + if (_flatMode) { - const CProxyFolder &item = _proxyFolderItem->Folders[itemIndex]; + const CProxyItem &item = _items[itemIndex]; + folder = item.Folder; + realIndex = item.Index; + } + else + { + folder = _proxyFolderItem; + realIndex = itemIndex; + } + + if (realIndex < (UINT32)folder->Folders.Size()) + { + const CProxyFolder &item = folder->Folders[realIndex]; switch(propID) { case kpidIsFolder: @@ -59,6 +147,9 @@ STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARI case kpidName: propVariant = item.Name; break; + case kpidPrefix: + GetPrefixIfAny(itemIndex, propVariant); + break; default: if (item.IsLeaf) return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); @@ -66,8 +157,8 @@ STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARI } else { - itemIndex -= _proxyFolderItem->Folders.Size(); - const CProxyFile &item = _proxyFolderItem->Files[itemIndex]; + realIndex -= folder->Folders.Size(); + const CProxyFile &item = folder->Files[realIndex]; switch(propID) { case kpidIsFolder: @@ -76,26 +167,53 @@ STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARI case kpidName: propVariant = item.Name; break; + case kpidPrefix: + GetPrefixIfAny(itemIndex, propVariant); + break; default: - return _agentSpec->GetArchive()->GetProperty(item.Index, - propID, value); + return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); } } propVariant.Detach(value); return S_OK; } -STDMETHODIMP CAgentFolder::BindToFolder(UINT32 index, IFolderFolder **resultFolder) +HRESULT CAgentFolder::BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder) { - COM_TRY_BEGIN - if (index >= (UINT32)_proxyFolderItem->Folders.Size()) - return E_INVALIDARG; + CMyComPtr<IFolderFolder> parentFolder; + if (folder->Parent != _proxyFolderItem) + { + RINOK(BindToFolder(folder->Parent, &parentFolder)); + } + else + parentFolder = this; CAgentFolder *folderSpec = new CAgentFolder; CMyComPtr<IFolderFolder> agentFolder = folderSpec; - folderSpec->Init(_proxyArchive, &_proxyFolderItem->Folders[index], - this, _agentSpec); + folderSpec->Init(_proxyArchive, folder, parentFolder, _agentSpec); *resultFolder = agentFolder.Detach(); return S_OK; +} + +STDMETHODIMP CAgentFolder::BindToFolder(UINT32 index, IFolderFolder **resultFolder) +{ + COM_TRY_BEGIN + + CProxyFolder *folder; + UInt32 realIndex; + if (_flatMode) + { + const CProxyItem &item = _items[index]; + folder = item.Folder; + realIndex = item.Index; + } + else + { + folder = _proxyFolderItem; + realIndex = index; + } + if (realIndex >= (UINT32)folder->Folders.Size()) + return E_INVALIDARG; + return BindToFolder(&folder->Folders[realIndex], resultFolder); COM_TRY_END } @@ -138,7 +256,10 @@ struct CArchiveItemPropertyTemp STDMETHODIMP CAgentFolder::GetNumberOfProperties(UINT32 *numProperties) { COM_TRY_BEGIN - return _agentSpec->GetArchive()->GetNumberOfProperties(numProperties); + RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProperties)); + if (_flatMode) + (*numProperties)++; + return S_OK; COM_TRY_END } @@ -146,9 +267,20 @@ STDMETHODIMP CAgentFolder::GetPropertyInfo(UINT32 index, BSTR *name, PROPID *propID, VARTYPE *varType) { COM_TRY_BEGIN - RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)); - if (*propID == kpidPath) - *propID = kpidName; + UINT32 numProperties; + _agentSpec->GetArchive()->GetNumberOfProperties(&numProperties); + if (index < numProperties) + { + RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)); + if (*propID == kpidPath) + *propID = kpidName; + } + else + { + *name = NULL; + *propID = kpidPrefix; + *varType = VT_BSTR; + } return S_OK; COM_TRY_END } @@ -195,6 +327,25 @@ STDMETHODIMP CAgentFolder::GetPath(BSTR *path) } #endif +void CAgentFolder::GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const +{ + if (!_flatMode) + { + _proxyFolderItem->GetRealIndices(indices, numItems, realIndices); + return; + } + realIndices.Clear(); + for(UINT32 i = 0; i < numItems; i++) + { + const CProxyItem &item = _items[indices[i]]; + const CProxyFolder *folder = item.Folder; + UInt32 realIndex = item.Index; + if (realIndex < (UINT32)folder->Folders.Size()) + continue; + realIndices.Add(folder->Files[realIndex - folder->Folders.Size()].Index); + } + realIndices.Sort(); +} STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices, UINT32 numItems, @@ -214,6 +365,12 @@ STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices, pathParts.Insert(0, currentProxyFolder->Name); currentProxyFolder = currentProxyFolder->Parent; } + + /* + if (_flatMode) + pathMode = NExtract::NPathMode::kNoPathnames; + */ + extractCallbackSpec->Init(_agentSpec->GetArchive(), extractCallback2, false, @@ -227,12 +384,18 @@ STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices, // ,_agentSpec->_srcDirectoryPrefix ); CUIntVector realIndices; - _proxyFolderItem->GetRealIndices(indices, numItems, realIndices); + GetRealIndices(indices, numItems, realIndices); return _agentSpec->GetArchive()->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallback); COM_TRY_END } +STDMETHODIMP CAgentFolder::SetFlatMode(Int32 flatMode) +{ + _flatMode = IntToBool(flatMode); + return S_OK; +} + ///////////////////////////////////////// // CAgent diff --git a/7zip/UI/Agent/Agent.h b/7zip/UI/Agent/Agent.h index e631d2bb..41f80266 100755 --- a/7zip/UI/Agent/Agent.h +++ b/7zip/UI/Agent/Agent.h @@ -32,6 +32,12 @@ public: STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder) PURE; }; +struct CProxyItem +{ + CProxyFolder *Folder; + UInt32 Index; +}; + class CAgent; class CAgentFolder: @@ -43,6 +49,7 @@ class CAgentFolder: public IFolderGetTypeID, public IFolderGetPath, public IFolderOperations, + public IFolderSetFlatMode, #endif public CMyUnknownImp { @@ -57,12 +64,17 @@ public: MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID) MY_QUERYINTERFACE_ENTRY(IFolderGetPath) MY_QUERYINTERFACE_ENTRY(IFolderOperations) + MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) #endif MY_QUERYINTERFACE_END MY_ADDREF_RELEASE // IFolderFolder - + + void LoadFolder(CProxyFolder *folder); + HRESULT BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder); + void GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const; + STDMETHOD(LoadItems)(); STDMETHOD(GetNumberOfItems)(UINT32 *numItems); STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value); @@ -102,10 +114,10 @@ public: const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress); STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress); + STDMETHOD(SetFlatMode)(Int32 flatMode); + #endif -#endif - - CAgentFolder(): _proxyFolderItem(NULL) {} + CAgentFolder(): _proxyFolderItem(NULL), _flatMode(0) {} void Init(CProxyArchive *proxyHandler, CProxyFolder *proxyFolderItem, @@ -130,12 +142,20 @@ public: IFolderArchiveUpdateCallback *updateCallback100); + UString GetPrefix(UInt32 index) const; + UString GetName(UInt32 index) const; + UString GetFullPathPrefixPlusPrefix(UInt32 index) const; + void GetPrefixIfAny(UInt32 index, NWindows::NCOM::CPropVariant &propVariant) const; + public: CProxyArchive *_proxyArchive; CProxyFolder *_proxyFolderItem; CMyComPtr<IFolderFolder> _parentFolder; CMyComPtr<IInFolderArchive> _agent; CAgent *_agentSpec; + + CRecordVector<CProxyItem> _items; + bool _flatMode; private: }; @@ -252,7 +272,7 @@ public: UString _folderPrefix; UString _archiveNamePrefix; - CProxyFolder *_archiveFolderItem; + CAgentFolder *_agentFolder; UString _archiveFilePath; diff --git a/7zip/UI/Agent/AgentOut.cpp b/7zip/UI/Agent/AgentOut.cpp index b898d461..3ce22077 100755 --- a/7zip/UI/Agent/AgentOut.cpp +++ b/7zip/UI/Agent/AgentOut.cpp @@ -36,25 +36,21 @@ STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder) _archiveNamePrefix.Empty(); if (folder == NULL) { - _archiveFolderItem = NULL; + _agentFolder = NULL; return S_OK; - // folder = m_RootFolder; } else { CMyComPtr<IFolderFolder> archiveFolder = folder; CMyComPtr<IArchiveFolderInternal> archiveFolderInternal; - RINOK(archiveFolder.QueryInterface( - IID_IArchiveFolderInternal, &archiveFolderInternal)); - CAgentFolder *agentFolder; - RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder)); - _archiveFolderItem = agentFolder->_proxyFolderItem; + RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal)); + RINOK(archiveFolderInternal->GetAgentFolder(&_agentFolder)); } UStringVector pathParts; pathParts.Clear(); CMyComPtr<IFolderFolder> folderItem = folder; - if (_archiveFolderItem != NULL) + if (folderItem != NULL) while (true) { CMyComPtr<IFolderFolder> newFolder; @@ -353,7 +349,7 @@ STDMETHODIMP CAgent::DeleteItems( CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); CUIntVector realIndices; - _archiveFolderItem->GetRealIndices(indices, numItems, realIndices); + _agentFolder->GetRealIndices(indices, numItems, realIndices); CObjectVector<CUpdatePair2> updatePairs; int curIndex = 0; UInt32 numItemsInArchive; @@ -420,7 +416,7 @@ HRESULT CAgent::CreateFolder( dirItem.Attributes = FILE_ATTRIBUTE_DIRECTORY; dirItem.Size = 0; - dirItem.Name = _archiveFolderItem->GetFullPathPrefix() + folderName; + dirItem.Name = _agentFolder->_proxyFolderItem->GetFullPathPrefix() + folderName; SYSTEMTIME systemTime; FILETIME fileTime; @@ -455,11 +451,10 @@ HRESULT CAgent::RenameItem( CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec); CUIntVector realIndices; - _archiveFolderItem->GetRealIndices(indices, numItems, realIndices); + _agentFolder->GetRealIndices(indices, numItems, realIndices); - UString fullPrefix = _archiveFolderItem->GetFullPathPrefix(); - UString oldItemPath = fullPrefix + - _archiveFolderItem->GetItemName(indices[0]); + UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]); + UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]); UString newItemPath = fullPrefix + newItemName; CObjectVector<CUpdatePair2> updatePairs; diff --git a/7zip/UI/Agent/ArchiveFolder.cpp b/7zip/UI/Agent/ArchiveFolder.cpp index cb834fcc..2cecbde5 100755 --- a/7zip/UI/Agent/ArchiveFolder.cpp +++ b/7zip/UI/Agent/ArchiveFolder.cpp @@ -41,11 +41,15 @@ STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems, IID_IFolderArchiveExtractCallback, &extractCallback2)); } + NExtract::NPathMode::EEnum pathMode = _flatMode ? + NExtract::NPathMode::kNoPathnames : + NExtract::NPathMode::kCurrentPathnames; + extractCallbackSpec->Init(_agentSpec->GetArchive(), extractCallback2, false, path, - NExtract::NPathMode::kCurrentPathnames, + pathMode, NExtract::NOverwriteMode::kAskBefore, pathParts, _agentSpec->DefaultName, @@ -54,7 +58,7 @@ STDMETHODIMP CAgentFolder::CopyTo(const UINT32 *indices, UINT32 numItems, // ,_agentSpec->_srcDirectoryPrefix ); CUIntVector realIndices; - _proxyFolderItem->GetRealIndices(indices, numItems, realIndices); + GetRealIndices(indices, numItems, realIndices); return _agentSpec->GetArchive()->Extract(&realIndices.Front(), realIndices.Size(), BoolToInt(false), extractCallback); COM_TRY_END diff --git a/7zip/UI/Agent/ArchiveFolderOut.cpp b/7zip/UI/Agent/ArchiveFolderOut.cpp index b16d106d..9e2d3c55 100755 --- a/7zip/UI/Agent/ArchiveFolderOut.cpp +++ b/7zip/UI/Agent/ArchiveFolderOut.cpp @@ -180,18 +180,15 @@ STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress if (progress != 0) { CMyComPtr<IProgress> progressWrapper = progress; - RINOK(progressWrapper.QueryInterface( - IID_IFolderArchiveUpdateCallback, &updateCallback100)); + RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100)); } - return CommonUpdateOperation(false, true, false, name, NULL, NULL, - 0, updateCallback100); + return CommonUpdateOperation(false, true, false, name, NULL, NULL, 0, updateCallback100); COM_TRY_END } STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgress *progress) { COM_TRY_BEGIN - CUIntVector realIndices; CUIntVector indices; indices.Add(index); RINOK(_agentSpec->SetFolder(this)); @@ -199,8 +196,7 @@ STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgres if (progress != 0) { CMyComPtr<IProgress> progressWrapper = progress; - RINOK(progressWrapper.QueryInterface( - IID_IFolderArchiveUpdateCallback, &updateCallback100)); + RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100)); } return CommonUpdateOperation(false, false, true, newName, NULL, &indices.Front(), indices.Size(), updateCallback100); diff --git a/7zip/UI/Common/ArchiveCommandLine.cpp b/7zip/UI/Common/ArchiveCommandLine.cpp index a482abdf..68937e89 100755 --- a/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/7zip/UI/Common/ArchiveCommandLine.cpp @@ -837,6 +837,8 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options) ConvertToLongNames(archiveWildcardCensor); #endif + archiveWildcardCensor.ExtendExclude(); + CObjectVector<CDirItem> dirItems; { UStringVector errorPaths; @@ -960,4 +962,5 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options) } else throw kUserErrorMessage; + options.WildcardCensor.ExtendExclude(); } diff --git a/Common/Wildcard.cpp b/Common/Wildcard.cpp index 80cd82d8..1923a339 100755 --- a/Common/Wildcard.cpp +++ b/Common/Wildcard.cpp @@ -346,6 +346,19 @@ void CCensorNode::AddItem2(bool include, const UString &path, bool recursive) AddItem(include, path2, recursive, forFile, forFolder); } +void CCensorNode::ExtendExclude(const CCensorNode &fromNodes) +{ + ExcludeItems += fromNodes.ExcludeItems; + for (int i = 0; i < fromNodes.SubNodes.Size(); i++) + { + const CCensorNode &node = fromNodes.SubNodes[i]; + int subNodeIndex = FindSubNode(node.Name); + if (subNodeIndex < 0) + subNodeIndex = SubNodes.Add(CCensorNode(node.Name, this)); + SubNodes[subNodeIndex].ExtendExclude(node); + } +} + int CCensor::FindPrefix(const UString &prefix) const { for (int i = 0; i < Pairs.Size(); i++) @@ -426,6 +439,20 @@ bool CCensor::CheckPath(const UString &path, bool isFile) const return finded; } +void CCensor::ExtendExclude() +{ + int i; + for (i = 0; i < Pairs.Size(); i++) + if (Pairs[i].Prefix.IsEmpty()) + break; + if (i == Pairs.Size()) + return; + int index = i; + for (i = 0; i < Pairs.Size(); i++) + if (index != i) + Pairs[i].Head.ExtendExclude(Pairs[index].Head); +} + } bool AreTheFileNamesDirDelimiterEqual(const UString &name1, const UString &name2) diff --git a/Common/Wildcard.h b/Common/Wildcard.h index 0dbe33b5..50dd305a 100755 --- a/Common/Wildcard.h +++ b/Common/Wildcard.h @@ -51,6 +51,7 @@ public: bool CheckPathToRoot(bool include, UStringVector &pathParts, bool isFile) const; // bool CheckPathToRoot(const UString &path, bool isFile, bool include) const; + void ExtendExclude(const CCensorNode &fromNodes); }; struct CPair @@ -69,6 +70,7 @@ public: { return (Pairs.Size() == 1 && Pairs.Front().Prefix.IsEmpty()); } void AddItem(bool include, const UString &path, bool recursive); bool CheckPath(const UString &path, bool isFile) const; + void ExtendExclude(); }; } diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi index d8ff3295..5a92a48f 100755 --- a/DOC/7zip.nsi +++ b/DOC/7zip.nsi @@ -2,7 +2,7 @@ ;Defines !define VERSION_MAJOR 4 -!define VERSION_MINOR 36 +!define VERSION_MINOR 37 !define VERSION_POSTFIX_FULL " beta" !ifdef WIN64 !ifdef IA64 diff --git a/DOC/lzma.txt b/DOC/lzma.txt index 580146e6..b7dd4361 100755 --- a/DOC/lzma.txt +++ b/DOC/lzma.txt @@ -1,4 +1,4 @@ -LZMA SDK 4.35 +LZMA SDK 4.37 ------------- LZMA SDK Copyright (C) 1999-2006 Igor Pavlov diff --git a/DOC/readme.txt b/DOC/readme.txt index ca1592c9..105b35a0 100755 --- a/DOC/readme.txt +++ b/DOC/readme.txt @@ -1,4 +1,4 @@ -7-Zip 4.36 Sources +7-Zip 4.37 Sources ------------------ 7-Zip is a file archiver for Windows 95/98/ME/NT/2000/2003/XP. |