534 lines
12 KiB
C++
534 lines
12 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/******************************************************************************
|
|
*
|
|
* FILE
|
|
* $Archive: /Commando/Code/Commando/DlgDownload.cpp $
|
|
*
|
|
* DESCRIPTION
|
|
* File download dialog.
|
|
*
|
|
* PROGRAMMER
|
|
* Denzil E. Long, Jr.
|
|
* $Author: Steve_t $
|
|
*
|
|
* VERSION INFO
|
|
* $Revision: 11 $
|
|
* $Modtime: 1/12/02 2:53p $
|
|
*
|
|
******************************************************************************/
|
|
|
|
#include "DlgDownload.h"
|
|
#include "DlgMessageBox.h"
|
|
#include "DlgRestart.h"
|
|
#include "Resource.h"
|
|
#include <WWUI\ProgressCtrl.h>
|
|
#include "String_IDs.h"
|
|
#include <WWTranslateDB\TranslateDB.h>
|
|
#include <WWDebug\WWDebug.h>
|
|
#include "mainloop.h"
|
|
#include "consolemode.h"
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning (push,3)
|
|
#endif
|
|
|
|
#include "systimer.h"
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
using namespace WWOnline;
|
|
|
|
static void PrintableSize(unsigned long size, WideStringClass& printable);
|
|
static void PrintableTime(unsigned long seconds, WideStringClass& printable);
|
|
|
|
bool DlgDownload::mQuietMode = false;
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::DoDialog
|
|
*
|
|
* DESCRIPTION
|
|
* Start download dialog
|
|
*
|
|
* INPUTS
|
|
* Title - Dialog title
|
|
* Files - List of files to download
|
|
*
|
|
* RESULT
|
|
* Success - True if dialog successfully started.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool DlgDownload::DoDialog(const WCHAR* title, const DownloadList& files, bool quiet)
|
|
{
|
|
if (!files.empty())
|
|
{
|
|
mQuietMode = quiet;
|
|
DlgDownload* popup = new DlgDownload;
|
|
|
|
if (popup)
|
|
{
|
|
if (popup->FinalizeCreate(files))
|
|
{
|
|
popup->Start_Dialog();
|
|
popup->Set_Title(title);
|
|
}
|
|
|
|
popup->Release_Ref();
|
|
}
|
|
|
|
return (popup != NULL);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::DlgDownload
|
|
*
|
|
* DESCRIPTION
|
|
* Constructor
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
DlgDownload::DlgDownload() :
|
|
PopupDialogClass(IDD_WOL_DOWNLOAD),
|
|
mDownloading(false)
|
|
{
|
|
WWDEBUG_SAY(("DlgDownload: Instantiated\n"));
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::~DlgDownload
|
|
*
|
|
* DESCRIPTION
|
|
* Destructor
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
DlgDownload::~DlgDownload()
|
|
{
|
|
WWDEBUG_SAY(("DlgDownload: Destructing\n"));
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::FinalizeCreate
|
|
*
|
|
* DESCRIPTION
|
|
* Finalize the dialog creation.
|
|
*
|
|
* INPUTS
|
|
* Files - List of files to download.
|
|
*
|
|
* RESULT
|
|
* True if successful.
|
|
*
|
|
******************************************************************************/
|
|
|
|
bool DlgDownload::FinalizeCreate(const DownloadList& files)
|
|
{
|
|
mWait = DownloadWait::Create(files);
|
|
return mWait.IsValid();
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::On_Init_Dialog
|
|
*
|
|
* DESCRIPTION
|
|
* One time dialog initialization.
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void DlgDownload::On_Init_Dialog(void)
|
|
{
|
|
// Set estimated time and read / total
|
|
WideStringClass text(0, true);
|
|
text.Format(TRANSLATE(IDS_MENU_TRANSFER_RATE_TIME), 0, 0, 0);
|
|
Set_Dlg_Item_Text(IDC_PROGRESSTEXT, text);
|
|
|
|
// Update transfer rate.
|
|
text.Format(TRANSLATE(IDS_MENU_TRANSFER_RATE), 0);
|
|
Set_Dlg_Item_Text(IDC_TRANSFERTEXT, text);
|
|
|
|
// Start the wait condition
|
|
mWait->SetCallback(DlgDownload::HandleCallback, (unsigned long)this);
|
|
mWait->WaitBeginning();
|
|
|
|
PopupDialogClass::On_Init_Dialog();
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::On_Command
|
|
*
|
|
* DESCRIPTION
|
|
* Process command message
|
|
*
|
|
* INPUTS
|
|
* Ctrl - ID of control
|
|
* Message -
|
|
* Param -
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void DlgDownload::On_Command(int ctrl, int message, DWORD param)
|
|
{
|
|
if (ctrl == IDCANCEL)
|
|
{
|
|
WWDEBUG_SAY(("DlgDownload: User Aborted\n"));
|
|
mWait->EndWait(WaitCondition::UserCancel, TRANSLATE(IDS_WOL_CANCELED));
|
|
}
|
|
|
|
PopupDialogClass::On_Command(ctrl, message, param);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::On_Periodic
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
* NONE
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void DlgDownload::On_Periodic(void)
|
|
{
|
|
PopupDialogClass::On_Periodic();
|
|
|
|
// Check the status of the wait condition
|
|
WaitCondition::WaitResult waitStatus = mWait->GetResult();
|
|
|
|
// If we are no longer waiting then process the result.
|
|
if (waitStatus != WaitCondition::Waiting)
|
|
{
|
|
if (waitStatus == WaitCondition::ConditionMet)
|
|
{
|
|
if (mQuietMode)
|
|
{
|
|
ConsoleBox.Print("Restarting....\n");
|
|
Stop_Main_Loop(RESTART_EXITCODE);
|
|
}
|
|
else
|
|
{
|
|
DlgRestart::DoDialog();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If the download was aborted or errored then show a message dialog
|
|
// describing the failure.
|
|
DlgMsgBox::DoDialog(TRANSLATE(IDS_WOL_DOWNLOADERROR), mWait->GetResultText());
|
|
}
|
|
|
|
End_Dialog();
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::UpdateProgress
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void DlgDownload::UpdateProgress(DownloadEvent& event)
|
|
{
|
|
const RefPtr<Download>& download = event.GetDownload();
|
|
|
|
switch (event.GetEvent())
|
|
{
|
|
case DownloadEvent::DOWNLOAD_STATUS:
|
|
Set_Dlg_Item_Text(IDC_STATUSTEXT, download->GetStatusText());
|
|
break;
|
|
|
|
case DownloadEvent::DOWNLOAD_PROGRESS:
|
|
{
|
|
int read = 0;
|
|
int size = 0;
|
|
int elapsed = 0;
|
|
int remaining = 0;
|
|
download->GetProgress(read, size, elapsed, remaining);
|
|
|
|
if (ConsoleBox.Is_Exclusive())
|
|
{
|
|
|
|
if (!mDownloading)
|
|
{
|
|
mStartTime = TIMEGETTIME();
|
|
mDownloading = true;
|
|
}
|
|
|
|
// Calculate the transfer rate
|
|
unsigned long transferRate = read;
|
|
unsigned long elapsedTime = ((TIMEGETTIME() - mStartTime) / 1000);
|
|
if (elapsedTime > 0)
|
|
{
|
|
transferRate = (read / elapsedTime);
|
|
}
|
|
|
|
ConsoleBox.Print("Got %d Kb of %d at %d Kb per second \r", read/1024, size/1024, transferRate / 1024);
|
|
}
|
|
else
|
|
{
|
|
// Update progress bar
|
|
ProgressCtrlClass* progress = (ProgressCtrlClass*)Get_Dlg_Item(IDC_PROGRESS);
|
|
|
|
if (progress)
|
|
{
|
|
// If we have just begun downloading then set the progress bar range
|
|
// for the size of the new file.
|
|
if (!mDownloading)
|
|
{
|
|
progress->Set_Range(0, size);
|
|
mStartTime = TIMEGETTIME();
|
|
mDownloading = true;
|
|
}
|
|
|
|
progress->Set_Position(read);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Update download statistics
|
|
//-----------------------------------------------------------------------
|
|
|
|
// Calculate the transfer rate
|
|
unsigned long transferRate = read;
|
|
unsigned long elapsedTime = ((TIMEGETTIME() - mStartTime) / 1000);
|
|
|
|
if (elapsedTime > 0)
|
|
{
|
|
transferRate = (read / elapsedTime);
|
|
}
|
|
|
|
// Update transfer rate.
|
|
WideStringClass sizetext(64, true);
|
|
PrintableSize(transferRate, sizetext);
|
|
|
|
WideStringClass text(0, true);
|
|
text.Format(TRANSLATE(IDS_MENU_TRANSFER_RATE_PER_SEC), (const WCHAR*)sizetext);
|
|
Set_Dlg_Item_Text(IDC_TRANSFERTEXT, text);
|
|
|
|
// Calculate estimated time based on the current transfer rate.
|
|
unsigned long estimatedTime = 0;
|
|
|
|
if (transferRate > 0)
|
|
{
|
|
estimatedTime = ((size - read) / transferRate);
|
|
}
|
|
|
|
// Update estimated time and read / total
|
|
WideStringClass timetext(64,true);
|
|
PrintableTime(estimatedTime, timetext);
|
|
|
|
WideStringClass readtext(64, true);
|
|
PrintableSize(read, readtext);
|
|
|
|
PrintableSize(size, sizetext);
|
|
|
|
text.Format(TRANSLATE(IDS_MENU_TRANSFER_TIME_LEFT),
|
|
(const WCHAR*)timetext, (const WCHAR*)readtext, (const WCHAR*)sizetext);
|
|
|
|
Set_Dlg_Item_Text(IDC_PROGRESSTEXT, text);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DownloadEvent::DOWNLOAD_BEGIN:
|
|
if (ConsoleBox.Is_Exclusive())
|
|
{
|
|
ConsoleBox.Print("\n");
|
|
}
|
|
break;
|
|
|
|
case DownloadEvent::DOWNLOAD_END:
|
|
if (ConsoleBox.Is_Exclusive())
|
|
{
|
|
ConsoleBox.Print("\nDownload complete\n");
|
|
}
|
|
WWDEBUG_SAY(("DlgDownload: Successful '%s' Elapsed time: %ld ms\n",
|
|
download->GetFilename(), (TIMEGETTIME() - mStartTime)));
|
|
|
|
mDownloading = false;
|
|
break;
|
|
|
|
case DownloadEvent::DOWNLOAD_STOPPED:
|
|
WWDEBUG_SAY(("DlgDownload: Stopped '%s'\n", download->GetFilename()));
|
|
mDownloading = false;
|
|
break;
|
|
|
|
case DownloadEvent::DOWNLOAD_ERROR:
|
|
WWDEBUG_SAY(("DlgDownload: Error '%s'\n", download->GetFilename()));
|
|
mDownloading = false;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* DlgDownload::HandleCallback
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* INPUTS
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void DlgDownload::HandleCallback(DownloadEvent& event, unsigned long userdata)
|
|
{
|
|
DlgDownload* dialog = (DlgDownload*)userdata;
|
|
|
|
if (dialog)
|
|
{
|
|
dialog->UpdateProgress(event);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* PrintableSize
|
|
*
|
|
* DESCRIPTION
|
|
* Get filesize in a printable format.
|
|
*
|
|
* INPUTS
|
|
* Size -
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void PrintableSize(unsigned long size, WideStringClass& printable)
|
|
{
|
|
float value = ((float)size / (float)(1024 * 1024));
|
|
|
|
if (value >= 1.0)
|
|
{
|
|
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_MB_FORMAT), value);
|
|
return;
|
|
}
|
|
|
|
value = ((float)size / 1024.0);
|
|
|
|
if (value >= 1.0)
|
|
{
|
|
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_KB_FORMAT), value);
|
|
return;
|
|
}
|
|
|
|
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_BYTE_FORMAT), size);
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* NAME
|
|
* PrintableTime
|
|
*
|
|
* DESCRIPTION
|
|
* Get time in a printable format.
|
|
*
|
|
* INPUTS
|
|
* Size -
|
|
*
|
|
* RESULT
|
|
* NONE
|
|
*
|
|
******************************************************************************/
|
|
|
|
void PrintableTime(unsigned long time, WideStringClass& printable)
|
|
{
|
|
unsigned long minutes = (time / 60);
|
|
unsigned long seconds = (time % 60);
|
|
|
|
if (minutes > 0)
|
|
{
|
|
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_MIN_SEC_FORMAT), minutes, seconds);
|
|
}
|
|
else
|
|
{
|
|
seconds = max<unsigned long>(seconds, 1);
|
|
printable.Format(TRANSLATE(IDS_MENU_TRANSFER_SEC_FORMAT), seconds);
|
|
}
|
|
}
|