1// ProgressDialog.cpp
2
3#include "StdAfx.h"
4
5#include "../../../Common/IntToString.h"
6
7#include "resource.h"
8
9#include "ProgressDialog.h"
10
11using namespace NWindows;
12
13extern HINSTANCE g_hInstance;
14
15static const UINT_PTR kTimerID = 3;
16static const UINT kTimerElapse = 100;
17
18#ifdef LANG
19#include "LangUtils.h"
20#endif
21
22HRESULT CProgressSync::ProcessStopAndPause()
23{
24  for (;;)
25  {
26    if (GetStopped())
27      return E_ABORT;
28    if (!GetPaused())
29      break;
30    ::Sleep(100);
31  }
32  return S_OK;
33}
34
35#ifndef _SFX
36CProgressDialog::~CProgressDialog()
37{
38  AddToTitle(L"");
39}
40void CProgressDialog::AddToTitle(LPCWSTR s)
41{
42  if (MainWindow != 0)
43    MySetWindowText(MainWindow, UString(s) + MainTitle);
44}
45#endif
46
47
48bool CProgressDialog::OnInit()
49{
50  _range = (UInt64)(Int64)-1;
51  _prevPercentValue = -1;
52
53  _wasCreated = true;
54  _dialogCreatedEvent.Set();
55
56  #ifdef LANG
57  LangSetDlgItems(*this, NULL, 0);
58  #endif
59
60  m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
61
62  if (IconID >= 0)
63  {
64    HICON icon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IconID));
65    SetIcon(ICON_BIG, icon);
66  }
67
68  _timer = SetTimer(kTimerID, kTimerElapse);
69  SetText(_title);
70  CheckNeedClose();
71  return CModalDialog::OnInit();
72}
73
74void CProgressDialog::OnCancel() { Sync.SetStopped(true); }
75void CProgressDialog::OnOK() { }
76
77void CProgressDialog::SetRange(UInt64 range)
78{
79  _range = range;
80  _peviousPos = (UInt64)(Int64)-1;
81  _converter.Init(range);
82  m_ProgressBar.SetRange32(0 , _converter.Count(range)); // Test it for 100%
83}
84
85void CProgressDialog::SetPos(UInt64 pos)
86{
87  bool redraw = true;
88  if (pos < _range && pos > _peviousPos)
89  {
90    UInt64 posDelta = pos - _peviousPos;
91    if (posDelta < (_range >> 10))
92      redraw = false;
93  }
94  if (redraw)
95  {
96    m_ProgressBar.SetPos(_converter.Count(pos));  // Test it for 100%
97    _peviousPos = pos;
98  }
99}
100
101bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
102{
103  if (Sync.GetPaused())
104    return true;
105
106  CheckNeedClose();
107
108  UInt64 total, completed;
109  Sync.GetProgress(total, completed);
110  if (total != _range)
111    SetRange(total);
112  SetPos(completed);
113
114  if (total == 0)
115    total = 1;
116
117  int percentValue = (int)(completed * 100 / total);
118  if (percentValue != _prevPercentValue)
119  {
120    wchar_t s[64];
121    ConvertUInt64ToString(percentValue, s);
122    UString title = s;
123    title += L"% ";
124    SetText(title + _title);
125    #ifndef _SFX
126    AddToTitle(title + MainAddTitle);
127    #endif
128    _prevPercentValue = percentValue;
129  }
130  return true;
131}
132
133bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
134{
135  switch(message)
136  {
137    case kCloseMessage:
138    {
139      KillTimer(_timer);
140      _timer = 0;
141      if (_inCancelMessageBox)
142      {
143        _externalCloseMessageWasReceived = true;
144        break;
145      }
146      return OnExternalCloseMessage();
147    }
148    /*
149    case WM_SETTEXT:
150    {
151      if (_timer == 0)
152        return true;
153    }
154    */
155  }
156  return CModalDialog::OnMessage(message, wParam, lParam);
157}
158
159bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
160{
161  switch(buttonID)
162  {
163    case IDCANCEL:
164    {
165      bool paused = Sync.GetPaused();
166      Sync.SetPaused(true);
167      _inCancelMessageBox = true;
168      int res = ::MessageBoxW(*this, L"Are you sure you want to cancel?", _title, MB_YESNOCANCEL);
169      _inCancelMessageBox = false;
170      Sync.SetPaused(paused);
171      if (res == IDCANCEL || res == IDNO)
172      {
173        if (_externalCloseMessageWasReceived)
174          OnExternalCloseMessage();
175        return true;
176      }
177      break;
178    }
179  }
180  return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
181}
182
183void CProgressDialog::CheckNeedClose()
184{
185  if (_needClose)
186  {
187    PostMessage(kCloseMessage);
188    _needClose = false;
189  }
190}
191
192bool CProgressDialog::OnExternalCloseMessage()
193{
194  End(0);
195  return true;
196}
197