1 // string_table_edit_dlg.cpp : implementation file
2 //
3 
4 //#include "stdafx.h"
5 //#include "studiox.h"
6 #include "studiox_includes.h"
7 #include "string_table_edit_dlg.h"
8 #include "xliff_read_write.h"
9 #include "csv_read_write.h"
10 #include "string_export_dlg.h"
11 
12 #ifdef _DEBUG
13 #define new DEBUG_NEW
14 #endif
15 
16 #define ENABLE_SEARCH
17 
18 extern "C" {
19     extern GX_DISPLAY  target_win_display;
20     extern VOID *_win32_canvas_memory_prepare(GX_CANVAS *canvas, GX_RECTANGLE *dirty);
21 }
22 //extern GX_WIDGET *one_app_widget_create(widget_info *info, GX_WIDGET *parent);
23 extern GX_WIDGET *app_child_widget_find(GX_WIDGET *parent, CString widget_name);
24 
25 
GetUtf8Text(CRichEditCtrl * edit)26 CString GetUtf8Text(CRichEditCtrl *edit)
27 {
28     CString return_val("");
29     wchar_t *mybuf;
30     GETTEXTEX gte ;
31     gte.cb = MAX_PATH;
32     gte.flags = GT_DEFAULT;
33     gte.codepage = 1200; // 1200 signifies UNICODE
34     int char_count;
35 
36     char_count = edit->GetTextLength();
37 
38     if (char_count)
39     {
40         char_count++;
41         mybuf = new wchar_t[char_count];
42         gte.cb = char_count * 2;
43         // get the text in UNICODE
44         edit->SendMessage(EM_GETTEXTEX,(unsigned int)&gte,(long)mybuf);
45 
46         // convert Unicode to UTF8
47 #ifdef _UNICODE
48         return_val = mybuf;
49 #else
50         char *utf8buf = new char[char_count * 6];
51         WideCharToMultiByte(CP_UTF8, 0, mybuf, -1, utf8buf, char_count * 6, NULL, NULL);
52         return_val = CString(utf8buf);
53         delete [] utf8buf;
54 #endif
55         delete[] mybuf;
56     }
57     return return_val;
58 }
59 
SetUtf8Text(CRichEditCtrl * edit,CString & text)60 void SetUtf8Text(CRichEditCtrl *edit, CString &text)
61 {
62 #ifdef _UNICODE
63 
64     // set the text in UNICODE
65     //edit->SendMessage(EM_SETTEXTEX, (unsigned int)&ste, (long)text.GetString());
66 
67     edit->SetSel(0, -1);
68     edit->ReplaceSel(text.GetString());
69 #else
70     SETTEXTEX ste ;
71     ste.flags = GT_DEFAULT;
72     ste.codepage = 1200; // 1200 signifies UNICODE
73 
74     if (text.IsEmpty())
75     {
76         edit->SetWindowText(_T(""));
77     }
78     else
79     {
80         wchar_t *mybuf;
81 
82         mybuf = CStringToWideChar(text);
83 
84         // set the text in UNICODE
85         edit->SendMessage(EM_SETTEXTEX, (unsigned int)&ste, (long)mybuf);
86         delete[] mybuf;
87     }
88 #endif
89 
90 }
91 
92 
93 #define BUTTON_BAR_HEIGHT 28
94 #define BUTTON_HEIGHT 24
95 #define BUTTON_WIDTH  72
96 
97 #define TABLE_HEADER_HEIGHT 24
98 
99 #define STRING_INFO_COLUMN_WIDTH 280
100 #define INFO_FIELD_WIDTH 50
101 #define INFO_FIELD_SPACE 10
102 
103 #define LABLE_WIDTH 70
104 #define LABLE_HEIGHT 20
105 
106 #define MIN_STRING_DIALOG_WIDTH 650
107 
108 #define STRING_REFERENCE_ROW_TEXT_HEIGHT 24
109 
110 ///////////////////////////////////////////////////////////////////////////////
111 enum table_button_ids {
112     ID_ADD_STRING = 1024,
113     ID_DELETE_STRING,
114     ID_IMPORT,
115     ID_EXPORT,
116     ID_ID_EDIT,
117     ID_TOP_STRING_EDIT,
118     ID_BOTTOM_STRING_EDIT,
119     ID_SEARCH_BUTTON,
120     ID_SEARCH_EDIT,
121     ID_FONT_SELECT,
122     ID_NOTES_EDIT,
123     ID_SORT_COMBOBOX,
124     ID_SORT_LABEL
125 };
126 
127 enum string_table_edit_dlg_test_command{
128     TEST_GET_STRING_COUNT = 1,
129     TEST_ADD_STRING,
130     TEST_DELETE_STRING,
131     TEST_IMPORT_XLIFF,
132     TEST_EXPORT_XLIFF,
133     TEST_TOGGLE_THREE_COLUMN_MODE,
134     TEST_INCREMENT_TRANS_LANGUAGE,
135     TEST_DECREMENT_TRANS_LANGUAGE,
136     TEST_EDIT_TOP_STRING,
137     TEST_EDIT_BOTTOM_STRING,
138     TEST_EDIT_STRING_ID,
139     TEST_SELECT_STRING,
140     TEST_SAVE_STRING_EDIT,
141     TEST_CANCEL_STRING_EDIT,
142     TEST_SORT_STRING
143 };
144 
145 
146 extern CString target_class_name;
147 
148 ///////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(string_table_edit_dlg,express_dialog)149 BEGIN_MESSAGE_MAP(string_table_edit_dlg, express_dialog)
150     ON_WM_CREATE()
151     ON_WM_SIZE()
152     ON_WM_CTLCOLOR()
153     ON_EN_KILLFOCUS(ID_ID_EDIT, OnIdEdit)
154     ON_EN_CHANGE(ID_TOP_STRING_EDIT, OnStringEdit)
155     ON_EN_CHANGE(ID_BOTTOM_STRING_EDIT, OnStringEdit)
156     ON_CBN_SELCHANGE(ID_FONT_SELECT, OnChangeFont)
157     ON_BN_CLICKED(IDCANCEL, OnCancel)
158     ON_WM_GETMINMAXINFO()
159     ON_MESSAGE(STUDIO_TEST, OnTestMessage)
160 
161     //ON_EN_KILLFOCUS(ID_TOP_STRING_EDIT, string_table_edit_dlg::SaveStringInfo)
162     //ON_EN_KILLFOCUS(ID_ID_EDIT, string_table_edit_dlg::SaveStringInfo)
163 ON_WM_PAINT()
164 ON_WM_SETTINGCHANGE()
165 END_MESSAGE_MAP()
166 
167 ///////////////////////////////////////////////////////////////////////////////
168 BEGIN_MESSAGE_MAP(table_row, CWnd)
169     ON_WM_PAINT()
170     ON_WM_SETFOCUS()
171     ON_WM_LBUTTONDOWN()
172 END_MESSAGE_MAP()
173 
174 ///////////////////////////////////////////////////////////////////////////////
175 BEGIN_MESSAGE_MAP(table_header, CWnd)
176     ON_WM_PAINT()
177     ON_WM_LBUTTONDOWN()
178     ON_WM_RBUTTONDOWN()
179 END_MESSAGE_MAP()
180 
181 
182 IMPLEMENT_DYNAMIC(string_table_edit_dlg, express_dialog)
183 
184 ///////////////////////////////////////////////////////////////////////////////
185 string_table_edit_dlg::string_table_edit_dlg(string_table *table, CWnd* pParent /*=NULL*/)
186 	: express_dialog(string_table_edit_dlg::IDD, pParent)
187 {
188     IconId = IDB_STRINGS;
189     SetTitleText("String Table Editor");
190 
191     mpTable = table;
192     mpWinHeader = NULL;
193     mpButtonFrame = NULL;
194     mpTableFrame = NULL;
195     mpTableHeader = NULL;
196     mpStrReferenceWin = NULL;
197     mRowId = 0;
198     mThreeColumnMode = FALSE;
199     mNotesBrush = new CBrush(GetSysColor(COLOR_WINDOW));
200     mViewEditBrush = new CBrush(GetSysColor(COLOR_WINDOW));
201 
202     m_sys_dpi = GetSystemDPI();
203 
204     int text_scaler = GetTextScaler();
205     SetControlDimensions(text_scaler);
206     CreateDialogFont(text_scaler);
207 }
208 
209 ///////////////////////////////////////////////////////////////////////////////
~string_table_edit_dlg()210 string_table_edit_dlg::~string_table_edit_dlg()
211 {
212     if (mpWinHeader)
213     {
214         delete mpWinHeader;
215     }
216     if (mpButtonFrame)
217     {
218         delete mpButtonFrame;
219     }
220 
221     if (mpTableFrame)
222     {
223         delete mpTableFrame;
224     }
225     if (mpTableHeader)
226     {
227         delete mpTableHeader;
228     }
229 
230     if (mpStrReferenceWin)
231     {
232         delete mpStrReferenceWin;
233     }
234     delete mNotesBrush;
235     delete mViewEditBrush;
236 }
237 
238 ///////////////////////////////////////////////////////////////////////////////
SetControlDimensions(int text_scaler)239 void string_table_edit_dlg::SetControlDimensions(int text_scaler)
240 {
241     m_button_bar_height = MulDiv(BUTTON_BAR_HEIGHT, m_sys_dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
242     m_table_header_height = MulDiv(TABLE_HEADER_HEIGHT, m_sys_dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
243     m_string_info_column_width = MulDiv(STRING_INFO_COLUMN_WIDTH, m_sys_dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
244     m_info_field_width = MulDiv(INFO_FIELD_WIDTH, m_sys_dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
245     m_info_field_space = MulDiv(INFO_FIELD_SPACE, m_sys_dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
246     m_min_string_dialog_width = MulDiv(MIN_STRING_DIALOG_WIDTH, m_sys_dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
247     m_lable_width = MulDiv(LABLE_WIDTH, m_sys_dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
248     m_lable_height = MulDiv(LABLE_HEIGHT, m_sys_dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
249 }
250 
251 ///////////////////////////////////////////////////////////////////////////////
DoDataExchange(CDataExchange * pDX)252 void string_table_edit_dlg::DoDataExchange(CDataExchange* pDX)
253 {
254     CDialog::DoDataExchange(pDX);
255 }
256 
257 ///////////////////////////////////////////////////////////////////////////////
OnCtlColor(CDC * pDC,CWnd * pWnd,UINT nCtlColor)258 HBRUSH string_table_edit_dlg::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor)
259 {
260     if (pWnd == &mNotesEdit)
261     {
262         pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
263         pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
264         return (HBRUSH) mNotesBrush->GetSafeHandle();
265     }
266 
267     return express_dialog::OnCtlColor(pDC, pWnd, nCtlColor);
268 }
269 
270 
271 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)272 int string_table_edit_dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
273 {
274     CRect size;
275 
276     GetTargetView()->GetWindowRect(&size);
277     if (size.Width() < MIN_STRING_DIALOG_WIDTH)
278     {
279         int diff = (MIN_STRING_DIALOG_WIDTH - size.Width() + 2) / 2;
280         size.left -= diff;
281         size.right += diff;
282     }
283     MoveWindow(size);
284 
285     CFont *font = &m_dialog_font;
286 
287     mpButtonFrame = new button_frame(mpTable);
288     mpButtonFrame->CreateEx(WS_EX_CONTROLPARENT, target_class_name, _T("button_frame"),
289         WS_VISIBLE|WS_CHILD, CRect(0, 0, 0, 0), this, 0);
290 
291     // create a scrolling frame to contains table rows
292     mpTableFrame = new table_frame(this, mpTable);
293     mpTableFrame->Create(target_class_name, _T("table_frame"),
294         WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_TABSTOP, CRect(0, 0, 0, 0), this, 0);
295 
296     // create the header that goes across top of table rows
297     mpTableHeader = new table_header(mpTableFrame, mpTable);
298     mpTableHeader->Create(target_class_name, _T("table_header"),
299         WS_VISIBLE|WS_CHILD, CRect(0, 0, 0, 0), this, 0);
300 
301     mStrReferenceLabel.Create(_T("Widgets that use this string:"), WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this);
302     mStrReferenceLabel.SetFont(font);
303     mpStrReferenceWin = new string_reference_win(this, mpTable, -1);
304     mpStrReferenceWin->Create(target_class_name, _T("string_reference_win"),
305         WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_BORDER, CRect(0, 0, 0, 0), this, 0);
306 
307     mIdLabel.Create(_T("String ID:"), WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this);
308     mIdLabel.SetFont(font);
309     mIdEdit.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT|ES_UPPERCASE|WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_ID_EDIT);
310     mIdEdit.SetFont(font);
311     SetAccessibleFullDescription(mIdEdit.GetSafeHwnd(), L"Required");
312     SetAccessibleDescription(mIdEdit.GetSafeHwnd(), L"Required");
313 
314     mRequiredIndicationLable.Create(_T("Indicates required field"), WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this, IDC_REQUIRED_FIELD_LEGEND);
315     mRequiredIndicationLable.SetFont(font);
316 
317     mTopEditLabel.Create(_T("String Text:"), WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this);
318     mTopEditLabel.SetFont(font);
319     mTopStringEdit.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_TOP_STRING_EDIT);
320     mBottomStringEdit.Create(WS_CHILD|WS_BORDER|ES_LEFT|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_BOTTOM_STRING_EDIT);
321 
322     if (string_table::IsRight2LeftLanguage(0))
323     {
324         //Displays text using right-to-left reading order.
325         SetRichEditReadingDirection(&mTopStringEdit, PFE_RTLPARA);
326     }
327 
328     memset(&lf, 0, sizeof(LOGFONT));
329     lf.lfHeight = MulDiv(20, m_sys_dpi, DEFAULT_DPI_96);
330     lf.lfWeight = FW_NORMAL;
331     lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
332     _tcscpy(lf.lfFaceName, _T("Arial Unicode MS"));
333     mUniFont.CreateFontIndirect(&lf);
334 
335     mTopStringEdit.SetFont(&mUniFont);
336     mBottomStringEdit.SetFont(&mUniFont);
337 
338     mNumRefLabel.Create(_T("Number of references:"), WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this);
339     mNumRefLabel.SetFont(font);
340     mNumReferences.Create(_T("0"), WS_CHILD | WS_VISIBLE | SS_RIGHT | SS_SUNKEN, CRect(0, 0, 0, 0), this);
341     mNumReferences.SetFont(font);
342 
343     mWidthLabel.Create(_T("String width (pixels):"), WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this);
344     mWidthLabel.SetFont(font);
345     mWidth.Create(_T("0"), WS_CHILD | WS_VISIBLE | SS_RIGHT | SS_SUNKEN, CRect(0, 0, 0, 0), this);
346     mWidth.SetFont(font);
347 
348     mFontLabel.Create(_T("Font:"), WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), this);
349     mFontLabel.SetFont(font);
350     mFontCombo.Create(WS_CHILD|WS_TABSTOP|WS_VSCROLL|CBS_DROPDOWNLIST, CRect(0, 0, 0, 0), this, ID_FONT_SELECT);
351     mFontCombo.SetFont(font);
352 
353     studiox_project *project = GetOpenProject();
354     int font_id;
355     int active_display = GetProjectView()->GetActiveDisplay();
356     int active_theme = project->mDisplays[active_display].active_theme;
357 
358     for (font_id = 0; font_id < project->CountResources(active_display, RES_TYPE_FONT); font_id++)
359     {
360         res_info *info = project->FindResource(active_display, active_theme, RES_TYPE_FONT, font_id);
361 
362         if (info)
363         {
364             mFontCombo.AddString(info->name);
365         }
366     }
367     mFontCombo.SetCurSel(0);
368     mFontCombo.ShowWindow(SW_SHOW);
369 
370     mNotesLabel.Create(_T("Notes:"), WS_CHILD|WS_VISIBLE, CRect(0, 0, 0, 0), this);
371     mNotesLabel.SetFont(font);
372     mNotesEdit.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT|ES_MULTILINE|ES_WANTRETURN|ES_AUTOVSCROLL|WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_NOTES_EDIT);
373     mNotesEdit.SetFont(font);
374 
375     express_dialog::OnCreate(lpCreateStruct);
376     AddCancelButton();
377     AddSaveButton();
378 
379     return 0;
380 }
381 
382 ///////////////////////////////////////////////////////////////////////////////
OnSize(UINT nType,int cx,int cy)383 void string_table_edit_dlg::OnSize(UINT nType, int cx, int cy)
384 {
385     express_dialog::OnSize(nType, cx, cy);
386     PositionChildren();
387 }
388 
389 ///////////////////////////////////////////////////////////////////////////////
UpdateSearchMessage()390 void string_table_edit_dlg::UpdateSearchMessage()
391 {
392     CString HelpString;
393     CMainFrame* pMain = (CMainFrame*)AfxGetApp()->GetMainWnd();
394     HelpString.Format(_T("Search found %d matching string table entries"), mpTableFrame->GetRowCount() - 1);
395 
396     if (pMain)
397     {
398         pMain->GetStatusMsgControl()->SetWindowText(HelpString);
399         pMain->GetStatusMsgControl()->NotifyWinEvent(
400             EVENT_OBJECT_LIVEREGIONCHANGED,
401             OBJID_CLIENT,
402             CHILDID_SELF);
403      }
404 }
405 
406 ///////////////////////////////////////////////////////////////////////////////
OnGetMinMaxInfo(MINMAXINFO * lpMMI)407 void string_table_edit_dlg::OnGetMinMaxInfo(MINMAXINFO *lpMMI)
408 {
409     CDialog::OnGetMinMaxInfo(lpMMI);
410     lpMMI->ptMinTrackSize.x = m_min_string_dialog_width;
411 }
412 
413 ///////////////////////////////////////////////////////////////////////////////
OnInitDialog()414 BOOL string_table_edit_dlg::OnInitDialog()
415 {
416     express_dialog::OnInitDialog();
417 
418     // TODO:  Add extra initialization
419     mpTableFrame->SelectFirstRow();
420 
421     return TRUE;  // return TRUE unless you set the focus to a control
422                   // EXCEPTION: OCX Property Pages should return FALSE
423 }
424 
425 
426 ///////////////////////////////////////////////////////////////////////////////
PositionChildren()427 void string_table_edit_dlg::PositionChildren()
428 {
429     CRect size;
430     CRect childsize;
431 
432     if (!mpTableFrame)
433     {
434         return;
435     }
436 
437     GetClientRect(&size);
438 
439     int width = size.right - size.left;
440     int height = size.bottom - size.top;
441     int field_top;
442 
443     childsize = size;
444 
445     // position the frame around the buttonsr
446     childsize.top += (m_title_bar_height + 4);
447     childsize.bottom = childsize.top + m_button_bar_height;
448     childsize.left += 4;
449     childsize.right -= 4;
450     mpButtonFrame->MoveWindow(childsize);
451 
452     childsize.right = size.right - m_string_info_column_width - 4;
453     childsize.top = childsize.bottom + 1;
454     childsize.bottom = childsize.top + m_table_header_height;
455     mpTableHeader->MoveWindow(childsize);
456 
457     childsize.top = childsize.bottom + 1;
458     childsize.bottom = size.top + (height / 2) - 12;
459     mpTableFrame->MoveWindow(childsize);
460     childsize.bottom += 12;
461 
462     // position the label of string reference window
463     childsize.right = size.right - 4;
464     childsize.left = size.right - m_string_info_column_width + m_info_field_space;
465     childsize.top -= m_table_header_height;
466     childsize.bottom = childsize.top + m_table_header_height;
467     mStrReferenceLabel.MoveWindow(childsize);
468 
469     // position string reference widnow
470     childsize.top = childsize.bottom + 1;
471     childsize.bottom = size.top + (height / 2) - 12;
472     mpStrReferenceWin->MoveWindow(childsize);
473 
474     // position required indication lable.
475     childsize.right = size.right - m_string_info_column_width - 4;
476     childsize.top = childsize.bottom + 4;
477     childsize.bottom = childsize.top + m_lable_height;
478     CDC* dc = GetDC();
479     SIZE sz;
480     CFont *old_font = dc->SelectObject(&m_dialog_font);
481     CString text;
482     mRequiredIndicationLable.GetWindowTextW(text);
483     GetTextExtentPoint32W(dc->GetSafeHdc(), text, text.GetLength(), &sz);
484     childsize.left = childsize.right - sz.cx;
485     childsize.top += (childsize.Height() - sz.cy) / 2;
486     mRequiredIndicationLable.MoveWindow(childsize);
487 
488     childsize.left = size.left + 4;
489     childsize.right = size.right - 4;
490 
491     // position the label for the id edit field
492     mIdLabel.GetWindowTextW(text);
493     GetTextExtentPoint32W(dc->GetSafeHdc(), text, text.GetLength(), &sz);
494     dc->SelectObject(old_font);
495     ReleaseDC(dc);
496     childsize.right = childsize.left + sz.cx;
497     childsize.top = childsize.bottom + 4;
498     field_top = childsize.top;
499     childsize.bottom = childsize.top + m_lable_height;
500     mIdLabel.MoveWindow(childsize);
501 
502     int offset = m_lable_height + 4;
503     // position the label for the string edit field
504     childsize.OffsetRect(0, offset);
505     childsize.right = childsize.left + m_lable_width;
506     mTopEditLabel.MoveWindow(childsize);
507 
508     // position the id edit field.
509     childsize.OffsetRect(0, -offset);
510     childsize.left = childsize.right + 4;
511     childsize.right = size.right - m_string_info_column_width - 4;
512     mIdEdit.MoveWindow(childsize);
513 
514     // position the references label
515     childsize.right = size.right - (m_info_field_width + 8);
516     childsize.left = size.right - m_string_info_column_width + m_info_field_space;
517     childsize.bottom = childsize.top + m_lable_height;
518     mNumRefLabel.MoveWindow(childsize);
519 
520     // position the string width label
521     childsize.OffsetRect(0, offset);
522     mWidthLabel.MoveWindow(childsize);
523 
524     // position the references value
525     childsize.OffsetRect(0, -offset);
526     childsize.left = childsize.right + 8;
527     childsize.right = size.right - 4;
528     mNumReferences.MoveWindow(childsize);
529 
530     // position the width value:
531     childsize.OffsetRect(0, offset);
532     mWidth.MoveWindow(childsize);
533 
534     // position the font label:
535     childsize.top = childsize.bottom + 4;
536     childsize.bottom = childsize.top + m_lable_height;
537     childsize.left = size.right - m_string_info_column_width + m_info_field_space;
538     childsize.right = childsize.left + m_lable_width;
539     mFontLabel.MoveWindow(childsize);
540 
541     // position the font combo
542     childsize.left = childsize.right + 4;
543     childsize.right = size.right - 4;
544     childsize.bottom = childsize.top + 200;
545     mFontCombo.MoveWindow(childsize);
546 
547     // position the notes label:
548     childsize.top += 44;
549     childsize.bottom = childsize.top + m_lable_height;
550     childsize.left = size.right - m_string_info_column_width + m_info_field_space;
551     childsize.right = childsize.left + m_lable_width;
552     mNotesLabel.MoveWindow(childsize);
553 
554     // position the notes edit box:
555     childsize.top += offset;
556     childsize.bottom = size.bottom - (m_status_bar_height + 10);
557     childsize.right = size.right - 4;
558     mNotesEdit.MoveWindow(childsize);
559 
560     // position the top string edit field
561     childsize.top = field_top + offset;
562     childsize.left = size.left + m_lable_width + 8;
563     childsize.right = size.right - m_string_info_column_width - 4;
564 
565     offset = m_status_bar_height + 10;
566 
567     if (mThreeColumnMode)
568     {
569         childsize.bottom = (childsize.top + (size.bottom - offset)) / 2;
570     }
571     else
572     {
573         childsize.bottom = size.bottom - offset;
574     }
575     mTopStringEdit.MoveWindow(childsize);
576 
577     if (mThreeColumnMode)
578     {
579         childsize.top = childsize.bottom;
580         childsize.bottom = size.bottom - offset;
581         mBottomStringEdit.MoveWindow(childsize);
582     }
583 
584     Invalidate();
585 }
586 
587 ///////////////////////////////////////////////////////////////////////////////
UpdateStringWidth(GX_RESOURCE_ID font_id,CString & str)588 void string_table_edit_dlg::UpdateStringWidth(GX_RESOURCE_ID font_id, CString &str)
589 {
590     GX_FONT *font;
591     GX_VALUE string_width;
592     CString width_val;
593     GX_STRING string;
594 
595     if (str.IsEmpty())
596     {
597         mWidth.SetWindowText(_T("0"));
598     }
599     else
600     {
601         if (font_id < get_target_view_display()->gx_display_font_table_size)
602         {
603             font = get_target_view_display()->gx_display_font_table[font_id];
604             string.gx_string_ptr = (GX_CHAR *) str.GetString();
605             string.gx_string_length = str.GetLength();
606             _gx_system_string_width_get_ext(font, &string, &string_width);
607             width_val.Format(_T("%d"), string_width);
608             mWidth.SetWindowText(width_val);
609         }
610     }
611 }
612 
613 ///////////////////////////////////////////////////////////////////////////////
UpdateEditFieldContent()614 void string_table_edit_dlg::UpdateEditFieldContent()
615 {
616     CString ref_count;
617     studiox_project *project = GetOpenProject();
618 
619     if (mRowId > 0)
620     {
621         int string_index = mpTableFrame->GetStringIndex(mRowId);
622         m_record = mpTable->GetRecord(string_index);
623         mIdEdit.SetWindowText(m_record.id_name);
624         SetUtf8Text(&mTopStringEdit, m_record.strings[0]);
625 
626         if (mThreeColumnMode)
627         {
628             SetUtf8Text(&mBottomStringEdit, m_record.strings[mpTableFrame->GetTransLanguage()]);
629             UpdateStringWidth(m_record.font_id, m_record.strings[mpTableFrame->GetTransLanguage()]);
630 
631             if (string_table::IsRight2LeftLanguage(mpTableFrame->GetTransLanguage()))
632             {
633                 SetRichEditReadingDirection(&mBottomStringEdit, PFE_RTLPARA);
634             }
635             else
636             {
637                 SetRichEditReadingDirection(&mBottomStringEdit, 0);
638             }
639         }
640         else
641         {
642             UpdateStringWidth(m_record.font_id, m_record.strings[0]);
643         }
644 
645         int resource_id = mpTable->GetResourceId(m_record.id_name);
646         ref_count.Format(_T("%d"), widget_factory::CountReferences(project, RES_TYPE_STRING, resource_id));
647         mNumReferences.SetWindowText(ref_count);
648         mNotesEdit.SetWindowText(m_record.notes);
649 
650         CComboBox *pBox = (CComboBox *) GetDlgItem(ID_FONT_SELECT);
651 
652         if (pBox)
653         {
654             pBox->SetCurSel(m_record.font_id);
655         }
656     }
657     else
658     {
659         mIdEdit.SetWindowText(_T(""));
660         mTopStringEdit.SetWindowText(_T(""));
661         mBottomStringEdit.SetWindowText(_T(""));
662     }
663 
664 }
665 
666 ///////////////////////////////////////////////////////////////////////////////
StringSelected(int row_id,BOOL bIdEdit)667 BOOL string_table_edit_dlg::StringSelected(int row_id, BOOL bIdEdit)
668 {
669     if (SaveStringInfo())
670     {
671         if (row_id < 0 || row_id > mpTableFrame->GetRowCount())
672         {
673             row_id = 0;
674         }
675         mRowId = row_id;
676 
677         UpdateEditFieldContent();
678 
679         if (row_id > 0)
680         {
681             if (bIdEdit)
682             {
683                 mIdEdit.SetSel(0x0000ffff);
684                 //mIdEdit.SetFocus();
685             }
686             else
687             {
688                 if (mThreeColumnMode)
689                 {
690                     mBottomStringEdit.SetSel(0, 0x0000ffff);
691                     //mBottomStringEdit.SetFocus();
692                 }
693                 else
694                 {
695                     mTopStringEdit.SetSel(0, 0x0000ffff);
696                     //mTopStringEdit.SetFocus();
697                 }
698             }
699         }
700 
701         mpStrReferenceWin->StringSelected(mpTableFrame->GetStringIndex(mRowId));
702         return TRUE;
703     }
704     return FALSE;
705 
706 }
707 
708 ///////////////////////////////////////////////////////////////////////////////
SetThreeColumnMode(BOOL bOnOff)709 void string_table_edit_dlg::SetThreeColumnMode(BOOL bOnOff)
710 {
711     mThreeColumnMode = bOnOff;
712 
713     if (mThreeColumnMode)
714     {
715         mBottomStringEdit.ShowWindow(SW_SHOW);
716 
717         if (GetFocus() == &mTopStringEdit)
718         {
719             // Move focus to bottom edit before disable the top edit
720             mBottomStringEdit.SetFocus();
721         }
722 
723         mTopStringEdit.EnableWindow(FALSE);
724     }
725     else
726     {
727         mTopStringEdit.EnableWindow(TRUE);
728 
729         if (GetFocus() == &mBottomStringEdit)
730         {
731             // Move focus to top edit before hide bottom edit
732             mTopStringEdit.SetFocus();
733         }
734         mBottomStringEdit.ShowWindow(SW_HIDE);
735     }
736 
737     PositionChildren();
738     UpdateEditFieldContent();
739 }
740 
741 
742 ///////////////////////////////////////////////////////////////////////////////
Exit(int code)743 void string_table_edit_dlg::Exit(int code)
744 {
745     // TODO: Add your control notification handler code here
746     //SaveStringInfo();
747 
748     if (code == IDOK)
749     {
750         if (SaveStringInfo())
751         {
752             express_dialog::OnOK();
753         }
754     }
755     else
756     {
757         express_dialog::OnCancel();
758     }
759 }
760 
761 ///////////////////////////////////////////////////////////////////////////////
762 // catch this event to prevent the dialog from closing every time the user
763 // presses the Enter key. Make them click a button.
OnOK()764 void string_table_edit_dlg::OnOK()
765 {
766     if (SaveStringInfo())
767     {
768         express_dialog::OnOK();
769     }
770 }
771 
772 
773 ///////////////////////////////////////////////////////////////////////////////
SaveStringInfo()774 BOOL string_table_edit_dlg::SaveStringInfo()
775 {
776     if (mRowId > 0)
777     {
778         CString val;
779         CString IdString;
780         CString TextString;
781         GX_BOOL sort_string_table = FALSE;
782 
783         int string_index = mpTableFrame->GetStringIndex(mRowId);
784         m_record = mpTable->GetRecord(string_index);
785         mIdEdit.GetWindowText(IdString);
786 
787         if (IdString != m_record.id_name)
788         {
789             //check if the new id name is already exist
790             int index = mpTable->FindStringIndex(IdString);
791             if ((index != 0) && (index != string_index))
792             {
793                 mIdEdit.SetWindowText(m_record.id_name);
794                 CString message;
795                 message.Format(_T("Duplicate String ID %s, String Id must be unique."), IdString);
796                 ErrorMsg(message, this);
797                 return FALSE;
798             }
799 
800             //check if the new id name meet ANSI C variable naming rules
801             if (!TestInputName(&mIdEdit, "String ID", m_record.id_name, this))
802             {
803                 return FALSE;
804             }
805 
806             if (mpTable->GetSortColumn() == 0)
807             {
808                 sort_string_table = TRUE;
809             }
810         }
811 
812         if (mThreeColumnMode)
813         {
814             val = GetUtf8Text(&mBottomStringEdit);
815             int language_id = mpTableFrame->GetTransLanguage();
816 
817             if ((mpTable->GetSortColumn() == language_id + 1) &&
818                 (m_record.strings[language_id] != val))
819             {
820                 sort_string_table = TRUE;
821             }
822 
823             mpTable->SetString(string_index, m_record.id_name, language_id, val);
824         }
825         else
826         {
827             val = GetUtf8Text(&mTopStringEdit);
828 
829             if ((mpTable->GetSortColumn() == 1) &&
830                 (m_record.strings[0] != val))
831             {
832                 sort_string_table = TRUE;
833             }
834 
835             mpTable->SetString(string_index, m_record.id_name, 0, val);
836         }
837 
838         mpStrReferenceWin->UpdateResourceTable();
839 
840         mNotesEdit.GetWindowText(TextString);
841         mpTable->SetNotes(string_index, TextString);
842         mpTableFrame->InvalidateRow(mRowId);
843 
844         if (sort_string_table)
845         {
846             mpButtonFrame->SendMessage(WM_COMMAND, MAKEWPARAM(ID_SORT_COMBOBOX, CBN_SELCHANGE), (LPARAM)(mpButtonFrame)->m_hWnd);
847         }
848     }
849     return TRUE;
850 }
851 
852 ///////////////////////////////////////////////////////////////////////////////
UpdateStringFields()853 void string_table_edit_dlg::UpdateStringFields()
854 {
855     if (mRowId > 0)
856     {
857         CString IdString;
858         CString TextString;
859         int string_index = mpTableFrame->GetStringIndex(mRowId);
860 
861         mIdEdit.GetWindowText(IdString);
862 
863         if (mThreeColumnMode)
864         {
865             TextString = GetUtf8Text(&mBottomStringEdit);
866             mpTable->SetString(string_index, IdString, mpTableFrame->GetTransLanguage(), TextString);
867         }
868         else
869         {
870             TextString = GetUtf8Text(&mTopStringEdit);
871             mpTable->SetString(string_index, IdString, 0, TextString);
872         }
873         mpStrReferenceWin->UpdateResourceTable();
874         mpTableFrame->Invalidate();
875     }
876 }
877 
878 ///////////////////////////////////////////////////////////////////////////////
SetRichEditReadingDirection(CRichEditCtrl * edit,INT reading_order)879 void string_table_edit_dlg::SetRichEditReadingDirection(CRichEditCtrl* edit, INT reading_order)
880 {
881     // Modify the paragraph format
882     PARAFORMAT pf;
883     pf.cbSize = sizeof(PARAFORMAT);
884     pf.dwMask = PFM_RTLPARA;
885     pf.wEffects = reading_order;
886 
887     edit->SetSel(0, edit->GetTextLength() - 1);
888     edit->SetParaFormat(pf);
889     edit->SetSel(edit->GetTextLength(), edit->GetTextLength());
890 }
891 
892 ///////////////////////////////////////////////////////////////////////////////
OnIdEdit()893 void string_table_edit_dlg::OnIdEdit()
894 {
895 
896 }
897 
898 ///////////////////////////////////////////////////////////////////////////////
OnStringEdit()899 void string_table_edit_dlg::OnStringEdit()
900 {
901     CString new_val;
902 
903     if (mRowId)
904     {
905         if (mThreeColumnMode)
906         {
907             new_val = GetUtf8Text(&mBottomStringEdit);
908         }
909         else
910         {
911             new_val = GetUtf8Text(&mTopStringEdit);
912         }
913         UpdateStringWidth(m_record.font_id, new_val);
914         UpdateStringFields();
915     }
916 }
917 
918 ///////////////////////////////////////////////////////////////////////////////
OnChangeFont()919 void string_table_edit_dlg::OnChangeFont()
920 {
921     CComboBox *pBox = (CComboBox *) GetDlgItem(ID_FONT_SELECT);
922 
923     if (pBox && mpTable && mRowId)
924     {
925         int Selected = pBox->GetCurSel();
926         int string_index = mpTableFrame->GetStringIndex(mRowId);
927         mpTable->SetDisplayFont(string_index, Selected);
928         m_record.font_id = Selected;
929         UpdateStringWidth(m_record.font_id, m_record.strings[0]);
930     }
931 }
932 
933 ///////////////////////////////////////////////////////////////////////////////
OnTestMessage(WPARAM wParam,LPARAM lParam)934 afx_msg LRESULT string_table_edit_dlg::OnTestMessage(WPARAM wParam, LPARAM lParam)
935 {
936     CWnd *pWnd;
937 
938     switch (wParam)
939     {
940     case TEST_GET_STRING_COUNT:
941         return mpTable->CountStrings() - 1;
942 
943     case TEST_ADD_STRING:
944         pWnd = mpButtonFrame->GetDlgItem(ID_ADD_STRING);
945         mpButtonFrame->SendMessage(WM_COMMAND, MAKEWPARAM(ID_ADD_STRING, BN_CLICKED), (LPARAM)pWnd->GetSafeHwnd());
946         break;
947 
948     case TEST_EDIT_TOP_STRING:
949         mTopStringEdit.SetWindowText(GetTestingParam(0));
950         SendMessage(WM_COMMAND, MAKEWPARAM(ID_TOP_STRING_EDIT, EN_CHANGE), (LPARAM)mTopStringEdit.m_hWnd);
951         break;
952 
953     case TEST_EDIT_BOTTOM_STRING:
954         mBottomStringEdit.SetWindowText(GetTestingParam(0));
955         SendMessage(WM_COMMAND, MAKEWPARAM(ID_BOTTOM_STRING_EDIT, EN_CHANGE), (LPARAM)mBottomStringEdit.m_hWnd);
956         break;
957 
958     case TEST_EDIT_STRING_ID:
959          mIdEdit.SetWindowText(GetTestingParam(0));
960         break;
961 
962     case TEST_SELECT_STRING:
963     {
964         table_row *row = (table_row *)mpTableFrame->GetWindow(GW_CHILD);
965         int string_id = lParam;
966 
967         while (string_id && row)
968         {
969             row = (table_row *)row->GetWindow(GW_HWNDNEXT);
970             string_id--;
971         }
972 
973         if (row)
974         {
975             CRect rect;
976             row->GetWindowRect(&rect);
977             row->ScreenToClient(&rect);
978             row->SendMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.left + 1, rect.top + 1));
979         }
980 
981         break;
982     }
983 
984     case TEST_DELETE_STRING:
985         pWnd = mpButtonFrame->GetDlgItem(ID_DELETE_STRING);
986         mpButtonFrame->SendMessage(WM_COMMAND, MAKEWPARAM(ID_DELETE_STRING, BN_CLICKED), (LPARAM)pWnd->GetSafeHwnd());
987         break;
988 
989     case TEST_IMPORT_XLIFF:
990         mpTableFrame->ImportString(GetTestingParam(1));
991         break;
992 
993     case TEST_EXPORT_XLIFF:
994         pWnd = mpButtonFrame->GetDlgItem(ID_EXPORT);
995         mpButtonFrame->SendMessage(WM_COMMAND, MAKEWPARAM(ID_EXPORT, BN_CLICKED), (LPARAM)pWnd->GetSafeHwnd());
996         break;
997 
998     case TEST_TOGGLE_THREE_COLUMN_MODE:
999     {
1000         CRect rect;
1001         CRect frame_rect;
1002         mpTableHeader->GetClientRect(&rect);
1003         mpTableFrame->GetClientRect(&frame_rect);
1004 
1005         if (mpTableFrame->IsThreeColumnMode())
1006         {
1007             mpTableHeader->SendMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(frame_rect.Width() * 2 / 3 + 1, rect.top + 1));
1008         }
1009         else
1010         {
1011             mpTableHeader->SendMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.right - 1, rect.top + 1));
1012         }
1013 
1014         break;
1015     }
1016 
1017     case TEST_INCREMENT_TRANS_LANGUAGE:
1018         if (mpTableFrame->IsThreeColumnMode())
1019         {
1020             CRect rect;
1021             mpTableHeader->GetWindowRect(&rect);
1022             mpTableHeader->ScreenToClient(&rect);
1023 
1024             mpTableHeader->SendMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.right - 1, rect.top + 1));
1025         }
1026         break;
1027 
1028     case TEST_DECREMENT_TRANS_LANGUAGE:
1029         if (mpTableFrame->IsThreeColumnMode())
1030         {
1031             CRect rect;
1032             mpTableHeader->GetWindowRect(&rect);
1033             mpTableHeader->ScreenToClient(&rect);
1034 
1035             mpTableHeader->SendMessage(WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(rect.right - mpTableHeader->GetIconWidth() - 1, rect.top + 1));
1036         }
1037         break;
1038 
1039     case TEST_SAVE_STRING_EDIT:
1040         OnOK();
1041         break;
1042 
1043     case TEST_CANCEL_STRING_EDIT:
1044         OnCancel();
1045         break;
1046 
1047     case TEST_SORT_STRING:
1048         pWnd = mpButtonFrame->GetDlgItem(ID_SORT_COMBOBOX);
1049         ((CComboBox *)pWnd)->SelectString(0, GetTestingParam(0));
1050         mpButtonFrame->SendMessage(WM_COMMAND, MAKEWPARAM(ID_SORT_COMBOBOX, CBN_SELCHANGE), (LPARAM)(mpButtonFrame->m_hWnd));
1051         break;
1052     }
1053 
1054     return 0;
1055 }
1056 
1057 ///////////////////////////////////////////////////////////////////////////////
BEGIN_MESSAGE_MAP(button_frame,CWnd)1058 BEGIN_MESSAGE_MAP(button_frame, CWnd)
1059     ON_WM_CREATE()
1060     ON_WM_SIZE()
1061     ON_BN_CLICKED(ID_DELETE_STRING, button_frame::OnDeleteClicked)
1062     ON_BN_CLICKED(ID_ADD_STRING, button_frame::OnAddString)
1063     ON_BN_CLICKED(ID_SEARCH_BUTTON, button_frame::OnSearchButton)
1064     ON_BN_CLICKED(ID_IMPORT, button_frame::OnImportString)
1065     ON_BN_CLICKED(ID_EXPORT, button_frame::OnExportString)
1066     ON_CBN_SELCHANGE(ID_SORT_COMBOBOX, OnSortStringTable)
1067     ON_WM_CTLCOLOR()
1068 END_MESSAGE_MAP()
1069 
1070 ///////////////////////////////////////////////////////////////////////////////
1071 ///////////////////////////////////////////////////////////////////////////////
1072 ///////////////////////////////////////////////////////////////////////////////
1073 button_frame::button_frame(string_table *table)
1074 {
1075     mpTable = table;
1076 
1077     UpdateControlDimensions(GetTextScaler());
1078 }
1079 
1080 ///////////////////////////////////////////////////////////////////////////////
~button_frame()1081 button_frame::~button_frame()
1082 {
1083 }
1084 
1085 ///////////////////////////////////////////////////////////////////////////////
UpdateControlDimensions(int text_scaler)1086 void button_frame::UpdateControlDimensions(int text_scaler)
1087 {
1088     int dpi = GetSystemDPI();
1089     m_button_width = MulDiv(BUTTON_WIDTH, dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
1090     m_button_height = MulDiv(BUTTON_HEIGHT, dpi, DEFAULT_DPI_96) * text_scaler / DEFAULT_TEXT_SCALER;
1091 }
1092 
1093 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)1094 int button_frame::OnCreate(LPCREATESTRUCT lpCreateStruct)
1095 {
1096     CWnd::OnCreate(lpCreateStruct);
1097 
1098     string_table_edit_dlg* dlg = (string_table_edit_dlg*)GetParent();
1099     CFont *font = dlg->GetDialogFont();
1100 
1101     // create the buttons along the top of the frame
1102     mAddButton.Create(_T("Add String"), BS_PUSHBUTTON|BS_CENTER|BS_VCENTER|WS_CHILD|WS_VISIBLE|WS_TABSTOP, CRect(0,0,0,0), this, ID_ADD_STRING);
1103     mAddButton.SetFont(font);
1104     mDeleteButton.Create(_T("Delete String"), BS_PUSHBUTTON | BS_CENTER | BS_VCENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_DELETE_STRING);
1105     mDeleteButton.SetFont(font);
1106 
1107     mImportButton.Create(_T("Import"), BS_PUSHBUTTON | BS_CENTER | BS_VCENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_IMPORT);
1108     mImportButton.SetFont(font);
1109     mExportButton.Create(_T("Export"), BS_PUSHBUTTON | BS_CENTER | BS_VCENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_EXPORT);
1110     mExportButton.SetFont(font);
1111 
1112     #ifdef ENABLE_SEARCH
1113     mSearchBitmap.LoadBitmap(IDB_SEARCH);
1114     mSearchString.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT|WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_SEARCH_EDIT);
1115     SetControlAccessibleName(mSearchString.GetSafeHwnd(), _T("Search"));
1116 
1117     mSearchButton.Create(_T("Search"), BS_PUSHBUTTON | BS_BITMAP | WS_CHILD | WS_VISIBLE | WS_TABSTOP, CRect(0, 0, 0, 0), this, ID_SEARCH_BUTTON);
1118     mSearchButton.SetBitmap(mSearchBitmap);
1119     #endif
1120 
1121     mSortLabel.Create(_T("Sorting By:"), WS_CHILD | WS_VISIBLE | SS_RIGHT, CRect(0, 0, 0, 0), this, ID_SORT_LABEL);
1122     mSortLabel.SetFont(font);
1123 
1124     mSortCombobox.Create(WS_CHILD | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, CRect(0, 0, 0, 0), this, ID_SORT_COMBOBOX);
1125     mSortCombobox.SetFont(font);
1126     mSortCombobox.SetItemHeight(-1, 16);
1127 
1128     int id = 0;
1129     studiox_project *project = GetOpenProject();
1130 
1131     mSortCombobox.AddString(_T("None"));
1132     mSortCombobox.AddString(_T("String ID"));
1133     // insert all languages
1134     for (id = 0; id < project->mHeader.num_languages; id++)
1135     {
1136         mSortCombobox.AddString(project->mHeader.languages[id].name);
1137     }
1138     mSortCombobox.AddString(_T("Reference Count"));
1139     mSortCombobox.SetCurSel(mpTable->GetSortColumn() + 1);
1140     mSortCombobox.ShowWindow(SW_SHOW);
1141 
1142     if (mpTable->GetSortColumn() == mpTable->CountLanguages() + 1)
1143     {
1144         mpTable->Sort();
1145     }
1146     return 0;
1147 }
1148 
1149 ///////////////////////////////////////////////////////////////////////////////
PositionChildren()1150 void button_frame::PositionChildren()
1151 {
1152     CRect client;
1153     CRect childsize;
1154 
1155     GetClientRect(&client);
1156     int width = client.right - client.left;
1157     int height = client.bottom - client.top;
1158 
1159     childsize = client;
1160     childsize.top += 2;
1161     childsize.left += 4;
1162     childsize.right = childsize.left + m_button_width;
1163     childsize.bottom = childsize.top + m_button_height;
1164     mAddButton.MoveWindow(&childsize);
1165 
1166     childsize.OffsetRect(m_button_width + 2, 0);
1167     mDeleteButton.MoveWindow(&childsize);
1168 
1169     childsize.OffsetRect(m_button_width + 2, 0);
1170     mImportButton.MoveWindow(&childsize);
1171 
1172     childsize.OffsetRect(m_button_width + 2, 0);
1173     mExportButton.MoveWindow(&childsize);
1174 
1175     #ifdef ENABLE_SEARCH
1176     childsize.OffsetRect(m_button_width + 12, 0);
1177     childsize.right += m_button_width / 2;
1178     mSearchString.MoveWindow(&childsize);
1179 
1180     childsize.OffsetRect(childsize.Width(), 0);
1181     childsize.right = childsize.left + 30;
1182     mSearchButton.MoveWindow(&childsize);
1183     #endif
1184 
1185     childsize.right = client.right - 4;
1186     childsize.left = childsize.right - m_button_width - 30;
1187     mSortCombobox.MoveWindow(&childsize);
1188 
1189     childsize.right = childsize.left - 4;
1190     childsize.left = childsize.right - m_button_width;
1191     childsize.top += 4;
1192     mSortLabel.MoveWindow(&childsize);
1193 }
1194 
1195 ///////////////////////////////////////////////////////////////////////////////
OnSize(UINT nType,int cx,int cy)1196 void button_frame::OnSize(UINT nType, int cx, int cy)
1197 {
1198     CWnd::OnSize(nType, cx, cy);
1199     PositionChildren();
1200 }
1201 
1202 ///////////////////////////////////////////////////////////////////////////////
PreTranslateMessage(MSG * pMsg)1203 BOOL button_frame::PreTranslateMessage(MSG* pMsg)
1204 {
1205     // TODO: Add your specialized code here and/or call the base class
1206     if ((pMsg->message == WM_KEYDOWN) &&
1207         (pMsg->wParam == VK_RETURN))
1208     {
1209         CWnd* focus_owner = GetFocus();
1210         if (focus_owner)
1211         {
1212             int ctrl_id = focus_owner->GetDlgCtrlID();
1213 
1214             switch(ctrl_id)
1215             {
1216             case ID_ADD_STRING:
1217                 OnAddString();
1218                 return TRUE;
1219 
1220             case ID_DELETE_STRING:
1221                 OnDeleteClicked();
1222                 return TRUE;
1223 
1224             case ID_IMPORT:
1225                 OnImportString();
1226                 return TRUE;
1227 
1228             case ID_EXPORT:
1229                 OnExportString();
1230                 return TRUE;
1231 
1232             case ID_SEARCH_BUTTON:
1233             case ID_SEARCH_EDIT:
1234                 OnSearchButton();
1235                 return TRUE;
1236             }
1237         }
1238     }
1239 
1240     return CWnd::PreTranslateMessage(pMsg);
1241 }
1242 
1243 ///////////////////////////////////////////////////////////////////////////////
OnAddString()1244 void button_frame::OnAddString()
1245 {
1246     if (mpTable)
1247     {
1248         string_table_edit_dlg *dlg = (string_table_edit_dlg *)GetParent();
1249 
1250         dlg->SaveStringInfo();
1251 
1252         mpTable->AddString();
1253 
1254         dlg->GetTableFrame()->AddString();
1255 
1256         //Sort string table
1257         OnSortStringTable();
1258     }
1259 }
1260 
1261 
1262 ///////////////////////////////////////////////////////////////////////////////
OnDeleteClicked()1263 void button_frame::OnDeleteClicked()
1264 {
1265     string_table_edit_dlg *dlg = (string_table_edit_dlg *) GetParent();
1266     dlg->StringSelected(0, TRUE);
1267 
1268     table_frame *p_table_frame = dlg->GetTableFrame();
1269 
1270     if (!p_table_frame)
1271     {
1272         return;
1273     }
1274 
1275     int selected_row_id = p_table_frame->GetSelectedId();
1276     int selected_string_index = p_table_frame->GetStringIndex(selected_row_id);
1277     studiox_project *project = GetOpenProject();
1278 
1279     if (project && selected_string_index > 0)
1280     {
1281         string_table_record record = mpTable->GetRecord(selected_string_index);
1282 
1283         int resource_id = mpTable->GetResourceId(record.id_name);
1284         if (mpTable->RemoveString(selected_string_index))
1285         {
1286             // ask the widget factory to update all references to this
1287             // string id (and decrement all higher ids as well).
1288             widget_factory::StringDeleted(project, resource_id);
1289             dlg->GetStrReferenceWin()->UpdateResourceTable();
1290             dlg->GetTableFrame()->DeleteString(selected_row_id);
1291         }
1292     }
1293 }
1294 
1295 ///////////////////////////////////////////////////////////////////////////////
OnSearchButton()1296 void button_frame::OnSearchButton()
1297 {
1298     CString SearchString;
1299     string_table_edit_dlg *dlg = (string_table_edit_dlg *) GetParent();
1300 
1301     GetDlgItemText(ID_SEARCH_EDIT, SearchString);
1302     dlg->GetTableFrame()->SetSearchString(SearchString);
1303     dlg->UpdateSearchMessage();
1304 }
1305 
1306 ///////////////////////////////////////////////////////////////////////////////
OnImportString()1307 void button_frame::OnImportString()
1308 {
1309     CString pathname;
1310 
1311     if (BrowseForSingleFile(_T("Select XLIFF/CSV file"),
1312         _T("XLIFF/CSV Files\0*.xlf;*.xliff;*.xml;*.csv\0"),
1313         _T("xliff"), pathname, this))
1314     {
1315         string_table_edit_dlg *dlg = (string_table_edit_dlg *)GetParent();
1316         dlg->GetTableFrame()->ImportString(pathname);
1317     }
1318 }
1319 
1320 ///////////////////////////////////////////////////////////////////////////////
OnExportString()1321 void button_frame::OnExportString()
1322 {
1323     string_export_dlg dlg;
1324 
1325     dlg.SetOwner(GetParent());
1326 
1327     if (dlg.DoModal() == IDOK)
1328     {
1329         studiox_project *project = GetOpenProject();
1330 
1331         if(!project)
1332         {
1333             return;
1334         }
1335 
1336         if (project->mHeader.string_export_filetype == STRING_EXPORT_TYPE_XLIFF)
1337         {
1338             xliff_read_write writer;
1339             if (writer.ExportLanguage(project))
1340             {
1341                 Notify("String data successfully exported to XLIFF file", GetParent());
1342             }
1343             else
1344             {
1345                 ErrorMsg("Failed to write xliff file. Check path and filename.", GetParent());
1346             }
1347         }
1348         else
1349         {
1350             csv_read_write writer;
1351             if (writer.ExportLanguage(project))
1352             {
1353                 Notify("String data successfully exported to CSV file", GetParent());
1354             }
1355             else
1356             {
1357                 ErrorMsg("Failed to write csv file. Check path and filename.", GetParent());
1358             }
1359         }
1360     }
1361 }
1362 
1363 ///////////////////////////////////////////////////////////////////////////////
OnSortStringTable()1364 void button_frame::OnSortStringTable()
1365 {
1366     int index = mSortCombobox.GetCurSel();
1367     string_table_edit_dlg *dlg = (string_table_edit_dlg *)GetParent();
1368     mpTable->SetSortColumn(index - 1);
1369 
1370     if (index > 0)
1371     {
1372         dlg->GetTableFrame()->SortStringTable();
1373     }
1374 }
1375 
OnCtlColor(CDC * pDC,CWnd * pWnd,UINT nCtlColor)1376 HBRUSH button_frame::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
1377 {
1378 
1379     if (pWnd->GetDlgCtrlID() == ID_SORT_LABEL)
1380     {
1381         //set sort label background to white
1382         pDC->SetBkColor(RGB(255, 255, 255));
1383         return (HBRUSH)GetStockObject(NULL_BRUSH);
1384     }
1385     else
1386     {
1387         return CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
1388     }
1389 }
1390 
1391 ///////////////////////////////////////////////////////////////////////////////
1392 //void button_frame::OnSearchEdit()
1393 //{
1394 //    mSearchButton.SetCheck(BST_UNCHECKED);
1395 //}
1396 
1397 #if 0
1398 BOOL string_id_win::OnEraseBkgnd(CDC* pDC)
1399    {
1400       // Set brush to desired background color
1401       CBrush backBrush(RGB(255, 128, 128));
1402 
1403       // Save old brush
1404       CBrush* pOldBrush = pDC->SelectObject(&backBrush);
1405 
1406       CRect rect;
1407       pDC->GetClipBox(&rect);     // Erase the area needed
1408 
1409       pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),
1410           PATCOPY);
1411       pDC->SelectObject(pOldBrush);
1412       return TRUE;
1413    }
1414 #endif
1415 
1416 
BEGIN_MESSAGE_MAP(table_frame,CWnd)1417 BEGIN_MESSAGE_MAP(table_frame, CWnd)
1418     ON_WM_CREATE()
1419     ON_WM_DESTROY()
1420     //ON_WM_ERASEBKGND()
1421     //ON_WM_PAINT()
1422     ON_WM_SIZE()
1423     //ON_WM_CTLCOLOR()
1424     //ON_WM_SYSCHAR()
1425 
1426     ON_WM_VSCROLL()
1427     ON_WM_MOUSEWHEEL()
1428     ON_WM_LBUTTONDOWN()
1429     ON_WM_NCLBUTTONDOWN()
1430     ON_WM_SETFOCUS()
1431     ON_WM_PAINT()
1432     ON_WM_KILLFOCUS()
1433 END_MESSAGE_MAP()
1434 
1435 ///////////////////////////////////////////////////////////////////////////////
1436 table_frame::table_frame(CWnd *parent, string_table *table)
1437 {
1438     mTransLanguage = 1;
1439     mpTable = table;
1440     mThreeColumnMode = FALSE;
1441     mSearchString = "";
1442     m_scroll_helper = new CScrollHelper;
1443     m_scroll_helper->AttachWnd(this);
1444     mSelectedRow = 0;
1445 }
1446 
1447 ///////////////////////////////////////////////////////////////////////////////
~table_frame()1448 table_frame::~table_frame()
1449 {
1450     delete m_scroll_helper;
1451 }
1452 
1453 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)1454 int table_frame::OnCreate(LPCREATESTRUCT lpCreateStruct)
1455 {
1456     CString filter;
1457     CWnd::OnCreate(lpCreateStruct);
1458     CreateTableRows();
1459     PositionChildren();
1460     return 0;
1461 }
1462 
1463 ///////////////////////////////////////////////////////////////////////////////
OnDestroy()1464 void table_frame::OnDestroy()
1465 {
1466     CWnd *child = GetWindow(GW_CHILD);
1467 
1468     while(child)
1469     {
1470         child->DestroyWindow();
1471         delete child;
1472         child = GetWindow(GW_CHILD);
1473     }
1474 }
1475 
1476 ///////////////////////////////////////////////////////////////////////////////
OnPaint()1477 void table_frame::OnPaint()
1478 {
1479     CPaintDC dc(this); // device context for painting
1480                        // TODO: Add your message handler code here
1481                        // Do not call CWnd::OnPaint() for painting messages
1482 
1483     if ((GetFocus() == this) && (mSelectedRow < 1))
1484     {
1485         CRect rect;
1486         GetClientRect(&rect);
1487         dc.DrawFocusRect(&rect);
1488     }
1489 }
1490 
1491 ///////////////////////////////////////////////////////////////////////////////
IncludeInSearch(int RowId)1492 BOOL table_frame::IncludeInSearch(int RowId)
1493 {
1494     CString text;
1495     int language;
1496 
1497     if (mSearchString.IsEmpty())
1498     {
1499         return TRUE;
1500     }
1501     text = mpTable->GetStringId(RowId);
1502     text.MakeUpper();
1503 
1504     if (text.Find(mSearchString) >= 0)
1505     {
1506         return TRUE;
1507     }
1508 
1509     for (language = 0; language < mpTable->CountLanguages(); language++)
1510     {
1511         text = mpTable->GetString(RowId, language);
1512         text.MakeUpper();
1513         if (text.Find(mSearchString) >= 0)
1514         {
1515             return TRUE;
1516         }
1517     }
1518     return FALSE;
1519 }
1520 
1521 ///////////////////////////////////////////////////////////////////////////////
SetSearchString(CString & search)1522 void table_frame::SetSearchString(CString &search)
1523 {
1524     mSearchString = search;
1525     mSearchString.MakeUpper();
1526 
1527     RowSelected(0, 0);
1528     CreateTableRows();
1529 
1530     m_scroll_helper->SetScrollPos(SB_VERT, 0);
1531 
1532     PositionChildren();
1533     SelectFirstRow();
1534 }
1535 
1536 
1537 ///////////////////////////////////////////////////////////////////////////////
CountFilterRows()1538 int table_frame::CountFilterRows()
1539 {
1540     int count = mpTable->CountStrings();
1541     int passed = 0;
1542     int StringId;
1543 
1544     if (mSearchString.IsEmpty())
1545     {
1546         return count - 1;
1547     }
1548 
1549     for (StringId = 1; StringId < count; StringId++)
1550     {
1551         if (IncludeInSearch(StringId))
1552         {
1553             passed++;
1554         }
1555     }
1556     return passed;
1557 }
1558 
1559 ///////////////////////////////////////////////////////////////////////////////
CreateTableRows()1560 void table_frame::CreateTableRows()
1561 {
1562     int index;
1563     table_row *row;
1564     CWnd *child = GetWindow(GW_CHILD);
1565 
1566     while(child)
1567     {
1568         child->DestroyWindow();
1569         delete child;
1570         child = GetWindow(GW_CHILD);
1571     }
1572     int rowcount = mpTable->CountStrings();
1573 
1574     index = 1;
1575     mRowCount = 1;
1576 
1577     while(index < rowcount)
1578     {
1579         if (IncludeInSearch(index))
1580         {
1581             row = new table_row(this, mRowCount++, index, mpTable);
1582             row->Create(target_class_name, _T("string_row"), WS_VISIBLE | WS_CHILD, CRect(0, 0, 0, 0), this, 0);
1583         }
1584         index++;
1585     }
1586 }
1587 
1588 
1589 
1590 ///////////////////////////////////////////////////////////////////////////////
OnVScroll(UINT nSBCode,UINT nPos,CScrollBar * pScrollBar)1591 void table_frame::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
1592 {
1593     // Compute the desired change or delta in scroll position.
1594     m_scroll_helper->OnVScroll(nSBCode, nPos, pScrollBar);
1595 }
1596 
1597 ///////////////////////////////////////////////////////////////////////////////
OnMouseWheel(UINT nFlags,short zDelta,CPoint pt)1598 BOOL table_frame::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
1599 {
1600     BOOL wasScrolled = m_scroll_helper->OnMouseWheel(nFlags, zDelta, pt);
1601     return wasScrolled;
1602 }
1603 
1604 ///////////////////////////////////////////////////////////////////////////////
OnNcLButtonDown(UINT nHitTest,CPoint point)1605 void table_frame::OnNcLButtonDown(UINT nHitTest, CPoint point)
1606 {
1607     // TODO: Add your message handler code here and/or call default
1608     SetFocus();
1609     CWnd::OnNcLButtonDown(nHitTest, point);
1610 }
1611 
1612 ///////////////////////////////////////////////////////////////////////////////
GetTransLanguage()1613 int table_frame::GetTransLanguage()
1614 {
1615     if (mThreeColumnMode)
1616     {
1617         return mTransLanguage;
1618     }
1619     return -1;
1620 }
1621 
1622 ///////////////////////////////////////////////////////////////////////////////
ToggleThreeColumnMode()1623 void table_frame::ToggleThreeColumnMode()
1624 {
1625     string_table_edit_dlg *dlg = (string_table_edit_dlg *)GetParent();
1626 
1627     if (!dlg->SaveStringInfo())
1628     {
1629         return;
1630     }
1631 
1632     int active_language = 0;
1633     BOOL update = FALSE;
1634 
1635     if (mThreeColumnMode)
1636     {
1637         mThreeColumnMode = FALSE;
1638         update = TRUE;
1639     }
1640     else
1641     {
1642         if (GetOpenProject()->mHeader.num_languages > 1)
1643         {
1644             mThreeColumnMode = TRUE;
1645             active_language = mTransLanguage;
1646             update = TRUE;
1647         }
1648     }
1649 
1650     if (update)
1651     {
1652         dlg->SetThreeColumnMode(mThreeColumnMode);
1653 
1654         string_reference_win* reference_win = dlg->GetStrReferenceWin();
1655         if (reference_win)
1656         {
1657             reference_win->SetActiveLanguage(active_language);
1658         }
1659         Invalidate();
1660     }
1661 }
1662 
1663 ///////////////////////////////////////////////////////////////////////////////
OnSize(UINT nType,int cx,int cy)1664 void table_frame::OnSize(UINT nType, int cx, int cy)
1665 {
1666     CWnd::OnSize(nType, cx, cy);
1667     CRect childsize;
1668     CRect client;
1669     GetClientRect(&client);
1670 
1671     table_row *row = (table_row *) GetWindow(GW_CHILD);
1672 
1673     if (row)
1674     {
1675         mRowHeight = row->GetRowHeight();
1676     }
1677 
1678     m_scroll_helper->OnSize(nType, cx, cy);
1679     PositionChildren();
1680 }
1681 
1682 ///////////////////////////////////////////////////////////////////////////////
PreTranslateMessage(MSG * pMsg)1683 BOOL table_frame::PreTranslateMessage(MSG* pMsg)
1684 {
1685     CRect rect;
1686 
1687     // TODO: Add your specialized code here and/or call the base class
1688     if (pMsg->message == WM_KEYDOWN)
1689     {
1690         switch (pMsg->wParam)
1691         {
1692         case VK_UP:
1693             if (mSelectedRow > 1)
1694             {
1695                 RowSelected(mTransLanguage, mSelectedRow - 1, TRUE);
1696                 SelectedVisible();
1697             }
1698             return TRUE;
1699 
1700         case VK_DOWN:
1701             if (mSelectedRow < mRowCount - 1)
1702             {
1703                 RowSelected(mTransLanguage, mSelectedRow + 1, TRUE);
1704                 SelectedVisible();
1705             }
1706             return TRUE;
1707 
1708         case VK_HOME:
1709             if (mSelectedRow > 1)
1710             {
1711                 RowSelected(mTransLanguage, 1, TRUE);
1712                 SelectedVisible();
1713             }
1714             break;
1715 
1716         case VK_END:
1717             if (mSelectedRow < mRowCount - 1)
1718             {
1719                 RowSelected(mTransLanguage, mRowCount - 1, TRUE);
1720                 SelectedVisible();
1721             }
1722             break;
1723 
1724         case VK_PRIOR:
1725             GetClientRect(&rect);
1726             if (m_scroll_helper->Scroll(SB_VERT, -rect.Height()))
1727             {
1728                 table_row * row = (table_row*)GetWindow(GW_CHILD);
1729                 int pagesize = rect.Height() / row->GetRowHeight();
1730 
1731                 RowSelected(mTransLanguage, max(1, mSelectedRow - pagesize), TRUE);
1732                 SelectedVisible();
1733             }
1734             break;
1735 
1736         case VK_NEXT:
1737             GetClientRect(&rect);
1738             if (m_scroll_helper->Scroll(SB_VERT, rect.Height()))
1739             {
1740                 table_row* row = (table_row*)GetWindow(GW_CHILD);
1741                 int pagesize = rect.Height() / row->GetRowHeight();
1742 
1743                 RowSelected(mTransLanguage, min(mRowCount - 1, mSelectedRow + pagesize), TRUE);
1744                 SelectedVisible();
1745             }
1746             break;
1747 
1748         case VK_LEFT:
1749             if (mThreeColumnMode)
1750             {
1751                 if (!DecrementTransLanguage())
1752                 {
1753                     ToggleThreeColumnMode();
1754                 }
1755             }
1756             return TRUE;
1757 
1758         case VK_RIGHT:
1759             if (mThreeColumnMode)
1760             {
1761                 IncrementTransLanguage();
1762             }
1763             else
1764             {
1765                 ToggleThreeColumnMode();
1766             }
1767             return TRUE;
1768 
1769         case VK_TAB:
1770             InvalidateRow(mSelectedRow);
1771             break;
1772         }
1773     }
1774 
1775     return CWnd::PreTranslateMessage(pMsg);
1776 }
1777 
1778 ///////////////////////////////////////////////////////////////////////////////
OnSetFocus(CWnd * pOldWnd)1779 void table_frame::OnSetFocus(CWnd* pOldWnd)
1780 {
1781     CWnd::OnSetFocus(pOldWnd);
1782 
1783     // TODO: Add your message handler code here
1784     CWnd* row = GetRow(mSelectedRow);
1785     if (row)
1786     {
1787         row->Invalidate();
1788         row->SetFocus();
1789     }
1790     else
1791     {
1792         Invalidate();
1793     }
1794 }
1795 
1796 ///////////////////////////////////////////////////////////////////////////////
OnKillFocus(CWnd * pNewWnd)1797 void table_frame::OnKillFocus(CWnd* pNewWnd)
1798 {
1799     CWnd::OnKillFocus(pNewWnd);
1800 
1801     Invalidate();
1802 }
1803 
1804 
1805 ///////////////////////////////////////////////////////////////////////////////
PositionChildren()1806 void table_frame::PositionChildren()
1807 {
1808     int rowheight;
1809     CRect client;
1810     GetClientRect(&client);
1811     CRect childsize = client;
1812     table_row *row = (table_row *) GetWindow(GW_CHILD);
1813 
1814     if (row)
1815     {
1816         rowheight = row->GetRowHeight();
1817 
1818         childsize.top -=(m_scroll_helper->GetScrollPos()).cy;
1819         childsize.bottom = childsize.top + rowheight - 1;
1820         int index = 1;
1821         CString name;
1822 
1823         while(row)
1824         {
1825             //update row text
1826 			GetRowName(index, name);
1827             row->SetWindowText(name);
1828 
1829             row->MoveWindow(&childsize);
1830             childsize.top += rowheight;
1831             childsize.bottom += rowheight;
1832             row = (table_row *) row->GetWindow(GW_HWNDNEXT);
1833             index++;
1834         }
1835     }
1836 
1837     m_scroll_helper->SetDisplaySize(0, CountFilterRows() * mRowHeight);
1838 
1839     Invalidate();
1840 }
1841 
1842 ///////////////////////////////////////////////////////////////////////////////
RowSelected(int column,int row_id,bool assign_focus)1843 void table_frame::RowSelected(int column, int row_id, bool assign_focus)
1844 {
1845     string_table_edit_dlg *dlg = (string_table_edit_dlg *) GetParent();
1846 
1847     if (column == 0)
1848     {
1849         if (dlg->StringSelected(row_id, TRUE))
1850             mSelectedRow = row_id;
1851     }
1852     else
1853     {
1854         if (dlg->StringSelected(row_id, FALSE))
1855             mSelectedRow = row_id;
1856     }
1857 
1858     if (mSelectedRow > 0)
1859     {
1860         CWnd* row = GetRow(mSelectedRow);
1861         if (row)
1862         {
1863             row->Invalidate();
1864 
1865             if (assign_focus)
1866             {
1867                 row->SetFocus();
1868             }
1869         }
1870     }
1871 }
1872 
SelectedVisible()1873 void table_frame::SelectedVisible()
1874 {
1875     if (mSelectedRow >= 0)
1876     {
1877         int min_scroll_value = (mSelectedRow * mRowHeight) - m_scroll_helper->GetPageSize().cy;
1878         int max_scroll_value = min_scroll_value + m_scroll_helper->GetPageSize().cy - mRowHeight;
1879 
1880         if (min_scroll_value < 0)
1881         {
1882             min_scroll_value = 0;
1883         }
1884 
1885         if (max_scroll_value > m_scroll_helper->GetDisplaySize().cy - m_scroll_helper->GetPageSize().cy)
1886         {
1887             max_scroll_value = m_scroll_helper->GetDisplaySize().cy - m_scroll_helper->GetPageSize().cy;
1888         }
1889 
1890         int current_scroll_value = m_scroll_helper->GetScrollPos().cy;
1891         if ((current_scroll_value < min_scroll_value) || (current_scroll_value > max_scroll_value))
1892         {
1893             // scroll so that selected item is visible
1894             m_scroll_helper->SetScrollPos(SB_VERT, min_scroll_value);
1895         }
1896     }
1897 }
1898 ///////////////////////////////////////////////////////////////////////////////
1899 // this is called when the user adds a new string. scroll to the end and
1900 // select it automatically
AddString()1901 void table_frame::AddString()
1902 {
1903     CRect size;
1904 
1905     if (!mSearchString.IsEmpty())
1906     {
1907         mSearchString = "";
1908         CreateTableRows();
1909     }
1910     else
1911     {
1912         table_row *row = new table_row(this, mRowCount, mRowCount, mpTable);
1913         row->Create(target_class_name, _T("string_row"), WS_VISIBLE | WS_CHILD, CRect(0, 0, 0, 0), this, 0);
1914         mRowCount++;
1915     }
1916 
1917     PositionChildren();
1918 
1919     RowSelected(NULL, mpTable->CountStrings() - 1, FALSE);
1920 
1921     //scroll to make selected item visible
1922     SelectedVisible();
1923 }
1924 
DeleteString(int row_id)1925 void table_frame::DeleteString(int row_id)
1926 {
1927     table_row *row = (table_row *) GetWindow(GW_CHILD);
1928 
1929     if (row)
1930     {
1931         while(row->GetWindow(GW_HWNDNEXT))
1932         {
1933             row = (table_row *) row->GetWindow(GW_HWNDNEXT);
1934         }
1935         row->DestroyWindow();
1936         delete row;
1937         mRowCount--;
1938 
1939         PositionChildren();
1940 
1941         if (row_id >= mRowCount)
1942         {
1943             row_id--;
1944         }
1945         RowSelected(NULL, row_id, FALSE);
1946     }
1947 }
1948 
1949 ///////////////////////////////////////////////////////////////////////////////
IncrementTransLanguage()1950 BOOL table_frame::IncrementTransLanguage()
1951 {
1952     if (mTransLanguage < GetOpenProject()->mHeader.num_languages - 1)
1953     {
1954         string_table_edit_dlg *dlg = (string_table_edit_dlg *) GetParent();
1955         if (!dlg->SaveStringInfo())
1956         {
1957             return FALSE;
1958         }
1959         mTransLanguage++;
1960         dlg->UpdateEditFieldContent();
1961 
1962         string_reference_win *reference_win = dlg->GetStrReferenceWin();
1963         if (reference_win)
1964         {
1965             reference_win->SetActiveLanguage(mTransLanguage);
1966         }
1967         dlg->InvalideTableHeader();
1968         Invalidate();
1969 
1970         return TRUE;
1971     }
1972 
1973     return FALSE;
1974 }
1975 
1976 ///////////////////////////////////////////////////////////////////////////////
DecrementTransLanguage()1977 BOOL table_frame::DecrementTransLanguage()
1978 {
1979     if (mTransLanguage > 1)
1980     {
1981         string_table_edit_dlg *dlg = (string_table_edit_dlg *)GetParent();
1982         if (!dlg->SaveStringInfo())
1983         {
1984             return FALSE;
1985         }
1986         mTransLanguage--;
1987         dlg->UpdateEditFieldContent();
1988 
1989         string_reference_win *reference_win = dlg->GetStrReferenceWin();
1990         if (reference_win)
1991         {
1992             reference_win->SetActiveLanguage(mTransLanguage);
1993         }
1994         dlg->InvalideTableHeader();
1995         Invalidate();
1996 
1997         return TRUE;
1998     }
1999 
2000     return FALSE;
2001 }
2002 
2003 ///////////////////////////////////////////////////////////////////////////////
SelectFirstRow()2004 void table_frame::SelectFirstRow()
2005 {
2006     table_row *row = (table_row *) GetWindow(GW_CHILD);
2007 
2008     if (row)
2009     {
2010         RowSelected(0, row->GetRowId());
2011     }
2012 }
2013 
2014 ///////////////////////////////////////////////////////////////////////////////
GetRowName(int row_id,CString & name)2015 void table_frame::GetRowName(int row_id, CString& name)
2016 {
2017     name.Format(_T("row %d"), row_id);
2018 }
2019 
2020 ///////////////////////////////////////////////////////////////////////////////
GetRow(int row_id)2021 CWnd *table_frame::GetRow(int row_id)
2022 {
2023     CWnd* child;
2024 
2025     if (row_id <= 0)
2026     {
2027         return NULL;
2028     }
2029 
2030     child = GetWindow(GW_CHILD);
2031 
2032     while ((row_id > 1) && child)
2033     {
2034         child = child->GetWindow(GW_HWNDNEXT);
2035         row_id--;
2036     }
2037 
2038     return child;
2039 }
2040 
2041 ///////////////////////////////////////////////////////////////////////////////
InvalidateRow(int row_id)2042 void table_frame::InvalidateRow(int row_id)
2043 {
2044 
2045     CWnd *child = GetRow(row_id);
2046 
2047     if (child)
2048     {
2049         child->Invalidate();
2050     }
2051 }
2052 
2053 ///////////////////////////////////////////////////////////////////////////////
GetStringIndex(int row_id)2054 int table_frame::GetStringIndex(int row_id)
2055 {
2056     table_row *row = (table_row *)GetRow(row_id);
2057     if (row)
2058     {
2059         return row->GetStringIndex();
2060     }
2061 
2062     return -1;
2063 }
2064 
2065 ///////////////////////////////////////////////////////////////////////////////
ImportString(CString pathname)2066 void table_frame::ImportString(CString pathname)
2067 {
2068     BOOL successed = FALSE;
2069     CString extention = PathFindExtension(pathname);
2070     extention.MakeLower();
2071 
2072     if (extention == ".csv")
2073     {
2074         csv_read_write reader;
2075         if (reader.ImportCsvFile(GetOpenProject(), pathname))
2076         {
2077             successed = TRUE;
2078         }
2079     }
2080     else
2081     {
2082         xliff_read_write reader;
2083 
2084         if (reader.ImportXliffFile(GetOpenProject(), pathname))
2085         {
2086             successed = TRUE;
2087         }
2088     }
2089 
2090     if (successed)
2091     {
2092         CreateTableRows();
2093         PositionChildren();
2094 
2095         string_table_edit_dlg *dlg = (string_table_edit_dlg *)GetParent();
2096         dlg->UpdateEditFieldContent();
2097 
2098         Notify("String data import completed", this);
2099     }
2100     else
2101     {
2102         ErrorMsg("String table import failed", this);
2103     }
2104 }
2105 
2106 ///////////////////////////////////////////////////////////////////////////////
GetUniFont()2107 CFont * table_frame::GetUniFont()
2108 {
2109     string_table_edit_dlg *string_dlg = (string_table_edit_dlg *)GetParent();
2110     return string_dlg->GetUniFont();
2111 }
2112 
2113 ///////////////////////////////////////////////////////////////////////////////
SortStringTable()2114 void table_frame::SortStringTable()
2115 {
2116     //record old selected row
2117     string_table_record selected_record = mpTable->GetRecord(GetSelectedId());
2118 
2119     if (!mSearchString.IsEmpty())
2120     {
2121         mSearchString = "";
2122 
2123         CreateTableRows();
2124         PositionChildren();
2125     }
2126 
2127     //de-select table row
2128     RowSelected(NULL, -1);
2129 
2130     mpTable->Sort();
2131 
2132     //select table row
2133     string_table_record current;
2134     int index;
2135     CString text;
2136     CWnd *child = GetWindow(GW_CHILD);
2137 
2138     for (index = 1; index < mpTable->CountStrings(); index++)
2139     {
2140         current = mpTable->GetRecord(index);
2141         if (current.id_name == selected_record.id_name)
2142         {
2143             int column;
2144             if (IsThreeColumnMode())
2145             {
2146                 column = 2;
2147             }
2148             else
2149             {
2150                 column = 1;
2151             }
2152 
2153             RowSelected(column, index);
2154         }
2155 
2156         if (child)
2157         {
2158             //update row name
2159             GetRowName(index, text);
2160             child->SetWindowText(text);
2161             child = child->GetWindow(GW_HWNDNEXT);
2162         }
2163     }
2164 
2165     //scroll to make selected item visible
2166     SelectedVisible();
2167 
2168     Invalidate();
2169 }
2170 
2171 ///////////////////////////////////////////////////////////////////////////////
2172 ///////////////////////////////////////////////////////////////////////////////
table_header(table_frame * frame,string_table * table)2173 table_header::table_header(table_frame *frame, string_table *table)
2174 {
2175     mpFrame = frame;
2176     mpTable = table;
2177 
2178     CBitmap map;
2179     BITMAP  bmp;
2180 
2181     map.LoadBitmap(IDB_LEFT_ARROW);
2182     map.GetBitmap(&bmp);
2183 
2184     int dpi = GetSystemDPI();
2185     m_icon_width = MulDiv(bmp.bmWidth, dpi, DEFAULT_DPI_96);
2186 }
2187 
2188 ///////////////////////////////////////////////////////////////////////////////
PaintHeader(CDC * dc,CRect & size)2189 void table_header::PaintHeader(CDC *dc, CRect &size)
2190 {
2191     CString text;
2192     CPen line_pen;
2193     CRect framesize;
2194     studiox_project *project = GetOpenProject();
2195 
2196     if (!project)
2197     {
2198         return;
2199     }
2200     CBrush gray_brush(RGB(229, 229, 229));
2201     //null_pen.CreatePen(PS_SOLID, 0, RGB(210, 210, 210));
2202     line_pen.CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
2203 
2204     CPen *old_pen = dc->SelectObject(&line_pen);
2205     CBrush *old_brush = dc->SelectObject(&gray_brush);
2206 
2207     dc->SetTextColor(RGB(0, 0, 0));
2208     dc->SetBkMode(TRANSPARENT);
2209 
2210     dc->FillRect(&size, &gray_brush);
2211     dc->MoveTo(size.left, size.top);
2212     dc->LineTo(size.right, size.top);
2213     dc->MoveTo(size.left, size.bottom - 1);
2214     dc->LineTo(size.right, size.bottom -1);
2215     dc->MoveTo(size.left, size.top);
2216     dc->LineTo(size.left, size.bottom -1);
2217     dc->MoveTo(size.right - 1, size.top);
2218     dc->LineTo(size.right - 1, size.bottom -1);
2219 
2220     string_table_edit_dlg* dlg = (string_table_edit_dlg*)GetParent();
2221     CFont *old_font = dc->SelectObject(dlg->GetDialogFont());
2222     mpFrame->GetClientRect(&framesize);
2223     CRect boxsize = size;
2224     boxsize.top += 2;
2225     boxsize.right = boxsize.left + framesize.Width() / 3;
2226     boxsize.left += 4;
2227     dc->DrawText(_T("StringId"), &boxsize, DT_LEFT);
2228 
2229     PaintBmp(dc, boxsize.left + dc->GetTextExtent(_T("String Id")).cx + 8, boxsize.top + 4, IDB_DOWN_ARROW);
2230     dc->MoveTo(boxsize.right, boxsize.top);
2231     dc->LineTo(boxsize.right, boxsize.bottom);
2232 
2233     boxsize.left = boxsize.right + 4;
2234 
2235     text = project->mHeader.languages[0].name;
2236 
2237     if (mpFrame->GetTransLanguage() < 0)
2238     {
2239         boxsize.right = size.right;
2240     }
2241     else
2242     {
2243         boxsize.right = boxsize.left + framesize.Width() / 3 - 4;
2244     }
2245     dc->DrawText(text, &boxsize, DT_LEFT);
2246 
2247     // paint down arrow for sorting
2248     PaintBmp(dc, boxsize.left + dc->GetTextExtent(text).cx + 8, boxsize.top + 4, IDB_DOWN_ARROW);
2249 
2250     // paint right or left arrow to toggle three column mode
2251 
2252     if (mpFrame->GetTransLanguage() >= 0)
2253     {
2254         boxsize.left = boxsize.right + 1;
2255         boxsize.right = size.right;
2256         dc->MoveTo(boxsize.left, boxsize.top);
2257         dc->LineTo(boxsize.left, boxsize.bottom);
2258         PaintBmp(dc, boxsize.left + 1, boxsize.top + 4, IDB_RIGHT_ARROW);
2259         boxsize.left += 20;
2260         text = project->mHeader.languages[mpFrame->GetTransLanguage()].name;
2261         dc->DrawText(text, &boxsize, DT_LEFT);
2262 
2263         // paint left-right arrows for selecting trans language
2264         PaintBmp(dc, boxsize.right - (m_icon_width << 1) - 1, boxsize.top + 3, IDB_LEFT_ARROW);
2265         PaintBmp(dc, boxsize.right - m_icon_width - 1, boxsize.top + 3, IDB_RIGHT_ARROW);
2266     }
2267     else
2268     {
2269         PaintBmp(dc, boxsize.right - m_icon_width - 1, boxsize.top + 4, IDB_LEFT_ARROW);
2270     }
2271 
2272     dc->SelectObject(old_brush);
2273     dc->SelectObject(old_pen);
2274     dc->SelectObject(old_font);
2275 }
2276 
2277 
2278 ///////////////////////////////////////////////////////////////////////////////
OnPaint()2279 void table_header::OnPaint()
2280 {
2281     CRect size;
2282     GetClientRect(&size);
2283     CDC *dc = GetDC();
2284     CWnd::OnPaint();
2285 
2286     PaintHeader(dc, size);
2287     ReleaseDC(dc);
2288 }
2289 
2290 ///////////////////////////////////////////////////////////////////////////////
OnLButtonDown(UINT di,CPoint cp)2291 void table_header::OnLButtonDown(UINT di, CPoint cp)
2292 {
2293     CRect size;
2294     CRect framesize;
2295     int xpos;
2296     GetClientRect(&size);
2297     mpFrame->GetClientRect(&framesize);
2298 
2299     if (mpFrame->IsThreeColumnMode())
2300     {
2301         xpos = size.left + ((framesize.Width() * 2) / 3);
2302         if (cp.x > xpos)
2303         {
2304             if (cp.x <= xpos + m_icon_width)
2305             {
2306                 mpFrame->ToggleThreeColumnMode();
2307             }
2308             else
2309             {
2310                 if (cp.x >= size.right - (m_icon_width << 1))
2311                 {
2312                     if (cp.x >= size.right - m_icon_width)
2313                     {
2314                         mpFrame->IncrementTransLanguage();
2315                     }
2316                     else
2317                     {
2318                         mpFrame->DecrementTransLanguage();
2319                     }
2320                 }
2321             }
2322         }
2323     }
2324     else
2325     {
2326         if (cp.x >= size.right - m_icon_width)
2327         {
2328             mpFrame->ToggleThreeColumnMode();
2329         }
2330     }
2331 }
2332 
2333 ///////////////////////////////////////////////////////////////////////////////
2334 ///////////////////////////////////////////////////////////////////////////////
table_row(CWnd * parent,int Id,int string_index,string_table * table)2335 table_row::table_row(CWnd *parent, int Id, int string_index, string_table *table)
2336 {
2337     mpFrame = (table_frame *) parent;
2338     mRowId = Id;
2339     mStringIndex = string_index;
2340     mRowHeight = 0;
2341     mpTable = table;
2342 }
2343 
2344 ///////////////////////////////////////////////////////////////////////////////
PaintStringRow(CDC * dc,CRect & size)2345 void table_row::PaintStringRow(CDC *dc, CRect &size)
2346 {
2347     CPen line_pen;
2348     BOOL bSelected = FALSE;
2349     CString text;
2350     CBrush view_only(GetSysColor(COLOR_WINDOW));
2351     CBrush edit_brush(GetSysColor(COLOR_HIGHLIGHTTEXT));
2352 
2353     line_pen.CreatePen(PS_SOLID, 0, RGB(128, 128, 128));
2354     CPen *old_pen = dc->SelectObject(&line_pen);
2355     CBrush *old_brush = dc->SelectObject(&edit_brush);
2356 
2357     dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
2358     dc->SetBkMode(TRANSPARENT);
2359 
2360     table_frame *frame = (table_frame *) GetParent();
2361 
2362     CFont *old_font = dc->SelectObject(frame->GetUniFont());
2363 
2364     if (mRowId == frame->GetSelectedId())
2365     {
2366         bSelected = TRUE;
2367     }
2368 
2369     // paint the string id name:
2370     CRect boxsize = size;
2371     boxsize.right = boxsize.left + boxsize.Width() / 3;
2372 
2373     if (bSelected)
2374     {
2375         CBrush select_brush;
2376 
2377         if (GetFocus() == this)
2378         {
2379             select_brush.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
2380             dc->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
2381         }
2382         else
2383         {
2384             select_brush.CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
2385             dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
2386 
2387         }
2388 
2389         // background highlight for the selected row
2390         dc->FillRect(size, &select_brush);
2391     }
2392     else
2393     {
2394         dc->FillRect(boxsize, &edit_brush);
2395         dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
2396     }
2397     boxsize.left += 4;
2398     dc->DrawText(mpTable->GetStringId(mStringIndex), &boxsize, DT_LEFT);
2399     dc->MoveTo(boxsize.right, size.top);
2400     dc->LineTo(boxsize.right, size.bottom -1);
2401 
2402     // draw the reference language string
2403     boxsize.left = boxsize.right + 1;
2404 
2405     if (frame->IsThreeColumnMode())
2406     {
2407         boxsize.right = boxsize.left + size.Width() / 3 - 1;
2408     }
2409     else
2410     {
2411         boxsize.right = size.right;
2412     }
2413 
2414     if (!bSelected)
2415     {
2416         dc->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
2417         if (frame->IsThreeColumnMode())
2418         {
2419             dc->FillRect(boxsize, &view_only);
2420         }
2421         else
2422         {
2423             dc->FillRect(boxsize, &edit_brush);
2424         }
2425     }
2426 
2427     text = mpTable->GetString(mStringIndex, 0);
2428 
2429     if (text.IsEmpty() == FALSE)
2430     {
2431         boxsize.left += 4;
2432 #ifdef _UNICODE
2433         DrawTextW(*dc, text.GetString(), -1, &boxsize, DT_LEFT);
2434 #else
2435         wchar_t *uni_text = CStringToWideChar(text);
2436 
2437         if (uni_text)
2438         {
2439             DrawTextW(*dc, uni_text, -1, &boxsize, DT_LEFT);
2440             delete [] uni_text;
2441         }
2442 #endif
2443     }
2444 
2445     if (mpFrame->GetTransLanguage() >= 0)
2446     {
2447         boxsize.left = boxsize.right + 1;
2448         boxsize.right = size.right;
2449 
2450         // vertical line to divide columns
2451         dc->MoveTo(boxsize.left, boxsize.top);
2452         dc->LineTo(boxsize.left, boxsize.bottom);
2453 
2454         text = mpTable->GetString(mStringIndex, mpFrame->GetTransLanguage());
2455 
2456         if (text.IsEmpty() == FALSE)
2457         {
2458             boxsize.left += 4;
2459 #ifdef _UNICODE
2460             DrawTextW(*dc, text.GetString(), -1, &boxsize, DT_LEFT);
2461 #else
2462             wchar_t *uni_text = CStringToWideChar(text);
2463 
2464             if (uni_text)
2465             {
2466                 DrawTextW(*dc, uni_text, -1, &boxsize, DT_LEFT);
2467                 delete [] uni_text;
2468             }
2469 #endif
2470         }
2471     }
2472 
2473     dc->MoveTo(size.left, size.top);
2474     dc->LineTo(size.left, size.bottom -1);
2475     dc->MoveTo(size.right - 1, size.top);
2476     dc->LineTo(size.right - 1, size.bottom -1);
2477     dc->MoveTo(size.left, size.bottom - 1);
2478     dc->LineTo(size.right, size.bottom - 1);
2479     dc->SelectObject(old_brush);
2480     dc->SelectObject(old_pen);
2481     dc->SelectObject(old_font);
2482 }
2483 
2484 ///////////////////////////////////////////////////////////////////////////////
OnPaint()2485 void table_row::OnPaint()
2486 {
2487     CRect size;
2488     GetClientRect(&size);
2489     CDC *dc = GetDC();
2490     CWnd::OnPaint();
2491 
2492     PaintStringRow(dc, size);
2493     ReleaseDC(dc);
2494 }
2495 
2496 ///////////////////////////////////////////////////////////////////////////////
OnSetFocus(CWnd * Wnd)2497 VOID table_row::OnSetFocus(CWnd *Wnd)
2498 {
2499     CMainFrame *pMain = (CMainFrame*) AfxGetApp()->GetMainWnd();
2500 
2501      if (pMain)
2502      {
2503         CString msg = _T("");
2504         msg.Format(_T("String Id: %s. String text: %s"), mpTable->GetStringId(mStringIndex), mpTable->GetString(mStringIndex));
2505 
2506         // This works for Narrator, but not for NVDA
2507         pMain->GetStatusMsgControl()->SetWindowText(msg);
2508         pMain->GetStatusMsgControl()->NotifyWinEvent(
2509             EVENT_OBJECT_LIVEREGIONCHANGED,
2510             OBJID_CLIENT,
2511             CHILDID_SELF);
2512 
2513         // And this works for NVDA - but not for Narrator
2514         SetAccessibleDescription(GetSafeHwnd(), msg);
2515     }
2516 }
2517 
2518 ///////////////////////////////////////////////////////////////////////////////
OnLButtonDown(UINT di,CPoint cp)2519 void table_row::OnLButtonDown(UINT di, CPoint cp)
2520 {
2521     CRect size;
2522     int column = 0;
2523 
2524     if (mRowId > 0)
2525     {
2526         table_frame *ps = (table_frame *) GetParent();
2527 
2528         GetClientRect(&size);
2529         if (cp.x > size.left + size.Width() / 3)
2530         {
2531             if (ps->IsThreeColumnMode())
2532             {
2533                 column = 2;
2534             }
2535             else
2536             {
2537                 column = 1;
2538             }
2539         }
2540         ps->RowSelected(column, mRowId);
2541         Invalidate();
2542     }
2543 
2544     SetFocus();
2545 }
2546 
2547 ///////////////////////////////////////////////////////////////////////////////
GetRowHeight()2548 int table_row::GetRowHeight()
2549 {
2550     CDC *dc = GetDC();
2551 
2552     table_frame *frame = (table_frame*)GetParent();
2553 
2554     CFont *old_font = dc->SelectObject(frame->GetUniFont());
2555 
2556     mRowHeight = dc->GetTextExtent(_T("A"), 1).cy + 5;
2557 
2558     dc->SelectObject(old_font);
2559     ReleaseDC(dc);
2560     return mRowHeight;
2561 }
2562 
BEGIN_MESSAGE_MAP(string_reference_win,CWnd)2563 BEGIN_MESSAGE_MAP(string_reference_win, CWnd)
2564     ON_WM_CREATE()
2565     ON_WM_DESTROY()
2566     ON_WM_HSCROLL()
2567     ON_WM_VSCROLL()
2568 END_MESSAGE_MAP()
2569 
2570 ///////////////////////////////////////////////////////////////////////////////
2571 string_reference_win::string_reference_win(CWnd *parent, string_table *table, int string_index)
2572 {
2573     mStringIndex = string_index;
2574     mpTable = table;
2575     mpDisplay = NULL;
2576 
2577     m_scroll_helper = new CScrollHelper();
2578     m_scroll_helper->AttachWnd(this);
2579 
2580     m_text_height = MulDiv(STRING_REFERENCE_ROW_TEXT_HEIGHT, GetSystemDPI(), DEFAULT_DPI_96);
2581 
2582     CreateDisplay();
2583 }
2584 
2585 ///////////////////////////////////////////////////////////////////////////////
~string_reference_win()2586 string_reference_win::~string_reference_win()
2587 {
2588     if (m_scroll_helper)
2589     {
2590         delete m_scroll_helper;
2591     }
2592 
2593     if (mpDisplay)
2594     {
2595         resource_view::CleanupDisplayResources(mpDisplay);
2596         guix_studio_delete_display(mpDisplay);
2597         delete mpDisplay;
2598     }
2599 }
2600 
2601 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpCreateStruct)2602 int string_reference_win::OnCreate(LPCREATESTRUCT lpCreateStruct)
2603 {
2604     if (CWnd::OnCreate(lpCreateStruct) == -1)
2605         return -1;
2606 
2607     // TODO:  Add your specialized creation code here
2608     CreateStringReferenceRows();
2609 
2610     m_scroll_helper->SetDisplaySize(0, 0);
2611 
2612     return 0;
2613 }
2614 
2615 ///////////////////////////////////////////////////////////////////////////////
OnDestroy()2616 void string_reference_win::OnDestroy()
2617 {
2618     CWnd::OnDestroy();
2619 
2620     // TODO: Add your message handler code here
2621     CWnd *child = GetWindow(GW_CHILD);
2622 
2623     while (child)
2624     {
2625         child->DestroyWindow();
2626         delete child;
2627         child = GetWindow(GW_CHILD);
2628     }
2629 }
2630 
2631 ///////////////////////////////////////////////////////////////////////////////
OnHScroll(UINT nSBCode,UINT nPos,CScrollBar * pScrollBar)2632 void string_reference_win::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
2633 {
2634     // TODO: Add your message handler code here and/or call default
2635 
2636     m_scroll_helper->OnHScroll(nSBCode, nPos, pScrollBar);
2637 }
2638 
2639 ///////////////////////////////////////////////////////////////////////////////
OnVScroll(UINT nSBCode,UINT nPos,CScrollBar * pScrollBar)2640 void string_reference_win::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
2641 {
2642     // TODO: Add your message handler code here and/or call default
2643 
2644     m_scroll_helper->OnVScroll(nSBCode, nPos, pScrollBar);
2645 }
2646 
2647 
2648 ///////////////////////////////////////////////////////////////////////////////
CreateStringReferenceRows(widget_info * info,int string_id)2649 void string_reference_win::CreateStringReferenceRows( widget_info *info, int string_id)
2650 {
2651     string_reference_row *row;
2652     widget_info *child;
2653     int string_count;
2654     GX_RESOURCE_ID *string_list;
2655 
2656     while (info)
2657     {
2658         if (info->basetype == GX_TYPE_STRING_SCROLL_WHEEL)
2659         {
2660             string_list = info->ewi.string_scroll_wheel.string_id_list;
2661             string_count = info->ewi.string_scroll_wheel.base.total_rows;
2662         }
2663         else
2664         {
2665             string_list = info->string_id;
2666             string_count = NUM_WIDGET_STRINGS;
2667         }
2668         if (string_list)
2669         {
2670             for (int index = 0; index < string_count; index++)
2671             {
2672                 if (string_id && (string_list[index] == string_id))
2673                 {
2674                     row = new string_reference_row(this, info, string_id);
2675                     row->Create(target_class_name, _T("string_reference_row"), WS_VISIBLE | WS_CHILD, CRect(0, 0, 0, 0), this, 0);
2676                     row->MakeWidgetPreview();
2677                     break;
2678                 }
2679             }
2680         }
2681         child = info->GetChildWidgetInfo();
2682 
2683         if (child)
2684         {
2685             CreateStringReferenceRows(child, string_id);
2686         }
2687 
2688         info = info->GetNextWidgetInfo();
2689     }
2690 }
2691 
2692 ///////////////////////////////////////////////////////////////////////////////
CreateStringReferenceRows()2693 void string_reference_win::CreateStringReferenceRows()
2694 {
2695     studiox_project *project = GetOpenProject();
2696     project_view *pview = GetProjectView();
2697 
2698     if (!project || !pview || mStringIndex < 0)
2699     {
2700         return;
2701     }
2702 
2703     CWnd *child = GetWindow(GW_CHILD);
2704 
2705     while (child)
2706     {
2707         child->DestroyWindow();
2708         delete child;
2709         child = GetWindow(GW_CHILD);
2710     }
2711 
2712     CString id_name = mpTable->GetStringId(mStringIndex);
2713     int string_id = mpTable->GetResourceId(id_name);
2714 
2715     //get active display index
2716     int display_index = display_index = pview->GetActiveDisplay();
2717 
2718     folder_info *folder = project->mDisplays[display_index].GetFirstChildFolder();
2719     widget_info *info;
2720 
2721     //find widgets that reference the selected string
2722     while (folder)
2723     {
2724         info = folder->GetFirstChildWidget();
2725 
2726         CreateStringReferenceRows(info, string_id);
2727         folder = folder->GetNextFolder();
2728     }
2729 }
2730 
2731 ///////////////////////////////////////////////////////////////////////////////
PositionChildren()2732 void string_reference_win::PositionChildren()
2733 {
2734     CRect childsize;
2735     CRect winrect;
2736     string_reference_row *row;
2737     GX_RECTANGLE size;
2738     int row_height;
2739     int row_width;
2740     int display_height = 0;
2741     int display_width = 0;
2742 
2743     CDC *dc = GetWindowDC();
2744 
2745     string_table_edit_dlg* dlg = (string_table_edit_dlg*)GetParent();
2746     CFont *oldFont = dlg->GetDialogFont();
2747     CSize text_extent;
2748 
2749     m_scroll_helper->ScrollToOrigin(TRUE, TRUE);
2750 
2751     // calculate maximum display width and display height
2752     row = (string_reference_row *)GetWindow(GW_CHILD);
2753     while (row)
2754     {
2755         size = row->GetWidgetPreviewSize();
2756 
2757         row_width = (size.gx_rectangle_right - size.gx_rectangle_left + 1);
2758         row_height = (size.gx_rectangle_bottom - size.gx_rectangle_top + 1);
2759 
2760         text_extent = dc->GetTextExtent(row->GetInfoText());
2761 
2762         if (text_extent.cx > row_width)
2763         {
2764             row_width = text_extent.cx;
2765         }
2766 
2767         if (row_width > display_width)
2768         {
2769             display_width = row_width;
2770         }
2771 
2772         display_height += row_height + 2 + m_text_height;
2773 
2774         row = (string_reference_row *)row->GetWindow(GW_HWNDNEXT);
2775     }
2776 
2777     //if display width + 4 < client width, make the display width = client width - 4
2778     GetClientRect(&winrect);
2779 
2780     int cxSB = ::GetSystemMetrics(SM_CXVSCROLL);
2781     int cySB = ::GetSystemMetrics(SM_CYHSCROLL);
2782 
2783     int style = GetStyle();
2784     if (style & WS_HSCROLL)
2785     {
2786         winrect.bottom += cySB;
2787     }
2788 
2789     if (style & WS_VSCROLL)
2790     {
2791         winrect.right += cxSB;
2792     }
2793 
2794     if (display_height + 2 > winrect.Height())
2795     {
2796         int cxSB = ::GetSystemMetrics(SM_CXVSCROLL);
2797 
2798         if (display_width + 4 < winrect.Width() - cxSB)
2799         {
2800             display_width = winrect.Width() - cxSB - 4;
2801         }
2802     }
2803     else
2804     {
2805         if (display_width + 4 < winrect.Width())
2806         {
2807             display_width = winrect.Width() - 4;
2808         }
2809     }
2810 
2811 
2812     //position children
2813     childsize.bottom = 0;
2814     childsize.left += 2;
2815 
2816     row = (string_reference_row *)GetWindow(GW_CHILD);
2817     while (row)
2818     {
2819         size = row->GetWidgetPreviewSize();
2820 
2821         row_height = (size.gx_rectangle_bottom - size.gx_rectangle_top + 1);
2822 
2823         childsize.top = childsize.bottom + 2;
2824         childsize.bottom = childsize.top + row_height + m_text_height;
2825         childsize.right = childsize.left + display_width;
2826 
2827         row->MoveWindow(&childsize);
2828 
2829         row = (string_reference_row *)row->GetWindow(GW_HWNDNEXT);
2830     }
2831 
2832     dc->SelectObject(oldFont);
2833 
2834     m_scroll_helper->SetDisplaySize(display_width + 4, display_height + 2);
2835 }
2836 
2837 ///////////////////////////////////////////////////////////////////////////////
CreateDisplay()2838 void string_reference_win::CreateDisplay()
2839 {
2840     studiox_project *project = GetOpenProject();
2841     project_view *pview = GetProjectView();
2842 
2843     if (!project || !pview)
2844     {
2845         return;
2846     }
2847 
2848     if (!mpDisplay)
2849     {
2850         // create a temporary screen and temporary
2851         // canvas to make a bitmap:
2852         GX_CANVAS *target_canvas = get_target_win_canvas();
2853 
2854         int canvas_width = target_canvas->gx_canvas_x_resolution;
2855         int canvas_height = target_canvas->gx_canvas_y_resolution;
2856 
2857         int active_display = pview->GetActiveDisplay();
2858         int active_theme = project->mDisplays[active_display].active_theme;
2859 
2860         display_info *info = &project->mDisplays[active_display];
2861 
2862         mpDisplay = new GX_DISPLAY;
2863 
2864         int memsize;
2865 
2866         memsize = guix_create_app_display(mpDisplay, "string_test_display",
2867                   canvas_width, canvas_height,
2868                   info->colorformat,
2869                   project->mHeader.target_cpu,
2870                   IsRenesasDave2D(project),
2871                   IsDave2dFontFormat(project, active_display),
2872                   info->themes[active_theme].palette,
2873                   info->themes[active_theme].palette_total_size,
2874                   project->mHeader.palette_mode_aa_text_colors);
2875 
2876         if (memsize)
2877         {
2878             GetResourceView()->BuildResourceTables(active_display, mpDisplay, FALSE);
2879             string_table::EnableDisableRuntimeBidiText(mpDisplay->gx_display_active_language);
2880         }
2881         else
2882         {
2883             delete mpDisplay;
2884             mpDisplay = GX_NULL;
2885         }
2886     }
2887 }
2888 
2889 ///////////////////////////////////////////////////////////////////////////////
UpdateResourceTable()2890 void string_reference_win::UpdateResourceTable()
2891 {
2892     studiox_project *project = GetOpenProject();
2893     project_view *pview = GetProjectView();
2894 
2895     if (!project || !pview)
2896     {
2897         return;
2898     }
2899 
2900     int active_display = pview->GetActiveDisplay();
2901     GetResourceView()->BuildResourceTables(active_display, mpDisplay, FALSE);
2902 }
2903 
2904 ///////////////////////////////////////////////////////////////////////////////
SetActiveLanguage(int language)2905 void string_reference_win::SetActiveLanguage(int language)
2906 {
2907     studiox_project *project = GetOpenProject();
2908 
2909     if (!project)
2910     {
2911         return;
2912     }
2913 
2914     gx_display_active_language_set(mpDisplay, language);
2915     string_table::EnableDisableRuntimeBidiText(language);
2916 
2917     StringSelected(mStringIndex);
2918 }
2919 
2920 ///////////////////////////////////////////////////////////////////////////////
StringSelected(int string_index)2921 void string_reference_win::StringSelected(int string_index)
2922 {
2923     if (mStringIndex != string_index)
2924     {
2925         mStringIndex = string_index;
2926 
2927         CreateStringReferenceRows();
2928         PositionChildren();
2929     }
2930     else
2931     {
2932         CWnd *child = GetWindow(GW_CHILD);
2933 
2934         while (child)
2935         {
2936             ((string_reference_row *)child)->MakeWidgetPreview();
2937             child = child->GetWindow(GW_HWNDNEXT);
2938         }
2939     }
2940 
2941     Invalidate();
2942 }
2943 
2944 ///////////////////////////////////////////////////////////////////////////////
GetDialogFont()2945 CFont *string_reference_win::GetDialogFont()
2946 {
2947     string_table_edit_dlg *dlg = (string_table_edit_dlg*)GetParent();
2948     return dlg->GetDialogFont();
2949 }
2950 
BEGIN_MESSAGE_MAP(string_reference_row,CWnd)2951 BEGIN_MESSAGE_MAP(string_reference_row, CWnd)
2952 ON_WM_PAINT()
2953 END_MESSAGE_MAP()
2954 
2955 ///////////////////////////////////////////////////////////////////////////////
2956 string_reference_row::string_reference_row(CWnd *parent, widget_info *info, int string_id)
2957 {
2958     mpInfo = info;
2959     mStringId = string_id;
2960     mpWidget = NULL;
2961     mpCanvas = NULL;
2962     mpRoot = NULL;
2963     mInfoText = info->app_name;
2964 
2965     int dpi = GetSystemDPI();
2966     m_text_height = MulDiv(STRING_REFERENCE_ROW_TEXT_HEIGHT, dpi, DEFAULT_DPI_96);
2967     m_preview_size.gx_rectangle_left = MulDiv(info->size.gx_rectangle_left, dpi, DEFAULT_DPI_96);
2968     m_preview_size.gx_rectangle_top = MulDiv(info->size.gx_rectangle_top, dpi, DEFAULT_DPI_96);
2969     m_preview_size.gx_rectangle_right = MulDiv(info->size.gx_rectangle_right, dpi, DEFAULT_DPI_96);
2970     m_preview_size.gx_rectangle_bottom = MulDiv(info->size.gx_rectangle_bottom, dpi, DEFAULT_DPI_96);
2971 
2972     studiox_project *project = GetOpenProject();
2973     project_view *pView = GetProjectView();
2974 
2975     if (project || pView)
2976     {
2977         widget_info *parent = NULL;
2978         parent = pView->FindTopLevelWidget(info);
2979 
2980         if (parent && (parent != info))
2981         {
2982             mInfoText.Format(_T("%s.%s"), parent->app_name, mpInfo->app_name);
2983         }
2984     }
2985 }
2986 
2987 ///////////////////////////////////////////////////////////////////////////////
~string_reference_row()2988 string_reference_row::~string_reference_row()
2989 {
2990     if (mpWidget)
2991     {
2992         if (mpWidget->gx_widget_type == GX_TYPE_STRING_SCROLL_WHEEL)
2993         {
2994             GX_STRING_SCROLL_WHEEL *wheel = (GX_STRING_SCROLL_WHEEL *)mpWidget;
2995 
2996             if (wheel->gx_string_scroll_wheel_string_id_list)
2997             {
2998                 delete wheel->gx_string_scroll_wheel_string_id_list;
2999                 wheel->gx_string_scroll_wheel_string_id_list = NULL;
3000             }
3001         }
3002         widget_factory::DeleteWidgets(mpWidget);
3003     }
3004 
3005     if (mpRoot)
3006     {
3007         gx_window_root_delete(mpRoot);
3008         delete mpRoot;
3009     }
3010 
3011     if (mpCanvas)
3012     {
3013         if (mpCanvas->gx_canvas_memory)
3014         {
3015             delete mpCanvas->gx_canvas_memory;
3016         }
3017         gx_canvas_delete(mpCanvas);
3018         delete mpCanvas;
3019     }
3020 }
3021 
3022 ///////////////////////////////////////////////////////////////////////////////
OnPaint()3023 void string_reference_row::OnPaint()
3024 {
3025     CPaintDC dc(this); // device context for painting
3026     // TODO: Add your message handler code here
3027     // Do not call CWnd::OnPaint() for painting messages
3028 
3029     if (mpInfo)
3030     {
3031         CRect client;
3032         CRect rect;
3033         GetClientRect(&client);
3034 
3035         if (mpCanvas)
3036         {
3037             string_reference_win *parent = (string_reference_win *)GetParent();
3038             CFont *oldFont = dc.SelectObject(parent->GetDialogFont());
3039             dc.SetBkMode(TRANSPARENT);
3040             dc.SetTextColor(NORMAL_TEXT_COLOR);
3041 
3042             rect = client;
3043             rect.bottom = client.top + m_text_height - 2;
3044             dc.DrawText(mInfoText, &rect, DT_SINGLELINE | DT_VCENTER);
3045             dc.SelectObject(oldFont);
3046 
3047             UCHAR *memptr = (UCHAR *)_win32_canvas_memory_prepare(mpCanvas, &mpWidget->gx_widget_size);
3048 
3049             //Draw widget preview
3050             int des_width = (m_preview_size.gx_rectangle_right - m_preview_size.gx_rectangle_left + 1);
3051             int des_height = (m_preview_size.gx_rectangle_bottom - m_preview_size.gx_rectangle_top + 1);
3052 
3053             int src_width = m_bitmap.gx_bmp_header.biWidth;
3054             int src_height = m_bitmap.gx_bmp_header.biHeight;
3055 
3056             SetMapMode(dc.GetSafeHdc(), MM_TEXT);
3057 
3058             StretchDIBits(dc.GetSafeHdc(), client.left, client.top + m_text_height - 2, des_width, des_height,
3059                 0, src_height + 1, src_width, -src_height, memptr,
3060                 (BITMAPINFO*)&m_bitmap,
3061                 DIB_RGB_COLORS,
3062                 SRCCOPY);
3063 
3064             CPen brush(PS_SOLID, 1, LINE_COLOR);
3065             CPen *oldPen = dc.SelectObject(&brush);
3066             dc.MoveTo(client.left, client.bottom - 1);
3067             dc.LineTo(client.right, client.bottom - 1);
3068             dc.SelectObject(oldPen);
3069         }
3070     }
3071 }
3072 
3073 /**************************************************************************/
one_app_widget_create(widget_info * info)3074 GX_WIDGET *one_app_widget_create(widget_info *info)
3075 {
3076     GX_WIDGET *created = NULL;
3077     widget_info *child;
3078 
3079     child = info->GetChildWidgetInfo();
3080     info->SetChildWidgetInfo(NULL);
3081     created = widget_factory::GenerateAppScreen(NULL, info);
3082     info->SetChildWidgetInfo(child);
3083     return created;
3084 }
3085 
3086 
3087 ///////////////////////////////////////////////////////////////////////////////
MakeWidgetPreview()3088 void string_reference_row::MakeWidgetPreview()
3089 {
3090     studiox_project *project = GetOpenProject();
3091     project_view *pview = GetProjectView();
3092 
3093     if (!project || !pview)
3094     {
3095         return;
3096     }
3097 
3098     string_reference_win *parent = (string_reference_win *)GetParent();
3099     GX_DISPLAY *display = parent->GetDisplay();
3100 
3101     if (!display)
3102     {
3103         return;
3104     }
3105 
3106     int active_display = pview->GetActiveDisplay();
3107 
3108     if (!mpWidget)
3109     {
3110         int widget_width = mpInfo->size.gx_rectangle_right - mpInfo->size.gx_rectangle_left + 1;
3111         int widget_height = mpInfo->size.gx_rectangle_bottom - mpInfo->size.gx_rectangle_top + 1;
3112         GX_RECTANGLE fill_rect;
3113         gx_utility_rectangle_define(&fill_rect, 0, 0, widget_width - 1, widget_height - 1);
3114 
3115         int bpp = project->mDisplays[active_display].bits_per_pix;
3116         switch (bpp)
3117         {
3118         case 24:
3119             bpp = 32;
3120             break;
3121         }
3122 
3123         //calculate memory size
3124         int  memsize = widget_width * widget_height * bpp;
3125         memsize >>= 3;
3126 
3127         UCHAR *mem =  new UCHAR[memsize];
3128         mpCanvas = new GX_CANVAS;
3129         mpRoot = new GX_WINDOW_ROOT;
3130 
3131         //create canvas and root window for widget drawing
3132         gx_canvas_create(mpCanvas, "string_test_canvas",
3133             display, GX_CANVAS_SIMPLE,
3134             widget_width, widget_height, (GX_COLOR *)mem, memsize);
3135 
3136         gx_window_root_create(mpRoot, "string_test_root", mpCanvas,
3137             GX_STYLE_BORDER_NONE, GX_ID_NONE, &fill_rect);
3138 
3139         mpWidget = one_app_widget_create(mpInfo);
3140 
3141         if (mpWidget)
3142         {
3143             gx_widget_attach(mpRoot, mpWidget);
3144 
3145             gx_widget_style_remove(mpWidget, GX_STYLE_ENABLED);
3146             gx_widget_style_add(mpWidget, GX_STYLE_TRANSPARENT);
3147 
3148             if (mpWidget->gx_widget_type == GX_TYPE_STRING_SCROLL_WHEEL)
3149             {
3150                 GX_STRING_SCROLL_WHEEL *wheel = (GX_STRING_SCROLL_WHEEL *)mpWidget;
3151 
3152                 int list_count = mpInfo->ewi.string_scroll_wheel.base.total_rows;
3153                 GX_RESOURCE_ID *id_list = new GX_RESOURCE_ID[list_count];
3154                 for (int index = 0; index < list_count; index++)
3155                 {
3156                     id_list[index] = mStringId;
3157                 }
3158                 wheel->gx_string_scroll_wheel_string_id_list = id_list;
3159             }
3160 
3161             int xpos = mpInfo->size.gx_rectangle_left;
3162             int ypos = mpInfo->size.gx_rectangle_top;
3163 
3164             if (xpos || ypos)
3165             {
3166                 gx_widget_shift(mpWidget, -xpos, -ypos, FALSE);
3167             }
3168 
3169             GX_WIN32_DISPLAY_DRIVER_DATA *data = (GX_WIN32_DISPLAY_DRIVER_DATA *)target_win_display.gx_display_driver_data;
3170             m_bitmap = data->win32_driver_bmpinfo;
3171             m_bitmap.gx_bmp_header.biWidth = widget_width;
3172             m_bitmap.gx_bmp_header.biHeight = widget_height;
3173         }
3174     }
3175 
3176     if (mpWidget)
3177     {
3178         GX_CHAR *text;
3179         switch (mpInfo->basetype)
3180         {
3181         case GX_TYPE_MULTI_LINE_TEXT_INPUT:
3182         case GX_TYPE_SINGLE_LINE_TEXT_INPUT:
3183             text = new GX_CHAR[mpInfo->ewi.text_info.buffer_size + 1];
3184             widget_service_provider *provider = widget_factory::GetServiceProvider(mpInfo->basetype);
3185             if (provider)
3186             {
3187                 provider->GetStringText((char*)text, mpInfo->ewi.text_info.buffer_size, mpInfo);
3188             }
3189             GX_STRING string;
3190             string.gx_string_ptr = text;
3191             string.gx_string_length = strlen(text);
3192             if (mpInfo->basetype == GX_TYPE_MULTI_LINE_TEXT_INPUT)
3193             {
3194                 gx_multi_line_text_input_text_set_ext((GX_MULTI_LINE_TEXT_INPUT *)mpWidget, &string);
3195             }
3196             else
3197             {
3198                 gx_single_line_text_input_text_set_ext((GX_SINGLE_LINE_TEXT_INPUT *)mpWidget, &string);
3199             }
3200             delete [] text;
3201             break;
3202         }
3203         //Draw widget
3204         gx_canvas_drawing_initiate(mpCanvas, NULL, &mpWidget->gx_widget_size);
3205 
3206         GX_BRUSH *brush;
3207         gx_context_brush_get(&brush);
3208 
3209         int old_brush_width = brush->gx_brush_width;
3210         int old_brush_style = brush->gx_brush_style;
3211         brush->gx_brush_style |= GX_BRUSH_SOLID_FILL;
3212         brush->gx_brush_width = 0;
3213         gx_context_raw_fill_color_set(GX_COLOR_LIGHTGRAY);
3214         gx_canvas_rectangle_draw(&mpWidget->gx_widget_size);
3215 
3216         brush->gx_brush_width = old_brush_width;
3217         brush->gx_brush_style = old_brush_style;
3218         if (display)
3219         {
3220             int text_color_id = mpInfo->color_id[DISABLED_TEXT_COLOR_INDEX];
3221             gx_display_color_set(display, text_color_id, GX_COLOR_BLACK);
3222         }
3223 
3224         gx_widget_show(mpWidget);
3225         mpWidget->gx_widget_draw_function(mpWidget);
3226         gx_widget_hide(mpWidget);
3227 
3228         gx_canvas_drawing_complete(mpCanvas, FALSE);
3229     }
3230 }
3231 
3232 
3233 ///////////////////////////////////////////////////////////////////////////////
OnPaint()3234 void string_table_edit_dlg::OnPaint()
3235 {
3236     CPaintDC dc(this); // device context for painting
3237 
3238     PaintRequiredAsterisk(ID_ID_EDIT);
3239     PaintRequiredAsterisk(IDC_REQUIRED_FIELD_LEGEND);
3240 }
3241 
3242 ///////////////////////////////////////////////////////////////////////////////
DoModal()3243 INT_PTR string_table_edit_dlg::DoModal()
3244 {
3245     int new_text_scaler = GetTextScaler();
3246     if (m_text_scaler != new_text_scaler)
3247     {
3248         SetControlDimensions(new_text_scaler);
3249     }
3250 
3251     return express_dialog::DoModal();
3252 }
3253 
3254 ///////////////////////////////////////////////////////////////////////////////
OnSettingChange(UINT uFlags,LPCTSTR lpszSection)3255 void string_table_edit_dlg::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
3256 {
3257     int new_text_scaler = GetTextScaler();
3258     if (m_text_scaler != new_text_scaler)
3259     {
3260         SetControlDimensions(new_text_scaler);
3261         mpButtonFrame->UpdateControlDimensions(new_text_scaler);
3262     }
3263 
3264     express_dialog::OnSettingChange(uFlags, lpszSection);
3265 }