📄 updatedlg.cpp
字号:
#include "updatedlg.h"
#include <wx/xrc/xmlres.h>
#include <wx/msgdlg.h>
#include <wx/button.h>
#include <wx/gauge.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/combobox.h>
#include <wx/checkbox.h>
#include <wx/file.h>
#include <wx/menu.h>
#include <wx/log.h>
#include "devpakinstaller.h"
#include "crc32.h"
#include <configmanager.h>
#include <manager.h>
#include <messagemanager.h>
#include <globals.h>
int idNet = wxNewId();
int idPopupInstall = wxNewId();
int idPopupDownload = wxNewId();
int idPopupDownloadAndInstall = wxNewId();
int idPopupUninstall = wxNewId();
BEGIN_EVENT_TABLE(UpdateDlg, wxDialog)
EVT_UPDATE_UI(-1, UpdateDlg::OnUpdateUI)
EVT_TREE_SEL_CHANGED(XRCID("tvCategories"), UpdateDlg::OnTreeSelChanged)
EVT_LIST_ITEM_SELECTED(XRCID("lvFiles"), UpdateDlg::OnFileSelected)
EVT_LIST_ITEM_DESELECTED(XRCID("lvFiles"), UpdateDlg::OnFileDeSelected)
EVT_LIST_ITEM_RIGHT_CLICK(XRCID("lvFiles"), UpdateDlg::OnFileRightClick)
EVT_MENU(idPopupDownload, UpdateDlg::OnDownload)
EVT_MENU(idPopupDownloadAndInstall, UpdateDlg::OnDownloadAndInstall)
EVT_MENU(idPopupInstall, UpdateDlg::OnInstall)
EVT_MENU(idPopupUninstall, UpdateDlg::OnUninstall)
EVT_COMBOBOX(XRCID("cmbServer"), UpdateDlg::OnServerChange)
EVT_COMBOBOX(XRCID("cmbFilter"), UpdateDlg::OnFilterChange)
EVT_CHECKBOX(XRCID("chkCache"), UpdateDlg::OnServerChange)
EVT_CBNET_CONNECT(idNet, UpdateDlg::OnConnect)
EVT_CBNET_DISCONNECT(idNet, UpdateDlg::OnDisConnect)
EVT_CBNET_PROGRESS(idNet, UpdateDlg::OnProgress)
EVT_CBNET_ABORTED(idNet, UpdateDlg::OnAborted)
EVT_CBNET_START_DOWNLOAD(idNet, UpdateDlg::OnDownloadStarted)
EVT_CBNET_END_DOWNLOAD(idNet, UpdateDlg::OnDownloadEnded)
END_EVENT_TABLE()
UpdateDlg::UpdateDlg(wxWindow* parent)
: m_Recs(0),
m_RecsCount(0),
m_CurrFileSize(0),
m_LastBlockSize(0),
m_HasUpdated(false),
m_FirstTimeCheck(true),
m_Net(this, idNet, _T("http://devpaks.sourceforge.net/"))
{
//ctor
wxXmlResource::Get()->LoadDialog(this, parent, _T("MainFrame"));
CreateListColumns();
FillServers();
UpdateStatus(_("Ready"), 0);
}
UpdateDlg::~UpdateDlg()
{
//dtor
delete[] m_Recs;
m_RecsCount = 0;
}
void UpdateDlg::EndModal(int retCode)
{
if (!m_Net.IsConnected() || retCode != wxID_CANCEL)
{
wxDialog::EndModal(retCode);
return;
}
if (m_Net.IsConnected())
m_Net.Abort();
}
void UpdateDlg::CreateListColumns()
{
wxListCtrl* lst = XRCCTRL(*this, "lvFiles", wxListCtrl);
lst->InsertColumn(0, _("Title"));
lst->InsertColumn(1, _("Version"));
lst->InsertColumn(2, _("Installed"));
lst->InsertColumn(3, _("Size"), wxLIST_FORMAT_RIGHT);
lst->SetColumnWidth(0, lst->GetSize().x - (64 * 3) - 2); // 1st column takes all remaining space
lst->SetColumnWidth(1, 64);
lst->SetColumnWidth(2, 64);
lst->SetColumnWidth(3, 64);
}
void UpdateDlg::AddRecordToList(UpdateRec* rec)
{
if (!rec)
return;
wxListCtrl* lst = XRCCTRL(*this, "lvFiles", wxListCtrl);
int idx = lst->GetItemCount();
lst->InsertItem(idx, rec->title);
lst->SetItem(idx, 1, rec->version);
lst->SetItem(idx, 2, rec->installed_version);
lst->SetItem(idx, 3, rec->size);
}
void UpdateDlg::SetListColumnText(int idx, int col, const wxString& text)
{
wxListCtrl* lst = XRCCTRL(*this, "lvFiles", wxListCtrl);
int index = idx == -1 ? lst->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) : idx;
wxListItem it;
it.m_itemId = index;
it.m_col = col;
it.m_mask = wxLIST_MASK_TEXT;
it.m_text = text;
lst->SetItem(it);
}
void UpdateDlg::UpdateStatus(const wxString& status, int curProgress, int maxProgress)
{
wxStaticText* lbl = XRCCTRL(*this, "lblStatus", wxStaticText);
if (lbl->GetLabel() != status)
lbl->SetLabel(status);
if (curProgress != -1)
XRCCTRL(*this, "gauProgress", wxGauge)->SetValue(curProgress);
if (maxProgress != -1)
XRCCTRL(*this, "gauProgress", wxGauge)->SetRange(maxProgress);
}
void UpdateDlg::EnableButtons(bool update, bool abort)
{
wxButton* btnCl = XRCCTRL(*this, "wxID_CANCEL", wxButton);
btnCl->Enable(abort);
// disable server list and cache checkbox while downloading
XRCCTRL(*this, "cmbServer", wxComboBox)->Enable(!m_Net.IsConnected());
XRCCTRL(*this, "chkCache", wxCheckBox)->Enable(!m_Net.IsConnected());
wxYield();
}
void UpdateDlg::FillGroups()
{
UpdateStatus(_("Parsing list of updates"), 0, m_RecsCount - 1);
// get a list of unique group names
wxArrayString groups;
for (int i = 0; i < m_RecsCount; ++i)
{
for (unsigned int x = 0; x < m_Recs[i].groups.GetCount(); ++x)
{
if (m_Recs[i].groups[x].IsEmpty())
continue;
if (groups.Index(m_Recs[i].groups[x]) == wxNOT_FOUND)
{
if (FilterRec(&m_Recs[i]))
groups.Add(m_Recs[i].groups[x]);
}
}
}
// create the groups tree
wxTreeCtrl* tree = XRCCTRL(*this, "tvCategories", wxTreeCtrl);
tree->Freeze();
tree->DeleteAllItems();
wxTreeItemId root = tree->AddRoot(_("All categories"));
for (unsigned int i = 0; i < groups.GetCount(); ++i)
{
tree->AppendItem(root, groups[i]);
}
tree->SortChildren(root);
tree->Thaw();
tree->Expand(root);
tree->SelectItem(root); // this calls the event
UpdateStatus(_("Done parsing list of updates"), 0);
}
void UpdateDlg::FillFiles(const wxTreeItemId& id)
{
wxTreeCtrl* tree = XRCCTRL(*this, "tvCategories", wxTreeCtrl);
wxListCtrl* lst = XRCCTRL(*this, "lvFiles", wxListCtrl);
lst->Freeze();
lst->ClearAll();
CreateListColumns();
wxString group = id == tree->GetRootItem() ? _T("") : tree->GetItemText(id);
// add files belonging to group
int counter = 0;
for (int i = 0; i < m_RecsCount; ++i)
{
if (group.IsEmpty() || (!m_Recs[i].groups.IsEmpty() && m_Recs[i].groups.Index(group) != wxNOT_FOUND))
{
// filter
if (FilterRec(&m_Recs[i]))
{
AddRecordToList(&m_Recs[i]);
++counter;
}
}
}
lst->Thaw();
// select first item
lst->SetItemState(0, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED);
}
void UpdateDlg::FillFileDetails(const wxListItem& id)
{
wxTextCtrl* txt = XRCCTRL(*this, "txtInfo", wxTextCtrl);
txt->Clear();
UpdateRec* cur = GetRecFromListView();
if (!cur)
{
txt->Clear();
EnableButtons();
return;
}
txt->AppendText(_("Name: ") + cur->name + _T("\n"));
// txt->AppendText(_("Server: ") + cur->remote_server + _T("\n"));
// txt->AppendText(_("File: ") + cur->remote_file + _T("\n"));
txt->AppendText(_("Version: ") + cur->version + _T("\n"));
txt->AppendText(_("Size: ") + cur->size + _T("\n"));
txt->AppendText(_("Date: ") + cur->date + _T("\n\n"));
txt->AppendText(_("Description: \n"));
txt->AppendText(cur->desc);
txt->SetSelection(0, 0);
txt->SetInsertionPoint(0);
}
void UpdateDlg::InternetUpdate(bool forceDownload)
{
UpdateStatus(_("Please wait..."));
m_HasUpdated = false;
m_Net.SetServer(GetCurrentServer());
EnableButtons(false);
forceDownload = forceDownload || !XRCCTRL(*this, "chkCache", wxCheckBox)->GetValue();
bool forceDownloadMirrors = forceDownload || !wxFileExists(GetMirrorsFilename());
if (forceDownloadMirrors)
{
if (!m_Net.DownloadFile(_T("mirrors.cfg"), GetMirrorsFilename()))
{
UpdateStatus(_("Error downloading list of mirrors"), 0, 0);
return;
}
else
{
FillServers();
m_Net.SetServer(GetCurrentServer()); // update server based on mirrors
}
}
wxString config = GetConfFilename();
forceDownload = forceDownload || !wxFileExists(config);
if (forceDownload && !m_Net.DownloadFile(_T("webupdate.conf"), config))
{
UpdateStatus(_("Error downloading list of updates"), 0, 0);
return;
}
else
{
IniParser ini;
if (!ini.ParseFile(config))
{
UpdateStatus(_("Failed to retrieve the list of updates"), 0, 0);
return;
}
ini.Sort();
if (m_Recs)
delete[] m_Recs;
// remember to delete[] m_Recs when we 're done with it!!!
// it's our responsibility once given to us
m_Recs = ReadConf(ini, &m_RecsCount, GetCurrentServer(), GetPackagePath());
FillGroups();
}
EnableButtons();
UpdateStatus(_("Ready"), 0, 0);
m_HasUpdated = true;
}
void UpdateDlg::FillServers()
{
wxComboBox* cmb = XRCCTRL(*this, "cmbServer", wxComboBox);
cmb->Clear();
m_Servers.Clear();
IniParser ini;
ini.ParseFile(GetMirrorsFilename());
int group = ini.FindGroupByName(_T("WebUpdate mirrors"));
for (int i = 0; group != -1 && i < ini.GetKeysCount(group); ++i)
{
cmb->Append(ini.GetKeyName(group, i));
m_Servers.Add(ini.GetKeyValue(group, i));
}
if (cmb->GetCount() == 0)
{
cmb->Append(_("devpaks.org Community Devpaks"));
m_Servers.Add(_T("http://devpaks.sourceforge.net/"));
}
cmb->SetSelection(0);
}
wxString UpdateDlg::GetConfFilename()
{
int server_hash = GetTextCRC32(GetCurrentServer().mb_str());
wxString config;
config.Printf(_T("%s/webupdate-%x.conf"), wxGetHomeDir().c_str(), server_hash);
return config;
}
wxString UpdateDlg::GetMirrorsFilename()
{
wxString config;
config << wxGetHomeDir() << _T("/mirrors.cfg");
return config;
}
wxString UpdateDlg::GetCurrentServer()
{
return m_Servers[XRCCTRL(*this, "cmbServer", wxComboBox)->GetSelection()];
}
wxString UpdateDlg::GetBasePath()
{
return g_MasterPath + wxFILE_SEP_PATH;
}
wxString UpdateDlg::GetPackagePath()
{
return GetBasePath() + _T("Packages") + wxFILE_SEP_PATH;
}
bool UpdateDlg::FilterRec(UpdateRec* rec)
{
if (!rec)
return false;
wxComboBox* cmb = XRCCTRL(*this, "cmbFilter", wxComboBox);
switch (cmb->GetSelection())
{
case 0: // All
return true;
case 1: // Installed
return rec->installed;
case 2: // installed with update available
return rec->installed && rec->version != rec->installed_version;
case 3: // downloaded but not installed
return rec->downloaded && !rec->installed;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -