📄 updateform.cpp
字号:
/*
This file is part of KCeasy (http://www.kceasy.com)
Copyright (C) 2002-2004 Markus Kern <mkern@kceasy.com>
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 2
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.
*/
//---------------------------------------------------------------------------
#include <vcl.h>
#include <KCeasy.h>
#pragma hdrstop
#include "UpdateForm.h"
#include "AboutDialog.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TAutoUpdate *AutoUpdate;
//---------------------------------------------------------------------------
// local path for storing update.conf
const char* UPDATE_FILE_PATH = "\\update.conf";
//---------------------------------------------------------------------------
__fastcall TAutoUpdate::TAutoUpdate(TComponent* AOwner, bool Silent)
: TForm(AOwner),
Download(NULL),
UpdateConf(NULL),
AutoStep(1),
SilentIfCurrent(Silent)
{
TranslateComponent(this);
Caption = Brand->ReplaceAppName(Caption);
HeadLbl->Caption = Brand->ReplaceAppName(HeadLbl->Caption);
ManualDescrLbl->Caption = Brand->ReplaceAppName(ManualDescrLbl->Caption);
AutoDescrLbl->Caption = Brand->ReplaceAppName(AutoDescrLbl->Caption);
AutoStep2Lbl->Caption = Brand->ReplaceAppName(AutoStep2Lbl->Caption);
AppLogoImage->Picture = Brand->GetLogo48Gray();
HeadVersionLbl->Caption = AnsiString::Format(HeadVersionLbl->Caption,
ARRAYOFCONST((Brand->GetVersionString())));
if(!StartUpdate()) {
ModalResult = mrCancel;
Close();
}
}
__fastcall TAutoUpdate::~TAutoUpdate()
{
// free download
if(Download) {
Download->Cancel();
Download->Release();
}
// free config
if(UpdateConf)
delete UpdateConf;
}
//---------------------------------------------------------------------------
// WARNING: Accessing OpenFT.conf from here!
void TAutoUpdate::UpdateOpenft(TFileConfig* UpdateConf)
{
string ConfPath = Application->ExeName.c_str();
ConfPath.erase(ConfPath.rfind('\\'));
ConfPath += OPENFT_CONF_PATH;
TFileConfig* OpenFTConf = new TFileConfig(ConfPath);
if(!OpenFTConf->Load(true))
return;
static const struct {
char *UpdateName;
char *OpenFTName;
} Keys[] = {
{ "openft/promote_chance", "autopromote/promote_chance" },
{ "openft/demote_chance", "autopromote/demote_chance" },
{ "openft/impoverish_min", "autopromote/impoverish_min" },
{ "openft/surplus_min", "autopromote/surplus_min" },
{ NULL, NULL }
};
bool Dirty = false;
for(int i=0; Keys[i].UpdateName; i++) {
if (UpdateConf->ValueExists(Keys[i].UpdateName))
{
OpenFTConf->SetValue(Keys[i].OpenFTName, UpdateConf->GetValue(Keys[i].UpdateName));
Dirty = true;
}
}
if(Dirty)
OpenFTConf->Save();
delete OpenFTConf;
}
//---------------------------------------------------------------------------
bool TAutoUpdate::StartUpdate()
{
if(Download)
return false;
// create url
if(Brand->GetAutoUpdateUrl() == "")
return false;
string Url(Brand->GetAutoUpdateUrl());
Url += string("?") + Brand->GetUrlSignature();
// create save path
string Path = Application->ExeName.c_str();
Path.erase(Path.rfind('\\'));
Path += UPDATE_FILE_PATH;
// create and start http download
Download = new THttpDownload(this->Handle, WM_UPDATE_CB);
if(!Download->Start(Url, Path))
return false;
return true;
}
void __fastcall TAutoUpdate::WMUpdateCb(TMessage& Msg)
{
if(!Download || UpdateConf)
return; // can't happen
switch(Download->GetState()) {
case HttpDownloadCancelled:
case HttpDownloadFailed:
// release download
Download->Release();
Download = NULL;
// close form
ModalResult = mrCancel;
Close();
break;
case HttpDownloadCompleted: {
UpdateConf = new TFileConfig(Download->GetSavePath());
// release download
Download->Release();
Download = NULL;
if(!UpdateConf->Load()) {
ModalResult = mrCancel;
Close();
break;
}
// Updated OpenFT auto promotion parameters
UpdateOpenft(UpdateConf);
int MajorVersion = UpdateConf->GetValueInt("kceasy/major_version");
int MinorVersion = UpdateConf->GetValueInt("kceasy/minor_version");
if((MajorVersion < Brand->GetMajorVersion() ||
(MajorVersion == Brand->GetMajorVersion() &&
MinorVersion <= Brand->GetMinorVersion())) &&
!UpdateConf->GetValueInt("kceasy/should_update"))
{
// tell user that he has the current version
if (!SilentIfCurrent) {
MessageDlg(_("You are using the latest stable version of {AppName}.\n") +
_("There are no new updates at this time." ),
mtInformation, TMsgDlgButtons() << mbOK,0);
}
ModalResult = mrCancel;
Close();
break;
}
NewVersionGrp->Caption = AnsiString::Format(NewVersionGrp->Caption,
ARRAYOFCONST((MajorVersion, MinorVersion)));
// insert lines into decription memo
list<string> Lines = string_split(UpdateConf->GetValue("kceasy/description"), "|");
DescrMemo->Clear();
for(list<string>::iterator itr=Lines.begin(); itr != Lines.end(); ++itr)
DescrMemo->Lines->Add((*itr).c_str());
// set manual update url
ManualUrlLbl->Caption = UpdateConf->GetValue("kceasy/manual_url").c_str();
ManualSizeLbl->Caption = AnsiString("[") + FormatNumber(UpdateConf->GetValueInt("kceasy/filesize"),"B",2).c_str() + "]";
// show the dialog
MessageBeep(MB_ICONEXCLAMATION);
Show();
break;
}
}
}
//---------------------------------------------------------------------------
bool TAutoUpdate::StartDownload()
{
if(Download || !UpdateConf)
return false; // erm?
// create save path
string Path = Application->ExeName.c_str();
Path.erase(Path.rfind('\\'));
Path += string("\\") + UpdateConf->GetValue("kceasy/filename");
// create url
string Url = UpdateConf->GetValue("kceasy/auto_url");
// create and start http download
Download = new THttpDownload(this->Handle, WM_DOWNLOAD_CB);
if(!Download->Start(Url, Path))
return false;
return true;
}
void __fastcall TAutoUpdate::WMDownloadCb(TMessage& Msg)
{
if(!Download || !UpdateConf)
return; // can't happen
switch(Download->GetState()) {
case HttpDownloadActive:
// update progress bar
if(Download->GetProgressMax() > 0)
AutoProgressBar->Position = Download->GetProgress() * 100 / Download->GetProgressMax();
else
AutoProgressBar->Position = 0;
break;
case HttpDownloadCancelling:
break;
case HttpDownloadCancelled:
break;
case HttpDownloadFailed:
// release download
Download->Release();
Download = NULL;
// TRANSLATOR: Error when automatic download of update failed.
AutoStep1Lbl->Caption = _("Error: Automatic download failed. Please update manually.");
AutoStep1Lbl->Font->Color = clRed;
break;
case HttpDownloadCompleted: {
// check that size of download is correct
DWORD FileSize = 0xFFFFFFFF;
HANDLE hFile = CreateFile(Download->GetSavePath().c_str(),GENERIC_READ,
FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
if(hFile != INVALID_HANDLE_VALUE) {
FileSize = GetFileSize(hFile, NULL);
CloseHandle(hFile);
}
if((int)FileSize != UpdateConf->GetValueInt("kceasy/filesize")) {
// something went wrong with the download
// TRANSLATOR: Error when automatic download of update failed.
AutoStep1Lbl->Caption = _("Error: Automatic download failed. Please update manually.");
AutoStep1Lbl->Font->Color = clRed;
} else {
// next step
AutoStep = 2;
// update UI
AutoStep1Lbl->Font->Color = clWindowText;
AutoStep1Lbl->Font->Style = TFontStyles();
AutoStep2Lbl->Font->Color = clBlue;
AutoStep2Lbl->Font->Style = TFontStyles() << fsBold;
// TRANSLATOR: Auto update button caption after file is downloaded and ready to be installed.
UpdateBtn->Caption = _("Install");
UpdateBtn->Enabled = true;
UpdateBtn->Default = true;
}
// notify user and wait for install confirmation
if(WindowState == wsMinimized)
WindowState = wsNormal;
MessageBeep(MB_ICONEXCLAMATION);
Show();
break;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TAutoUpdate::FormCloseQuery(TObject *Sender,
bool &CanClose)
{
if(ModalResult == mrNone) {
// user tried to close via system menu
// TRANSLATOR: message box when user tries to close update dialog via the X at the top right
AnsiString Msg = _("Not so fast!\n\n{AppName} is constantly under development and using "
"old versions will hurt the networks it uses.\nYou should really "
"update. It will only take a minute and all your downloads and "
"settings will remain unchanged.");
MessageDlg(Brand->ReplaceAppName(Msg),mtWarning,TMsgDlgButtons() << mbOK,0);
CanClose = false;
}
}
void __fastcall TAutoUpdate::FormClose(TObject *Sender,
TCloseAction &Action)
{
Action = caFree;
}
//---------------------------------------------------------------------------
void __fastcall TAutoUpdate::UpdateBtnClick(TObject *Sender)
{
// handle launch case
switch(AutoStep) {
case 1: {
UpdateBtn->Enabled = false;
// start download
if(!StartDownload()) {
// TRANSLATOR: Error when automatic download of update failed.
AutoStep1Lbl->Caption = _("Error: Automatic download failed. Please update manually.");
AutoStep1Lbl->Font->Color = clRed;
}
break;
}
case 2: {
UpdateBtn->Enabled = false;
// launch installer
string Path = Download->GetSavePath();
string Dir = Path.substr(0,Path.rfind('\\'));
if((int)ShellExecute(0,"open",Path.c_str(),"/autoupdate",Dir.c_str(),SW_SHOWNORMAL) <= 32) {
// launching installer failed
// TRANSLATOR: Auto update error when start of downloaded update failed.
AutoStep2Lbl->Caption = _("Error: Automatic installation failed. Please update manually.");
AutoStep2Lbl->Font->Color = clRed;
break;
}
// close kceasy
::PostMessage (MainForm->MessageTarget->GetWndHandle(),
WM_KCEASY_EXTERNAL_SHUTDOWN,0,0);
// close this dialog
ModalResult = mrOk;
Close();
break;
}
default:
// cannot happen
break;
}
}
void __fastcall TAutoUpdate::CancelBtnClick(TObject *Sender)
{
ModalResult = mrCancel;
Close();
}
//---------------------------------------------------------------------------
void __fastcall TAutoUpdate::ManualUrlLblMouseEnter(TObject *Sender)
{
ManualUrlLbl->Font->Style = TFontStyles() << fsUnderline;
}
void __fastcall TAutoUpdate::ManualUrlLblMouseLeave(TObject *Sender)
{
ManualUrlLbl->Font->Style = TFontStyles();
}
void __fastcall TAutoUpdate::ManualUrlLblClick(TObject *Sender)
{
ShellExecute(0,"open",ManualUrlLbl->Caption.c_str(),NULL,NULL,SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -