From e24f7fba53cc8f28d74b5039f7279d9bf945ff25 Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Thu, 19 Nov 2015 00:00:00 +0000 Subject: 15.11 --- CPP/7zip/UI/FileManager/FM.cpp | 3 +- CPP/7zip/UI/FileManager/Panel.h | 58 ++++++-- CPP/7zip/UI/FileManager/PanelItemOpen.cpp | 6 +- CPP/7zip/UI/FileManager/PanelItems.cpp | 214 +++++++++++++++++++--------- CPP/7zip/UI/FileManager/PanelListNotify.cpp | 2 +- CPP/7zip/UI/FileManager/PanelSort.cpp | 16 ++- CPP/7zip/UI/FileManager/RegistryUtils.cpp | 2 +- CPP/7zip/UI/FileManager/SysIconUtils.cpp | 2 +- CPP/7zip/UI/FileManager/ViewSettings.cpp | 2 + CPP/7zip/UI/FileManager/ViewSettings.h | 8 ++ 10 files changed, 223 insertions(+), 90 deletions(-) (limited to 'CPP/7zip/UI/FileManager') diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp index 1a7ed060..a320c016 100644 --- a/CPP/7zip/UI/FileManager/FM.cpp +++ b/CPP/7zip/UI/FileManager/FM.cpp @@ -42,6 +42,7 @@ using namespace NFind; #define MENU_HEIGHT 26 +bool g_RAM_Size_Defined; UInt64 g_RAM_Size; #ifdef _WIN32 @@ -425,7 +426,7 @@ static void ErrorMessage(const wchar_t *s) static int WINAPI WinMain2(int nCmdShow) { - g_RAM_Size = NSystem::GetRamSize(); + g_RAM_Size_Defined = NSystem::GetRamSize(g_RAM_Size); #ifdef _WIN32 diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h index bb579947..709ef0f5 100644 --- a/CPP/7zip/UI/FileManager/Panel.h +++ b/CPP/7zip/UI/FileManager/Panel.h @@ -69,31 +69,67 @@ struct CPanelCallback void PanelCopyItems(); -struct CItemProperty + +struct CPropColumn { - UString Name; + int Order; PROPID ID; VARTYPE Type; - int Order; bool IsVisible; bool IsRawProp; UInt32 Width; + UString Name; - int Compare(const CItemProperty &a) const { return MyCompare(Order, a.Order); } + bool IsEqualTo(const CPropColumn &a) const + { + return Order == a.Order + && ID == a.ID + && Type == a.Type + && IsVisible == a.IsVisible + && IsRawProp == a.IsRawProp + && Width == a.Width + && Name == a.Name; + } + + int Compare(const CPropColumn &a) const { return MyCompare(Order, a.Order); } + + int Compare_NameFirst(const CPropColumn &a) const + { + if (ID == kpidName) + { + if (a.ID != kpidName) + return -1; + } + else if (a.ID == kpidName) + return 1; + return MyCompare(Order, a.Order); + } }; -class CItemProperties: public CObjectVector + +class CPropColumns: public CObjectVector { public: - int FindItemWithID(PROPID id) + int FindItem_for_PropID(PROPID id) const { FOR_VECTOR (i, (*this)) if ((*this)[i].ID == id) return i; return -1; } + + bool IsEqualTo(const CPropColumns &props) const + { + if (Size() != props.Size()) + return false; + FOR_VECTOR (i, (*this)) + if (!(*this)[i].IsEqualTo(props[i])) + return false; + return true; + } }; + struct CTempFileInfo { UInt32 FileIndex; // index of file in folder @@ -284,8 +320,8 @@ private: void ChangeWindowSize(int xSize, int ySize); HRESULT InitColumns(); - // void InitColumns2(PROPID sortID); - void InsertColumn(unsigned index); + void DeleteColumn(unsigned index); + void AddColumn(const CPropColumn &prop); void SetFocusedSelectedItem(int index, bool select); HRESULT RefreshListCtrl(const UString &focusedName, int focusedPos, bool selectFocused, @@ -446,7 +482,6 @@ public: void SetFocusToLastRememberedItem(); - void ReadListViewInfo(); void SaveListViewInfo(); CPanel() : @@ -484,8 +519,9 @@ public: bool _needSaveInfo; UString _typeIDString; CListViewInfo _listViewInfo; - CItemProperties _properties; - CItemProperties _visibleProperties; + + CPropColumns _columns; + CPropColumns _visibleColumns; PROPID _sortID; // int _sortIndex; diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp index a4ab254d..c37ac64f 100644 --- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp +++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp @@ -36,6 +36,7 @@ using namespace NSynchronization; using namespace NFile; using namespace NDir; +extern bool g_RAM_Size_Defined; extern UInt64 g_RAM_Size; #ifndef _UNICODE @@ -1173,7 +1174,10 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo { NCOM::CPropVariant prop; _folder->GetProperty(index, kpidSize, &prop); - UInt64 fileLimit = g_RAM_Size / 4; + UInt64 fileLimit = 1 << 22; + if (g_RAM_Size_Defined) + fileLimit = g_RAM_Size / 4; + UInt64 fileSize = 0; if (!ConvertPropVariantToUInt64(prop, fileSize)) fileSize = fileLimit; diff --git a/CPP/7zip/UI/FileManager/PanelItems.cpp b/CPP/7zip/UI/FileManager/PanelItems.cpp index e6b89cbe..e72d1bb6 100644 --- a/CPP/7zip/UI/FileManager/PanelItems.cpp +++ b/CPP/7zip/UI/FileManager/PanelItems.cpp @@ -82,15 +82,33 @@ static int GetColumnAlign(PROPID propID, VARTYPE varType) } } + +static int ItemProperty_Compare_NameFirst(void *const *a1, void *const *a2, void * /* param */) +{ + return (*(*((const CPropColumn **)a1))).Compare_NameFirst(*(*((const CPropColumn **)a2))); +} + HRESULT CPanel::InitColumns() { - if (_needSaveInfo) - SaveListViewInfo(); + SaveListViewInfo(); _listView.DeleteAllItems(); _selectedStatusVector.Clear(); - ReadListViewInfo(); + { + // ReadListViewInfo(); + const UString oldType = _typeIDString; + _typeIDString = GetFolderTypeID(); + // an empty _typeIDString is allowed. + + // we read registry only for new FolderTypeID + if (!_needSaveInfo || _typeIDString != oldType) + _listViewInfo.Read(_typeIDString); + + // folders with same FolderTypeID can have different columns + // so we still read columns for that case. + // if (_needSaveInfo && _typeIDString == oldType) return S_OK; + } // PROPID sortID; /* @@ -101,9 +119,8 @@ HRESULT CPanel::InitColumns() _ascending = _listViewInfo.Ascending; - _properties.Clear(); + _columns.Clear(); - _needSaveInfo = true; bool isFsFolder = IsFSFolder() || IsAltStreamsFolder(); { @@ -125,7 +142,7 @@ HRESULT CPanel::InitColumns() } if (propID == kpidIsDir) continue; - CItemProperty prop; + CPropColumn prop; prop.Type = varType; prop.ID = propID; prop.Name = GetNameOfProperty(propID, name); @@ -133,7 +150,7 @@ HRESULT CPanel::InitColumns() prop.IsVisible = GetColumnVisible(propID, isFsFolder); prop.Width = GetColumnWidth(propID, varType); prop.IsRawProp = false; - _properties.Add(prop); + _columns.Add(prop); } } @@ -141,13 +158,15 @@ HRESULT CPanel::InitColumns() { UInt32 numProps; _folderRawProps->GetNumRawProps(&numProps); + for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; - RINOK(_folderRawProps->GetRawPropInfo(i, &name, &propID)); - - CItemProperty prop; + HRESULT res = _folderRawProps->GetRawPropInfo(i, &name, &propID); + if (res != S_OK) + continue; + CPropColumn prop; prop.Type = VT_EMPTY; prop.ID = propID; prop.Name = GetNameOfProperty(propID, name); @@ -155,83 +174,147 @@ HRESULT CPanel::InitColumns() prop.IsVisible = GetColumnVisible(propID, isFsFolder); prop.Width = GetColumnWidth(propID, VT_BSTR);; prop.IsRawProp = true; - _properties.Add(prop); + _columns.Add(prop); } } - // InitColumns2(sortID); - - for (;;) - if (!_listView.DeleteColumn(0)) - break; - unsigned order = 0; unsigned i; for (i = 0; i < _listViewInfo.Columns.Size(); i++) { const CColumnInfo &columnInfo = _listViewInfo.Columns[i]; - int index = _properties.FindItemWithID(columnInfo.PropID); + int index = _columns.FindItem_for_PropID(columnInfo.PropID); if (index >= 0) { - CItemProperty &item = _properties[index]; - item.IsVisible = columnInfo.IsVisible; + CPropColumn &item = _columns[index]; + if (item.Order >= 0) + continue; // we ignore duplicated items + bool isVisible = columnInfo.IsVisible; + // we enable kpidName, if it was disabled by some incorrect code + if (columnInfo.PropID == kpidName) + isVisible = true; + item.IsVisible = isVisible; item.Width = columnInfo.Width; - if (columnInfo.IsVisible) + if (isVisible) item.Order = order++; continue; } } + + for (i = 0; i < _columns.Size(); i++) + { + CPropColumn &item = _columns[i]; + if (item.IsVisible && item.Order < 0) + item.Order = order++; + } - for (i = 0; i < _properties.Size(); i++) + for (i = 0; i < _columns.Size(); i++) { - CItemProperty &item = _properties[i]; + CPropColumn &item = _columns[i]; if (item.Order < 0) item.Order = order++; } - _visibleProperties.Clear(); - for (i = 0; i < _properties.Size(); i++) + CPropColumns newColumns; + + for (i = 0; i < _columns.Size(); i++) { - const CItemProperty &prop = _properties[i]; + const CPropColumn &prop = _columns[i]; if (prop.IsVisible) - _visibleProperties.Add(prop); + newColumns.Add(prop); } - // _sortIndex = 0; - _sortID = kpidName; + /* + _sortIndex = 0; if (_listViewInfo.SortIndex >= 0) { - int sortIndex = _properties.FindItemWithID(sortID); + int sortIndex = _columns.FindItem_for_PropID(sortID); if (sortIndex >= 0) _sortIndex = sortIndex; } */ - _sortID = _listViewInfo.SortID; - _visibleProperties.Sort(); + if (_listViewInfo.IsLoaded) + _sortID = _listViewInfo.SortID; + else + { + _sortID = 0; + if (IsFSFolder() || IsAltStreamsFolder() || IsArcFolder()) + _sortID = kpidName; + } + + /* There are restrictions in ListView control: + 1) main column (kpidName) must have (LV_COLUMNW::iSubItem = 0) + So we need special sorting for columns. + 2) when we add new column, LV_COLUMNW::iOrder can not be larger than already inserted columns) + So we set column order after all columns are added. + */ + newColumns.Sort(ItemProperty_Compare_NameFirst, NULL); + + if (newColumns.IsEqualTo(_visibleColumns)) + return S_OK; + + CIntArr columns(newColumns.Size()); + for (i = 0; i < newColumns.Size(); i++) + columns[i] = -1; + + bool orderError = false; + + for (i = 0; i < newColumns.Size(); i++) + { + const CPropColumn &prop = newColumns[i]; + if (prop.Order < (int)newColumns.Size() && columns[prop.Order] == -1) + columns[prop.Order] = i; + else + orderError = true; + } + + for (;;) + { + unsigned numColumns = _visibleColumns.Size(); + if (numColumns == 0) + break; + DeleteColumn(numColumns - 1); + } + + for (i = 0; i < newColumns.Size(); i++) + AddColumn(newColumns[i]); + + // columns[0], columns[1], .... should be displayed from left to right: + if (!orderError) + _listView.SetColumnOrderArray(_visibleColumns.Size(), columns); - for (i = 0; i < _visibleProperties.Size(); i++) - InsertColumn(i); + _needSaveInfo = true; return S_OK; } -void CPanel::InsertColumn(unsigned index) + +void CPanel::DeleteColumn(unsigned index) { - const CItemProperty &prop = _visibleProperties[index]; + _visibleColumns.Delete(index); + _listView.DeleteColumn(index); +} + +void CPanel::AddColumn(const CPropColumn &prop) +{ + const int index = _visibleColumns.Size(); + LV_COLUMNW column; column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_ORDER; column.cx = prop.Width; column.fmt = GetColumnAlign(prop.ID, prop.Type); - column.iOrder = prop.Order; - // iOrder must be <= _listView.ItemCount - column.iSubItem = index; + column.iOrder = index; // must be <= _listView.ItemCount + column.iSubItem = index; // must be <= _listView.ItemCount column.pszText = const_cast((const wchar_t *)prop.Name); + + _visibleColumns.Add(prop); _listView.InsertColumn(index, &column); } + HRESULT CPanel::RefreshListCtrl() { return RefreshListCtrl(UString(), -1, true, UStringVector()); @@ -959,20 +1042,17 @@ UInt64 CPanel::GetItemSize(int itemIndex) const return 0; } -void CPanel::ReadListViewInfo() -{ - _typeIDString = GetFolderTypeID(); - if (!_typeIDString.IsEmpty()) - _listViewInfo.Read(_typeIDString); -} void CPanel::SaveListViewInfo() { + if (!_needSaveInfo) + return; + unsigned i; - for (i = 0; i < _visibleProperties.Size(); i++) + for (i = 0; i < _visibleColumns.Size(); i++) { - CItemProperty &prop = _visibleProperties[i]; + CPropColumn &prop = _visibleColumns[i]; LVCOLUMN winColumnInfo; winColumnInfo.mask = LVCF_ORDER | LVCF_WIDTH; if (!_listView.GetColumn(i, &winColumnInfo)) @@ -983,14 +1063,18 @@ void CPanel::SaveListViewInfo() CListViewInfo viewInfo; - // PROPID sortPropID = _properties[_sortIndex].ID; + // PROPID sortPropID = _columns[_sortIndex].ID; PROPID sortPropID = _sortID; - _visibleProperties.Sort(); + // we save columns as "sorted by order" to registry + + CPropColumns sortedProperties = _visibleColumns; + + sortedProperties.Sort(); - for (i = 0; i < _visibleProperties.Size(); i++) + for (i = 0; i < sortedProperties.Size(); i++) { - const CItemProperty &prop = _visibleProperties[i]; + const CPropColumn &prop = sortedProperties[i]; CColumnInfo columnInfo; columnInfo.IsVisible = prop.IsVisible; columnInfo.PropID = prop.ID; @@ -998,13 +1082,13 @@ void CPanel::SaveListViewInfo() viewInfo.Columns.Add(columnInfo); } - for (i = 0; i < _properties.Size(); i++) + for (i = 0; i < _columns.Size(); i++) { - const CItemProperty &prop = _properties[i]; - if (!prop.IsVisible) + const CPropColumn &prop = _columns[i]; + if (sortedProperties.FindItem_for_PropID(prop.ID) < 0) { CColumnInfo columnInfo; - columnInfo.IsVisible = prop.IsVisible; + columnInfo.IsVisible = false; columnInfo.PropID = prop.ID; columnInfo.Width = prop.Width; viewInfo.Columns.Add(columnInfo); @@ -1040,9 +1124,9 @@ void CPanel::ShowColumnsContextMenu(int x, int y) menu.CreatePopup(); const int kCommandStart = 100; - FOR_VECTOR (i, _properties) + FOR_VECTOR (i, _columns) { - const CItemProperty &prop = _properties[i]; + const CPropColumn &prop = _columns[i]; UINT flags = MF_STRING; if (prop.IsVisible) flags |= MF_CHECKED; @@ -1053,25 +1137,22 @@ void CPanel::ShowColumnsContextMenu(int x, int y) int menuResult = menu.Track(TPM_LEFTALIGN | TPM_RETURNCMD | TPM_NONOTIFY, x, y, _listView); - if (menuResult >= kCommandStart && menuResult <= kCommandStart + (int)_properties.Size()) + if (menuResult >= kCommandStart && menuResult <= kCommandStart + (int)_columns.Size()) { int index = menuResult - kCommandStart; - CItemProperty &prop = _properties[index]; + CPropColumn &prop = _columns[index]; prop.IsVisible = !prop.IsVisible; if (prop.IsVisible) { - unsigned num = _visibleProperties.Size(); - prop.Order = num; - _visibleProperties.Add(prop); - InsertColumn(num); + prop.Order = _visibleColumns.Size(); + AddColumn(prop); } else { - int visibleIndex = _visibleProperties.FindItemWithID(prop.ID); + int visibleIndex = _visibleColumns.FindItem_for_PropID(prop.ID); if (visibleIndex >= 0) { - _visibleProperties.Delete(visibleIndex); /* if (_sortIndex == index) { @@ -1084,8 +1165,7 @@ void CPanel::ShowColumnsContextMenu(int x, int y) _sortID = kpidName; _ascending = true; } - - _listView.DeleteColumn(visibleIndex); + DeleteColumn(visibleIndex); } } } diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp index 408ffae1..39c29681 100644 --- a/CPP/7zip/UI/FileManager/PanelListNotify.cpp +++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp @@ -175,7 +175,7 @@ LRESULT CPanel::SetItemText(LVITEMW &item) if (item.cchTextMax <= 1) return 0; - const CItemProperty &property = _visibleProperties[item.iSubItem]; + const CPropColumn &property = _visibleColumns[item.iSubItem]; PROPID propID = property.ID; if (realIndex == kParentIndex) diff --git a/CPP/7zip/UI/FileManager/PanelSort.cpp b/CPP/7zip/UI/FileManager/PanelSort.cpp index 82d6756e..59b785b8 100644 --- a/CPP/7zip/UI/FileManager/PanelSort.cpp +++ b/CPP/7zip/UI/FileManager/PanelSort.cpp @@ -83,9 +83,9 @@ static inline const wchar_t *GetExtensionPtr(const UString &name) void CPanel::SetSortRawStatus() { _isRawSortProp = false; - FOR_VECTOR (i, _properties) + FOR_VECTOR (i, _columns) { - const CItemProperty &prop = _properties[i]; + const CPropColumn &prop = _columns[i]; if (prop.ID == _sortID) { _isRawSortProp = prop.IsRawProp ? 1 : 0; @@ -169,7 +169,7 @@ int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData) return ::CompareFileTime(&file1.MTime, &file2.MTime); */ - // PROPID propID = panel->_properties[panel->_sortIndex].ID; + // PROPID propID = panel->_columns[panel->_sortIndex].ID; NCOM::CPropVariant prop1, prop2; // Name must be first property @@ -215,7 +215,7 @@ void CPanel::SortItems(int index) { _sortIndex = index; _ascending = true; - switch (_properties[_sortIndex].ID) + switch (_columns[_sortIndex].ID) { case kpidSize: case kpidPackedSize: @@ -229,13 +229,15 @@ void CPanel::SortItems(int index) _listView.SortItems(CompareItems, (LPARAM)this); _listView.EnsureVisible(_listView.GetFocusedItem(), false); } + void CPanel::SortItemsWithPropID(PROPID propID) { - int index = _properties.FindItemWithID(propID); + int index = _columns.FindItem_for_PropID(propID); if (index >= 0) SortItems(index); } */ + void CPanel::SortItemsWithPropID(PROPID propID) { if (propID == _sortID) @@ -264,8 +266,8 @@ void CPanel::SortItemsWithPropID(PROPID propID) void CPanel::OnColumnClick(LPNMLISTVIEW info) { /* - int index = _properties.FindItemWithID(_visibleProperties[info->iSubItem].ID); + int index = _columns.FindItem_for_PropID(_visibleColumns[info->iSubItem].ID); SortItems(index); */ - SortItemsWithPropID(_visibleProperties[info->iSubItem].ID); + SortItemsWithPropID(_visibleColumns[info->iSubItem].ID); } diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.cpp b/CPP/7zip/UI/FileManager/RegistryUtils.cpp index ffcb5555..84dada2b 100644 --- a/CPP/7zip/UI/FileManager/RegistryUtils.cpp +++ b/CPP/7zip/UI/FileManager/RegistryUtils.cpp @@ -164,4 +164,4 @@ bool ReadFlatView(UInt32 panelIndex) { return ReadOption(GetFlatViewName(panelIn /* void Save_ShowDeleted(bool enable) { SaveOption(kShowDeletedFiles, enable); } bool Read_ShowDeleted() { return ReadOption(kShowDeletedFiles, false); } -*/ \ No newline at end of file +*/ diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/CPP/7zip/UI/FileManager/SysIconUtils.cpp index c400bc29..c8ea8b95 100644 --- a/CPP/7zip/UI/FileManager/SysIconUtils.cpp +++ b/CPP/7zip/UI/FileManager/SysIconUtils.cpp @@ -252,4 +252,4 @@ int CExtToIconMap::GetIconIndex(DWORD attrib, const UString &fileName) { return GetIconIndex(attrib, fileName, NULL); } -*/ \ No newline at end of file +*/ diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp index 2818d0f3..9292d120 100644 --- a/CPP/7zip/UI/FileManager/ViewSettings.cpp +++ b/CPP/7zip/UI/FileManager/ViewSettings.cpp @@ -97,6 +97,8 @@ void CListViewInfo::Read(const UString &id) Get32(buf + 4, SortID); GetBool(buf + 8, Ascending); + IsLoaded = true; + size -= kListViewHeaderSize; if (size % kColumnInfoSize != 0) return; diff --git a/CPP/7zip/UI/FileManager/ViewSettings.h b/CPP/7zip/UI/FileManager/ViewSettings.h index dbb98dc6..aeb68979 100644 --- a/CPP/7zip/UI/FileManager/ViewSettings.h +++ b/CPP/7zip/UI/FileManager/ViewSettings.h @@ -23,14 +23,22 @@ struct CListViewInfo CRecordVector Columns; PROPID SortID; bool Ascending; + bool IsLoaded; void Clear() { SortID = 0; Ascending = true; + IsLoaded = false; Columns.Clear(); } + CListViewInfo(): + SortID(0), + Ascending(true), + IsLoaded(false) + {} + /* int FindColumnWithID(PROPID propID) const { -- cgit v1.2.3