Home | History | Annotate | Download | only in FileManager
      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 
     11 using namespace NWindows;
     12 
     13 extern HINSTANCE g_hInstance;
     14 
     15 static const UINT_PTR kTimerID = 3;
     16 static const UINT kTimerElapse = 100;
     17 
     18 #ifdef LANG
     19 #include "LangUtils.h"
     20 #endif
     21 
     22 HRESULT 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
     36 CProgressDialog::~CProgressDialog()
     37 {
     38   AddToTitle(L"");
     39 }
     40 void CProgressDialog::AddToTitle(LPCWSTR s)
     41 {
     42   if (MainWindow != 0)
     43     MySetWindowText(MainWindow, UString(s) + MainTitle);
     44 }
     45 #endif
     46 
     47 
     48 bool 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 
     74 void CProgressDialog::OnCancel() { Sync.SetStopped(true); }
     75 void CProgressDialog::OnOK() { }
     76 
     77 void 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 
     85 void 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 
    101 bool 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 
    133 bool 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 
    159 bool 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 
    183 void CProgressDialog::CheckNeedClose()
    184 {
    185   if (_needClose)
    186   {
    187     PostMessage(kCloseMessage);
    188     _needClose = false;
    189   }
    190 }
    191 
    192 bool CProgressDialog::OnExternalCloseMessage()
    193 {
    194   End(0);
    195   return true;
    196 }
    197