NeroPluginNLS.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. /******************************************************************************
  2. |* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. |* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. |* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. |* PARTICULAR PURPOSE.
  6. |*
  7. |* Copyright 1995-2005 Nero AG. All Rights Reserved.
  8. |*-----------------------------------------------------------------------------
  9. |* NeroSDK / AudioPluginManager
  10. |*
  11. |* FILE: NeroPluginNLS.h
  12. |*
  13. |* PURPOSE: Implementation of NLS support for Nero plugins
  14. ******************************************************************************/
  15. #include "stdafx.h"
  16. #include "NeroPluginNls.h"
  17. //#include "resource.h"
  18. #define ESPERANTO_TITLE "[ENG]"
  19. #define NLS_RES_TYPE _T("NLSData")
  20. #define MAX_STRING 10000
  21. #define MAX_CLASS_NAME 500
  22. #define MAX_MENU_ITEM_SIZE 500
  23. struct LANGINFO
  24. {
  25. LANGID m_LangID;
  26. const char *m_szAbbrev;
  27. }
  28. g_LangInfos[] =
  29. {
  30. { MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), "CHS" },
  31. { MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL), "CHT" },
  32. { MAKELANGID(LANG_DANISH, SUBLANG_NEUTRAL), "DAN" },
  33. { MAKELANGID(LANG_GERMAN, SUBLANG_NEUTRAL), "DEU" },
  34. { MAKELANGID(LANG_GREEK, SUBLANG_NEUTRAL), "ELL" },
  35. { MAKELANGID(LANG_SPANISH, SUBLANG_NEUTRAL), "ESP" },
  36. { MAKELANGID(LANG_FINNISH, SUBLANG_NEUTRAL), "FIN" },
  37. { MAKELANGID(LANG_FRENCH, SUBLANG_NEUTRAL), "FRA" },
  38. { MAKELANGID(LANG_HUNGARIAN, SUBLANG_NEUTRAL), "HUN" },
  39. { MAKELANGID(LANG_ITALIAN, SUBLANG_NEUTRAL), "ITA" },
  40. { MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL), "JPN" },
  41. { MAKELANGID(LANG_KOREAN, SUBLANG_NEUTRAL), "KOR" },
  42. { MAKELANGID(LANG_DUTCH, SUBLANG_NEUTRAL), "NDL" },
  43. { MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL), "NOR" },
  44. { MAKELANGID(LANG_POLISH, SUBLANG_NEUTRAL), "PLK" },
  45. { MAKELANGID(LANG_PORTUGUESE, SUBLANG_NEUTRAL), "PTG" },
  46. { MAKELANGID(LANG_ROMANIAN, SUBLANG_NEUTRAL), "ROM" },
  47. { MAKELANGID(LANG_RUSSIAN, SUBLANG_NEUTRAL), "RUS" },
  48. { MAKELANGID(LANG_SLOVENIAN, SUBLANG_NEUTRAL), "SLV" },
  49. { MAKELANGID(LANG_SWEDISH, SUBLANG_NEUTRAL), "SVE" },
  50. { MAKELANGID(LANG_UKRAINIAN, SUBLANG_NEUTRAL), "UKR" },
  51. { MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), "ENG" },
  52. { MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), "ENG" },
  53. { MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), "ENU" },
  54. { MAKELANGID(LANG_UKRAINIAN, SUBLANG_DEFAULT), "UKR" },
  55. { MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT), "JPN" },
  56. { MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT), "RUS" },
  57. { MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), "DEU" },
  58. { MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT), "ESP" },
  59. { MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), "FRA" },
  60. { MAKELANGID(LANG_ITALIAN, SUBLANG_DEFAULT), "ITA" },
  61. { MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE), "PTG" },
  62. { MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT), "DAN" },
  63. { MAKELANGID(LANG_DUTCH, SUBLANG_DEFAULT), "NLD" },
  64. { MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL), "CHT" },
  65. { MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), "CHS" },
  66. { MAKELANGID(LANG_FINNISH, SUBLANG_DEFAULT), "FIN" },
  67. { MAKELANGID(LANG_HUNGARIAN, SUBLANG_DEFAULT), "HUN" },
  68. { MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), "PLK" },
  69. { MAKELANGID(LANG_SWEDISH, SUBLANG_DEFAULT), "SVE" },
  70. { MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL), "NOR" },
  71. { MAKELANGID(LANG_CZECH, SUBLANG_DEFAULT), "CSY" },
  72. { MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT), "KOR" },
  73. { MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN), "PTB" },
  74. { MAKELANGID(LANG_SLOVAK, SUBLANG_DEFAULT), "SKY" },
  75. { MAKELANGID(LANG_SLOVENIAN, SUBLANG_DEFAULT), "SLV" },
  76. { MAKELANGID(LANG_GREEK, SUBLANG_DEFAULT), "ELL" },
  77. { MAKELANGID(LANG_TURKISH, SUBLANG_DEFAULT), "TRK" },
  78. { MAKELANGID(LANG_THAI, SUBLANG_DEFAULT), "THA" },
  79. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_CHILE), "ESL" },
  80. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), "ESP" },
  81. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), "ESP" },
  82. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA), "ESL" },
  83. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_BOLIVIA), "ESL" },
  84. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_COLOMBIA), "ESL" },
  85. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_COSTA_RICA), "ESL" },
  86. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_DOMINICAN_REPUBLIC), "ESL" },
  87. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_ECUADOR), "ESL" },
  88. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_GUATEMALA), "ESL" },
  89. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_HONDURAS), "ESL" },
  90. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MEXICAN), "ESL" },
  91. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_NICARAGUA), "ESL" },
  92. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_PANAMA), "ESL" },
  93. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_PARAGUAY), "ESL" },
  94. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_PERU), "ESL" },
  95. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_PUERTO_RICO), "ESL" },
  96. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_EL_SALVADOR), "ESL" },
  97. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_URUGUAY), "ESL" },
  98. { MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_VENEZUELA), "ESL" },
  99. { MAKELANGID(LANG_CROATIAN, SUBLANG_DEFAULT), "HRV" },
  100. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_SAUDI_ARABIA), "ARA" },
  101. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_ALGERIA), "ARA" },
  102. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_BAHRAIN), "ARA" },
  103. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_EGYPT), "ARA" },
  104. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_IRAQ), "ARA" },
  105. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_JORDAN), "ARA" },
  106. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_KUWAIT), "ARA" },
  107. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_LEBANON), "ARA" },
  108. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_LIBYA), "ARA" },
  109. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_MOROCCO), "ARA" },
  110. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_OMAN), "ARA" },
  111. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_QATAR), "ARA" },
  112. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_SYRIA), "ARA" },
  113. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_TUNISIA), "ARA" },
  114. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_UAE), "ARA" },
  115. { MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_YEMEN), "ARA" },
  116. { MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT), "HEB" }
  117. };
  118. // Creates the translator object and returns it's pointer.
  119. CTranslator * CreateTranslator(WORD wResID, LANGID id)
  120. {
  121. const char *szLang = "ENG";
  122. for(int i =0; i < (sizeof(g_LangInfos) / sizeof(LANGINFO)); i++)
  123. {
  124. if(id == g_LangInfos[i].m_LangID)
  125. szLang = g_LangInfos[i].m_szAbbrev;
  126. }
  127. CTranslator *pTranslator = new CTranslator(wResID, szLang);
  128. ASSERT(pTranslator);
  129. return pTranslator;
  130. }
  131. // Destroys the translator object.
  132. void DestroyTranslator(CTranslator *pTranslator)
  133. {
  134. if(pTranslator)
  135. delete pTranslator;
  136. else
  137. {
  138. ASSERT(FALSE);
  139. }
  140. }
  141. // Tries to find a translation for the expression stored in "szWord" and writes
  142. // it to "*pcs". If the translation cannot be found, copies szWord to *pcs.
  143. void CTranslator::GetWordTranslation(const char *szWord, CString *pcs)
  144. {
  145. if(!(szWord && pcs))
  146. {
  147. ASSERT(FALSE);
  148. return;
  149. }
  150. CString csWord;
  151. for(const char *pc = szWord; *pc; pc++)
  152. {
  153. if(*pc != '&')
  154. csWord += *pc;
  155. }
  156. szWord = csWord;
  157. for(int i = 0, iLen = m_strarEng.GetSize(); i < iLen; i++)
  158. {
  159. if(m_strarEng[i] == szWord)
  160. {
  161. if(m_strarTgt.GetSize() > i)
  162. {
  163. CString csTemp = m_strarTgt[i];
  164. if(!csTemp.IsEmpty())
  165. {
  166. *pcs = csTemp;
  167. return;
  168. }
  169. }
  170. }
  171. }
  172. *pcs = szWord;
  173. }
  174. // Recursively translates all the child windows of hMainWnd window i.e. their
  175. // window texts and contents of list and combo boxes.
  176. void CTranslator::TranslateWindow(HWND hMainWnd)
  177. {
  178. // The window itself
  179. char szText[1000];
  180. ::GetWindowText(hMainWnd, szText, 1000);
  181. CString csTranslation;
  182. GetWordTranslation(szText, &csTranslation);
  183. SetWindowText(hMainWnd, csTranslation);
  184. CTranslateAction *pAction = NULL;
  185. if(m_History.Lookup((void*)hMainWnd, (void*&)pAction))
  186. {
  187. // This means that the window is translated for the second time.
  188. ASSERT(FALSE);
  189. }
  190. else
  191. // Everything is OK, the window is not translated yet.
  192. {
  193. pAction = new CTranslateAction(hMainWnd, szText);
  194. m_History.SetAt((void*)hMainWnd, pAction);
  195. }
  196. ASSERT(pAction);
  197. // Container controls
  198. ::GetClassName(hMainWnd, szText, 1000);
  199. // We cannot translate sorted combo boxes
  200. if(!strcmpi(szText, "COMBOBOX") &&
  201. !(::GetWindowLong(hMainWnd, GWL_STYLE) & CBS_SORT))
  202. {
  203. CComboBox *pCombo = (CComboBox*)CWnd::FromHandle(hMainWnd);
  204. int iCurSel = pCombo->GetCurSel();
  205. for(int i = 0, iLen = pCombo->GetCount(); i < iLen; i++)
  206. {
  207. CString csPrevText;
  208. pCombo->GetLBText(i, csPrevText);
  209. GetWordTranslation(csPrevText, &csTranslation);
  210. DWORD dw = pCombo->GetItemData(i);
  211. pCombo->DeleteString(i);
  212. pCombo->InsertString(i, csTranslation);
  213. pCombo->SetItemData(i, dw);
  214. if (iCurSel == i)
  215. pCombo->SetCurSel(iCurSel);
  216. pAction->AddSubItemAction(i, csPrevText);
  217. }
  218. }
  219. // We cannot translate sorted list boxes
  220. if(!strcmpi(szText, "LISTBOX") &&
  221. !(::GetWindowLong(hMainWnd, GWL_STYLE) & LBS_SORT))
  222. {
  223. CListBox *pLB = (CListBox*)CWnd::FromHandle(hMainWnd);
  224. int iCurSel = pLB->GetCurSel();
  225. for(int i = 0, iLen = pLB->GetCount(); i < iLen; i++)
  226. {
  227. CString csPrevText;
  228. pLB->GetText(i, csPrevText);
  229. GetWordTranslation(csPrevText, &csTranslation);
  230. DWORD dw = pLB->GetItemData(i);
  231. pLB->DeleteString(i);
  232. pLB->InsertString(i, csTranslation);
  233. pLB->SetItemData(i, dw);
  234. pAction->AddSubItemAction(i, csPrevText);
  235. }
  236. pLB->SetCurSel(iCurSel);
  237. }
  238. // And child windows
  239. for(HWND hWnd = ::GetWindow(hMainWnd, GW_CHILD|GW_HWNDFIRST); hWnd;
  240. hWnd = ::GetWindow(hWnd, GW_HWNDNEXT))
  241. {
  242. TranslateWindow(hWnd);
  243. }
  244. }
  245. void CTranslator::TranslateMenu(HMENU hMenu)
  246. {
  247. for(int i = 0, iCount = GetMenuItemCount(hMenu); i < iCount; i++)
  248. {
  249. char szItem[MAX_MENU_ITEM_SIZE];
  250. if(GetMenuString( hMenu,
  251. i,
  252. szItem,
  253. sizeof(szItem),
  254. MF_BYPOSITION))
  255. {
  256. CString csTranslation;
  257. GetWordTranslation(szItem, &csTranslation);
  258. ModifyMenu(hMenu, i, MF_BYPOSITION|MF_STRING, GetMenuItemID(hMenu, i),
  259. csTranslation);
  260. }
  261. HMENU hSubMenu = GetSubMenu(hMenu, i);
  262. if(hSubMenu)
  263. TranslateMenu(hSubMenu);
  264. }
  265. }
  266. // This class doesn't have a default constructor. It must be created by this one
  267. // to initialize it. wResID is the ID of resource containing the translation
  268. // text.
  269. CTranslator::CTranslator(WORD wResID, const char *szLang)
  270. : m_csLang (szLang)
  271. {
  272. HINSTANCE hInst = AfxGetInstanceHandle();
  273. HRSRC hRes = NULL;
  274. HGLOBAL hResData = NULL;
  275. try
  276. {
  277. CString csRes;
  278. csRes.Format("#%d", wResID);
  279. hRes = FindResource(hInst, csRes, NLS_RES_TYPE);
  280. if(!hRes)
  281. throw 0;
  282. DWORD dwResSize = SizeofResource(hInst, hRes);
  283. hResData = LoadResource(hInst, hRes);
  284. if(!hResData)
  285. throw 0;
  286. char *pcRes = (char*)LockResource(hResData);
  287. // Start the parsing of the resource data
  288. enum { Out, English, National} status = Out;
  289. DWORD dwCurPos = 0;
  290. CString csCurWord;
  291. BOOL bEnglishDone = FALSE,
  292. bNationalDone = FALSE;
  293. for(char *pcTemp = pcRes; dwCurPos < dwResSize; dwCurPos++, pcTemp++)
  294. {
  295. if(*pcTemp != '\r' && *pcTemp != '\n' && *pcTemp != '\t')
  296. {
  297. char cNext = pcTemp[1];
  298. if(*pcTemp == '\\' && (cNext == 'n' || cNext == 'r' || cNext == 't'))
  299. {
  300. csCurWord += (cNext == 'n')? '\n': ((cNext == 'r')? '\r': '\t');
  301. dwCurPos++;
  302. pcTemp++;
  303. }
  304. else
  305. csCurWord += *pcTemp;
  306. }
  307. else
  308. {
  309. if(!csCurWord.IsEmpty())
  310. {
  311. if(status == Out)
  312. {
  313. if(!bEnglishDone)
  314. {
  315. if(!csCurWord.CompareNoCase(ESPERANTO_TITLE))
  316. {
  317. status = English;
  318. }
  319. }
  320. if(!bNationalDone && status == Out)
  321. {
  322. CString csTemp;
  323. csTemp.Format("[%s]", szLang);
  324. if(!csCurWord.CompareNoCase(csTemp))
  325. status = National;
  326. }
  327. }
  328. else
  329. {
  330. if (isdigit(csCurWord[0]))
  331. {
  332. int iNumber = 0;
  333. CString csString;
  334. for(const char *pc = csCurWord; *pc; pc++)
  335. {
  336. if (*pc == ' ')
  337. break;
  338. }
  339. iNumber = atoi(csCurWord);
  340. csString = (char*)(pc + 1);
  341. if(status == English)
  342. {
  343. m_strarEng.SetAtGrow(iNumber, csString);
  344. }
  345. else // National
  346. {
  347. m_strarTgt.SetAtGrow(iNumber, csString);
  348. }
  349. }
  350. else
  351. {
  352. status = Out;
  353. pcTemp--;
  354. continue;
  355. }
  356. }
  357. csCurWord.Empty();
  358. }
  359. }
  360. }
  361. }
  362. catch(...)
  363. {
  364. }
  365. }
  366. CTranslator::~CTranslator()
  367. {
  368. for(POSITION pos = m_History.GetStartPosition(); pos; )
  369. {
  370. CTranslateAction *pAction = NULL;
  371. HWND hWnd = NULL;
  372. m_History.GetNextAssoc(pos, (void*&)hWnd, (void*&)pAction);
  373. ASSERT(pAction);
  374. if(pAction)
  375. delete pAction;
  376. }
  377. }
  378. void CTranslator::UndoTranslation()
  379. {
  380. for(POSITION pos = m_History.GetStartPosition(); pos; )
  381. {
  382. CTranslateAction *pAction = NULL;
  383. HWND hWnd = NULL;
  384. m_History.GetNextAssoc(pos, (void*&)hWnd, (void*&)pAction);
  385. ASSERT(pAction);
  386. if(pAction)
  387. pAction->Undo();
  388. }
  389. }
  390. //////////////////////////////////////////////////////////// CTranslateAction //
  391. CTranslateAction::CTranslateAction(HWND hWnd, const char *szPrevText)
  392. : m_csPrevText (szPrevText),
  393. m_hWnd (hWnd),
  394. m_type (ETT_Other),
  395. m_bUndone (false)
  396. {
  397. char szClassName[MAX_CLASS_NAME];
  398. if(!::IsWindow(hWnd) ||
  399. !::GetClassName(hWnd, szClassName, MAX_CLASS_NAME))
  400. {
  401. // We cannot obtain the window class name or the window doesn't exist.
  402. m_type = ETT_Wrong;
  403. return;
  404. }
  405. if(!strcmpi(szClassName, "COMBOBOX"))
  406. m_type = ETT_Combo;
  407. if(!strcmpi(szClassName, "LISTBOX"))
  408. m_type = ETT_ListBox;
  409. }
  410. CTranslateAction::~CTranslateAction()
  411. {
  412. }
  413. void CTranslateAction::Undo()
  414. {
  415. if(m_bUndone)
  416. {
  417. ASSERT(FALSE);
  418. return;
  419. }
  420. ::SetWindowText(m_hWnd, m_csPrevText);
  421. for(int i = 0, iCount = m_SubActions.GetSize(); i < iCount; i++)
  422. {
  423. SUBACTION &sa = m_SubActions[i];
  424. switch(m_type)
  425. {
  426. case ETT_Combo:
  427. {
  428. CComboBox *pCB = (CComboBox*)CWnd::FromHandle(m_hWnd);
  429. DWORD dwItemData = pCB->GetItemData(sa.m_iItem);
  430. pCB->DeleteString(i);
  431. pCB->InsertString(sa.m_iItem, sa.m_csPrevText);
  432. pCB->SetItemData(sa.m_iItem, dwItemData);
  433. break;
  434. }
  435. case ETT_ListBox:
  436. {
  437. CListBox *pLB = (CListBox*)CWnd::FromHandle(m_hWnd);
  438. DWORD dwItemData = pLB->GetItemData(sa.m_iItem);
  439. pLB->DeleteString(i);
  440. pLB->InsertString(sa.m_iItem, sa.m_csPrevText);
  441. pLB->SetItemData(sa.m_iItem, dwItemData);
  442. break;
  443. }
  444. case ETT_Other:
  445. default:
  446. {
  447. break;
  448. }
  449. }
  450. }
  451. m_bUndone = true;
  452. }
  453. void CTranslateAction::AddSubItemAction(int iNum, const char *szPrevText)
  454. {
  455. m_SubActions.Add(SUBACTION(iNum, szPrevText));
  456. }