Imported Upstream version 9.20
[platform/upstream/7zip.git] / CPP / 7zip / UI / FileManager / PanelListNotify.cpp
1 // PanelListNotify.cpp\r
2 \r
3 #include "StdAfx.h"\r
4 \r
5 #include "resource.h"\r
6 \r
7 #include "Common/IntToString.h"\r
8 #include "Common/StringConvert.h"\r
9 \r
10 #include "Windows/PropVariant.h"\r
11 #include "Windows/PropVariantConversions.h"\r
12 \r
13 #include "../Common/PropIDUtils.h"\r
14 #include "../../PropID.h"\r
15 \r
16 #include "Panel.h"\r
17 #include "FormatUtils.h"\r
18 \r
19 using namespace NWindows;\r
20 \r
21 /*\r
22 static UString ConvertSizeToStringShort(UInt64 value)\r
23 {\r
24   wchar_t s[32];\r
25   wchar_t c, c2 = L'B';\r
26   if (value < (UInt64)10000)\r
27   {\r
28     c = L'B';\r
29     c2 = L'\0';\r
30   }\r
31   else if (value < ((UInt64)10000 << 10))\r
32   {\r
33     value >>= 10;\r
34     c = L'K';\r
35   }\r
36   else if (value < ((UInt64)10000 << 20))\r
37   {\r
38     value >>= 20;\r
39     c = L'M';\r
40   }\r
41   else\r
42   {\r
43     value >>= 30;\r
44     c = L'G';\r
45   }\r
46   ConvertUInt64ToString(value, s);\r
47   int p = MyStringLen(s);\r
48   s[p++] = L' ';\r
49   s[p++] = c;\r
50   s[p++] = c2;\r
51   s[p++] = L'\0';\r
52   return s;\r
53 }\r
54 */\r
55 \r
56 UString ConvertSizeToString(UInt64 value)\r
57 {\r
58   wchar_t s[32];\r
59   ConvertUInt64ToString(value, s);\r
60   int i = MyStringLen(s);\r
61   int pos = sizeof(s) / sizeof(s[0]);\r
62   s[--pos] = L'\0';\r
63   while (i > 3)\r
64   {\r
65     s[--pos] = s[--i];\r
66     s[--pos] = s[--i];\r
67     s[--pos] = s[--i];\r
68     s[--pos] = L' ';\r
69   }\r
70   while (i > 0)\r
71     s[--pos] = s[--i];\r
72   return s + pos;\r
73 }\r
74 \r
75 LRESULT CPanel::SetItemText(LVITEMW &item)\r
76 {\r
77   if (_dontShowMode)\r
78     return 0;\r
79 \r
80   UINT32 realIndex = GetRealIndex(item);\r
81   /*\r
82   if ((item.mask & LVIF_IMAGE) != 0)\r
83   {\r
84     bool defined  = false;\r
85     CComPtr<IFolderGetSystemIconIndex> folderGetSystemIconIndex;\r
86     _folder.QueryInterface(&folderGetSystemIconIndex);\r
87     if (folderGetSystemIconIndex)\r
88     {\r
89       folderGetSystemIconIndex->GetSystemIconIndex(index, &item.iImage);\r
90       defined = (item.iImage > 0);\r
91     }\r
92     if (!defined)\r
93     {\r
94       NCOM::CPropVariant prop;\r
95       _folder->GetProperty(index, kpidAttrib, &prop);\r
96       UINT32 attrib = 0;\r
97       if (prop.vt == VT_UI4)\r
98         attrib = prop.ulVal;\r
99       else if (IsItemFolder(index))\r
100         attrib |= FILE_ATTRIBUTE_DIRECTORY;\r
101       if (_currentFolderPrefix.IsEmpty())\r
102         throw 1;\r
103       else\r
104         item.iImage = _extToIconMap.GetIconIndex(attrib, GetSystemString(GetItemName(index)));\r
105     }\r
106     // item.iImage = 1;\r
107   }\r
108   */\r
109 \r
110   if ((item.mask & LVIF_TEXT) == 0)\r
111     return 0;\r
112 \r
113   if (realIndex == kParentIndex)\r
114     return 0;\r
115   UString s;\r
116   UINT32 subItemIndex = item.iSubItem;\r
117   PROPID propID = _visibleProperties[subItemIndex].ID;\r
118   /*\r
119   {\r
120     NCOM::CPropVariant property;\r
121     if (propID == kpidType)\r
122       string = GetFileType(index);\r
123     else\r
124     {\r
125       HRESULT result = m_ArchiveFolder->GetProperty(index, propID, &property);\r
126       if (result != S_OK)\r
127       {\r
128         // PrintMessage("GetPropertyValue error");\r
129         return 0;\r
130       }\r
131       string = ConvertPropertyToString(property, propID, false);\r
132     }\r
133   }\r
134   */\r
135   // const NFind::CFileInfo &aFileInfo = m_Files[index];\r
136 \r
137   NCOM::CPropVariant prop;\r
138   /*\r
139   bool needRead = true;\r
140   if (propID == kpidSize)\r
141   {\r
142     CComPtr<IFolderGetItemFullSize> getItemFullSize;\r
143     if (_folder.QueryInterface(&getItemFullSize) == S_OK)\r
144     {\r
145       if (getItemFullSize->GetItemFullSize(index, &prop) == S_OK)\r
146         needRead = false;\r
147     }\r
148   }\r
149   if (needRead)\r
150   */\r
151 \r
152   HRESULT res = _folder->GetProperty(realIndex, propID, &prop);\r
153   if (res != S_OK)\r
154     s = UString(L"Error: ") + HResultToMessage(res);\r
155   else\r
156   if ((prop.vt == VT_UI8 || prop.vt == VT_UI4) && (\r
157       propID == kpidSize ||\r
158       propID == kpidPackSize ||\r
159       propID == kpidNumSubDirs ||\r
160       propID == kpidNumSubFiles ||\r
161       propID == kpidPosition ||\r
162       propID == kpidNumBlocks ||\r
163       propID == kpidClusterSize ||\r
164       propID == kpidTotalSize ||\r
165       propID == kpidFreeSpace\r
166       ))\r
167     s = ConvertSizeToString(ConvertPropVariantToUInt64(prop));\r
168   else\r
169   {\r
170     s = ConvertPropertyToString(prop, propID, false);\r
171     s.Replace(wchar_t(0xA), L' ');\r
172     s.Replace(wchar_t(0xD), L' ');\r
173   }\r
174   int size = item.cchTextMax;\r
175   if (size > 0)\r
176   {\r
177     if (s.Length() + 1 > size)\r
178       s = s.Left(size - 1);\r
179     MyStringCopy(item.pszText, (const wchar_t *)s);\r
180   }\r
181   return 0;\r
182 }\r
183 \r
184 #ifndef UNDER_CE\r
185 extern DWORD g_ComCtl32Version;\r
186 #endif\r
187 \r
188 void CPanel::OnItemChanged(NMLISTVIEW *item)\r
189 {\r
190   int index = (int)item->lParam;\r
191   if (index == kParentIndex)\r
192     return;\r
193   bool oldSelected = (item->uOldState & LVIS_SELECTED) != 0;\r
194   bool newSelected = (item->uNewState & LVIS_SELECTED) != 0;\r
195   // Don't change this code. It works only with such check\r
196   if (oldSelected != newSelected)\r
197     _selectedStatusVector[index] = newSelected;\r
198 }\r
199 \r
200 extern bool g_LVN_ITEMACTIVATE_Support;\r
201 \r
202 void CPanel::OnNotifyActivateItems()\r
203 {\r
204   // bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0;\r
205   // bool rightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0;\r
206   bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;\r
207   bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;\r
208   bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;\r
209   if (!shift && alt && !ctrl)\r
210     Properties();\r
211   else\r
212     OpenSelectedItems(!shift || alt || ctrl);\r
213 }\r
214 \r
215 bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)\r
216 {\r
217   switch(header->code)\r
218   {\r
219     case LVN_ITEMCHANGED:\r
220     {\r
221       if (_enableItemChangeNotify)\r
222       {\r
223         if (!_mySelectMode)\r
224           OnItemChanged((LPNMLISTVIEW)header);\r
225         RefreshStatusBar();\r
226       }\r
227       return false;\r
228     }\r
229     /*\r
230 \r
231     case LVN_ODSTATECHANGED:\r
232       {\r
233       break;\r
234       }\r
235     */\r
236 \r
237     case LVN_GETDISPINFOW:\r
238     {\r
239       LV_DISPINFOW *dispInfo = (LV_DISPINFOW *)header;\r
240 \r
241       //is the sub-item information being requested?\r
242 \r
243       if ((dispInfo->item.mask & LVIF_TEXT) != 0 ||\r
244         (dispInfo->item.mask & LVIF_IMAGE) != 0)\r
245         SetItemText(dispInfo->item);\r
246       return false;\r
247     }\r
248     case LVN_KEYDOWN:\r
249     {\r
250       bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header), result);\r
251       RefreshStatusBar();\r
252       return boolResult;\r
253     }\r
254 \r
255     case LVN_COLUMNCLICK:\r
256       OnColumnClick(LPNMLISTVIEW(header));\r
257       return false;\r
258 \r
259     case LVN_ITEMACTIVATE:\r
260       if (g_LVN_ITEMACTIVATE_Support)\r
261       {\r
262         OnNotifyActivateItems();\r
263         return false;\r
264       }\r
265       break;\r
266     case NM_DBLCLK:\r
267     case NM_RETURN:\r
268       if (!g_LVN_ITEMACTIVATE_Support)\r
269       {\r
270         OnNotifyActivateItems();\r
271         return false;\r
272       }\r
273       break;\r
274 \r
275     case NM_RCLICK:\r
276       RefreshStatusBar();\r
277       break;\r
278 \r
279     /*\r
280       return OnRightClick((LPNMITEMACTIVATE)header, result);\r
281     */\r
282       /*\r
283       case NM_CLICK:\r
284       SendRefreshStatusBarMessage();\r
285       return 0;\r
286       \r
287         // TODO : Handler default action...\r
288         return 0;\r
289         case LVN_ITEMCHANGED:\r
290         {\r
291         NMLISTVIEW *pNMLV = (NMLISTVIEW *) lpnmh;\r
292         SelChange(pNMLV);\r
293         return TRUE;\r
294         }\r
295         case NM_SETFOCUS:\r
296         return onSetFocus(NULL);\r
297         case NM_KILLFOCUS:\r
298         return onKillFocus(NULL);\r
299       */\r
300     case NM_CLICK:\r
301     {\r
302       // we need SetFocusToList, if we drag-select items from other panel.\r
303       SetFocusToList();\r
304       RefreshStatusBar();\r
305       if (_mySelectMode)\r
306         #ifndef UNDER_CE\r
307         if (g_ComCtl32Version >= MAKELONG(71, 4))\r
308         #endif\r
309           OnLeftClick((MY_NMLISTVIEW_NMITEMACTIVATE *)header);\r
310       return false;\r
311     }\r
312     case LVN_BEGINLABELEDITW:\r
313       result = OnBeginLabelEdit((LV_DISPINFOW *)header);\r
314       return true;\r
315     case LVN_ENDLABELEDITW:\r
316       result = OnEndLabelEdit((LV_DISPINFOW *)header);\r
317       return true;\r
318 \r
319     case NM_CUSTOMDRAW:\r
320     {\r
321       if (_mySelectMode)\r
322         return OnCustomDraw((LPNMLVCUSTOMDRAW)header, result);\r
323       break;\r
324     }\r
325     case LVN_BEGINDRAG:\r
326     {\r
327       OnDrag((LPNMLISTVIEW)header);\r
328       RefreshStatusBar();\r
329       break;\r
330     }\r
331     // case LVN_BEGINRDRAG:\r
332   }\r
333   return false;\r
334 }\r
335 \r
336 bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result)\r
337 {\r
338   switch(lplvcd->nmcd.dwDrawStage)\r
339   {\r
340   case CDDS_PREPAINT :\r
341     result = CDRF_NOTIFYITEMDRAW;\r
342     return true;\r
343     \r
344   case CDDS_ITEMPREPAINT:\r
345     /*\r
346     SelectObject(lplvcd->nmcd.hdc,\r
347     GetFontForItem(lplvcd->nmcd.dwItemSpec,\r
348     lplvcd->nmcd.lItemlParam) );\r
349     lplvcd->clrText = GetColorForItem(lplvcd->nmcd.dwItemSpec,\r
350     lplvcd->nmcd.lItemlParam);\r
351     lplvcd->clrTextBk = GetBkColorForItem(lplvcd->nmcd.dwItemSpec,\r
352     lplvcd->nmcd.lItemlParam);\r
353     */\r
354     int realIndex = (int)lplvcd->nmcd.lItemlParam;\r
355     bool selected = false;\r
356     if (realIndex != kParentIndex)\r
357       selected = _selectedStatusVector[realIndex];\r
358     if (selected)\r
359       lplvcd->clrTextBk = RGB(255, 192, 192);\r
360     // lplvcd->clrText = RGB(255, 0, 128);\r
361     else\r
362       lplvcd->clrTextBk = _listView.GetBkColor();\r
363     // lplvcd->clrText = RGB(0, 0, 0);\r
364     // result = CDRF_NEWFONT;\r
365     result = CDRF_NOTIFYITEMDRAW;\r
366     return true;\r
367     \r
368     // return false;\r
369     // return true;\r
370     /*\r
371     case CDDS_SUBITEM | CDDS_ITEMPREPAINT:\r
372     if (lplvcd->iSubItem == 0)\r
373     {\r
374     // lplvcd->clrText = RGB(255, 0, 0);\r
375     lplvcd->clrTextBk = RGB(192, 192, 192);\r
376     }\r
377     else\r
378     {\r
379     lplvcd->clrText = RGB(0, 0, 0);\r
380     lplvcd->clrTextBk = RGB(255, 255, 255);\r
381     }\r
382     return true;\r
383     */\r
384 \r
385         /* At this point, you can change the background colors for the item\r
386         and any subitems and return CDRF_NEWFONT. If the list-view control\r
387         is in report mode, you can simply return CDRF_NOTIFYSUBITEMREDRAW\r
388         to customize the item's subitems individually */\r
389   }\r
390   return false;\r
391 }\r
392 \r
393 void CPanel::OnRefreshStatusBar()\r
394 {\r
395   CRecordVector<UINT32> indices;\r
396   GetOperatedItemIndices(indices);\r
397 \r
398   _statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, 0x02000301, NumberToString(indices.Size())));\r
399 \r
400   UString selectSizeString;\r
401 \r
402   if (indices.Size() > 0)\r
403   {\r
404     UInt64 totalSize = 0;\r
405     for (int i = 0; i < indices.Size(); i++)\r
406       totalSize += GetItemSize(indices[i]);\r
407     selectSizeString = ConvertSizeToString(totalSize);\r
408   }\r
409   _statusBar.SetText(1, selectSizeString);\r
410 \r
411   int focusedItem = _listView.GetFocusedItem();\r
412   UString sizeString;\r
413   UString dateString;\r
414   if (focusedItem >= 0 && _listView.GetSelectedCount() > 0)\r
415   {\r
416     int realIndex = GetRealItemIndex(focusedItem);\r
417     if (realIndex != kParentIndex)\r
418     {\r
419       sizeString = ConvertSizeToString(GetItemSize(realIndex));\r
420       NCOM::CPropVariant prop;\r
421       if (_folder->GetProperty(realIndex, kpidMTime, &prop) == S_OK)\r
422         dateString = ConvertPropertyToString(prop, kpidMTime, false);\r
423     }\r
424   }\r
425   _statusBar.SetText(2, sizeString);\r
426   _statusBar.SetText(3, dateString);\r
427   // _statusBar.SetText(4, nameString);\r
428   // _statusBar2.SetText(1, MyFormatNew(L"{0} bytes", NumberToStringW(totalSize)));\r
429 }\r