// MultiLanguage.cpp: implementation of the CMultiLanguage class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cp_main.h"
#include "MultiLanguage.h"
#include "shared/TextConvert.h"
#include "shared/TextConvert.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMultiLanguage::CMultiLanguage()
{
m_csAuthor = "";
m_csLangCode = "";
m_lFileVersion = 0;
m_bOnlyGetHeader = false;
}
CMultiLanguage::~CMultiLanguage()
{
ClearArrays();
}
void CMultiLanguage::ClearArrays()
{
m_csAuthor = "";
m_csLangCode = "";
m_lFileVersion = 0;
m_bOnlyGetHeader = false;
ClearArray(m_RightClickMenu);
ClearArray(m_GroupsRightClickMenu);
ClearArray(m_ClipProperties);
ClearArray(m_OptionsGeneral);
ClearArray(m_OptionsSupportedTypes);
ClearArray(m_OptionsShortcuts);
ClearArray(m_OptionsQuickPaste);
ClearArray(m_OptionsQuickPasteKeyboard);
ClearArray(m_OptionsFriends);
ClearArray(m_OptionsFriendsDetail);
ClearArray(m_OptionsStats);
ClearArray(m_OptionsSupportedTypesAdd);
ClearArray(m_MoveToGroups);
ClearArray(m_TrayIconRightClickMenu);
ClearArray(m_OptionsSheet);
ClearArray(m_OptionsCopyBuffers);
ClearArray(m_GlobalHotKeys);
ClearMap(m_StringMap);
}
void CMultiLanguage::ClearArray(LANGUAGE_ARRAY &Array)
{
INT_PTR size = Array.GetSize();
for(int i = 0; i < size; i++)
{
CLangItem *plItem = Array[i];
delete plItem;
plItem = NULL;
}
Array.RemoveAll();
}
void CMultiLanguage::ClearMap(LANGUAGE_MAP &Map)
{
POSITION pos = Map.GetStartPosition();
CLangItem *plItem;
CString csKey;
while(pos)
{
Map.GetNextAssoc(pos, csKey, plItem);
if(plItem)
{
delete plItem;
plItem = NULL;
}
}
Map.RemoveAll();
}
CString CMultiLanguage::GetString(CString csID, CString csDefault)
{
CLangItem *pItem;
if(m_StringMap.Lookup(csID, pItem) == FALSE)
{
return csDefault;
}
if(pItem->m_csForeignLang.GetLength() <= 0)
return csDefault;
return pItem->m_csForeignLang;
}
CString CMultiLanguage::GetGlobalHotKeyString(CString csID, CString csDefault)
{
INT_PTR size = m_GlobalHotKeys.GetSize();
for(int i = 0; i < size; i++)
{
CLangItem *plItem = m_GlobalHotKeys[i];
if(plItem->m_csID == csID)
{
return plItem->m_csForeignLang;
}
}
return csDefault;
}
CString CMultiLanguage::GetDeleteClipDataString(CString csID, CString csDefault)
{
INT_PTR size = m_DeleteClipData.GetSize();
for(int i = 0; i < size; i++)
{
CLangItem *plItem = m_DeleteClipData[i];
if(plItem->m_csID == csID)
{
return plItem->m_csForeignLang;
}
}
return csDefault;
}
CString CMultiLanguage::GetQuickPasteKeyboardString(int id, CString csDefault)
{
INT_PTR size = m_OptionsQuickPasteKeyboard.GetSize();
for (int i = 0; i < size; i++)
{
CLangItem *plItem = m_OptionsQuickPasteKeyboard[i];
if (plItem->m_nID == id)
{
return plItem->m_csForeignLang;
}
}
return csDefault;
}
bool CMultiLanguage::UpdateRightClickMenu(CMenu *pMenu)
{
return UpdateMenuToLanguage(pMenu, m_RightClickMenu);
}
bool CMultiLanguage::UpdateGroupsRightClickMenu(CMenu *pMenu)
{
return UpdateMenuToLanguage(pMenu, m_GroupsRightClickMenu);
}
bool CMultiLanguage::UpdateTrayIconRightClickMenu(CMenu *pMenu)
{
return UpdateMenuToLanguage(pMenu, m_TrayIconRightClickMenu);
}
bool CMultiLanguage::UpdateClipProperties(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_ClipProperties);
}
bool CMultiLanguage::UpdateOptionGeneral(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsGeneral);
}
bool CMultiLanguage::UpdateOptionSupportedTypes(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsSupportedTypes);
}
bool CMultiLanguage::UpdateOptionShortcuts(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsShortcuts);
}
bool CMultiLanguage::UpdateOptionQuickPaste(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsQuickPaste);
}
bool CMultiLanguage::UpdateOptionQuickPasteKeyboard(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsQuickPasteKeyboard);
}
bool CMultiLanguage::UpdateOptionFriends(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsFriends);
}
bool CMultiLanguage::UpdateOptionFriendsDetail(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsFriendsDetail);
}
bool CMultiLanguage::UpdateOptionStats(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsStats);
}
bool CMultiLanguage::UpdateOptionSupportedTypesAdd(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsSupportedTypesAdd);
}
bool CMultiLanguage::UpdateMoveToGroups(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_MoveToGroups);
}
bool CMultiLanguage::UpdateOptionsSheet(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsSheet);
}
bool CMultiLanguage::UpdateOptionCopyBuffers(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_OptionsCopyBuffers);
}
bool CMultiLanguage::UpdateGlobalHotKeys(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_GlobalHotKeys);
}
bool CMultiLanguage::UpdateDeleteClipData(CWnd *pParent)
{
return UpdateWindowToLanguage(pParent, m_DeleteClipData);
}
bool CMultiLanguage::UpdateMenuToLanguage(CMenu *pMenu, LANGUAGE_ARRAY &Array)
{
INT_PTR size = Array.GetSize();
for(int i = 0; i < size; i++)
{
CLangItem *plItem = Array[i];
if(plItem->m_csForeignLang.GetLength() > 0)
{
if(plItem->m_nID > 0)
{
pMenu->ModifyMenu(plItem->m_nID, MF_BYCOMMAND, plItem->m_nID, plItem->m_csForeignLang);
}
else
{
//If an item doesn't have a menu id then its a group menu
//just search for the text and update the text with the foreign text
int nMenuPos;
CMenu *pNewMenu = GetMenuPos(pMenu, plItem->m_csEnglishLang, nMenuPos);
if(pNewMenu)
{
pNewMenu->ModifyMenu(nMenuPos, MF_BYPOSITION, -1, plItem->m_csForeignLang);
}
}
}
}
return true;
}
bool CMultiLanguage::UpdateWindowToLanguage(CWnd *pParent, LANGUAGE_ARRAY &Array)
{
INT_PTR size = Array.GetSize();
for(int i = 0; i < size; i++)
{
CLangItem *plItem = Array[i];
if(plItem->m_csForeignLang.GetLength() > 0)
{
if(plItem->m_nID > 0)
{
CWnd *pWnd = pParent->GetDlgItem(plItem->m_nID);
if(pWnd)
{
pWnd->SetWindowText(plItem->m_csForeignLang);
}
}
//If item id is -1 then set the title for the dialog
else if(plItem->m_nID == -1)
{
pParent->SetWindowText(plItem->m_csForeignLang);
}
}
}
return true;
}
CMenu * CMultiLanguage::GetMenuPos(CMenu *pMenu, const CString &csLookingForMenuText, int &nMenuPos, bool returnChildIfOne)
{
CMenu *pSubMenu;
CString csMenuText;
int nCount = pMenu->GetMenuItemCount();
for(int i = 0; i < nCount; i++)
{
pMenu->GetMenuString(i, csMenuText, MF_BYPOSITION);
if(csMenuText == csLookingForMenuText)
{
nMenuPos = i;
if (returnChildIfOne)
{
pSubMenu = pMenu->GetSubMenu(i);
if (pSubMenu != NULL)
{
return pSubMenu;
}
}
return pMenu;
}
pSubMenu = pMenu->GetSubMenu(i);
if(pSubMenu)
{
CMenu *pMenuReturn = GetMenuPos(pSubMenu, csLookingForMenuText, nMenuPos, returnChildIfOne);
if(pMenuReturn)
return pMenuReturn;
}
}
return NULL;
}
bool CMultiLanguage::LoadLanguageFile(CString csFile)
{
m_csLastError = "";
CString csPath = CGetSetOptions::GetPath(PATH_LANGUAGE);
csPath += csFile;
csPath += ".xml";
ClearArrays();
if(csFile.GetLength() <= 0)
{
m_csLastError = "Language file is blank";
return false;
}
CStringA csPathA = CTextConvert::UnicodeToAnsi(csPath);
TiXmlDocument doc(csPathA);
if(!doc.LoadFile())
{
m_csLastError.Format(_T("Error loading file %s - reason = %s, Line: %d, column: %d"), csFile, CTextConvert::AnsiToUnicode(doc.ErrorDesc()), doc.ErrorRow(), doc.ErrorCol());
Log(m_csLastError);
return false;
}
TiXmlElement *ItemHeader = doc.FirstChildElement("Ditto_Language_File");
if(!ItemHeader)
{
m_csLastError.Format(_T("Error finding the section Ditto_Language_File"));
ASSERT(!m_csLastError);
Log(m_csLastError);
return false;
}
CString csVersion = ItemHeader->Attribute("Version");
m_lFileVersion = ATOI(csVersion);
m_csAuthor = ItemHeader->Attribute("Author");
m_csNotes = ItemHeader->Attribute("Notes");
m_csLangCode = ItemHeader->Attribute("LanguageCode");
if(m_bOnlyGetHeader)
return true;
bool bRet = LoadSection(*ItemHeader, m_RightClickMenu, "Ditto_Right_Click_Menu");
bRet = LoadSection(*ItemHeader, m_GroupsRightClickMenu, "Ditto_Groups_Right_Click_Menu");
bRet = LoadSection(*ItemHeader, m_OptionsGeneral, "Ditto_Options_General");
bRet = LoadSection(*ItemHeader, m_ClipProperties, "Ditto_Clip_Properties");
bRet = LoadSection(*ItemHeader, m_OptionsSupportedTypes, "Ditto_Options_Supported_Types");
bRet = LoadSection(*ItemHeader, m_OptionsShortcuts, "Ditto_Options_Shortcuts");
bRet = LoadSection(*ItemHeader, m_OptionsQuickPaste, "Ditto_Options_Quick_Paste");
bRet = LoadSection(*ItemHeader, m_OptionsQuickPasteKeyboard, "Ditto_Options_Quick_Paste_Keyboard");
bRet = LoadSection(*ItemHeader, m_OptionsFriends, "Ditto_Options_Friends");
bRet = LoadSection(*ItemHeader, m_OptionsFriendsDetail, "Ditto_Options_Friends_Detail");
bRet = LoadSection(*ItemHeader, m_OptionsStats, "Ditto_Options_Stats");
bRet = LoadSection(*ItemHeader, m_OptionsSupportedTypesAdd, "Ditto_Options_Supported_Types_Add");
bRet = LoadSection(*ItemHeader, m_MoveToGroups, "Ditto_Move_To_Groups");
bRet = LoadSection(*ItemHeader, m_OptionsSheet, "Ditto_Options_Sheet");
bRet = LoadSection(*ItemHeader, m_TrayIconRightClickMenu, "Ditto_Tray_Icon_Menu");
bRet = LoadSection(*ItemHeader, m_OptionsCopyBuffers, "Ditto_Options_CopyBuffers");
bRet = LoadSection(*ItemHeader, m_GlobalHotKeys, "Ditto_GlobalHotKeys");
bRet = LoadSection(*ItemHeader, m_DeleteClipData, "Ditto_DeleteClipData");
bRet = LoadStringTableSection(*ItemHeader, m_StringMap, "Ditto_String_Table");
return true;
}
bool CMultiLanguage::LoadSection(TiXmlNode &doc, LANGUAGE_ARRAY &Array, CString csSection)
{
CStringA csSectionA = CTextConvert::UnicodeToAnsi(csSection);
TiXmlNode *node = doc.FirstChild(csSectionA);
if(!node)
{
m_csLastError.Format(_T("Error finding the section %s"), csSection);
//ASSERT(!m_csLastError);
Log(m_csLastError);
return false;
}
TiXmlNode* ForeignNode;
CString csID;
CString csLineFeed("\n");
TiXmlElement *ItemElement = node->FirstChildElement();
//load all items for this section
//they look like
//
while(ItemElement)
{
ForeignNode = ItemElement->FirstChild();
if(ForeignNode)
{
CLangItem *plItem = new CLangItem;
if(plItem)
{
plItem->m_csEnglishLang = ItemElement->Attribute("English_Text");
csID = ItemElement->Attribute("ID");
plItem->m_nID = ATOI(csID);
if(plItem->m_nID == 0)
{
plItem->m_csID = csID;
}
LPCSTR Value = ForeignNode->Value();
plItem->m_csForeignLang = CTextConvert::Utf8ToUnicode(Value);
//Replace the literal "\n" with line feeds
plItem->m_csForeignLang.Replace(_T("\\n"), csLineFeed);
Array.Add(plItem);
}
}
ItemElement = ItemElement->NextSiblingElement();
}
return true;
}
bool CMultiLanguage::LoadStringTableSection(TiXmlNode &doc, LANGUAGE_MAP &Map, CString csSection)
{
CStringA csSectionA = CTextConvert::UnicodeToAnsi(csSection);
TiXmlNode *node = doc.FirstChild(csSectionA);
if(!node)
{
CString cs;
cs.Format(_T("Error finding the section %s"), csSection);
ASSERT(!cs);
Log(cs);
return false;
}
CString csLineFeed("\n");
TiXmlNode* ForeignNode;
TiXmlElement *ItemElement = node->FirstChildElement();
//load all items for this section
//they look like
//
while(ItemElement)
{
CLangItem *plItem = new CLangItem;
plItem->m_csEnglishLang = ItemElement->Attribute("English_Text");
plItem->m_csID = ItemElement->Attribute("ID");
ForeignNode = ItemElement->FirstChild();
if(ForeignNode)
{
LPCSTR Value = ForeignNode->Value();
plItem->m_csForeignLang = CTextConvert::Utf8ToUnicode(Value);
//Replace the literal "\n" with line feeds
plItem->m_csForeignLang.Replace(_T("\\n"), csLineFeed);
}
Map.SetAt(plItem->m_csID, plItem);
ItemElement = ItemElement->NextSiblingElement();
}
return true;
}