1
2 #include "studiox_includes.h"
3
4 #ifdef _DEBUG
5 #define new DEBUG_NEW
6 #endif
7
8
9 static CString right_to_left_language_list[] = {
10 L"Arabic",
11 L"Hebrew",
12 L"Kurdish",
13 L"Persian",
14 L"Urdu",
15 L""
16 };
17
18 ///////////////////////////////////////////////////////////////////////////////
string_table()19 string_table::string_table()
20 {
21 m_languages = 0;
22 m_active_language = 0;
23 m_sort_column = 0;
24 m_records.SetSize(0, 10);
25 m_dictionary.SetSize(0, 10);
26 }
27
28 ///////////////////////////////////////////////////////////////////////////////
string_table(const string_table & other)29 string_table::string_table(const string_table &other)
30 {
31 int record;
32 int string;
33
34 Initialize(other.m_languages, other.m_records.GetCount());
35
36 for (record = 0; record < m_records.GetCount(); record++)
37 {
38 m_dictionary[record] = other.m_dictionary[record];
39
40 string_table_record src = other.m_records[record];
41 m_records[record].font_id = src.font_id;
42 m_records[record].id_name = src.id_name;
43 m_records[record].notes = src.notes;
44
45 for (string = 0; string < m_languages; string++)
46 {
47 m_records[record].strings[string] = src.strings[string];
48 char_map.AddToMap(m_records[record].strings[string]);
49 }
50 }
51 m_sort_column = other.m_sort_column;
52 m_active_language = other.m_active_language;
53 }
54
55 ///////////////////////////////////////////////////////////////////////////////
~string_table()56 string_table::~string_table()
57 {
58 CleanupStringTable();
59
60 //Clean up string dictionary
61 m_dictionary.RemoveAll();
62
63 CleanUpMLViewRefereceRecord();
64 }
65
66 ///////////////////////////////////////////////////////////////////////////////
IsRight2LeftLanguage(int language_index)67 BOOL string_table::IsRight2LeftLanguage(int language_index)
68 {
69 studiox_project* project = GetOpenProject();
70
71 if (project)
72 {
73
74 int index = 0;
75
76 while (!right_to_left_language_list[index].IsEmpty())
77 {
78 if (right_to_left_language_list[index] == project->mHeader.languages[language_index].name)
79 {
80 return TRUE;
81 }
82
83 index++;
84 }
85 }
86
87 return FALSE;
88 }
89
90 ///////////////////////////////////////////////////////////////////////////////
EnableDisableRuntimeBidiText(int language_index)91 void string_table::EnableDisableRuntimeBidiText(int language_index)
92 {
93 studiox_project *project = GetOpenProject();
94 if (project->mHeader.languages[language_index].support_bidi_text)
95 {
96 gx_system_bidi_text_enable();
97 }
98 else
99 {
100 gx_system_bidi_text_disable();
101 }
102 }
103
104 ///////////////////////////////////////////////////////////////////////////////
TestGenerateLanguageDirectionTable()105 BOOL string_table::TestGenerateLanguageDirectionTable()
106 {
107 studiox_project* project = GetOpenProject();
108
109 if (project && project_lib_version() >= GX_VERSION_BIDI_TEXT_BASE_DIRECTION_FIX)
110 {
111 for (int language = 0; language < project->mHeader.num_languages; language++)
112 {
113 if (project->mHeader.languages[language].support_bidi_text &&
114 !project->mHeader.languages[language].gen_reordered_bidi_text)
115 {
116 return TRUE;
117 }
118 }
119 }
120
121 return FALSE;
122 }
123
124 ///////////////////////////////////////////////////////////////////////////////
CleanupStringTable()125 void string_table::CleanupStringTable()
126 {
127 int index;
128 char_map.Clear();
129
130 if (m_records.GetCount() > 0)
131 {
132 for (index = 0; index < m_records.GetCount(); index++)
133 {
134 if (m_records[index].strings)
135 {
136 delete [] m_records[index].strings;
137 }
138 }
139 m_records.RemoveAll();
140 }
141
142 m_languages = 0;
143 }
144
145 ///////////////////////////////////////////////////////////////////////////////
CreateId(CString & id_name,CString base_name)146 void string_table::CreateId(CString &id_name, CString base_name)
147 {
148 CString test;
149 CString num;
150 int val = 1;
151
152 if (base_name.IsEmpty())
153 {
154 test = CString("STRING_");
155 }
156 else
157 {
158 test = base_name + CString("_");
159 }
160
161 while(1)
162 {
163 num.Format(_T("%d"), val);
164 id_name = test + num;
165 if (!FindStringIndex(id_name))
166 {
167 return;
168 }
169 val++;
170 }
171 }
172
173 ///////////////////////////////////////////////////////////////////////////////
Initialize(int num_languages,int num_strings)174 void string_table::Initialize(int num_languages, int num_strings)
175 {
176 CleanupStringTable();
177 m_records.SetSize(num_strings, 10);
178 m_dictionary.SetSize(num_strings, 10);
179
180 for (int record = 0; record < num_strings; record++)
181 {
182 m_records[record].strings = new CString[num_languages];
183 }
184 m_languages = num_languages;
185 }
186
187
188 ///////////////////////////////////////////////////////////////////////////////
AddString(CString & Id,CString & str,bool update_guix)189 int string_table::AddString(CString &Id, CString &str, bool update_guix)
190 {
191 string_table_record record;
192 record.id_name = Id;
193 record.strings = new CString[m_languages];
194 record.strings[0] = str;
195 record.font_id = 0;
196 record.notes = "";
197 m_records.Add(record);
198
199 AddToDictionary(Id);
200
201 if (update_guix)
202 {
203 UpdateGuixLanguageTable();
204 }
205
206 return m_records.GetCount() - 1;
207 }
208
209 ///////////////////////////////////////////////////////////////////////////////
ImportString(CString & string_id,CString & src_string,CString & target_string,CString & notes,int src_table_column,int target_table_column)210 void string_table::ImportString(CString &string_id,
211 CString &src_string,
212 CString &target_string,
213 CString ¬es,
214 int src_table_column,
215 int target_table_column)
216 {
217 int string_index = FindStringIndex(string_id);
218
219 if (string_index > 0)
220 {
221 SetString(string_index, target_table_column, target_string, FALSE);
222 }
223 else
224 {
225 string_index = AddString(string_id, CString(""), FALSE);
226 SetString(string_index, src_table_column, src_string, FALSE);
227 SetString(string_index, target_table_column, target_string, FALSE);
228 }
229
230 SetNotes(string_index, notes);
231 }
232
233 ///////////////////////////////////////////////////////////////////////////////
AddString()234 int string_table::AddString()
235 {
236 CString NewId;
237 CreateId(NewId);
238 int string_index = AddString(NewId, CString(""));
239 return string_index;
240 }
241
242 ///////////////////////////////////////////////////////////////////////////////
CheckAddString(CString & str,CString base_name)243 int string_table::CheckAddString(CString &str, CString base_name)
244 {
245 int index;
246 CString NewId;
247
248 for (index = 1; index < m_records.GetCount(); index++)
249 {
250 if (m_records[index].strings[0] == str)
251 {
252 return index;
253 }
254 }
255
256 CreateId(NewId, base_name);
257 index = AddString(NewId, str);
258 return index;
259 }
260
261 ///////////////////////////////////////////////////////////////////////////////
FindStringIndex(CString & id_name)262 int string_table::FindStringIndex(CString &id_name)
263 {
264 int index = 1;
265
266 while(index < m_records.GetCount())
267 {
268 if (m_records[index].id_name == id_name)
269 {
270 return index;
271 }
272 index++;
273 }
274 return 0;
275 }
276
277 ///////////////////////////////////////////////////////////////////////////////
RemoveString(CString & id_name)278 void string_table::RemoveString(CString &id_name)
279 {
280 int index = FindStringIndex(id_name);
281 if (index)
282 {
283 RemoveString(index);
284 UpdateGuixLanguageTable();
285 }
286 }
287
288 ///////////////////////////////////////////////////////////////////////////////
RemoveString(int string_index)289 BOOL string_table::RemoveString(int string_index)
290 {
291 if (string_index >= 0 && string_index < m_records.GetCount())
292 {
293 CString *strings = m_records[string_index].strings;
294
295 if (strings)
296 {
297 delete [] strings;
298 }
299 RemoveFromDictionary(m_records[string_index].id_name);
300 m_records.RemoveAt(string_index);
301 UpdateGuixLanguageTable();
302 return TRUE;
303 }
304 return FALSE;
305 }
306
307 ///////////////////////////////////////////////////////////////////////////////
SetString(CString & id_name,int language,CString & str,bool update_guix)308 void string_table::SetString(CString &id_name, int language, CString &str, bool update_guix)
309 {
310 studiox_project *project = GetOpenProject();
311
312 if (!project)
313 {
314 return;
315 }
316
317 int index = FindStringIndex(id_name);
318
319 if (index && language < m_languages)
320 {
321 if (m_records[index].strings[language] != str)
322 {
323 m_records[index].strings[language] = str;
324
325 if (update_guix)
326 {
327 UpdateGuixLanguageTable();
328 }
329
330 int string_id = GetResourceId(id_name);
331 widget_factory::UpdateInputWidgetText(project, string_id);
332 }
333 }
334 }
335
336 ///////////////////////////////////////////////////////////////////////////////
SetString(int index,CString & id_name,int language,CString & str,bool update_guix)337 void string_table::SetString(int index, CString &id_name, int language, CString &str, bool update_guix)
338 {
339 studiox_project *project = GetOpenProject();
340
341 if (!project)
342 {
343 return;
344 }
345
346 if (index >= 0 && index < m_records.GetCount() && language < m_languages)
347 {
348 if (m_records[index].id_name != id_name)
349 {
350 UpdateDictionaryResourceName(m_records[index].id_name, id_name);
351 m_records[index].id_name = id_name;
352 }
353
354 if (m_records[index].strings[language] != str)
355 {
356 m_records[index].strings[language] = str;
357
358 if (update_guix)
359 {
360 UpdateGuixLanguageTable();
361 }
362
363 int string_id = GetResourceId(id_name);
364 widget_factory::UpdateInputWidgetText(project, string_id);
365 }
366 }
367 }
368
369 ///////////////////////////////////////////////////////////////////////////////
SetStringId(int string_index,CString & id_name)370 BOOL string_table::SetStringId(int string_index, CString &id_name)
371 {
372 int existing = FindStringIndex(id_name);
373
374 if (!existing && string_index >= 0 && string_index < m_records.GetCount())
375 {
376 UpdateDictionaryResourceName(m_records[string_index].id_name, id_name);
377 m_records[string_index].id_name = id_name;
378 return TRUE;
379 }
380 return FALSE;
381 }
382
383 ///////////////////////////////////////////////////////////////////////////////
SetNotes(int string_index,CString & notes)384 void string_table::SetNotes(int string_index, CString ¬es)
385 {
386 if (string_index >= 0 && string_index < m_records.GetCount())
387 {
388 m_records[string_index].notes = notes;
389 }
390 }
391
392 ///////////////////////////////////////////////////////////////////////////////
SetDisplayFont(int string_index,int font_id)393 void string_table::SetDisplayFont(int string_index, int font_id)
394 {
395 if (string_index >= 0 && string_index < m_records.GetCount())
396 {
397 m_records[string_index].font_id = font_id;
398 }
399 }
400
401
402 ///////////////////////////////////////////////////////////////////////////////
SetString(int string_index,int language,CString & str,bool update_guix)403 void string_table::SetString(int string_index, int language, CString &str, bool update_guix)
404 {
405 studiox_project *project = GetOpenProject();
406
407 if (!project)
408 {
409 return;
410 }
411
412 if (string_index >= 0 && string_index < m_records.GetCount() && language < m_languages)
413 {
414 if (m_records[string_index].strings[language] != str)
415 {
416 m_records[string_index].strings[language] = str;
417
418 if (update_guix)
419 {
420 UpdateGuixLanguageTable();
421 }
422
423 int string_id = GetResourceId(m_records[string_index].id_name);
424 widget_factory::UpdateInputWidgetText(project, string_id);
425 }
426 }
427 }
428
compare_id(string_table_record * record_1,string_table_record * record_2)429 static int compare_id(string_table_record *record_1, string_table_record *record_2)
430 {
431 return record_1->id_name.Compare(record_2->id_name);
432 }
433
434 static int language_id;
compare_string(string_table_record * record_1,string_table_record * record_2)435 static int compare_string(string_table_record *record_1, string_table_record *record_2)
436 {
437 return record_1->strings[language_id].Compare(record_2->strings[language_id]);
438 }
439
440 ///////////////////////////////////////////////////////////////////////////////
SortById()441 void string_table::SortById()
442 {
443 qsort(&m_records.GetAt(1), m_records.GetSize() - 1, sizeof(string_table_record), (int(*)(const void *, const void *))compare_id);
444 }
445
446 ///////////////////////////////////////////////////////////////////////////////
SortByString()447 void string_table::SortByString()
448 {
449 language_id = m_sort_column - 1;
450 qsort(&m_records.GetAt(1), m_records.GetSize() - 1, sizeof(string_table_record), (int(*)(const void *, const void *))compare_string);
451 }
452
SortByReferenceCount()453 void string_table::SortByReferenceCount()
454 {
455 studiox_project *project = GetOpenProject();
456
457 if (project)
458 {
459 int index_1;
460 int index_2;
461 int count_1;
462 int count_2;
463 int resource_id;
464 string_table_record temp;
465
466 for (index_1 = 1; index_1 < m_records.GetCount() - 1; index_1++)
467 {
468 resource_id = GetResourceId(m_records.GetAt(index_1).id_name);
469 count_1 = widget_factory::CountReferences(project, RES_TYPE_STRING, resource_id);
470
471 for (index_2 = index_1 + 1; index_2 < m_records.GetCount(); index_2++)
472 {
473 resource_id = GetResourceId(m_records.GetAt(index_2).id_name);
474 count_2 = widget_factory::CountReferences(project, RES_TYPE_STRING, resource_id);
475
476 if (count_2 < count_1)
477 {
478 temp = m_records.GetAt(index_1);
479 m_records.SetAt(index_1, m_records.GetAt(index_2));
480 m_records.SetAt(index_2, temp);
481
482 count_1 = count_2;
483 }
484 }
485 }
486 }
487 }
488
489 ///////////////////////////////////////////////////////////////////////////////
Sort()490 void string_table::Sort()
491 {
492 if ((m_sort_column == -1) || (m_records.GetCount() < 3))
493 {
494 //no sort
495 return;
496 }
497 if (m_sort_column == 0)
498 {
499 SortById();
500 }
501 else if ((m_sort_column >= 1 && m_sort_column <= m_languages))
502 {
503 SortByString();
504 }
505 else if ((m_sort_column == m_languages + 1))
506 {
507 SortByReferenceCount();
508 }
509 else
510 {
511 ErrorMsg("Internal Error: Invalid sorting type.");
512 return;
513 }
514 }
515
516 CString NullString("");
517 string_table_record NullRecord;
518
519 ///////////////////////////////////////////////////////////////////////////////
GetRecord(int string_index)520 string_table_record &string_table::GetRecord(int string_index)
521 {
522 if (string_index >= 0 && string_index < m_records.GetCount())
523 {
524 return m_records.GetAt(string_index);
525 }
526 return NullRecord;
527 }
528
529 ///////////////////////////////////////////////////////////////////////////////
GetRecord(CString id_name)530 string_table_record &string_table::GetRecord(CString id_name)
531 {
532 for (int index = 0; index < m_records.GetCount(); index++)
533 {
534 if (m_records.GetAt(index).id_name == id_name)
535 {
536 return m_records.GetAt(index);
537 }
538 }
539 return NullRecord;
540 }
541
542 ///////////////////////////////////////////////////////////////////////////////
GetString(CString & id_name,int language)543 CString &string_table::GetString(CString &id_name, int language)
544 {
545 int index = FindStringIndex(id_name);
546
547 if (index && language < m_languages)
548 {
549 return GetString(index, language);
550 }
551 return NullString;
552 }
553
554 ///////////////////////////////////////////////////////////////////////////////
GetString(int string_index,int language)555 CString &string_table::GetString(int string_index, int language)
556 {
557 if (string_index >= 0 && string_index < m_records.GetCount() && language < m_languages)
558 {
559 return (m_records[string_index].strings[language]);
560 }
561 return NullString;
562 }
563
564 ///////////////////////////////////////////////////////////////////////////////
GetStringId(int string_index)565 CString &string_table::GetStringId(int string_index)
566 {
567 if (string_index >= 0 && string_index < m_records.GetCount())
568 {
569 return m_records[string_index].id_name;
570 }
571 return NullString;
572 }
573
574 ///////////////////////////////////////////////////////////////////////////////
GetNotes(int string_index)575 CString &string_table::GetNotes(int string_index)
576 {
577 if (string_index >= 0 && string_index < m_records.GetCount())
578 {
579 return m_records[string_index].notes;
580 }
581 return NullString;
582 }
583
584 ///////////////////////////////////////////////////////////////////////////////
CountStrings()585 int string_table::CountStrings()
586 {
587 return (int) m_records.GetCount();
588 }
589
590 ///////////////////////////////////////////////////////////////////////////////
CountLanguages()591 int string_table::CountLanguages()
592 {
593 return m_languages;
594 }
595
596 ///////////////////////////////////////////////////////////////////////////////
GenerateCleanCharacterMap()597 FontCharMap *string_table::GenerateCleanCharacterMap()
598 {
599 char_map.Clear();
600
601 int record;
602 int language;
603
604 for (record = 0; record < m_records.GetCount(); record++)
605 {
606 for (language = 0; language < m_languages; language++)
607 {
608 if (!m_records[record].strings[language].IsEmpty())
609 {
610 char_map.AddToMap(m_records[record].strings[language]);
611 }
612 }
613 }
614 return &char_map;
615 }
616
617 // This function builds a string table for GUIX and installs it
618 // using this object's data. First, it makes sure that this
619 // table is the active string table being displayed by GUIX
620
621 ///////////////////////////////////////////////////////////////////////////////
UpdateGuixLanguageTable(GX_DISPLAY * Display,BOOL update_resource_view)622 void string_table::UpdateGuixLanguageTable(GX_DISPLAY *Display, BOOL update_resource_view)
623 {
624 // first, make certain that this table instance is the one
625 // that is actively used by GUIX:
626 studiox_project *project = GetOpenProject();
627 if (!project)
628 {
629 return;
630 }
631 int display = GetProjectView()->GetActiveDisplay();
632
633 if (display < 0)
634 {
635 return;
636 }
637 if (project->mDisplays[display].stable != this)
638 {
639 return;
640 }
641
642 // yes, this table is the active table being displayed.
643 // keep pointer to old table to delete later:
644 GX_STRING **pOldTable;
645 GX_UBYTE old_language_count;
646 UINT old_string_count;
647 int StringId;
648 int language;
649
650 if (!Display)
651 {
652 Display = get_target_view_display();
653 }
654
655 gx_display_language_table_get_ext(Display, &pOldTable, &old_language_count, &old_string_count);
656
657 GX_UBYTE *pDirectionTable = new GX_UBYTE[m_languages];
658 GX_STRING **pLangTable = new GX_STRING *[m_languages];
659 memset(pLangTable, 0, m_languages * sizeof(GX_STRING *));
660 BOOL new_char = FALSE;
661 string_table_record record;
662 CString InString;
663
664 for (language = 0; language < m_languages; language++)
665 {
666 GX_STRING *pStringTable = new GX_STRING[m_dictionary.GetCount()];
667 pStringTable[0].gx_string_ptr = NULL;
668 pStringTable[0].gx_string_length = 0;
669
670 pLangTable[language] = pStringTable;
671
672 if (string_table::IsRight2LeftLanguage(language))
673 {
674 pDirectionTable[language] = GX_LANGUAGE_DIRECTION_RTL;
675 }
676 else
677 {
678 pDirectionTable[language] = GX_LANGUAGE_DIRECTION_LTR;
679 }
680
681 for (StringId = 1; StringId < m_dictionary.GetCount(); StringId++)
682 {
683 record = GetRecord(GetResourceIdName(StringId));
684 InString = record.strings[language];
685
686 if (InString.IsEmpty())
687 {
688 pStringTable[StringId].gx_string_ptr = NULL;
689 pStringTable[StringId].gx_string_length = 0;
690 }
691 else
692 {
693 if (char_map.AddToMap(InString))
694 {
695 new_char = TRUE;
696 }
697 resource_gen::MakeUtf8String(project, InString, language, &pStringTable[StringId], display, FALSE);
698 }
699 }
700 }
701
702 if (new_char)
703 {
704 SendMessage(GetResourceView()->GetSafeHwnd(), USR_MSG_UPDATE_STRING_TABLE_FONTS, (WPARAM)&char_map, 0);
705 }
706
707 gx_display_language_table_set_ext(Display, (GX_CONST GX_STRING **) pLangTable, m_languages, (UINT)m_records.GetCount());
708
709 // delete old direction table
710 DeleteGuixLanguageDirectionTable(Display);
711
712 gx_display_language_direction_table_set(Display, (GX_CONST GX_UBYTE *)pDirectionTable, m_languages);
713
714 // now delete the old table:
715
716 DeleteGuixLanguageTable(pOldTable, old_language_count, old_string_count);
717
718 if (update_resource_view)
719 {
720 // now tell the resource view about the new string table:
721 SendMessage(GetResourceView()->GetSafeHwnd(), USR_MSG_REBUILD_STIRNG_ITEMS, (WPARAM)FALSE, 0);
722 }
723 }
724
725 ///////////////////////////////////////////////////////////////////////////////
DeleteGuixLanguageDirectionTable(GX_DISPLAY * display)726 void string_table::DeleteGuixLanguageDirectionTable(GX_DISPLAY* display)
727 {
728 if (display->gx_display_language_direction_table)
729 {
730 delete display->gx_display_language_direction_table;
731 display->gx_display_language_direction_table = NULL;
732 }
733 }
734
735 ///////////////////////////////////////////////////////////////////////////////
DeleteGuixLanguageTable(GX_STRING ** pOldTable,int language_count,int string_count)736 void string_table::DeleteGuixLanguageTable(GX_STRING **pOldTable, int language_count, int string_count)
737 {
738 INT StringId;
739 INT language;
740 GX_STRING *pStringTable;
741
742 if (pOldTable && language_count > 0)
743 {
744 for (language = 0; language < language_count; language++)
745 {
746 pStringTable = pOldTable[language];
747
748 if (pStringTable)
749 {
750 for (StringId = 0; StringId < string_count; StringId++)
751 {
752 if (pStringTable[StringId].gx_string_ptr)
753 {
754 delete [] pStringTable[StringId].gx_string_ptr;
755 pStringTable[StringId].gx_string_ptr = NULL;
756 pStringTable[StringId].gx_string_length = 0;
757 }
758 }
759 delete [] pStringTable;
760 pOldTable[language] = NULL;
761 }
762 }
763 delete [] pOldTable;
764 }
765 }
766
767 ///////////////////////////////////////////////////////////////////////////////
AddToDictionary(CString & id_name,int res_id)768 void string_table::AddToDictionary(CString &id_name, int res_id)
769 {
770 if (res_id == -1)
771 {
772 m_dictionary.Add(id_name);
773 }
774 else
775 {
776 m_dictionary.SetAtGrow(res_id, id_name);
777 }
778 }
779
780 ///////////////////////////////////////////////////////////////////////////////
RemoveFromDictionary(CString & id_name)781 void string_table::RemoveFromDictionary(CString &id_name)
782 {
783 for (int index = 1; index < m_dictionary.GetCount(); index++)
784 {
785 if (m_dictionary.GetAt(index) == id_name)
786 {
787 m_dictionary.RemoveAt(index);
788 return;
789 }
790 }
791 }
792
793 ///////////////////////////////////////////////////////////////////////////////
UpdateRichTextResourceName(CString & val,int res_type,CString old_id_name,CString new_id_name)794 CString string_table::UpdateRichTextResourceName(CString& val, int res_type, CString old_id_name, CString new_id_name)
795 {
796 CString out("");
797 CString tag;
798 CString id_name;
799 int index = 0;
800
801 if (res_type == RES_TYPE_FONT)
802 {
803 old_id_name.Insert(0, _T("GX_FONT_ID_"));
804 new_id_name.Insert(0, _T("GX_FONT_ID_"));
805 }
806 else
807 {
808 old_id_name.Insert(0, _T("GX_COLOR_ID_"));
809 new_id_name.Insert(0, _T("GX_COLOR_ID_"));
810 }
811
812 while (1)
813 {
814 // Find tag start flag
815 index = val.Find('<');
816
817 if (index >= 0)
818 {
819 out.Append(val.Left(index + 1));
820 val = val.Mid(index + 1);
821
822 index = val.Find(_T(" "));
823
824 if (index >= 0)
825 {
826 // Get tag
827 tag = val.Left(index);
828
829 if ((tag != "f") && (tag != "c") && (tag != "hc"))
830 {
831 continue;
832 }
833
834 out.Append(val.Left(index + 1));
835 val = val.Mid(index + 1);
836
837 index = val.Find(_T(">"));
838 if (index >= 0)
839 {
840 // Get resource id name
841 id_name = val.Left(index);
842
843 if (id_name == old_id_name)
844 {
845 val = val.Mid(index + 1);
846 out.Append(new_id_name);
847 out.Append(_T(">"));
848 }
849 }
850 }
851 }
852 else
853 {
854 out.Append(val);
855 break;
856 }
857 }
858
859 return out;
860 }
861
862 ///////////////////////////////////////////////////////////////////////////////
UpdateStringTableRichTextResourceName(int res_type,CString & old_id_name,CString & new_id_name)863 void string_table::UpdateStringTableRichTextResourceName(int res_type, CString& old_id_name, CString& new_id_name)
864 {
865 int num_strings = m_records.GetCount();
866
867 for (int record = 0; record < num_strings; record++)
868 {
869 for (int language = 0; language < m_languages; language++)
870 {
871 if (!m_records[record].strings[language].IsEmpty())
872 {
873 m_records[record].strings[language] = UpdateRichTextResourceName(m_records[record].strings[language], res_type, old_id_name, new_id_name);
874 }
875 }
876 }
877 }
878
879 ///////////////////////////////////////////////////////////////////////////////
UpdateDictionaryResourceName(CString & old_id_name,CString & new_id_name)880 void string_table::UpdateDictionaryResourceName(CString& old_id_name, CString& new_id_name)
881 {
882 for (int index = 1; index < m_dictionary.GetCount(); index++)
883 {
884 if (m_dictionary.GetAt(index) == old_id_name)
885 {
886 m_dictionary.SetAt(index, new_id_name);
887 return;
888 }
889 }
890 }
891
892 ///////////////////////////////////////////////////////////////////////////////
GetResourceIdName(int res_id,widget_info * info)893 CString string_table::GetResourceIdName(int res_id, widget_info* info)
894 {
895 CString id_name("");
896
897 if (res_id > 0 && res_id < m_dictionary.GetCount())
898 {
899 id_name = m_dictionary.GetAt(res_id);
900 }
901
902 if (info)
903 {
904 string_reference_record *record = GetMLViewReferenceRecord(id_name);
905
906 if (record)
907 {
908 for (int index = 0; index < record->reference_list.GetCount(); index++)
909 {
910 if ((record->reference_list.GetAt(index) == info) && (record->reference_list.GetCount() > 1))
911 {
912 id_name.Format(L"%s_%s", id_name, info->app_name);
913 id_name.MakeUpper();
914 if (FindStringIndex(id_name))
915 {
916 CreateId(id_name, id_name);
917 }
918 }
919 }
920 }
921 }
922
923 return id_name;
924 }
925
926 ///////////////////////////////////////////////////////////////////////////////
GetResourceId(CString & id_name)927 GX_RESOURCE_ID string_table::GetResourceId(CString& id_name)
928 {
929 for (int index = 1; index < m_dictionary.GetCount(); index++)
930 {
931 if (m_dictionary.GetAt(index) == id_name)
932 {
933 return index;
934 }
935 }
936
937 return 0;
938 }
939
940
941 ////////////////////////////////////////////////////////////////////////////////////////////////
MakeMLViewReferenceRecord(widget_info * child)942 bool string_table::MakeMLViewReferenceRecord(widget_info* child)
943 {
944 string_reference_record* record;
945 CString id_name;
946
947 while (child)
948 {
949 if ((child->basetype == GX_TYPE_MULTI_LINE_TEXT_VIEW) && child->string_id[0])
950 {
951 id_name = GetResourceIdName(child->string_id[0]);
952 record = GetMLViewReferenceRecord(id_name);
953
954 if (record)
955 {
956 record->reference_list.Add(child);
957 }
958 else
959 {
960 record = new string_reference_record;
961 record->id_name = id_name;
962 record->reference_list.Add(child);
963 m_reference_records.Add(record);
964 }
965 }
966
967 MakeMLViewReferenceRecord(child->GetChildWidgetInfo());
968
969 child = child->GetNextWidgetInfo();
970 }
971
972 return FALSE;
973 }
974
975 ////////////////////////////////////////////////////////////////////////////////////////////////
MakeMLViewReferenceRecord(int display)976 void string_table::MakeMLViewReferenceRecord(int display)
977 {
978 studiox_project *project = GetOpenProject();
979 bool generate_unique_reference = FALSE;
980
981 for (int lang = 0; lang < project->mHeader.num_languages; lang++)
982 {
983 if (project->mHeader.languages[lang].support_bidi_text &&
984 project->mHeader.languages[lang].gen_reordered_bidi_text)
985 {
986 generate_unique_reference = TRUE;
987 break;
988 }
989 }
990
991 if (!generate_unique_reference)
992 {
993 return;
994 }
995
996 // Clear reference record.
997 CleanUpMLViewRefereceRecord();
998
999 // Make reference record.
1000 folder_info *folder;
1001
1002 folder = project->mDisplays[display].GetFirstChildFolder();
1003 while (folder)
1004 {
1005 MakeMLViewReferenceRecord(folder->GetFirstChildWidget());
1006
1007 folder = folder->GetNextFolder();
1008 }
1009 }
1010
1011 ///////////////////////////////////////////////////////////////////////////////
CleanUpMLViewRefereceRecord()1012 void string_table::CleanUpMLViewRefereceRecord()
1013 {
1014 string_reference_record* record = NULL;
1015
1016 for (int index = 0; index < m_reference_records.GetCount(); index++)
1017 {
1018 record = m_reference_records.GetAt(index);
1019 delete record;
1020 }
1021
1022 m_reference_records.RemoveAll();
1023 }
1024
1025 ///////////////////////////////////////////////////////////////////////////////
GetMLViewReferenceRecord(CString & id_name)1026 string_reference_record * string_table::GetMLViewReferenceRecord(CString& id_name)
1027 {
1028 string_reference_record *record = NULL;
1029
1030 for (int index = 0; index < m_reference_records.GetCount(); index++)
1031 {
1032 record = m_reference_records.GetAt(index);
1033 if (record->id_name == id_name)
1034 {
1035 return record;
1036 }
1037 }
1038
1039 return NULL;
1040 }
1041
1042 ///////////////////////////////////////////////////////////////////////////////
GetMLViewReferenceWidgetInfoList(CString & id_name)1043 CArray<widget_info *> *string_table::GetMLViewReferenceWidgetInfoList(CString& id_name)
1044 {
1045 string_reference_record* record = GetMLViewReferenceRecord(id_name);
1046
1047 if (record)
1048 {
1049 return &record->reference_list;
1050 }
1051
1052 return NULL;
1053 }
1054
1055 ///////////////////////////////////////////////////////////////////////////////
CountGeneratedStrings()1056 int string_table::CountGeneratedStrings()
1057 {
1058 string_reference_record* record;
1059 int count = CountStrings();
1060
1061 for (int index = 0; index < m_reference_records.GetCount(); index++)
1062 {
1063 record = m_reference_records.GetAt(index);
1064 count += (record->reference_list.GetCount() - 1);
1065 }
1066
1067 return count;
1068 }
1069
1070 ///////////////////////////////////////////////////////////////////////////////
AddLanguage()1071 void string_table::AddLanguage()
1072 {
1073 int old_languages = m_languages;
1074 m_languages++;
1075 int num_strings = m_records.GetCount();
1076
1077 for (int record = 0; record < num_strings; record++)
1078 {
1079 CString *old_strings = m_records[record].strings;
1080 m_records[record].strings = new CString[m_languages];
1081
1082 for (int language = 0; language < old_languages; language++)
1083 {
1084 if (!old_strings[language].IsEmpty())
1085 {
1086 m_records[record].strings[language] = old_strings[language];
1087 }
1088 }
1089 delete [] old_strings;
1090 }
1091 }
1092
1093 ///////////////////////////////////////////////////////////////////////////////
SetActiveLanguage(int language)1094 void string_table::SetActiveLanguage(int language)
1095 {
1096 studiox_project* project = GetOpenProject();
1097
1098 if (!project)
1099 {
1100 return;
1101 }
1102
1103 m_active_language = language;
1104
1105 GX_DISPLAY* display = get_target_view_display();
1106
1107 if (!display)
1108 {
1109 return;
1110 }
1111
1112 if (language >= display->gx_display_language_table_size)
1113 {
1114 UpdateGuixLanguageTable();
1115 }
1116 gx_display_active_language_set(display, language);
1117 EnableDisableRuntimeBidiText(language);
1118 }