summaryrefslogtreecommitdiff
path: root/cpp/demo/IcePatch2/MFC/PatchClientDlg.cpp
diff options
context:
space:
mode:
authorCory Winter <cory@zeroc.com>2005-01-28 16:51:52 +0000
committerCory Winter <cory@zeroc.com>2005-01-28 16:51:52 +0000
commite0e349fdef6a8e293a64b951393998f825df2514 (patch)
treeb7c9f5984d32949f53caca164e8e36284ee1d863 /cpp/demo/IcePatch2/MFC/PatchClientDlg.cpp
parentAdded Mac OS X support (diff)
downloadice-e0e349fdef6a8e293a64b951393998f825df2514.tar.bz2
ice-e0e349fdef6a8e293a64b951393998f825df2514.tar.xz
ice-e0e349fdef6a8e293a64b951393998f825df2514.zip
initial patch demo client
Diffstat (limited to 'cpp/demo/IcePatch2/MFC/PatchClientDlg.cpp')
-rwxr-xr-xcpp/demo/IcePatch2/MFC/PatchClientDlg.cpp508
1 files changed, 508 insertions, 0 deletions
diff --git a/cpp/demo/IcePatch2/MFC/PatchClientDlg.cpp b/cpp/demo/IcePatch2/MFC/PatchClientDlg.cpp
new file mode 100755
index 00000000000..4d29268fa7f
--- /dev/null
+++ b/cpp/demo/IcePatch2/MFC/PatchClientDlg.cpp
@@ -0,0 +1,508 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2004 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include "stdafx.h"
+#include "PatchClient.h"
+#include "PatchClientDlg.h"
+
+#include <IcePatch2/ClientUtil.h>
+#include <IcePatch2/Util.h>
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+class DialogPatcherFeedback : public IcePatch2::PatcherFeedback
+{
+public:
+
+ DialogPatcherFeedback(CPatchDlg* dialog) :
+ _dialog(dialog),
+ _filesPatched(0)
+ {
+ assert(_dialog);
+ }
+
+ virtual bool
+ noFileSummary(const std::string& reason)
+ {
+ return IDYES == AfxMessageBox("Cannot load file summary. Perform a thorough patch?", MB_YESNO|MB_ICONSTOP);
+ }
+
+ virtual bool
+ checksumStart()
+ {
+ return _dialog->checksumStart();
+ }
+
+ virtual bool
+ checksumProgress(const std::string& path)
+ {
+ return _dialog->checksumProgress(path);
+ }
+
+ virtual bool
+ checksumEnd()
+ {
+ return _dialog->checksumEnd();
+ }
+
+ virtual bool
+ fileListStart()
+ {
+ return _dialog->fileListStart();
+ }
+
+ virtual bool
+ fileListProgress(Ice::Int percent)
+ {
+ return _dialog->fileListProgress(percent);
+ }
+
+ virtual bool
+ fileListEnd()
+ {
+ return _dialog->fileListEnd();
+ }
+
+ virtual bool
+ patchStart(const std::string& path, Ice::Long size, Ice::Long totalProgress, Ice::Long totalSize)
+ {
+ return _dialog->patchStart(path, size, totalProgress, totalSize);
+ }
+
+ virtual bool
+ patchProgress(Ice::Long progress, Ice::Long size, Ice::Long totalProgress, Ice::Long totalSize)
+ {
+ return _dialog->patchProgress(progress, size, totalProgress, totalSize);
+ }
+
+ virtual bool
+ patchEnd()
+ {
+ ++_filesPatched;
+ return _dialog->patchEnd();
+ }
+
+ virtual int
+ filesPatched() const
+ {
+ return _filesPatched;
+ }
+
+private:
+
+ CPatchDlg* const _dialog;
+ int _filesPatched;
+};
+
+typedef IceUtil::Handle<DialogPatcherFeedback> DialogPatcherFeedbackPtr;
+
+CPatchDlg::CPatchDlg(const Ice::CommunicatorPtr& communicator, CWnd* pParent /*=NULL*/) :
+ CDialog(CPatchDlg::IDD, pParent), _communicator(communicator), _isCancel(false), _isPatch(false)
+{
+ _hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+bool
+CPatchDlg::checksumStart()
+{
+ _status->SetWindowText(CString(" Calculating checksums..."));
+
+ _progress->SetRange(0, 0);
+ _progress->SetPos(0);
+
+ processMessages();
+ return !_isCancel;
+}
+
+bool
+CPatchDlg::checksumProgress(const std::string& path)
+{
+ // TODO: indicate busy progress
+
+ CString file;
+ file.Format(" %s", IcePatch2::getBasename(path).c_str());
+ _file->SetWindowText(file);
+
+ processMessages();
+ return !_isCancel;
+}
+
+bool
+CPatchDlg::checksumEnd()
+{
+ processMessages();
+ return !_isCancel;
+}
+
+bool
+CPatchDlg::fileListStart()
+{
+ _status->SetWindowText(CString(" Retrieving file list..."));
+
+ _progress->SetRange(0, 100);
+ _progress->SetPos(0);
+
+ processMessages();
+ return !_isCancel;
+}
+
+bool
+CPatchDlg::fileListProgress(Ice::Int pcnt)
+{
+ CString percent;
+ percent.Format("%d%%", pcnt);
+ _percent->SetWindowText(percent);
+
+ _progress->SetPos(pcnt);
+
+ processMessages();
+ return !_isCancel;
+}
+
+bool
+CPatchDlg::fileListEnd()
+{
+ processMessages();
+ return !_isCancel;
+}
+
+bool
+CPatchDlg::patchStart(const std::string& path, Ice::Long size, Ice::Long totalProgress, Ice::Long totalSize)
+{
+ if(!_isPatch)
+ {
+ _startTime = IceUtil::Time::now();
+ _status->SetWindowText(CString(" Patching..."));
+ _speed->SetWindowText(CString(" 0.0 KB/s"));
+ _isPatch = true;
+ }
+
+ CString file;
+ file.Format(" %s", IcePatch2::getBasename(path).c_str());
+ _file->SetWindowText(file);
+
+ return patchProgress(0, size, totalProgress, totalSize);
+}
+
+bool
+CPatchDlg::patchProgress(Ice::Long, Ice::Long, Ice::Long totalProgress, Ice::Long totalSize)
+{
+ IceUtil::Time elapsed = IceUtil::Time::now() - _startTime;
+ if(elapsed.toSeconds() > 0)
+ {
+ CString speed;
+ speed.Format(" %s/s", convertSize(totalProgress / elapsed.toSeconds()));
+ _speed->SetWindowText(speed);
+ }
+
+ int pcnt = static_cast<int>(totalProgress * 100 / totalSize);
+ CString percent;
+ percent.Format("%d%%", pcnt);
+ _percent->SetWindowText(percent);
+
+ CString total;
+ total.Format(" %s / %s", convertSize(totalProgress), convertSize(totalSize));
+ _total->SetWindowText(total);
+
+ _progress->SetPos(pcnt);
+
+ processMessages();
+ return !_isCancel;
+}
+
+bool
+CPatchDlg::patchEnd()
+{
+ processMessages();
+ return !_isCancel;
+}
+
+void
+CPatchDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CPatchDlg, CDialog)
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ //}}AFX_MSG_MAP
+ ON_BN_CLICKED(IDC_SELECTDIR, OnSelectDir)
+ ON_BN_CLICKED(IDC_STARTPATCH, OnStartPatch)
+ ON_BN_CLICKED(IDC_CANCELPATCH, OnCancel)
+END_MESSAGE_MAP()
+
+BOOL
+CPatchDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // Set the icon for this dialog. The framework does this automatically
+ // when the application's main window is not a dialog
+ SetIcon(_hIcon, TRUE); // Set big icon
+ SetIcon(_hIcon, FALSE); // Set small icon
+
+ //
+ // Retrieve the controls.
+ //
+ _path = (CEdit*)GetDlgItem(IDC_PATH);
+ _thorough = (CButton*)GetDlgItem(IDC_THOROUGH);
+ _select = (CButton*)GetDlgItem(IDC_SELECTDIR);
+ _start = (CButton*)GetDlgItem(IDC_STARTPATCH);
+ _cancel = (CButton*)GetDlgItem(IDC_CANCELPATCH);
+ _file = (CStatic*)GetDlgItem(IDC_FILE);
+ _total = (CStatic*)GetDlgItem(IDC_TOTAL);
+ _speed = (CStatic*)GetDlgItem(IDC_SPEED);
+ _status = (CStatic*)GetDlgItem(IDC_STATUSBAR);
+ _percent = (CStatic*)GetDlgItem(IDC_PERCENT);
+ _progress = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS);
+
+ //
+ // Set the patch directory and thorough flag from properties.
+ //
+ Ice::PropertiesPtr properties = _communicator->getProperties();
+ CString path = properties->getPropertyWithDefault("IcePatch2.Directory", "").c_str();
+ _path->SetWindowText(path);
+
+ CString thorough = properties->getPropertyWithDefault("IcePatch2.Thorough", "0").c_str();
+ _thorough->SetCheck(thorough != "0");
+
+ //
+ // Indicate ready status.
+ //
+ reset(" Ready");
+
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+// to draw the icon. For MFC applications using the document/view model,
+// this is automatically done for you by the framework.
+
+void
+CPatchDlg::OnPaint()
+{
+ if(IsIconic())
+ {
+ CPaintDC dc(this); // device context for painting
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+ // Center icon in client rectangle
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // Draw the icon
+ dc.DrawIcon(x, y, _hIcon);
+ }
+ else
+ {
+ CDialog::OnPaint();
+ }
+}
+
+// The system calls this function to obtain the cursor to display while the user drags
+// the minimized window.
+HCURSOR
+CPatchDlg::OnQueryDragIcon()
+{
+ return static_cast<HCURSOR>(_hIcon);
+}
+
+void
+CPatchDlg::OnSelectDir()
+{
+ BROWSEINFO info = { 0 };
+ info.lpszTitle = _T("Select Patch Directory");
+ LPITEMIDLIST pidl = SHBrowseForFolder(&info);
+ if(pidl != 0)
+ {
+ //
+ // Get the name of the selected folder.
+ //
+ TCHAR path[MAX_PATH];
+ if(SHGetPathFromIDList(pidl, path))
+ {
+ _path->SetWindowText(path);
+ }
+
+ //
+ // Free up memory used.
+ //
+ IMalloc * imalloc = 0;
+ if(SUCCEEDED(SHGetMalloc(&imalloc)))
+ {
+ imalloc->Free(pidl);
+ imalloc->Release();
+ }
+ }
+}
+
+void
+CPatchDlg::OnStartPatch()
+{
+ try
+ {
+ Ice::PropertiesPtr properties = _communicator->getProperties();
+
+ //
+ // Set the patch directory.
+ //
+ CString path;
+ _path->GetWindowText(path);
+ if(path.IsEmpty())
+ {
+ AfxMessageBox(CString("Please select a patch directory."), MB_OK|MB_ICONEXCLAMATION);
+ return;
+ }
+ properties->setProperty("IcePatch2.Directory", std::string(path));
+
+ //
+ // Set the thorough patch flag.
+ //
+ std::string thorough = _thorough->GetCheck() == BST_CHECKED ? "1" : "0";
+ properties->setProperty("IcePatch2.Thorough", thorough);
+
+ DialogPatcherFeedbackPtr feedback = new DialogPatcherFeedback(this);
+ IcePatch2::PatcherPtr patcher = new IcePatch2::Patcher(_communicator, feedback);
+
+ //
+ // Disable a few controls during the patch process.
+ //
+ _path->EnableWindow(false);
+ _select->EnableWindow(false);
+ _thorough->EnableWindow(false);
+ _start->EnableWindow(false);
+
+ //
+ // Patch
+ //
+ bool aborted = !patcher->prepare();
+ if(!aborted)
+ {
+ aborted = !patcher->patch("");
+ }
+ if(!aborted)
+ {
+ patcher->finish();
+ }
+
+ //
+ // Reset and indicate the completion status.
+ //
+ reset(aborted ? " Aborted" : " Completed");
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ handleException(ex);
+ }
+ catch(const std::string& ex)
+ {
+ AfxMessageBox(CString(ex.c_str()), MB_OK|MB_ICONEXCLAMATION);
+ }
+}
+
+void
+CPatchDlg::OnCancel()
+{
+ _isCancel = true;
+ _status->SetWindowText(CString(" Canceled"));
+ CDialog::OnCancel();
+}
+
+void
+CPatchDlg::reset(const CString& status)
+{
+ _isPatch = false;
+
+ _path->EnableWindow(true);
+ _select->EnableWindow(true);
+ _thorough->EnableWindow(true);
+ _start->EnableWindow(true);
+
+ _status->SetWindowText(status);
+ _file->SetWindowText(CString());
+ _total->SetWindowText(CString());
+ _speed->SetWindowText(CString());
+ _percent->SetWindowText(CString());
+
+ _progress->SetPos(0);
+}
+
+void
+CPatchDlg::processMessages()
+{
+ MSG msg;
+ while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+}
+
+void
+CPatchDlg::handleException(const IceUtil::Exception& e)
+{
+ try
+ {
+ e.ice_throw();
+ }
+ catch(const IceUtil::Exception& ex)
+ {
+ std::ostringstream ostr;
+ ostr << ex;
+ std::string s = ostr.str();
+ AfxMessageBox(CString(s.c_str()), MB_OK|MB_ICONEXCLAMATION);
+ }
+
+ reset(" Ready");
+}
+
+CString
+CPatchDlg::convertSize(Ice::Long size) const
+{
+ CString units;
+ double start = static_cast<double>(size);
+ double final = start / gigabyte;
+ if(final >= 1)
+ {
+ units = "GB";
+ }
+ else
+ {
+ final = start / megabyte;
+ if(final >= 1)
+ {
+ units = "MB";
+ }
+ else
+ {
+ final = start / kilobyte;
+ if(final >= 1)
+ {
+ units = "KB";
+ }
+ else
+ {
+ final = start;
+ units = "B";
+ }
+ }
+ }
+
+ CString convert;
+ convert.Format("%.1f %s", final, units);
+ return convert;
+}