xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/ProgressDialog2.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // ProgressDialog2.h
2 
3 #ifndef ZIP7_INC_PROGRESS_DIALOG_2_H
4 #define ZIP7_INC_PROGRESS_DIALOG_2_H
5 
6 #include "../../../Common/MyCom.h"
7 
8 #include "../../../Windows/ErrorMsg.h"
9 #include "../../../Windows/Synchronization.h"
10 #include "../../../Windows/Thread.h"
11 
12 #include "../../../Windows/Control/Dialog.h"
13 #include "../../../Windows/Control/ListView.h"
14 #include "../../../Windows/Control/ProgressBar.h"
15 
16 #include "MyWindowsNew.h"
17 
18 struct CProgressMessageBoxPair
19 {
20   UString Title;
21   UString Message;
22 };
23 
24 struct CProgressFinalMessage
25 {
26   CProgressMessageBoxPair ErrorMessage;
27   CProgressMessageBoxPair OkMessage;
28 
ThereIsMessageCProgressFinalMessage29   bool ThereIsMessage() const { return !ErrorMessage.Message.IsEmpty() || !OkMessage.Message.IsEmpty(); }
30 };
31 
32 class CProgressSync
33 {
34   bool _stopped;
35   bool _paused;
36 public:
37   bool _filesProgressMode;
38   bool _isDir;
39   UInt64 _totalBytes;
40   UInt64 _completedBytes;
41   UInt64 _totalFiles;
42   UInt64 _curFiles;
43   UInt64 _inSize;
44   UInt64 _outSize;
45 
46   UString _titleFileName;
47   UString _status;
48   UString _filePath;
49 
50   UStringVector Messages;
51   CProgressFinalMessage FinalMessage;
52 
53   NWindows::NSynchronization::CCriticalSection _cs;
54 
55   CProgressSync();
56 
Get_Stopped()57   bool Get_Stopped()
58   {
59     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
60     return _stopped;
61   }
Set_Stopped(bool val)62   void Set_Stopped(bool val)
63   {
64     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
65     _stopped = val;
66   }
67 
68   bool Get_Paused();
Set_Paused(bool val)69   void Set_Paused(bool val)
70   {
71     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
72     _paused = val;
73   }
74 
Set_FilesProgressMode(bool filesProgressMode)75   void Set_FilesProgressMode(bool filesProgressMode)
76   {
77     NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
78     _filesProgressMode = filesProgressMode;
79   }
80 
81   HRESULT CheckStop();
82   void Clear_Stop_Status();
83   HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false);
84 
85   HRESULT Set_NumFilesTotal(UInt64 val);
86   void Set_NumBytesTotal(UInt64 val);
87   void Set_NumFilesCur(UInt64 val);
88   HRESULT Set_NumBytesCur(const UInt64 *val);
89   HRESULT Set_NumBytesCur(UInt64 val);
90   void Set_Ratio(const UInt64 *inSize, const UInt64 *outSize);
91 
92   void Set_TitleFileName(const UString &fileName);
93   void Set_Status(const UString &s);
94   HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false);
95   void Set_FilePath(const wchar_t *path, bool isDir = false);
96 
97   void AddError_Message(const wchar_t *message);
98   void AddError_Message_Name(const wchar_t *message, const wchar_t *name);
99   // void AddError_Code_Name(DWORD systemError, const wchar_t *name);
100   void AddError_Code_Name(HRESULT systemError, const wchar_t *name);
101 
ThereIsMessage()102   bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); }
103 };
104 
105 
106 class CProgressDialog: public NWindows::NControl::CModalDialog
107 {
108   bool _isDir;
109   bool _wasCreated;
110   bool _needClose;
111   bool _errorsWereDisplayed;
112   bool _waitCloseByCancelButton;
113   bool _cancelWasPressed;
114   bool _inCancelMessageBox;
115   bool _externalCloseMessageWasReceived;
116   bool _background;
117 public:
118   bool WaitMode;
119   bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages.
120   bool CompressingMode;
121   bool ShowCompressionInfo;
122 
123 private:
124   unsigned _numPostedMessages;
125   unsigned _numAutoSizeMessages;
126   unsigned _numMessages;
127 
128   UString _titleFileName;
129   UString _filePath;
130   UString _status;
131 
132   UString _background_String;
133   UString _backgrounded_String;
134   UString _foreground_String;
135   UString _pause_String;
136   UString _continue_String;
137   UString _paused_String;
138 
139   int _buttonSizeX;
140   int _buttonSizeY;
141 
142   UINT_PTR _timer;
143 
144   UString _title;
145 
146   class CU64ToI32Converter
147   {
148     unsigned _numShiftBits;
149     UInt64 _range;
150   public:
CU64ToI32Converter()151     CU64ToI32Converter(): _numShiftBits(0), _range(1) {}
Init(UInt64 range)152     void Init(UInt64 range)
153     {
154       _range = range;
155       // Windows CE doesn't like big number for ProgressBar.
156       for (_numShiftBits = 0; range >= ((UInt32)1 << 15); _numShiftBits++)
157         range >>= 1;
158     }
Count(UInt64 val)159     int Count(UInt64 val)
160     {
161       int res = (int)(val >> _numShiftBits);
162       if (val == _range)
163         res++;
164       return res;
165     }
166   };
167 
168   CU64ToI32Converter _progressConv;
169   UInt64 _progressBar_Pos;
170   UInt64 _progressBar_Range;
171 
172   NWindows::NControl::CProgressBar m_ProgressBar;
173   NWindows::NControl::CListView _messageList;
174 
175   UStringVector _messageStrings;
176 
177   // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
178   CMyComPtr<ITaskbarList3> _taskbarList;
179   // #endif
180   HWND _hwndForTaskbar;
181 
182   UInt32 _prevTime;
183   UInt64 _elapsedTime;
184 
185   UInt64 _prevPercentValue;
186   UInt64 _prevElapsedSec;
187   UInt64 _prevRemainingSec;
188 
189   UInt64 _totalBytes_Prev;
190   UInt64 _processed_Prev;
191   UInt64 _packed_Prev;
192   UInt64 _ratio_Prev;
193 
194   UString _filesStr_Prev;
195   UString _filesTotStr_Prev;
196 
197   unsigned _numReduceSymbols;
198   unsigned _prevSpeed_MoveBits;
199   UInt64 _prevSpeed;
200 
201   // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
SetTaskbarProgressState(TBPFLAG tbpFlags)202   void SetTaskbarProgressState(TBPFLAG tbpFlags)
203   {
204     if (_taskbarList && _hwndForTaskbar)
205       _taskbarList->SetProgressState(_hwndForTaskbar, tbpFlags);
206   }
207   // #endif
208   void SetTaskbarProgressState();
209 
210   void UpdateStatInfo(bool showAll);
211   void SetProgressRange(UInt64 range);
212   void SetProgressPos(UInt64 pos);
213   virtual bool OnTimer(WPARAM timerID, LPARAM callback) Z7_override;
214   virtual bool OnInit() Z7_override;
215   virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override;
216   virtual void OnCancel() Z7_override;
217   virtual void OnOK() Z7_override;
218   virtual bool OnNotify(UINT /* controlID */, LPNMHDR header) Z7_override;
219   void CopyToClipboard();
220 
221   NWindows::NSynchronization::CManualResetEvent _createDialogEvent;
222   NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
223   #ifndef Z7_SFX
224   void AddToTitle(LPCWSTR string);
225   #endif
226 
227   void SetPauseText();
228   void SetPriorityText();
229   void OnPauseButton();
230   void OnPriorityButton();
231   bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override;
232   bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override;
233 
234   void SetTitleText();
235   void ShowSize(unsigned id, UInt64 val, UInt64 &prev);
236 
237   void UpdateMessagesDialog();
238 
239   void AddMessageDirect(LPCWSTR message, bool needNumber);
240   void AddMessage(LPCWSTR message);
241 
242   bool OnExternalCloseMessage();
243   void EnableErrorsControls(bool enable);
244 
245   void ShowAfterMessages(HWND wndParent);
246 
247   void CheckNeedClose();
248 
249 public:
250   CProgressSync Sync;
251   int IconID;
252   HWND MainWindow;
253   #ifndef Z7_SFX
254   UString MainTitle;
255   UString MainAddTitle;
256   ~CProgressDialog() Z7_DESTRUCTOR_override;
257   #endif
258 
259   CProgressDialog();
WaitCreating()260   void WaitCreating()
261   {
262     _createDialogEvent.Set();
263     _dialogCreatedEvent.Lock();
264   }
265 
266   INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = NULL);
267 
268 
269   /* how it works:
270      1) the working thread calls ProcessWasFinished()
271         that sends kCloseMessage message to CProgressDialog (GUI) thread
272      2) CProgressDialog (GUI) thread receives kCloseMessage message and
273         calls ProcessWasFinished_GuiVirt();
274         So we can implement ProcessWasFinished_GuiVirt() and show special
275         results window in GUI thread with CProgressDialog as parent window
276   */
277 
278   void ProcessWasFinished();
ProcessWasFinished_GuiVirt()279   virtual void ProcessWasFinished_GuiVirt() {}
280 };
281 
282 
283 class CProgressCloser
284 {
285   CProgressDialog *_p;
286 public:
CProgressCloser(CProgressDialog & p)287   CProgressCloser(CProgressDialog &p) : _p(&p) {}
~CProgressCloser()288   ~CProgressCloser() { _p->ProcessWasFinished(); }
289 };
290 
291 
292 class CProgressThreadVirt: public CProgressDialog
293 {
294 protected:
295   FStringVector ErrorPaths;
296   CProgressFinalMessage FinalMessage;
297 
298   // error if any of HRESULT, ErrorMessage, ErrorPath
299   virtual HRESULT ProcessVirt() = 0;
300 public:
301   HRESULT Result;
302   bool ThreadFinishedOK; // if there is no fatal exception
303 
304   void Process();
AddErrorPath(const FString & path)305   void AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
306 
307   HRESULT Create(const UString &title, HWND parentWindow = NULL);
CProgressThreadVirt()308   CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
309 
GetMessagePair(bool isError)310   CProgressMessageBoxPair &GetMessagePair(bool isError) { return isError ? FinalMessage.ErrorMessage : FinalMessage.OkMessage; }
311 };
312 
313 UString HResultToMessage(HRESULT errorCode);
314 
315 /*
316 how it works:
317 
318 client code inherits CProgressThreadVirt and calls
319 CProgressThreadVirt::Create()
320 {
321   it creates new thread that calls CProgressThreadVirt::Process();
322   it creates modal progress dialog window with ProgressDialog.Create()
323 }
324 
325 CProgressThreadVirt::Process()
326 {
327   {
328     Result = ProcessVirt(); // virtual function that must implement real work
329   }
330   if (exceptions) or FinalMessage.ErrorMessage.Message
331   {
332     set message to ProgressDialog.Sync.FinalMessage.ErrorMessage.Message
333   }
334   else if (FinalMessage.OkMessage.Message)
335   {
336     set message to ProgressDialog.Sync.FinalMessage.OkMessage
337   }
338 
339   PostMsg(kCloseMessage);
340 }
341 
342 
343 CProgressDialog::OnExternalCloseMessage()
344 {
345   if (ProgressDialog.Sync.FinalMessage)
346   {
347     WorkWasFinishedVirt();
348     Show (ProgressDialog.Sync.FinalMessage)
349     MessagesDisplayed = true;
350   }
351 }
352 
353 */
354 
355 #endif
356