mirror of https://github.com/BOINC/boinc.git
1112 lines
38 KiB
C++
1112 lines
38 KiB
C++
// This file is part of BOINC.
|
||
// http://boinc.berkeley.edu
|
||
// Copyright (C) 2008 University of California
|
||
//
|
||
// BOINC is free software; you can redistribute it and/or modify it
|
||
// under the terms of the GNU Lesser General Public License
|
||
// as published by the Free Software Foundation,
|
||
// either version 3 of the License, or (at your option) any later version.
|
||
//
|
||
// BOINC 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 Lesser General Public License for more details.
|
||
//
|
||
// You should have received a copy of the GNU Lesser General Public License
|
||
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||
|
||
#if defined(__GNUG__) && !defined(__APPLE__)
|
||
#pragma implementation "BOINCBaseView.h"
|
||
#endif
|
||
|
||
#include "stdwx.h"
|
||
#include "BOINCGUIApp.h"
|
||
#include "MainDocument.h"
|
||
#include "BOINCBaseView.h"
|
||
#include "BOINCTaskCtrl.h"
|
||
#include "BOINCListCtrl.h"
|
||
#include "Events.h"
|
||
|
||
#include "res/boinc.xpm"
|
||
#include "res/sortascending.xpm"
|
||
#include "res/sortdescending.xpm"
|
||
|
||
|
||
IMPLEMENT_DYNAMIC_CLASS(CBOINCBaseView, wxPanel)
|
||
|
||
|
||
CBOINCBaseView::CBOINCBaseView() {}
|
||
|
||
CBOINCBaseView::CBOINCBaseView(wxNotebook* pNotebook) :
|
||
wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
|
||
{
|
||
m_bProcessingTaskRenderEvent = false;
|
||
m_bProcessingListRenderEvent = false;
|
||
|
||
m_bForceUpdateSelection = true;
|
||
m_bIgnoreUIEvents = false;
|
||
m_bNeedSort = false;
|
||
|
||
//
|
||
// Setup View
|
||
//
|
||
m_pTaskPane = NULL;
|
||
m_pListPane = NULL;
|
||
m_iProgressColumn = -1;
|
||
m_iSortColumn = -1;
|
||
m_SortArrows = NULL;
|
||
|
||
SetName(GetViewName());
|
||
SetAutoLayout(TRUE);
|
||
|
||
#if BASEVIEW_STRIPES
|
||
m_pWhiteBackgroundAttr = NULL;
|
||
m_pGrayBackgroundAttr = NULL;
|
||
#endif
|
||
}
|
||
|
||
|
||
CBOINCBaseView::CBOINCBaseView(wxNotebook* pNotebook, wxWindowID iTaskWindowID, int iTaskWindowFlags, wxWindowID iListWindowID, int iListWindowFlags) :
|
||
wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
|
||
{
|
||
m_bProcessingTaskRenderEvent = false;
|
||
m_bProcessingListRenderEvent = false;
|
||
|
||
m_bForceUpdateSelection = true;
|
||
m_bIgnoreUIEvents = false;
|
||
|
||
//
|
||
// Setup View
|
||
//
|
||
m_pTaskPane = NULL;
|
||
m_pListPane = NULL;
|
||
|
||
SetName(GetViewName());
|
||
SetAutoLayout(TRUE);
|
||
|
||
wxFlexGridSizer* itemFlexGridSizer = new wxFlexGridSizer(2, 0, 0);
|
||
wxASSERT(itemFlexGridSizer);
|
||
|
||
itemFlexGridSizer->AddGrowableRow(0);
|
||
itemFlexGridSizer->AddGrowableCol(1);
|
||
|
||
m_pTaskPane = new CBOINCTaskCtrl(this, iTaskWindowID, iTaskWindowFlags);
|
||
wxASSERT(m_pTaskPane);
|
||
|
||
m_pListPane = new CBOINCListCtrl(this, iListWindowID, iListWindowFlags);
|
||
wxASSERT(m_pListPane);
|
||
|
||
itemFlexGridSizer->Add(m_pTaskPane, 1, wxGROW|wxALL, 1);
|
||
itemFlexGridSizer->Add(m_pListPane, 1, wxGROW|wxALL, 1);
|
||
|
||
SetSizer(itemFlexGridSizer);
|
||
|
||
UpdateSelection();
|
||
|
||
#if USE_NATIVE_LISTCONTROL
|
||
m_pListPane->PushEventHandler(new MyEvtHandler(m_pListPane));
|
||
#else
|
||
(m_pListPane->GetMainWin())->PushEventHandler(new MyEvtHandler(m_pListPane));
|
||
#endif
|
||
|
||
m_iProgressColumn = -1;
|
||
m_iSortColumn = -1;
|
||
m_bReverseSort = false;
|
||
|
||
m_SortArrows = new wxImageList(16, 16, true);
|
||
m_SortArrows->Add( wxIcon( sortascending_xpm ) );
|
||
m_SortArrows->Add( wxIcon( sortdescending_xpm ) );
|
||
m_pListPane->SetImageList(m_SortArrows, wxIMAGE_LIST_SMALL);
|
||
|
||
#if BASEVIEW_STRIPES
|
||
m_pWhiteBackgroundAttr = new wxListItemAttr(
|
||
wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT),
|
||
wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW),
|
||
wxNullFont
|
||
);
|
||
m_pGrayBackgroundAttr = new wxListItemAttr(
|
||
wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT),
|
||
wxColour(240, 240, 240),
|
||
wxNullFont
|
||
);
|
||
#endif
|
||
|
||
}
|
||
|
||
|
||
CBOINCBaseView::~CBOINCBaseView() {
|
||
if (m_pListPane) {
|
||
#if USE_NATIVE_LISTCONTROL
|
||
m_pListPane->PopEventHandler(true);
|
||
#else
|
||
(m_pListPane->GetMainWin())->PopEventHandler(true);
|
||
#endif
|
||
}
|
||
if (m_SortArrows) {
|
||
delete m_SortArrows;
|
||
}
|
||
m_arrSelectedKeys1.Clear();
|
||
m_arrSelectedKeys2.Clear();
|
||
m_iSortedIndexes.Clear();
|
||
|
||
#if BASEVIEW_STRIPES
|
||
if (m_pWhiteBackgroundAttr) {
|
||
delete m_pWhiteBackgroundAttr;
|
||
m_pWhiteBackgroundAttr = NULL;
|
||
}
|
||
|
||
if (m_pGrayBackgroundAttr) {
|
||
delete m_pGrayBackgroundAttr;
|
||
m_pGrayBackgroundAttr = NULL;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
// The name of the view.
|
||
// If it has not been defined by the view "Undefined" is returned.
|
||
//
|
||
wxString& CBOINCBaseView::GetViewName() {
|
||
static wxString strViewName(wxT("Undefined"));
|
||
return strViewName;
|
||
}
|
||
|
||
|
||
// The user friendly name of the view.
|
||
// If it has not been defined by the view "Undefined" is returned.
|
||
//
|
||
wxString& CBOINCBaseView::GetViewDisplayName() {
|
||
static wxString strViewName(wxT("Undefined"));
|
||
return strViewName;
|
||
}
|
||
|
||
|
||
// The user friendly icon of the view.
|
||
// If it has not been defined by the view the BOINC icon is returned.
|
||
//
|
||
const char** CBOINCBaseView::GetViewIcon() {
|
||
wxASSERT(boinc_xpm);
|
||
return boinc_xpm;
|
||
}
|
||
|
||
|
||
// The rate at which the view is refreshed.
|
||
// If it has not been defined by the view 1 second is retrned.
|
||
//
|
||
const int CBOINCBaseView::GetViewRefreshRate() {
|
||
return 1;
|
||
}
|
||
|
||
|
||
// Get bit mask of current view(s).
|
||
//
|
||
const int CBOINCBaseView::GetViewCurrentViewPage() {
|
||
return 0;
|
||
}
|
||
|
||
|
||
wxString CBOINCBaseView::GetKeyValue1(int) {
|
||
return wxEmptyString;
|
||
}
|
||
|
||
|
||
wxString CBOINCBaseView::GetKeyValue2(int) {
|
||
return wxEmptyString;
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::FindRowIndexByKeyValues(wxString&, wxString&) {
|
||
return -1;
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::FireOnSaveState(wxConfigBase* pConfig) {
|
||
return OnSaveState(pConfig);
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::FireOnRestoreState(wxConfigBase* pConfig) {
|
||
return OnRestoreState(pConfig);
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::GetListRowCount() {
|
||
wxASSERT(m_pListPane);
|
||
return m_pListPane->GetItemCount();
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::FireOnListRender(wxTimerEvent& event) {
|
||
OnListRender(event);
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::FireOnListSelected(wxListEvent& event) {
|
||
OnListSelected(event);
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::FireOnListDeselected(wxListEvent& event) {
|
||
OnListDeselected(event);
|
||
}
|
||
|
||
|
||
wxString CBOINCBaseView::FireOnListGetItemText(long item, long column) const {
|
||
return OnListGetItemText(item, column);
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::FireOnListGetItemImage(long item) const {
|
||
return OnListGetItemImage(item);
|
||
}
|
||
|
||
|
||
#if BASEVIEW_STRIPES
|
||
wxListItemAttr* CBOINCBaseView::FireOnListGetItemAttr(long item) const {
|
||
return OnListGetItemAttr(item);
|
||
}
|
||
|
||
|
||
wxListItemAttr* CBOINCBaseView::OnListGetItemAttr(long item) const {
|
||
|
||
// If we are using some theme where the default background color isn't
|
||
// white, then our whole system is boned. Use defaults instead.
|
||
if (wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW) != wxColor(wxT("WHITE"))) return NULL;
|
||
|
||
return item % 2 ? m_pGrayBackgroundAttr : m_pWhiteBackgroundAttr;
|
||
}
|
||
#endif
|
||
|
||
|
||
void CBOINCBaseView::OnListRender(wxTimerEvent& event) {
|
||
if (!m_bProcessingListRenderEvent) {
|
||
m_bProcessingListRenderEvent = true;
|
||
|
||
wxASSERT(m_pListPane);
|
||
|
||
// Remember the key values of currently selected items
|
||
SaveSelections();
|
||
|
||
int iDocCount = GetDocCount();
|
||
int iCacheCount = GetCacheCount();
|
||
if (iDocCount != iCacheCount) {
|
||
if (0 >= iDocCount) {
|
||
EmptyCache();
|
||
m_pListPane->DeleteAllItems();
|
||
} else {
|
||
int iIndex = 0;
|
||
int iReturnValue = -1;
|
||
if (iDocCount > iCacheCount) {
|
||
for (iIndex = 0; iIndex < (iDocCount - iCacheCount); iIndex++) {
|
||
iReturnValue = AddCacheElement();
|
||
wxASSERT(!iReturnValue);
|
||
}
|
||
wxASSERT(GetDocCount() == GetCacheCount());
|
||
m_pListPane->SetItemCount(iDocCount);
|
||
m_bNeedSort = true;
|
||
} else {
|
||
// The virtual ListCtrl keeps a separate its list of selected rows;
|
||
// make sure it does not reference any rows beyond the new last row.
|
||
// We can ClearSelections() because we called SaveSelections() above.
|
||
ClearSelections();
|
||
m_pListPane->SetItemCount(iDocCount);
|
||
for (iIndex = (iCacheCount - 1); iIndex >= iDocCount; --iIndex) {
|
||
iReturnValue = RemoveCacheElement();
|
||
wxASSERT(!iReturnValue);
|
||
}
|
||
wxASSERT(GetDocCount() == GetCacheCount());
|
||
m_pListPane->RefreshItems(0, iDocCount - 1);
|
||
m_bNeedSort = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (iDocCount > 0) {
|
||
SynchronizeCache();
|
||
if (iDocCount > 1) {
|
||
if (_EnsureLastItemVisible() && (iDocCount != iCacheCount)) {
|
||
m_pListPane->EnsureVisible(iDocCount - 1);
|
||
}
|
||
}
|
||
|
||
if (m_pListPane->m_bIsSingleSelection) {
|
||
// If no item has been selected yet, select the first item.
|
||
#ifdef __WXMSW__
|
||
if ((m_pListPane->GetSelectedItemCount() == 0) &&
|
||
(m_pListPane->GetItemCount() >= 1)) {
|
||
|
||
long desiredstate = wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED;
|
||
m_pListPane->SetItemState(0, desiredstate, desiredstate);
|
||
}
|
||
#else
|
||
if ((m_pListPane->GetFirstSelected() < 0) &&
|
||
(m_pListPane->GetItemCount() >= 1)) {
|
||
m_pListPane->SetItemState(0, wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED,
|
||
wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED);
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
// Find the previously selected items by their key values and reselect them
|
||
RestoreSelections();
|
||
|
||
UpdateSelection();
|
||
|
||
m_bProcessingListRenderEvent = false;
|
||
}
|
||
|
||
event.Skip();
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::OnSaveState(wxConfigBase* pConfig) {
|
||
bool bReturnValue = true;
|
||
|
||
wxASSERT(pConfig);
|
||
wxASSERT(m_pTaskPane);
|
||
wxASSERT(m_pListPane);
|
||
|
||
if (!m_pTaskPane->OnSaveState(pConfig)) {
|
||
bReturnValue = false;
|
||
}
|
||
|
||
if (!m_pListPane->OnSaveState(pConfig)) {
|
||
bReturnValue = false;
|
||
}
|
||
|
||
return bReturnValue;
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::OnRestoreState(wxConfigBase* pConfig) {
|
||
wxASSERT(pConfig);
|
||
wxASSERT(m_pTaskPane);
|
||
wxASSERT(m_pListPane);
|
||
|
||
if (!m_pTaskPane->OnRestoreState(pConfig)) {
|
||
return false;
|
||
}
|
||
|
||
if (!m_pListPane->OnRestoreState(pConfig)) {
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::OnListSelected(wxListEvent& event) {
|
||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseView::OnListSelected - Function Begin"));
|
||
|
||
if (!m_bIgnoreUIEvents) {
|
||
m_bForceUpdateSelection = true;
|
||
UpdateSelection();
|
||
event.Skip();
|
||
}
|
||
|
||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseView::OnListSelected - Function End"));
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::OnListDeselected(wxListEvent& event) {
|
||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseView::OnListDeselected - Function Begin"));
|
||
|
||
if (!m_bIgnoreUIEvents) {
|
||
m_bForceUpdateSelection = true;
|
||
UpdateSelection();
|
||
event.Skip();
|
||
}
|
||
|
||
wxLogTrace(wxT("Function Start/End"), wxT("CBOINCBaseView::OnListDeselected - Function End"));
|
||
}
|
||
|
||
|
||
// Work around a bug (feature?) in virtual list control
|
||
// which does not send deselection events
|
||
void CBOINCBaseView::OnCacheHint(wxListEvent& event) {
|
||
static int oldSelectionCount = 0;
|
||
int newSelectionCount = m_pListPane->GetSelectedItemCount();
|
||
|
||
if (newSelectionCount < oldSelectionCount) {
|
||
wxListEvent leDeselectedEvent(wxEVT_COMMAND_LIST_ITEM_DESELECTED, m_windowId);
|
||
leDeselectedEvent.SetEventObject(this);
|
||
OnListDeselected(leDeselectedEvent);
|
||
}
|
||
oldSelectionCount = newSelectionCount;
|
||
event.Skip();
|
||
}
|
||
|
||
|
||
wxString CBOINCBaseView::OnListGetItemText(long WXUNUSED(item), long WXUNUSED(column)) const {
|
||
return wxString(wxT("Undefined"));
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::OnListGetItemImage(long WXUNUSED(item)) const {
|
||
return -1;
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::GetDocCount() {
|
||
return 0;
|
||
}
|
||
|
||
|
||
wxString CBOINCBaseView::OnDocGetItemImage(long WXUNUSED(item)) const {
|
||
return wxString(wxT("Undefined"));
|
||
}
|
||
|
||
|
||
wxString CBOINCBaseView::OnDocGetItemAttr(long WXUNUSED(item)) const {
|
||
return wxString(wxT("Undefined"));
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::AddCacheElement() {
|
||
return -1;
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::EmptyCache() {
|
||
return -1;
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::GetCacheCount() {
|
||
return -1;
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::RemoveCacheElement() {
|
||
return -1;
|
||
}
|
||
|
||
|
||
int CBOINCBaseView::SynchronizeCache() {
|
||
int iRowIndex = 0;
|
||
int iRowTotal = 0;
|
||
int iColumnIndex = 0;
|
||
int iColumnTotal = 0;
|
||
bool bNeedRefreshData = false;
|
||
|
||
iRowTotal = GetDocCount();
|
||
iColumnTotal = m_pListPane->GetColumnCount();
|
||
|
||
for (iRowIndex = 0; iRowIndex < iRowTotal; iRowIndex++) {
|
||
bNeedRefreshData = false;
|
||
|
||
for (iColumnIndex = 0; iColumnIndex < iColumnTotal; iColumnIndex++) {
|
||
if (SynchronizeCacheItem(iRowIndex, iColumnIndex)) {
|
||
#ifdef __WXMAC__
|
||
bNeedRefreshData = true;
|
||
#else
|
||
// To reduce flicker, refresh only changed columns
|
||
m_pListPane->RefreshCell(iRowIndex, iColumnIndex);
|
||
#endif
|
||
if (iColumnIndex == m_iSortColumn) {
|
||
m_bNeedSort = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Mac is double-buffered to avoid flicker, so this is more efficient
|
||
if (bNeedRefreshData) {
|
||
m_pListPane->RefreshItem(iRowIndex);
|
||
}
|
||
}
|
||
|
||
if (m_bNeedSort) {
|
||
sortData(); // Will mark moved items as needing refresh
|
||
m_bNeedSort = false;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::SynchronizeCacheItem(wxInt32 WXUNUSED(iRowIndex), wxInt32 WXUNUSED(iColumnIndex)) {
|
||
return false;
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::OnColClick(wxListEvent& event) {
|
||
wxListItem item;
|
||
int newSortColumn = event.GetColumn();
|
||
wxArrayInt selections;
|
||
int i, j, m;
|
||
|
||
item.SetMask(wxLIST_MASK_IMAGE);
|
||
if (newSortColumn == m_iSortColumn) {
|
||
m_bReverseSort = !m_bReverseSort;
|
||
} else {
|
||
// Remove sort arrow from old sort column
|
||
if (m_iSortColumn >= 0) {
|
||
item.SetImage(-1);
|
||
m_pListPane->SetColumn(m_iSortColumn, item);
|
||
}
|
||
m_iSortColumn = newSortColumn;
|
||
m_bReverseSort = false;
|
||
}
|
||
|
||
item.SetImage(m_bReverseSort ? 0 : 1);
|
||
m_pListPane->SetColumn(newSortColumn, item);
|
||
|
||
Freeze(); // To reduce flicker
|
||
// Remember which cache elements are selected and deselect them
|
||
m_bIgnoreUIEvents = true;
|
||
i = -1;
|
||
while (1) {
|
||
i = m_pListPane->GetNextSelected(i);
|
||
if (i < 0) break;
|
||
selections.Add(m_iSortedIndexes[i]);
|
||
m_pListPane->SelectRow(i, false);
|
||
}
|
||
|
||
sortData();
|
||
|
||
// Reselect previously selected cache elements in the sorted list
|
||
m = (int)selections.GetCount();
|
||
for (i=0; i<m; i++) {
|
||
if (selections[i] >= 0) {
|
||
j = m_iSortedIndexes.Index(selections[i]);
|
||
m_pListPane->SelectRow(j, true);
|
||
}
|
||
}
|
||
m_bIgnoreUIEvents = false;
|
||
|
||
Thaw();
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::InitSort() {
|
||
wxListItem item;
|
||
|
||
if (m_iSortColumn < 0) return;
|
||
item.SetMask(wxLIST_MASK_IMAGE);
|
||
item.SetImage(m_bReverseSort ? 0 : 1);
|
||
m_pListPane->SetColumn(m_iSortColumn, item);
|
||
Freeze(); // To reduce flicker
|
||
sortData();
|
||
Thaw();
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::sortData() {
|
||
if (m_iSortColumn < 0) return;
|
||
|
||
wxArrayInt oldSortedIndexes(m_iSortedIndexes);
|
||
int i, n = (int)m_iSortedIndexes.GetCount();
|
||
|
||
std::stable_sort(m_iSortedIndexes.begin(), m_iSortedIndexes.end(), m_funcSortCompare);
|
||
|
||
// Refresh rows which have moved
|
||
for (i=0; i<n; i++) {
|
||
if (m_iSortedIndexes[i] != oldSortedIndexes[i]) {
|
||
m_pListPane->RefreshItem(i);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::EmptyTasks() {
|
||
unsigned int i;
|
||
unsigned int j;
|
||
for (i=0; i<m_TaskGroups.size(); i++) {
|
||
for (j=0; j<m_TaskGroups[i]->m_Tasks.size(); j++) {
|
||
delete m_TaskGroups[i]->m_Tasks[j];
|
||
}
|
||
m_TaskGroups[i]->m_Tasks.clear();
|
||
delete m_TaskGroups[i];
|
||
}
|
||
m_TaskGroups.clear();
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::ClearSavedSelections() {
|
||
m_arrSelectedKeys1.Clear();
|
||
m_arrSelectedKeys2.Clear();
|
||
}
|
||
|
||
|
||
// Save the key values of the currently selected rows for later restore
|
||
void CBOINCBaseView::SaveSelections() {
|
||
if (!_IsSelectionManagementNeeded()) {
|
||
return;
|
||
}
|
||
|
||
m_arrSelectedKeys1.Clear();
|
||
m_arrSelectedKeys2.Clear();
|
||
m_bIgnoreUIEvents = true;
|
||
int i = -1;
|
||
while (1) {
|
||
i = m_pListPane->GetNextSelected(i);
|
||
if (i < 0) break;
|
||
m_arrSelectedKeys1.Add(GetKeyValue1(i));
|
||
m_arrSelectedKeys2.Add(GetKeyValue2(i));
|
||
}
|
||
m_bIgnoreUIEvents = false;
|
||
}
|
||
|
||
// Select all rows with formerly selected data based on key values
|
||
//
|
||
// Each RPC may add (insert) or delete items from the list, so
|
||
// the selected row numbers may now point to different data.
|
||
// We called SaveSelections() before updating the underlying
|
||
// data; this routine finds the data corresponding to each
|
||
// previous selection and makes any adjustments to ensure that
|
||
// the rows containing the originally selected data are selected.
|
||
void CBOINCBaseView::RestoreSelections() {
|
||
if (!_IsSelectionManagementNeeded()) {
|
||
return;
|
||
}
|
||
|
||
// To minimize flicker, this method selects or deselects only
|
||
// those rows which actually need their selection status changed.
|
||
// First, get a list of which rows should be selected
|
||
int i, j, m = 0, newCount = 0, oldCount = (int)m_arrSelectedKeys1.size();
|
||
bool found;
|
||
wxArrayInt arrSelRows;
|
||
for(i=0; i< oldCount; ++i) {
|
||
int index = FindRowIndexByKeyValues(m_arrSelectedKeys1[i], m_arrSelectedKeys2[i]);
|
||
if(index >= 0) {
|
||
arrSelRows.Add(index);
|
||
}
|
||
}
|
||
newCount = (int)arrSelRows.GetCount();
|
||
|
||
// Step through the currently selected row numbers and for each one determine
|
||
// whether it should remain selected.
|
||
m_bIgnoreUIEvents = true;
|
||
i = -1;
|
||
while (1) {
|
||
found = false;
|
||
i = m_pListPane->GetNextSelected(i);
|
||
if (i < 0) break;
|
||
m = (int)arrSelRows.GetCount();
|
||
for (j=0; j<m; ++j) {
|
||
if (arrSelRows[j] == i) {
|
||
arrSelRows.RemoveAt(j); // We have handled this one so remove from list
|
||
found = true; // Already selected, so no change needed
|
||
break;
|
||
}
|
||
}
|
||
if (!found) {
|
||
m_pListPane->SelectRow(i, false); // This row should no longer be selected
|
||
}
|
||
}
|
||
|
||
// Now select those rows which were not previously selected but should now be
|
||
m = (int)arrSelRows.GetCount();
|
||
for (j=0; j<m; ++j) {
|
||
m_pListPane->SelectRow(arrSelRows[j], true);
|
||
}
|
||
m_bIgnoreUIEvents = false;
|
||
|
||
if (oldCount != newCount) {
|
||
m_bForceUpdateSelection = true; // OnListRender() will call UpdateSelection()
|
||
}
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::ClearSelections() {
|
||
if (!m_pListPane) return;
|
||
|
||
m_bIgnoreUIEvents = true;
|
||
int i = -1;
|
||
while (1) {
|
||
i = m_pListPane->GetNextSelected(i);
|
||
if (i < 0) break;
|
||
m_pListPane->SelectRow(i, false);
|
||
}
|
||
m_bIgnoreUIEvents = false;
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::PreUpdateSelection(){
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::UpdateSelection(){
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::PostUpdateSelection(){
|
||
wxASSERT(m_pTaskPane);
|
||
m_pTaskPane->UpdateControls();
|
||
Layout();
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::UpdateWebsiteSelection(long lControlGroup, PROJECT* project){
|
||
unsigned int i;
|
||
CTaskItemGroup* pGroup = NULL;
|
||
CTaskItem* pItem = NULL;
|
||
|
||
wxASSERT(m_pTaskPane);
|
||
wxASSERT(m_pListPane);
|
||
|
||
if (m_bForceUpdateSelection) {
|
||
|
||
// Update the websites list
|
||
//
|
||
if (m_TaskGroups.size() > 1) {
|
||
|
||
// Delete task group, objects, and controls.
|
||
pGroup = m_TaskGroups[lControlGroup];
|
||
|
||
m_pTaskPane->DeleteTaskGroupAndTasks(pGroup);
|
||
for (i=0; i<pGroup->m_Tasks.size(); i++) {
|
||
delete pGroup->m_Tasks[i];
|
||
}
|
||
pGroup->m_Tasks.clear();
|
||
delete pGroup;
|
||
|
||
pGroup = NULL;
|
||
|
||
m_TaskGroups.erase( m_TaskGroups.begin() + 1 );
|
||
}
|
||
|
||
// If something is selected create the tasks and controls
|
||
//
|
||
if (m_pListPane->GetSelectedItemCount()) {
|
||
if (project) {
|
||
// Create the web sites task group
|
||
pGroup = new CTaskItemGroup( _("Project web pages") );
|
||
m_TaskGroups.push_back( pGroup );
|
||
|
||
// Default project url
|
||
pItem = new CTaskItem(
|
||
wxString("Home page", wxConvUTF8),
|
||
wxString(project->project_name.c_str(), wxConvUTF8) + wxT(" web site"),
|
||
wxString(project->master_url, wxConvUTF8),
|
||
ID_TASK_PROJECT_WEB_PROJDEF_MIN
|
||
);
|
||
pGroup->m_Tasks.push_back(pItem);
|
||
|
||
|
||
// Project defined urls
|
||
for (i=0;(i<project->gui_urls.size())&&(i<=ID_TASK_PROJECT_WEB_PROJDEF_MAX);i++) {
|
||
pItem = new CTaskItem(
|
||
wxGetTranslation(wxString(project->gui_urls[i].name.c_str(), wxConvUTF8)),
|
||
wxGetTranslation(wxString(project->gui_urls[i].description.c_str(), wxConvUTF8)),
|
||
wxString(project->gui_urls[i].url.c_str(), wxConvUTF8),
|
||
ID_TASK_PROJECT_WEB_PROJDEF_MIN + 1 + i
|
||
);
|
||
pGroup->m_Tasks.push_back(pItem);
|
||
}
|
||
}
|
||
}
|
||
|
||
m_bForceUpdateSelection = false;
|
||
}
|
||
}
|
||
|
||
|
||
// Make sure task pane background is properly erased
|
||
void CBOINCBaseView::RefreshTaskPane() {
|
||
if (m_pTaskPane) {
|
||
m_pTaskPane->Refresh(true);
|
||
}
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::_IsSelectionManagementNeeded() {
|
||
return IsSelectionManagementNeeded();
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::IsSelectionManagementNeeded() {
|
||
return false;
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::_EnsureLastItemVisible() {
|
||
return EnsureLastItemVisible();
|
||
}
|
||
|
||
|
||
bool CBOINCBaseView::EnsureLastItemVisible() {
|
||
return false;
|
||
}
|
||
|
||
|
||
double CBOINCBaseView::GetProgressValue(long) {
|
||
return 0.0;
|
||
}
|
||
|
||
|
||
wxString CBOINCBaseView::GetProgressText( long ) {
|
||
return wxEmptyString;
|
||
}
|
||
|
||
|
||
void CBOINCBaseView::append_to_status(wxString& existing, const wxChar* additional) {
|
||
if (existing.size() == 0) {
|
||
existing = additional;
|
||
} else {
|
||
existing = existing + wxT(", ") + additional;
|
||
}
|
||
}
|
||
|
||
|
||
// HTML Entity Conversion:
|
||
// http://www.webreference.com/html/reference/character/
|
||
// Completed: The ISO Latin 1 Character Set
|
||
//
|
||
wxString CBOINCBaseView::HtmlEntityEncode(wxString strRaw) {
|
||
wxString strEncodedHtml(strRaw);
|
||
|
||
#ifdef __WXMSW__
|
||
strEncodedHtml.Replace(wxT("&"), wxT("&"), true);
|
||
strEncodedHtml.Replace(wxT("\""), wxT("""), true);
|
||
strEncodedHtml.Replace(wxT("<"), wxT("<"), true);
|
||
strEncodedHtml.Replace(wxT(">"), wxT(">"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("‚"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ƒ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("„"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("…"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("†"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("‡"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Š"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Œ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("‘"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("’"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("“"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("”"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("•"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("–"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("—"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD><EFBFBD>~"), wxT("˜"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("™"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("š"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("œ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ÿ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¡"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¢"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("£"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¤"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¥"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¦"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("§"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¨"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("©"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ª"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("«"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¬"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("®"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¯"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("°"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("±"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("²"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("³"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("´"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("µ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¶"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("·"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¸"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¹"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("º"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("»"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¼"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("½"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¾"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("¿"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("À"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Á"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Â"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ã"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ä"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Å"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Æ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ç"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("È"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("É"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ê"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ë"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ì"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Í"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Î"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ï"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ð"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ñ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ò"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ó"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ô"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Õ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ö"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("×"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ø"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ù"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ú"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Û"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ü"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Ý"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("Þ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ß"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("à"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("á"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("â"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ã"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ä"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("å"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("æ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ç"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("è"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("é"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ê"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ë"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ì"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("í"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("î"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ï"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ð"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ñ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ò"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ó"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ô"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("õ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ö"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("÷"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ø"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ù"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ú"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("û"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ü"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ý"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("þ"), true);
|
||
strEncodedHtml.Replace(wxT("<EFBFBD>"), wxT("ÿ"), true);
|
||
#endif
|
||
|
||
return strEncodedHtml;
|
||
}
|
||
|
||
wxString CBOINCBaseView::HtmlEntityDecode(wxString strRaw) {
|
||
wxString strDecodedHtml(strRaw);
|
||
|
||
if (0 <= strDecodedHtml.Find(wxT("&"))) {
|
||
#ifdef __WXMSW__
|
||
strDecodedHtml.Replace(wxT("&"), wxT("&"), true);
|
||
strDecodedHtml.Replace(wxT("""), wxT("\""), true);
|
||
strDecodedHtml.Replace(wxT("<"), wxT("<"), true);
|
||
strDecodedHtml.Replace(wxT(">"), wxT(">"), true);
|
||
strDecodedHtml.Replace(wxT("‚"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ƒ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("„"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("…"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("†"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("‡"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Š"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Œ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("‘"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("’"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("“"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("”"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("•"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("–"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("—"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("˜"), wxT("<EFBFBD><EFBFBD>~"), true);
|
||
strDecodedHtml.Replace(wxT("™"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("š"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("œ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ÿ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¡"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¢"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("£"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¤"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¥"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¦"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("§"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¨"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("©"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ª"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("«"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¬"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("®"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¯"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("°"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("±"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("²"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("³"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("´"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("µ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¶"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("·"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¸"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¹"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("º"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("»"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¼"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("½"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¾"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("¿"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("À"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Á"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Â"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ã"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ä"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Å"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Æ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ç"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("È"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("É"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ê"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ë"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ì"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Í"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Î"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ï"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ð"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ñ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ò"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ó"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ô"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Õ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ö"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("×"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ø"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ù"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ú"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Û"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ü"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Ý"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("Þ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ß"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("à"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("á"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("â"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ã"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ä"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("å"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("æ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ç"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("è"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("é"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ê"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ë"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ì"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("í"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("î"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ï"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ð"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ñ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ò"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ó"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ô"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("õ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ö"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("÷"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ø"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ù"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ú"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("û"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ü"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ý"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("þ"), wxT("<EFBFBD>"), true);
|
||
strDecodedHtml.Replace(wxT("ÿ"), wxT("<EFBFBD>"), true);
|
||
#endif
|
||
}
|
||
|
||
return strDecodedHtml;
|
||
}
|
||
|