xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/ListViewDialog.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // ListViewDialog.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Windows/Clipboard.h"
6 
7 #include "EditDialog.h"
8 #include "ListViewDialog.h"
9 #include "RegistryUtils.h"
10 
11 #ifdef Z7_LANG
12 #include "LangUtils.h"
13 #endif
14 
15 using namespace NWindows;
16 
17 static const unsigned kOneStringMaxSize = 1024;
18 
19 
ListView_GetSelected(NControl::CListView & listView,CUIntVector & vector)20 static void ListView_GetSelected(NControl::CListView &listView, CUIntVector &vector)
21 {
22   vector.Clear();
23   int index = -1;
24   for (;;)
25   {
26     index = listView.GetNextSelectedItem(index);
27     if (index < 0)
28       break;
29     vector.Add((unsigned)index);
30   }
31 }
32 
33 
OnInit()34 bool CListViewDialog::OnInit()
35 {
36   #ifdef Z7_LANG
37   LangSetDlgItems(*this, NULL, 0);
38   #endif
39   _listView.Attach(GetItem(IDL_LISTVIEW));
40 
41   if (NumColumns > 1)
42   {
43     LONG_PTR style = _listView.GetStyle();
44     style &= ~(LONG_PTR)LVS_NOCOLUMNHEADER;
45     _listView.SetStyle(style);
46   }
47 
48   CFmSettings st;
49   st.Load();
50 
51   DWORD exStyle = 0;
52 
53   if (st.SingleClick)
54     exStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT;
55 
56   exStyle |= LVS_EX_FULLROWSELECT;
57   if (exStyle != 0)
58     _listView.SetExtendedListViewStyle(exStyle);
59 
60 
61   SetText(Title);
62 
63   const int kWidth = 400;
64 
65   LVCOLUMN columnInfo;
66   columnInfo.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
67   columnInfo.fmt = LVCFMT_LEFT;
68   columnInfo.iSubItem = 0;
69   columnInfo.cx = kWidth;
70   columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Property"
71 
72   if (NumColumns > 1)
73   {
74     columnInfo.cx = 100;
75     /*
76     // Windows always uses LVCFMT_LEFT for first column.
77     // if we need LVCFMT_RIGHT, we can create dummy column and then remove it
78 
79     // columnInfo.mask |= LVCF_TEXT;
80     _listView.InsertColumn(0, &columnInfo);
81 
82     columnInfo.iSubItem = 1;
83     columnInfo.fmt = LVCFMT_RIGHT;
84     _listView.InsertColumn(1, &columnInfo);
85     _listView.DeleteColumn(0);
86     */
87   }
88   // else
89     _listView.InsertColumn(0, &columnInfo);
90 
91   if (NumColumns > 1)
92   {
93     // columnInfo.fmt = LVCFMT_LEFT;
94     columnInfo.cx = kWidth - columnInfo.cx;
95     columnInfo.iSubItem = 1;
96     // columnInfo.pszText = NULL; // (TCHAR *)(const TCHAR *)""; // "Value"
97     _listView.InsertColumn(1, &columnInfo);
98   }
99 
100 
101   UString s;
102 
103   FOR_VECTOR (i, Strings)
104   {
105     _listView.InsertItem(i, Strings[i]);
106 
107     if (NumColumns > 1 && i < Values.Size())
108     {
109       s = Values[i];
110       if (s.Len() > kOneStringMaxSize)
111       {
112         s.DeleteFrom(kOneStringMaxSize);
113         s += " ...";
114       }
115       s.Replace(L"\r\n", L" ");
116       s.Replace(L"\n", L" ");
117       _listView.SetSubItem(i, 1, s);
118     }
119   }
120 
121   if (SelectFirst && Strings.Size() > 0)
122     _listView.SetItemState_FocusedSelected(0);
123 
124   _listView.SetColumnWidthAuto(0);
125   if (NumColumns > 1)
126     _listView.SetColumnWidthAuto(1);
127   StringsWereChanged = false;
128 
129   NormalizeSize();
130   return CModalDialog::OnInit();
131 }
132 
OnSize(WPARAM,int xSize,int ySize)133 bool CListViewDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
134 {
135   int mx, my;
136   GetMargins(8, mx, my);
137   int bx1, bx2, by;
138   GetItemSizes(IDCANCEL, bx1, by);
139   GetItemSizes(IDOK, bx2, by);
140   int y = ySize - my - by;
141   int x = xSize - mx - bx1;
142 
143   /*
144   RECT rect;
145   GetClientRect(&rect);
146   rect.top = y - my;
147   InvalidateRect(&rect);
148   */
149   InvalidateRect(NULL);
150 
151   MoveItem(IDCANCEL, x, y, bx1, by);
152   MoveItem(IDOK, x - mx - bx2, y, bx2, by);
153   /*
154   if (wParam == SIZE_MAXSHOW || wParam == SIZE_MAXIMIZED || wParam == SIZE_MAXHIDE)
155     mx = 0;
156   */
157   _listView.Move(mx, my, xSize - mx * 2, y - my * 2);
158   return false;
159 }
160 
161 
162 extern bool g_LVN_ITEMACTIVATE_Support;
163 
CopyToClipboard()164 void CListViewDialog::CopyToClipboard()
165 {
166   CUIntVector indexes;
167   ListView_GetSelected(_listView, indexes);
168   UString s;
169 
170   FOR_VECTOR (i, indexes)
171   {
172     unsigned index = indexes[i];
173     s += Strings[index];
174     if (NumColumns > 1 && index < Values.Size())
175     {
176       const UString &v = Values[index];
177       // if (!v.IsEmpty())
178       {
179         s += ": ";
180         s += v;
181       }
182     }
183     // if (indexes.Size() > 1)
184     {
185       s +=
186         #ifdef _WIN32
187           "\r\n"
188         #else
189           "\n"
190         #endif
191         ;
192     }
193   }
194 
195   ClipboardSetText(*this, s);
196 }
197 
198 
ShowItemInfo()199 void CListViewDialog::ShowItemInfo()
200 {
201   CUIntVector indexes;
202   ListView_GetSelected(_listView, indexes);
203   if (indexes.Size() != 1)
204     return;
205   unsigned index = indexes[0];
206 
207   CEditDialog dlg;
208   if (NumColumns == 1)
209     dlg.Text = Strings[index];
210   else
211   {
212     dlg.Title = Strings[index];
213     if (index < Values.Size())
214       dlg.Text = Values[index];
215   }
216 
217   #ifdef _WIN32
218   if (dlg.Text.Find(L'\r') < 0)
219     dlg.Text.Replace(L"\n", L"\r\n");
220   #endif
221 
222   dlg.Create(*this);
223 }
224 
225 
DeleteItems()226 void CListViewDialog::DeleteItems()
227 {
228   for (;;)
229   {
230     const int index = _listView.GetNextSelectedItem(-1);
231     if (index < 0)
232       break;
233     StringsWereChanged = true;
234     _listView.DeleteItem((unsigned)index);
235     if ((unsigned)index < Strings.Size())
236       Strings.Delete((unsigned)index);
237     if ((unsigned)index < Values.Size())
238       Values.Delete((unsigned)index);
239   }
240   const int focusedIndex = _listView.GetFocusedItem();
241   if (focusedIndex >= 0)
242     _listView.SetItemState_FocusedSelected(focusedIndex);
243   _listView.SetColumnWidthAuto(0);
244 }
245 
246 
OnEnter()247 void CListViewDialog::OnEnter()
248 {
249   if (IsKeyDown(VK_MENU)
250       || NumColumns > 1)
251   {
252     ShowItemInfo();
253     return;
254   }
255   OnOK();
256 }
257 
OnNotify(UINT,LPNMHDR header)258 bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
259 {
260   if (header->hwndFrom != _listView)
261     return false;
262   switch (header->code)
263   {
264     case LVN_ITEMACTIVATE:
265       if (g_LVN_ITEMACTIVATE_Support)
266       {
267         OnEnter();
268         return true;
269       }
270       break;
271     case NM_DBLCLK:
272     case NM_RETURN: // probabably it's unused
273       if (!g_LVN_ITEMACTIVATE_Support)
274       {
275         OnEnter();
276         return true;
277       }
278       break;
279 
280     case LVN_KEYDOWN:
281     {
282       LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header);
283       switch (keyDownInfo->wVKey)
284       {
285         case VK_DELETE:
286         {
287           if (!DeleteIsAllowed)
288             return false;
289           DeleteItems();
290           return true;
291         }
292         case 'A':
293         {
294           if (IsKeyDown(VK_CONTROL))
295           {
296             _listView.SelectAll();
297             return true;
298           }
299           break;
300         }
301         case VK_INSERT:
302         case 'C':
303         {
304           if (IsKeyDown(VK_CONTROL))
305           {
306             CopyToClipboard();
307             return true;
308           }
309           break;
310         }
311       }
312     }
313   }
314   return false;
315 }
316 
OnOK()317 void CListViewDialog::OnOK()
318 {
319   FocusedItemIndex = _listView.GetFocusedItem();
320   CModalDialog::OnOK();
321 }
322