ICE 3.4.2
[php5-ice-freebsdport.git] / cpp / demo / IcePatch2 / MFC / PatchClientDlg.cpp
blob07ff15e38c462107da28b7385ea12d38f7a164ad
1 // **********************************************************************
2 //
3 // Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
4 //
5 // This copy of Ice is licensed to you under the terms described in the
6 // ICE_LICENSE file included in this distribution.
7 //
8 // **********************************************************************
10 #include "stdafx.h"
11 #include "PatchClient.h"
12 #include "PatchClientDlg.h"
14 #include <IcePatch2/ClientUtil.h>
16 #ifdef _DEBUG
17 #define new DEBUG_NEW
18 #endif
20 using namespace std;
22 string
23 getBasename(const string& path)
25 string::size_type pos = path.rfind('/');
26 if(pos == string::npos)
28 pos = path.rfind('\\');
31 if(pos == string::npos)
33 return path;
35 else
37 return path.substr(pos + 1);
41 class DialogPatcherFeedback : public IcePatch2::PatcherFeedback
43 public:
45 DialogPatcherFeedback(CPatchDlg* dialog) :
46 _dialog(dialog),
47 _filesPatched(0)
49 assert(_dialog);
52 virtual bool
53 noFileSummary(const string& reason)
55 return IDYES == AfxMessageBox(L"Cannot load file summary. Perform a thorough patch?", MB_YESNO|MB_ICONSTOP);
58 virtual bool
59 checksumStart()
61 return _dialog->checksumStart();
64 virtual bool
65 checksumProgress(const string& path)
67 return _dialog->checksumProgress(path);
70 virtual bool
71 checksumEnd()
73 return _dialog->checksumEnd();
76 virtual bool
77 fileListStart()
79 return _dialog->fileListStart();
82 virtual bool
83 fileListProgress(Ice::Int percent)
85 return _dialog->fileListProgress(percent);
88 virtual bool
89 fileListEnd()
91 return _dialog->fileListEnd();
94 virtual bool
95 patchStart(const string& path, Ice::Long size, Ice::Long totalProgress, Ice::Long totalSize)
97 return _dialog->patchStart(path, size, totalProgress, totalSize);
100 virtual bool
101 patchProgress(Ice::Long progress, Ice::Long size, Ice::Long totalProgress, Ice::Long totalSize)
103 return _dialog->patchProgress(progress, size, totalProgress, totalSize);
106 virtual bool
107 patchEnd()
109 ++_filesPatched;
110 return _dialog->patchEnd();
113 virtual int
114 filesPatched() const
116 return _filesPatched;
119 private:
121 CPatchDlg* const _dialog;
122 int _filesPatched;
125 typedef IceUtil::Handle<DialogPatcherFeedback> DialogPatcherFeedbackPtr;
127 CPatchDlg::CPatchDlg(const Ice::CommunicatorPtr& communicator, CWnd* pParent /*=NULL*/) :
128 CDialog(CPatchDlg::IDD, pParent), _communicator(communicator), _isCancel(false), _isPatch(false)
130 _hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
133 bool
134 CPatchDlg::checksumStart()
136 _status->SetWindowText(CString(L" Calculating checksums..."));
138 _progress->SetRange(0, 0);
139 _progress->SetPos(0);
141 processMessages();
142 return !_isCancel;
145 bool
146 CPatchDlg::checksumProgress(const string& path)
148 // TODO: indicate busy progress
150 CString file;
151 file.Format(L" %s", IceUtil::stringToWstring(getBasename(path)).c_str());
152 _file->SetWindowText(file);
154 processMessages();
155 return !_isCancel;
158 bool
159 CPatchDlg::checksumEnd()
161 processMessages();
162 return !_isCancel;
165 bool
166 CPatchDlg::fileListStart()
168 _status->SetWindowText(CString(L" Retrieving file list..."));
170 _progress->SetRange(0, 100);
171 _progress->SetPos(0);
173 processMessages();
174 return !_isCancel;
177 bool
178 CPatchDlg::fileListProgress(Ice::Int pcnt)
180 CString percent;
181 percent.Format(L"%d%%", pcnt);
182 _percent->SetWindowText(percent);
184 _progress->SetPos(pcnt);
186 processMessages();
187 return !_isCancel;
190 bool
191 CPatchDlg::fileListEnd()
193 processMessages();
194 return !_isCancel;
197 bool
198 CPatchDlg::patchStart(const string& path, Ice::Long size, Ice::Long totalProgress, Ice::Long totalSize)
200 if(!_isPatch)
202 _startTime = IceUtil::Time::now(IceUtil::Time::Monotonic);
203 _status->SetWindowText(CString(L" Patching..."));
204 _speed->SetWindowText(CString(L" 0.0 KB/s"));
205 _isPatch = true;
208 CString file;
209 file.Format(L" %s", IceUtil::stringToWstring(getBasename(path)).c_str());
210 _file->SetWindowText(file);
212 return patchProgress(0, size, totalProgress, totalSize);
215 bool
216 CPatchDlg::patchProgress(Ice::Long, Ice::Long, Ice::Long totalProgress, Ice::Long totalSize)
218 IceUtil::Time elapsed = IceUtil::Time::now(IceUtil::Time::Monotonic) - _startTime;
219 if(elapsed.toSeconds() > 0)
221 CString speed;
222 speed.Format(L" %s/s", convertSize(totalProgress / elapsed.toSeconds()));
223 _speed->SetWindowText(speed);
226 int pcnt = 100;
227 if(totalSize > 0)
229 pcnt = static_cast<int>(totalProgress * 100 / totalSize);
231 CString percent;
232 percent.Format(L"%d%%", pcnt);
233 _percent->SetWindowText(percent);
235 CString total;
236 total.Format(L" %s / %s", convertSize(totalProgress), convertSize(totalSize));
237 _total->SetWindowText(total);
239 _progress->SetPos(pcnt);
241 processMessages();
242 return !_isCancel;
245 bool
246 CPatchDlg::patchEnd()
248 processMessages();
249 return !_isCancel;
252 void
253 CPatchDlg::DoDataExchange(CDataExchange* pDX)
255 CDialog::DoDataExchange(pDX);
258 BEGIN_MESSAGE_MAP(CPatchDlg, CDialog)
259 ON_WM_PAINT()
260 ON_WM_QUERYDRAGICON()
261 //}}AFX_MSG_MAP
262 ON_BN_CLICKED(IDC_SELECTDIR, OnSelectDir)
263 ON_BN_CLICKED(IDC_STARTPATCH, OnStartPatch)
264 ON_BN_CLICKED(IDC_CANCELPATCH, OnCancel)
265 END_MESSAGE_MAP()
267 BOOL
268 CPatchDlg::OnInitDialog()
270 CDialog::OnInitDialog();
272 // Set the icon for this dialog. The framework does this automatically
273 // when the application's main window is not a dialog
274 SetIcon(_hIcon, TRUE); // Set big icon
275 SetIcon(_hIcon, FALSE); // Set small icon
278 // Retrieve the controls.
280 _path = (CEdit*)GetDlgItem(IDC_PATH);
281 _thorough = (CButton*)GetDlgItem(IDC_THOROUGH);
282 _remove = (CButton*)GetDlgItem(IDC_ORPHAN);
283 _select = (CButton*)GetDlgItem(IDC_SELECTDIR);
284 _start = (CButton*)GetDlgItem(IDC_STARTPATCH);
285 _cancel = (CButton*)GetDlgItem(IDC_CANCELPATCH);
286 _file = (CStatic*)GetDlgItem(IDC_FILE);
287 _total = (CStatic*)GetDlgItem(IDC_TOTAL);
288 _speed = (CStatic*)GetDlgItem(IDC_SPEED);
289 _status = (CStatic*)GetDlgItem(IDC_STATUSBAR);
290 _percent = (CStatic*)GetDlgItem(IDC_PERCENT);
291 _progress = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS);
294 // Set the patch directory and thorough flag from properties.
296 Ice::PropertiesPtr properties = _communicator->getProperties();
297 CString path = IceUtil::stringToWstring(properties->getPropertyWithDefault("IcePatch2.Directory", "")).c_str();
298 _path->SetWindowText(path);
300 CString thorough = IceUtil::stringToWstring(properties->getPropertyWithDefault("IcePatch2.Thorough", "0")).c_str();
301 _thorough->SetCheck(thorough != "0");
303 CString remove = IceUtil::stringToWstring(properties->getPropertyWithDefault("IcePatch2.Remove", "0")).c_str();
304 _remove->SetCheck(remove != "0");
307 // Indicate ready status.
309 reset(L" Ready");
311 return TRUE; // return TRUE unless you set the focus to a control
314 // If you add a minimize button to your dialog, you will need the code below
315 // to draw the icon. For MFC applications using the document/view model,
316 // this is automatically done for you by the framework.
318 void
319 CPatchDlg::OnPaint()
321 if(IsIconic())
323 CPaintDC dc(this); // device context for painting
325 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
327 // Center icon in client rectangle
328 int cxIcon = GetSystemMetrics(SM_CXICON);
329 int cyIcon = GetSystemMetrics(SM_CYICON);
330 CRect rect;
331 GetClientRect(&rect);
332 int x = (rect.Width() - cxIcon + 1) / 2;
333 int y = (rect.Height() - cyIcon + 1) / 2;
335 // Draw the icon
336 dc.DrawIcon(x, y, _hIcon);
338 else
340 CDialog::OnPaint();
344 // The system calls this function to obtain the cursor to display while the user drags
345 // the minimized window.
346 HCURSOR
347 CPatchDlg::OnQueryDragIcon()
349 return static_cast<HCURSOR>(_hIcon);
352 void
353 CPatchDlg::OnSelectDir()
355 BROWSEINFO info = { 0 };
356 info.lpszTitle = _T("Select Patch Directory");
357 LPITEMIDLIST pidl = SHBrowseForFolder(&info);
358 if(pidl != 0)
361 // Get the name of the selected folder.
363 TCHAR path[MAX_PATH];
364 if(SHGetPathFromIDList(pidl, path))
366 _path->SetWindowText(path);
370 // Free up memory used.
372 IMalloc * imalloc = 0;
373 if(SUCCEEDED(SHGetMalloc(&imalloc)))
375 imalloc->Free(pidl);
376 imalloc->Release();
381 void
382 CPatchDlg::OnStartPatch()
386 Ice::PropertiesPtr properties = _communicator->getProperties();
389 // Set the patch directory.
391 CString path;
392 _path->GetWindowText(path);
393 if(path.IsEmpty())
395 AfxMessageBox(CString(L"Please select a patch directory."), MB_OK|MB_ICONEXCLAMATION);
396 return;
398 properties->setProperty("IcePatch2.Directory", IceUtil::wstringToString(wstring(path)));
401 // Set the thorough patch flag.
403 string thorough = _thorough->GetCheck() == BST_CHECKED ? "1" : "0";
404 properties->setProperty("IcePatch2.Thorough", thorough);
407 // Set the remove orphan flag.
409 string remove = _remove->GetCheck() == BST_CHECKED ? "1" : "0";
410 properties->setProperty("IcePatch2.Remove", remove);
412 DialogPatcherFeedbackPtr feedback = new DialogPatcherFeedback(this);
413 IcePatch2::PatcherPtr patcher = new IcePatch2::Patcher(_communicator, feedback);
416 // Disable a few controls during the patch process.
418 _path->EnableWindow(false);
419 _select->EnableWindow(false);
420 _thorough->EnableWindow(false);
421 _remove->EnableWindow(false);
422 _start->EnableWindow(false);
425 // Patch
427 bool aborted = !patcher->prepare();
428 if(!aborted)
430 aborted = !patcher->patch("");
432 if(!aborted)
434 patcher->finish();
438 // Reset and indicate the completion status.
440 reset(aborted ? L" Aborted" : L" Completed");
442 catch(const IceUtil::Exception& ex)
444 handleException(ex);
446 catch(const string& ex)
448 AfxMessageBox(CString(ex.c_str()), MB_OK|MB_ICONEXCLAMATION);
452 void
453 CPatchDlg::OnCancel()
455 _isCancel = true;
456 _status->SetWindowText(CString(L" Canceled"));
457 CDialog::OnCancel();
460 void
461 CPatchDlg::reset(const CString& status)
463 _isPatch = false;
465 _path->EnableWindow(true);
466 _select->EnableWindow(true);
467 _thorough->EnableWindow(true);
468 _remove->EnableWindow(true);
469 _start->EnableWindow(true);
471 _status->SetWindowText(status);
472 _file->SetWindowText(CString());
473 _total->SetWindowText(CString());
474 _speed->SetWindowText(CString());
475 _percent->SetWindowText(CString());
477 _progress->SetPos(0);
480 void
481 CPatchDlg::processMessages()
483 MSG msg;
484 while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
486 TranslateMessage(&msg);
487 DispatchMessage(&msg);
491 void
492 CPatchDlg::handleException(const IceUtil::Exception& e)
496 e.ice_throw();
498 catch(const IceUtil::Exception& ex)
500 ostringstream ostr;
501 ostr << ex;
502 string s = ostr.str();
503 AfxMessageBox(CString(s.c_str()), MB_OK|MB_ICONEXCLAMATION);
506 reset(L" Ready");
509 CString
510 CPatchDlg::convertSize(Ice::Long size) const
512 CString units;
513 double start = static_cast<double>(size);
514 double final = start / gigabyte;
515 if(final >= 1)
517 units = L"GB";
519 else
521 final = start / megabyte;
522 if(final >= 1)
524 units = L"MB";
526 else
528 final = start / kilobyte;
529 if(final >= 1)
531 units = L"KB";
533 else
535 final = start;
536 units = L"B";
541 CString convert;
542 convert.Format(L"%.1f %s", final, units);
543 return convert;