1 
2 #include "studiox_includes.h"
3 #include "font_path_dialog.h"
4 #include "edit_pixelmap_dlg.h"
5 #include "folder_name_dlg.h"
6 #include "string_table_edit_dlg.h"
7 #include "config_languages_dlg.h"
8 #include "color_edit_dialog.h"
9 #include "resource_view.h"
10 #include "resource_view_provider.h"
11 #include "resource_item_provider.h"
12 
13 #ifdef _DEBUG
14 #define new DEBUG_NEW
15 #endif
16 
17 #define VALID_PROJECT                            \
18     studiox_project *project = GetOpenProject(); \
19     if (!project) return;
20 
21 extern CString target_class_name;
22 
23 #define DRAG_MOVE_TIMER_ID   1
24 
25 enum resource_view_test_commands {
26     TEST_CLICK_RESOURCE_GROUP = 1,
27     TEST_CLICK_PIXELMAP_FOLDER,
28     TEST_CLICK_RESOURCE_ITEM,
29     TEST_ADD_COLOR,
30     TEST_EDIT_COLOR,
31     TEST_DELETE_COLOR,
32     TEST_ADD_FONT,
33     TEST_EDIT_FONT,
34     TEST_DELETE_FONT,
35     TEST_ADD_PIXELMAPS,
36     TEST_EDIT_PIXELMAP,
37     TEST_EDIT_PIXELMAPS,
38     TEST_DELETE_PIXELMAP,
39     TEST_ENABLE_PIXELMAP,
40     TEST_DISABLE_PIXELMAP,
41     TEST_ADD_PIXELMAP_FOLDER,
42     TEST_REMOVE_PIXELMAP_FOLDER,
43     TEST_ENABLE_PIXELMAP_FOLDER,
44     TEST_DISABLE_PIXELMAP_FOLDER,
45     TEST_SET_FOLDER_NAME,
46     TEST_SAVE_FOLDER_NAME_EDIT,
47     TEST_EDIT_STRING,
48     TEST_INCREMENT_ACTIVE_LANGUAGE_INDEX,
49     TEST_DECREMENT_ACTIVE_LANGUAGE_INDEX,
50     TEST_GENERATE_XML
51 };
52 
53 STRING_VAL_PAIR paste_conflict_options[] = {
54     { _T("Use Source Resource"), PASTE_CONFLICT_OPTION_USE_SOURCE },
55     { _T("Use Destination Resource"), PASTE_CONFLICT_OPTION_USE_DESTINATION },
56     { _T("Auto Rename The Resource ID"), PASTE_CONFLICT_OPTION_RENAME },
57     { _T("Abort the paste operation"), PASTE_CONFLICT_OPTION_ABORT },
58     { _T(""), 0 }
59 };
60 
IMPLEMENT_DYNCREATE(resource_view,CScrollView)61 IMPLEMENT_DYNCREATE(resource_view, CScrollView)
62 
63 ///////////////////////////////////////////////////////////////////////////////
64 BEGIN_MESSAGE_MAP(resource_view, CScrollView)
65     ON_WM_ERASEBKGND()
66     ON_WM_CREATE()
67     ON_WM_SIZE()
68 
69     ON_WM_LBUTTONDOWN()
70     ON_WM_LBUTTONUP()
71     ON_WM_RBUTTONDOWN()
72     ON_WM_LBUTTONDBLCLK()
73 
74     ON_COMMAND(ID_ADD_CUSTOM_COLOR, OnAddCustomColor)
75     ON_COMMAND(ID_EDIT_SYSTEM_COLOR, OnEditSystemColor)
76     ON_COMMAND(ID_EDITCOLOR, OnEditCustomColor)
77     ON_COMMAND(ID_DELETE_COLOR, OnDeleteCustomColor)
78     ON_COMMAND(ID_EDITFONT, OnEditFont)
79     ON_COMMAND(ID_DELETEFONT, OnDeleteFont)
80 
81     ON_COMMAND(ID_ADD_PIXELMAP, OnAddPixelmaps)
82     ON_COMMAND(ID_EDIT_PIXELMAPS, OnEditPixelmaps)
83     ON_COMMAND(ID_ADD_PIXELMAP_FOLDER, OnAddPixelmapFolder)
84     ON_COMMAND(ID_REMOVE_PIXELMAP_FOLDER, OnRemovePixelmapFolder)
85     ON_COMMAND(ID_RENAME_PIXELMAP_FOLDER, OnRenamePixelmapFolder)
86     ON_COMMAND(ID_ENABLE_PIXELMAP_FOLDER, OnEnablePixelmapFolder)
87     ON_COMMAND(ID_DISABLE_PIXELMAP_FOLDER, OnDisablePixelmapFolder)
88     ON_COMMAND(ID_PIXELMAP_EDIT, OnEditPixelmap)
89     ON_COMMAND(ID_PIXELMAP_DELETE, OnDeletePixelmap)
90     ON_COMMAND(ID_PIXELMAP_ENABLE, OnEnablePixelmap)
91     ON_COMMAND(ID_PIXELMAP_DISABLE, OnDisablePixelmap)
92     ON_COMMAND(ID_GENERATE_XML, OnGenerateXML)
93 
94     ON_COMMAND(ID_EDIT_STRING_TABLE, OnEditStringTable)
95     ON_COMMAND(ID_EDIT_LANGUAGES, OnEditLanguages)
96     //ON_COMMAND(ID_SET_ACTIVE_LANGUAGE, OnSetActiveLanguage)
97     ON_MESSAGE(USR_MSG_REBUILD_STIRNG_ITEMS, OnRebuildStringItems)
98     ON_MESSAGE(USR_MSG_UPDATE_STRING_TABLE_FONTS, OnUpdateStringTableFonts)
99     ON_MESSAGE(USR_MSG_OPEN_RESOURCE_ITEM, OnOpenResourceItem)
100     ON_MESSAGE(STUDIO_TEST, OnTestMessage)
101     ON_WM_TIMER()
102     ON_WM_SETFOCUS()
103     ON_WM_KILLFOCUS()
104     ON_WM_CONTEXTMENU()
105     ON_WM_SETTINGCHANGE()
106 END_MESSAGE_MAP()
107 
108 ///////////////////////////////////////////////////////////////////////////////
109 resource_view::resource_view()
110 {
111     mpTree = NULL;
112     mDisplayIndex = -1;
113     mpCurrentItem = NULL;
114     mpDragItem = NULL;
115     mpPalette = NULL;
116     mNewResourcePasted = FALSE;
117 
118     m_pResViewProvider = NULL;
119 }
120 
121 ///////////////////////////////////////////////////////////////////////////////
~resource_view()122 resource_view::~resource_view()
123 {
124     if (mpTree)
125     {
126         delete mpTree;
127     }
128 
129     if (m_pResViewProvider)
130     {
131         UiaDisconnectProvider(m_pResViewProvider);
132         m_pResViewProvider->Release();
133         m_pResViewProvider = NULL;
134     }
135 }
136 
137 ///////////////////////////////////////////////////////////////////////////////
PreCreateWindow(CREATESTRUCT & cs)138 BOOL resource_view::PreCreateWindow(CREATESTRUCT& cs)
139 {
140 	if( !CScrollView::PreCreateWindow(cs) )
141 		return FALSE;
142 	// TODO: Modify the Window class or styles here by modifying
143 	//  the CREATESTRUCT cs
144 	return TRUE;
145 }
146 
147 ///////////////////////////////////////////////////////////////////////////////
OnCreate(LPCREATESTRUCT lpcs)148 int resource_view::OnCreate(LPCREATESTRUCT lpcs)
149 {
150     CScrollView::OnCreate(lpcs);
151 //    p_tree = &GetTreeCtrl();
152 
153     CMainFrame *frame = (CMainFrame *) GetParentFrame();
154     frame ->SetResourceView(this);
155     SetWindowText(_T("Resource View"));
156     mpTree = new resource_tree(this);
157     return 0;
158 }
159 
160 ///////////////////////////////////////////////////////////////////////////////
OnInitialUpdate()161 void resource_view::OnInitialUpdate()
162 {
163     OnTreeSizeChange();
164 }
165 
166 ///////////////////////////////////////////////////////////////////////////////
OnDraw(CDC * pDC)167 void resource_view::OnDraw(CDC *pDC)
168 {
169     CView::OnDraw(pDC);
170     mpTree->Paint(pDC);
171 }
172 
173 ///////////////////////////////////////////////////////////////////////////////
OnEraseBkgnd(CDC * pDC)174 BOOL resource_view::OnEraseBkgnd(CDC *pDC)
175 {
176     /*
177     CBrush redbrush(RGB(88, 88, 88));
178     CBrush *pOldBrush = pDC->SelectObject(&redbrush);
179 
180     RECT size;
181     GetClientRect(&size);
182     pDC->Rectangle(&size);
183     pDC->SelectObject(pOldBrush);
184     */
185     return CScrollView::OnEraseBkgnd(pDC);
186     //return TRUE;
187 }
188 
189 ///////////////////////////////////////////////////////////////////////////////
OnSize(UINT nType,int cx,int cy)190 void resource_view::OnSize(UINT nType, int cx, int cy)
191 {
192     CScrollView::OnSize(nType, cx, cy);
193     mpTree->PositionItems();
194 }
195 
196 ///////////////////////////////////////////////////////////////////////////////
OnLButtonDown(UINT di,CPoint cp)197 void resource_view::OnLButtonDown(UINT di, CPoint cp)
198 {
199     cp.y += GetScrollPos(SB_VERT);
200     resource_item *item = mpTree->FindItem(mpTree->GetRoot(), cp);
201     int command = 0;
202 
203     if (item)
204     {
205         SetCurrentItem(item);
206 
207         int item_type = item->GetResType();
208 
209         switch(item_type)
210         {
211         case RES_TYPE_HEADER:
212             if (item->mpRes->folder_id == THEME_HEADER)
213             {
214                 command = item->CheckClickCommand(cp);
215 
216                 switch (command)
217                 {
218                 case CMD_INC_THEME:
219                     OnSetActiveTheme(1);
220                     break;
221 
222                 case CMD_DEC_THEME:
223                     OnSetActiveTheme(-1);
224                     break;
225                 }
226             }
227             break;
228 
229         case RES_TYPE_GROUP:
230             if (item->IsOpen())
231             {
232                 if (item->mpRes->folder_id == STRING_GROUP)
233                 {
234                     command = item->CheckClickCommand(cp);
235 
236                     if (command)
237                     {
238                         switch(command)
239                         {
240                         case CMD_INC_LANGUAGE:
241                             OnSetActiveLanguage(1);
242                             break;
243 
244                         case CMD_DEC_LANGUAGE:
245                             OnSetActiveLanguage(-1);
246                             break;
247                         }
248                         break;
249                     }
250                 }
251                 item->Close();
252             }
253             else
254             {
255                 item->Open();
256             }
257             break;
258 
259         case RES_TYPE_FOLDER:
260             if (item->IsOpen())
261             {
262                 item->Close();
263             }
264             else
265             {
266                 item->Open();
267             }
268 
269             mpTree->PositionItems();
270             break;
271 
272         case RES_TYPE_COLOR:
273         case RES_TYPE_FONT:
274         case RES_TYPE_PIXELMAP:
275         case RES_TYPE_STRING:
276             mpDragItem = item;
277             SetTimer(DRAG_MOVE_TIMER_ID, 75, NULL);
278             mTimerTicks = 0;
279 
280             SetCapture();
281             ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
282             break;
283 
284         case RES_TYPE_ADD_FONT:
285             OnAddFont();
286             break;
287 
288         case RES_TYPE_ADD_COLOR:
289             OnAddCustomColor();
290             break;
291 
292         case RES_TYPE_ADD_PIXELMAP:
293             OnAddPixelmaps();
294             break;
295 
296         case RES_TYPE_ADD_STRING:
297             OnEditStringTable();
298             break;
299         }
300     }
301 }
302 
303 ///////////////////////////////////////////////////////////////////////////////
OnLButtonUp(UINT nFlags,CPoint point)304 void resource_view::OnLButtonUp(UINT nFlags, CPoint point)
305 {
306     BOOL Shifted = FALSE;
307 
308     if (nFlags & MK_SHIFT)
309     {
310         Shifted = TRUE;
311     }
312     VALID_PROJECT
313 
314     if (GetCapture() == this)
315     {
316         ReleaseCapture();
317 
318         if (mpDragItem)
319         {
320             resource_item *new_parent = mpTree->FindItem(mpTree->GetRoot(), CPoint(point.x, point.y + GetScrollPos(SB_VERT)));
321             INT parent_id = DEFAULT_PIXELMAP_FOLDER;
322 
323             if (mpDragItem->Parent())
324             {
325                 parent_id = mpDragItem->Parent()->mpRes->folder_id;
326             }
327 
328             if (new_parent && (parent_id != DEFAULT_PIXELMAP_FOLDER))
329             {
330                 /* Draw resource file from one folder to another. */
331 
332                 if (new_parent->mpRes)
333                 {
334                     if (new_parent->mpRes->type == RES_TYPE_PIXELMAP)
335                     {
336                         new_parent = new_parent->Parent();
337                     }
338 
339                     if ((new_parent != mpDragItem->Parent()) &&
340                         (new_parent->mpRes->type == RES_TYPE_FOLDER) &&
341                         (new_parent->mpRes->folder_id == CUSTOM_PIXELMAP_FOLDER))
342                     {
343                         ChangeItemParent(mpDragItem, new_parent);
344 
345                         project->SetModified();
346                     }
347                 }
348             }
349             else
350             {
351                 /* Drag resource file to target screen. */
352                 ClientToScreen(&point);
353                 GetTargetScreen()->TestDropItem(mpDragItem, point, Shifted);
354             }
355         }
356     }
357     mpDragItem = NULL;
358     KillTimer(DRAG_MOVE_TIMER_ID);
359 }
360 
361 ///////////////////////////////////////////////////////////////////////////////
PopupMenu(int MenuId,CPoint & pos)362 void resource_view::PopupMenu(int MenuId, CPoint &pos)
363 {
364     VALID_PROJECT
365     resource_item *item = mpCurrentItem;
366     res_info *info = item->mpRes;
367 	CMenu menu;
368 	CMenu* pPopup;
369 
370     menu.LoadMenu(MenuId);
371 
372     if (MenuId == IDR_PIX_SUBFOLDER_MENU)
373     {
374         if (info->folder_id == PIXELMAP_GROUP)
375         {
376             menu.EnableMenuItem(ID_ADD_PIXELMAP, MF_DISABLED);
377             menu.EnableMenuItem(ID_ADD_PIXELMAP_FOLDER, MF_ENABLED);
378             menu.EnableMenuItem(ID_REMOVE_PIXELMAP_FOLDER, MF_DISABLED);
379             menu.EnableMenuItem(ID_RENAME_PIXELMAP_FOLDER, MF_DISABLED);
380         }
381         else if (info->folder_id == DEFAULT_PIXELMAP_FOLDER)
382         {
383             menu.EnableMenuItem(ID_ADD_PIXELMAP, MF_DISABLED);
384             menu.EnableMenuItem(ID_EDIT_PIXELMAPS, MF_ENABLED);
385             menu.EnableMenuItem(ID_ADD_PIXELMAP_FOLDER, MF_DISABLED);
386             menu.EnableMenuItem(ID_REMOVE_PIXELMAP_FOLDER, MF_DISABLED);
387             menu.EnableMenuItem(ID_RENAME_PIXELMAP_FOLDER, MF_DISABLED);
388         }
389         else
390         {
391             menu.EnableMenuItem(ID_ADD_PIXELMAP, MF_ENABLED);
392             menu.EnableMenuItem(ID_ADD_PIXELMAP_FOLDER, MF_DISABLED);
393             menu.EnableMenuItem(ID_REMOVE_PIXELMAP_FOLDER, MF_ENABLED);
394             menu.EnableMenuItem(ID_RENAME_PIXELMAP_FOLDER, MF_ENABLED);
395         }
396 
397         int enable_menu_state;
398         int disable_menu_state;
399 
400         switch (GetFolderEnableDisableState(info))
401         {
402         case RES_STATE_ENABLED:
403             enable_menu_state = MF_CHECKED;
404             disable_menu_state = MF_UNCHECKED;
405             break;
406 
407         case RES_STATE_DISABLED:
408             enable_menu_state = MF_UNCHECKED;
409             disable_menu_state = MF_CHECKED;
410             break;
411 
412         case RES_STATE_UNDETERMINED:
413         default:
414             enable_menu_state = MF_UNCHECKED;
415             disable_menu_state = MF_UNCHECKED;
416             break;
417 
418         }
419 
420         menu.CheckMenuItem(ID_ENABLE_PIXELMAP_FOLDER, enable_menu_state);
421         menu.CheckMenuItem(ID_DISABLE_PIXELMAP_FOLDER, disable_menu_state);
422     }
423     else
424     {
425         if (info->enabled)
426         {
427             menu.CheckMenuItem(ID_PIXELMAP_ENABLE, MF_CHECKED);
428             menu.CheckMenuItem(ID_PIXELMAP_DISABLE, MF_UNCHECKED);
429         }
430         else
431         {
432             menu.CheckMenuItem(ID_PIXELMAP_ENABLE, MF_UNCHECKED);
433             menu.CheckMenuItem(ID_PIXELMAP_DISABLE, MF_CHECKED);
434         }
435     }
436 
437 
438 	pPopup = menu.GetSubMenu(0);
439 	ClientToScreen(&pos);
440     pPopup->TrackPopupMenu(TPM_LEFTALIGN, pos.x, pos.y, this);
441 }
442 
443 ///////////////////////////////////////////////////////////////////////////////
OnLButtonDblClk(UINT nFlags,CPoint point)444 void resource_view::OnLButtonDblClk(UINT nFlags, CPoint point)
445 {
446     VALID_PROJECT
447     CPoint treepoint = point;
448     treepoint.y += GetScrollPos(SB_VERT);
449     resource_item *item = mpTree->FindItem(mpTree->GetRoot(), treepoint);
450     int item_type = RES_TYPE_STRING;
451 
452     if (!item)
453     {
454         return;
455     }
456 
457     SetCurrentItem(item);
458 
459     if (item->mpRes)
460     {
461         item_type = item->mpRes->type;
462     }
463 
464     switch(item_type)
465     {
466     case RES_TYPE_COLOR:
467         if (project->GetResourceId(mDisplayIndex, item->mpRes) >= GX_COLOR_ID_CANVAS)
468         {
469             if (item->mpRes->is_default)
470             {
471                 OnEditSystemColor();
472             }
473             else
474             {
475                 OnEditCustomColor();
476             }
477         }
478         break;
479 
480     case RES_TYPE_FONT:
481         OnEditFont();
482         break;
483 
484     case RES_TYPE_PIXELMAP:
485         OnEditPixelmap();
486         break;
487 
488     case RES_TYPE_STRING:
489         OnEditStringTable();
490         break;
491 
492     default:
493         break;
494     }
495 }
496 
497 ///////////////////////////////////////////////////////////////////////////////
OnContextMenu(CWnd * pWnd,CPoint point)498 void resource_view::OnContextMenu(CWnd* pWnd, CPoint point)
499 {
500     // TODO: Add your message handler code here
501     VALID_PROJECT
502 
503     if (!mpCurrentItem)
504     {
505         return;
506     }
507 
508     CPoint pt;
509 
510     if (point.x == -1 && point.y == -1)
511     {
512         // The contet menu is generated from the keyboard, for example the user types Shift+F10
513         // Pop up menu under selected item
514         CRect size = mpCurrentItem->GetPos();
515         pt.x = size.left;
516         pt.y = size.bottom - GetScrollPos(SB_VERT);;
517     }
518     else
519     {
520         pt.x = point.x;
521         pt.y = point.y;
522     }
523 
524     switch (mpCurrentItem->GetResType())
525     {
526     case RES_TYPE_COLOR:
527         if (project->GetResourceId(mDisplayIndex, mpCurrentItem->mpRes) >= GX_COLOR_ID_CANVAS)
528         {
529             if (mpCurrentItem->mpRes->is_default)
530             {
531                 PopupMenu(IDR_SYSTEM_COLOR_MENU, pt);
532             }
533             else
534             {
535                 PopupMenu(IDR_CUSTOM_COLOR_MENU, pt);
536             }
537         }
538         break;
539 
540     case RES_TYPE_FONT:
541         if (mpCurrentItem->mpRes->is_default)
542         {
543             PopupMenu(IDR_DEFAULT_FONT_MENU, pt);
544         }
545         else
546         {
547             PopupMenu(IDR_FONT_SUBMENU, pt);
548         }
549         break;
550 
551     case RES_TYPE_PIXELMAP:
552         PopupMenu(IDR_PIXELMAP_MENU, pt);
553         break;
554 
555     case RES_TYPE_FOLDER:
556     case RES_TYPE_GROUP:
557         if (mpCurrentItem->mpRes->folder_id == STRING_GROUP)
558         {
559             PopupMenu(IDR_STRING_MENU, pt);
560         }
561         else if ((mpCurrentItem->mpRes->folder_id == PIXELMAP_GROUP) ||
562                  (mpCurrentItem->mpRes->folder_id == CUSTOM_PIXELMAP_FOLDER) ||
563                  (mpCurrentItem->mpRes->folder_id == DEFAULT_PIXELMAP_FOLDER))
564         {
565             PopupMenu(IDR_PIX_SUBFOLDER_MENU, pt);
566         }
567         break;
568 
569     default:
570         break;
571     }
572 }
573 
574 ///////////////////////////////////////////////////////////////////////////////
OnRButtonDown(UINT nFlags,CPoint point)575 void resource_view::OnRButtonDown(UINT nFlags, CPoint point)
576 {
577     CPoint treepoint = point;
578     treepoint.y += GetScrollPos(SB_VERT);
579     resource_item *item = mpTree->FindItem(mpTree->GetRoot(), treepoint);
580 
581     if (!item)
582     {
583         return;
584     }
585 
586     SetCurrentItem(item);
587 
588     SendMessage(WM_CONTEXTMENU, (WPARAM)m_hWnd, point.x | (point.y << 16));
589 }
590 
591 ///////////////////////////////////////////////////////////////////////////////
OnOpenProject()592 void resource_view::OnOpenProject()
593 {
594     mpTree->DeleteAllItems();
595     mDisplayIndex = -1;
596 }
597 
598 ///////////////////////////////////////////////////////////////////////////////
AddStringItems(resource_item * parent)599 void resource_view::AddStringItems(resource_item *parent)
600 {
601     VALID_PROJECT
602 
603     if (mDisplayIndex < 0)
604     {
605         return;
606     }
607 
608     int StringId;
609     int NumStrings;
610     int language = 0;
611 
612     string_table *pt = project->mDisplays[mDisplayIndex].stable;
613 
614     if (pt)
615     {
616         language = pt->GetActiveLanguage();
617         NumStrings = pt->CountStrings();
618 
619         for (StringId = 1; StringId < NumStrings; StringId++)
620         {
621             mpTree->InsertItem(parent, pt->GetStringId(StringId), pt->GetString(StringId, language));
622         }
623     }
624 }
625 
626 ///////////////////////////////////////////////////////////////////////////////
RebuildStringItems(BOOL update_GUIX)627 void resource_view::RebuildStringItems(BOOL update_GUIX)
628 {
629     VALID_PROJECT
630     string_table *table = project->mDisplays[mDisplayIndex].stable;
631 
632     if (table)
633     {
634         // first, get rid of the old string items:
635         resource_item *string_group = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_GROUP, STRING_GROUP);
636 
637         if (string_group)
638         {
639             CRect size = string_group->GetPos();
640 
641             if (mpCurrentItem)
642             {
643                 //get position of current item
644                 resource_item* item = string_group->First();
645 
646                 while (item)
647                 {
648                     if (mpCurrentItem == item)
649                     {
650                         size = mpCurrentItem->GetPos();
651                         SetCurrentItem(NULL);
652                         break;
653                     }
654 
655                     item = item->Next();
656                 }
657             }
658 
659             int scrollpos = GetScrollPos(SB_VERT);
660 
661             while(string_group->First())
662             {
663                 mpTree->DeleteItem(string_group->First(), FALSE);
664             }
665 
666             // now re-add all the string items
667             AddStringItems(string_group);
668 
669             // Add string add item
670             res_info* pStringAdd = new res_info(RES_TYPE_ADD_STRING);
671             string_group->mpRes->Attach(pStringAdd);
672             mpTree->InsertItem(string_group, pStringAdd);
673 
674             mpTree->PositionItems();
675             SetScrollPos(SB_VERT, scrollpos, TRUE);
676 
677             if (mpCurrentItem == NULL)
678             {
679                 CPoint cp;
680                 cp.x = size.left;
681                 cp.y = ((size.top + size.bottom) >> 1);
682                 resource_item *item = mpTree->FindItem(mpTree->GetRoot(), cp);
683 
684                 while (!item)
685                 {
686                     item = mpTree->FindItem(mpTree->GetRoot(), cp);
687                     cp.y -= size.Height();
688                 }
689 
690                 if (item)
691                 {
692                     SetCurrentItem(item);
693                 }
694             }
695         }
696         else
697         {
698             ErrorMsg("Internal Error: resource view string group not found");
699         }
700 
701         if (update_GUIX)
702         {
703             // our tree view is now updated, update the GUIX side of things
704             table->UpdateGuixLanguageTable();
705         }
706     }
707 }
708 
709 ///////////////////////////////////////////////////////////////////////////////
InsertTreeResources(resource_item * parent,res_info * start)710 void resource_view::InsertTreeResources(resource_item *parent, res_info *start)
711 {
712     while(start)
713     {
714         resource_item *current = mpTree->InsertItem(parent, start);
715 
716         switch(start->type)
717         {
718         case RES_TYPE_HEADER:
719             if (current->mpRes->folder_id == THEME_HEADER)
720             {
721                 current->SetIcon(IDB_CONFIGURE_THEMES, IDB_CONFIGURE_THEMES_HIGHLIGHT);
722             }
723             break;
724 
725         case RES_TYPE_GROUP:
726             switch(current->mpRes->folder_id)
727             {
728             case COLOR_GROUP:
729                 current->SetIcon(IDB_COLORS, IDB_COLORS_HIGHLIGHT);
730                 break;
731 
732             case FONT_GROUP:
733                 current->SetIcon(IDB_FONTS, IDB_FONTS_HIGHLIGHT);
734                 break;
735 
736             case PIXELMAP_GROUP:
737                 current->SetIcon(IDB_PIXELMAPS, IDB_PIXELMAPS_HIGHLIGHT);
738                 break;
739 
740             case STRING_GROUP:
741                 current->SetIcon(IDB_STRINGS, IDB_STRINGS_HIGHLIGHT);
742 
743                 if (mDisplayIndex >= 0)
744                 {
745                     AddStringItems(current);
746                 }
747                 break;
748             }
749             break;
750 
751         case RES_TYPE_FOLDER:
752             current->SetIcon(IDB_FOLDER_CLOSE, 0);
753             break;
754 
755         case RES_TYPE_FONT:
756             break;
757 
758         case RES_TYPE_COLOR:
759             current->SetColorValue(start->colorval);
760             break;
761 
762         case RES_TYPE_PIXELMAP:
763         case RES_TYPE_STRING:
764         default:
765             break;
766         }
767         if (start->child)
768         {
769             InsertTreeResources(current, start->child);
770         }
771         start = start->next;
772     }
773 }
774 
775 ///////////////////////////////////////////////////////////////////////////////
GetNativeColor(GX_COLOR rgb_color,int color_format)776 GX_COLOR resource_view::GetNativeColor(GX_COLOR rgb_color, int color_format)
777 {
778     GX_COLOR native_color = 0;
779 
780     switch (color_format)
781     {
782     case GX_COLOR_FORMAT_MONOCHROME_INVERTED:
783     case GX_COLOR_FORMAT_2BIT_GRAY:
784     case GX_COLOR_FORMAT_2BIT_GRAY_INVERTED:
785     case GX_COLOR_FORMAT_4BIT_VGA:
786     case GX_COLOR_FORMAT_8BIT_GRAY:
787     case GX_COLOR_FORMAT_8BIT_GRAY_INVERTED:
788     case GX_COLOR_FORMAT_8BIT_PALETTE:
789         // the incoming color is really just a palette index, not rgb color
790         native_color = rgb_color;
791         break;
792 
793     case GX_COLOR_FORMAT_MONOCHROME:
794         image_reader::ConvertRGBToGray(rgb_color, (GX_UBYTE *)&native_color);
795         if ((native_color & 0xff) < 128)
796         {
797             native_color = 0x00;
798         }
799         else
800         {
801             native_color = 0x01;
802         }
803         break;
804 
805     case GX_COLOR_FORMAT_4BIT_GRAY:
806         image_reader::ConvertRGBToGray(rgb_color, (GX_UBYTE *)&native_color);
807         native_color >>= 4;
808         break;
809 
810     case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
811         native_color = ((rgb_color & 0xe00000) >> 16) | ((rgb_color & 0x00e000) >> 11) | ((rgb_color & 0x0000c0) >> 6);
812         break;
813 
814     case GX_COLOR_FORMAT_5551BGRX:
815         native_color = (((rgb_color & 0xf8) << 8) | ((rgb_color & 0xf800) >> 5) | ((rgb_color & 0xf80000) >> 15));
816         break;
817 
818     case GX_COLOR_FORMAT_1555XRGB:
819         native_color = (((rgb_color & 0xf80000) >> 9) | ((rgb_color & 0xf800) >> 6) | ((rgb_color & 0xf8) >> 3));
820         break;
821 
822     case GX_COLOR_FORMAT_4444ARGB:
823         native_color = ((rgb_color & 0xf00000) >> 12) | ((rgb_color & 0x00f000) >> 8) | ((rgb_color & 0x0000f0) >> 4) | 0xf000;
824         break;
825 
826     case GX_COLOR_FORMAT_4444BGRA:
827         native_color = ((rgb_color & 0xf00000) >> 20) | ((rgb_color & 0x00f000) >> 4) | ((rgb_color & 0x0000f0) << 8) | 0x000f;
828         break;
829 
830     case GX_COLOR_FORMAT_565RGB:
831         native_color = ((rgb_color & 0xf80000) >> 8) | ((rgb_color & 0x00fc00) >> 5) | ((rgb_color & 0x0000ff) >> 3);
832         break;
833 
834     case GX_COLOR_FORMAT_565BGR:
835         native_color = ((rgb_color & 0x0000f8) << 8) | ((rgb_color & 0x00fc00) >> 5) | ((rgb_color & 0xf80000) >> 19);
836         break;
837 
838     case GX_COLOR_FORMAT_24RGB:
839     case GX_COLOR_FORMAT_24BGR:
840     case GX_COLOR_FORMAT_24XRGB:
841     case GX_COLOR_FORMAT_24BGRX:
842     case GX_COLOR_FORMAT_32ARGB:
843     case GX_COLOR_FORMAT_32RGBA:
844     case GX_COLOR_FORMAT_32ABGR:
845     case GX_COLOR_FORMAT_32BGRA:
846         native_color = rgb_color;
847         break;
848     }
849     return native_color;
850 }
851 
852 ///////////////////////////////////////////////////////////////////////////////
GetColorRef(GX_COLOR gx_color,int color_format,GX_COLOR * palette,int palsize)853 COLORREF resource_view::GetColorRef(GX_COLOR gx_color, int color_format, GX_COLOR *palette, int palsize)
854 {
855     COLORREF color = 0;
856     int red = 0;
857     int green = 0;
858     int blue = 0;
859 
860     switch (color_format)
861     {
862     case GX_COLOR_FORMAT_8BIT_PALETTE:
863     case GX_COLOR_FORMAT_MONOCHROME:
864     case GX_COLOR_FORMAT_4BIT_GRAY:
865         if (palette && ((int)gx_color < palsize))
866         {
867             color = palette[gx_color];
868             red = (color & 0xff0000) >> 16;
869             green = (color & 0xff00) >> 8;
870             blue = (color & 0xff);
871         }
872         break;
873 
874     case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
875         red = (gx_color & 0xe0) >> 5;
876         red = (red << 5) | (red << 2) || (red >> 1);
877 
878         green = (gx_color & 0x18) >> 3;
879         green = (green << 5) | (green << 2) | (green >> 1);
880 
881         blue = (gx_color & 0x1f);
882         blue = (blue << 5) | (blue << 2) | (blue >> 1);
883         break;
884 
885     case GX_COLOR_FORMAT_5551BGRX:
886         blue = (gx_color & 0x7c) >> 10;
887         blue = (blue << 3) | (blue >> 2);
888 
889         green = (gx_color & 0x3e) >> 5;
890         green = (green << 3) | (red >> 2);
891 
892         red = (gx_color & 0x1f);
893         red = (red << 3) | (red >> 2);
894         break;
895 
896     case GX_COLOR_FORMAT_1555XRGB:
897         red = (gx_color & 0x7c) >> 10;
898         red = (red << 3) | (red >> 2);
899 
900         green = (gx_color & 0x3e) >> 5;
901         green = (green << 3) | (red >> 2);
902 
903         blue = (gx_color & 0x1f);
904         blue = (blue << 3) | (blue >> 2);
905         break;
906 
907     case GX_COLOR_FORMAT_4444ARGB:
908         red = (gx_color & 0xf00) >> 16;
909         red = (red << 8) | red;
910 
911         green = (gx_color & 0xf0) >> 8;
912         green = (green << 8) | green;
913 
914         blue = (gx_color & 0xf);
915         blue = (blue << 8) | blue;
916         break;
917 
918     case GX_COLOR_FORMAT_4444BGRA:
919         blue = (gx_color & 0xf000) >> 24;
920         blue = (blue << 8) | blue;
921 
922         green = (gx_color & 0xf00) >> 16;
923         green = (green << 8) | green;
924 
925         red = (gx_color & 0xf0) >> 8;
926         red = (red << 8) | red;
927         break;
928 
929     case GX_COLOR_FORMAT_565RGB:
930         red = (gx_color & 0xf100) >> 11;
931         red = (red << 3) | (red >> 2);
932 
933         green = (gx_color & 0x7e0) >> 5;
934         green = (green << 2) | (green >> 4);
935 
936         blue = (gx_color & 0x1f);
937         blue = (blue << 3) | (blue >> 2);
938         break;
939 
940     case GX_COLOR_FORMAT_24RGB:
941     case GX_COLOR_FORMAT_32ABGR:
942     default:
943         red = (gx_color >> 16) & 0xff;
944         green = (gx_color >> 8) & 0xff;
945         blue = (gx_color) & 0xff;
946         break;
947     }
948 
949     color = RGB(red, green, blue);
950 
951     return color;
952 }
953 
954 
955 ///////////////////////////////////////////////////////////////////////////////
BuildColorTable(int DisplayIndex,int ThemeIndex,int color_format,color_table * table)956 int resource_view::BuildColorTable(int DisplayIndex, int ThemeIndex, int color_format, color_table *table)
957 {
958     GX_COLOR color_val;
959     GX_COLOR native_color;
960     studiox_project *project = GetOpenProject();
961     int color_id;
962     CString color_name;
963 
964     res_info *res = project->mDisplays[DisplayIndex].themes[ThemeIndex].GetFirstResourceInfo();
965     res_info *color_res;
966     int numcolors = project->CountResources(DisplayIndex, RES_TYPE_COLOR);
967 
968     table->colors = NULL;
969     table->num_colors = numcolors;
970 
971     if (numcolors)
972     {
973         table->colors = new GX_COLOR[numcolors];
974         memset(table->colors, 0, (numcolors * sizeof(GX_COLOR)));
975 
976         for (color_id = 0; color_id < numcolors; color_id++)
977         {
978             project->GetResourceName(DisplayIndex, RES_TYPE_COLOR, color_id, color_name);
979             color_res = project->FindResource(res, RES_TYPE_COLOR, color_name);
980 
981             if (color_res)
982             {
983                 color_val = color_res->colorval;
984                 native_color = GetNativeColor(color_val, color_format);
985                 table->colors[color_id] = native_color;
986             }
987         }
988     }
989     return TRUE;
990 }
991 
992 
993 ///////////////////////////////////////////////////////////////////////////////
BuildFontTable(int DisplayIndex,int ThemeIndex,font_table * table)994 int resource_view::BuildFontTable(int DisplayIndex, int ThemeIndex, font_table *table)
995 {
996     studiox_project *project = GetOpenProject();
997     int font_id;
998     res_info *font_res;
999     CString font_name;
1000 
1001     res_info *res = project->mDisplays[DisplayIndex].themes[ThemeIndex].GetFirstResourceInfo();
1002     int numfonts = project->CountResources(DisplayIndex, RES_TYPE_FONT);
1003 
1004     table->fonts = NULL;
1005     table->num_fonts = numfonts;
1006 
1007     if (numfonts)
1008     {
1009         table->fonts = new GX_FONT *[numfonts];
1010         memset(table->fonts, 0, (numfonts * sizeof(GX_FONT *)));
1011 
1012         for (font_id = 0; font_id < numfonts; font_id++)
1013         {
1014             project->GetResourceName(DisplayIndex, RES_TYPE_FONT, font_id, font_name);
1015             font_res = project->FindResource(res, RES_TYPE_FONT, font_name);
1016 
1017             if (font_res)
1018             {
1019                 table->fonts[font_id] = font_res->font;
1020             }
1021         }
1022     }
1023     return TRUE;
1024 }
1025 
1026 
1027 ///////////////////////////////////////////////////////////////////////////////
BuildPixelmapTable(int DisplayIndex,int ThemeIndex,pixelmap_table * table)1028 int resource_view::BuildPixelmapTable(int DisplayIndex, int ThemeIndex, pixelmap_table *table)
1029 {
1030     studiox_project *project = GetOpenProject();
1031     int pixelmap_id;
1032     res_info *pixelmap_res;
1033     CString pixelmap_name;
1034 
1035     res_info *res = project->mDisplays[DisplayIndex].themes[ThemeIndex].GetFirstResourceInfo();
1036     int num_pixelmaps = project->CountResources(DisplayIndex, RES_TYPE_PIXELMAP);
1037 
1038     table->maps = NULL;
1039     table->num_maps = num_pixelmaps;
1040 
1041     if (num_pixelmaps)
1042     {
1043         table->maps = new GX_PIXELMAP *[num_pixelmaps];
1044         memset(table->maps, 0, (num_pixelmaps * sizeof(GX_PIXELMAP *)));
1045         table->maps[0] = GX_NULL;
1046 
1047         for (pixelmap_id = 1; pixelmap_id < num_pixelmaps; pixelmap_id++)
1048         {
1049             project->GetResourceName(DisplayIndex, RES_TYPE_PIXELMAP, pixelmap_id, pixelmap_name);
1050             pixelmap_res = project->FindResource(res, RES_TYPE_PIXELMAP, pixelmap_name);
1051 
1052             if (pixelmap_res)
1053             {
1054                 table->maps[pixelmap_id] = pixelmap_res->GetPixelmap();
1055             }
1056         }
1057     }
1058     return TRUE;
1059 }
1060 
1061 ///////////////////////////////////////////////////////////////////////////////
CheckInstallPalette(int DisplayIndex,GX_DISPLAY * display)1062 void resource_view::CheckInstallPalette(int DisplayIndex, GX_DISPLAY *display)
1063 {
1064     VALID_PROJECT
1065 
1066     if (!display)
1067     {
1068         return;
1069     }
1070 
1071     if (project->IsPaletteMode(DisplayIndex) &&
1072         display->gx_display_driver_palette_set)
1073     {
1074         // if this is a palette mode driver, install the palette:
1075         int theme_index = project->mDisplays[DisplayIndex].active_theme;
1076         GX_COLOR *pPalette = project->mDisplays[DisplayIndex].themes[theme_index].palette;
1077 
1078         if (pPalette)
1079         {
1080             display->gx_display_driver_palette_set(display, pPalette,
1081                 project->mDisplays[DisplayIndex].themes[theme_index].palette_total_size);
1082         }
1083     }
1084 }
1085 
1086 ///////////////////////////////////////////////////////////////////////////////
InstallColorTable(int DisplayIndex,GX_DISPLAY * display)1087 void resource_view::InstallColorTable(int DisplayIndex, GX_DISPLAY *display)
1088 {
1089     VALID_PROJECT
1090 
1091     color_table table;
1092 
1093     if (DisplayIndex < 0)
1094     {
1095         return;
1096     }
1097 
1098     int ThemeIndex = GetOpenProject()->mDisplays[DisplayIndex].active_theme;
1099 
1100     if (!display)
1101     {
1102          display = get_target_view_display();
1103     }
1104 
1105     CheckInstallPalette(DisplayIndex, display);
1106 
1107     BuildColorTable(DisplayIndex, ThemeIndex, project->mDisplays[DisplayIndex].colorformat, &table);
1108 
1109     if (display)
1110     {
1111         GX_COLOR *old_color_table = display->gx_display_color_table;
1112         gx_display_color_table_set(display, table.colors, table.num_colors);
1113 
1114         if (old_color_table)
1115         {
1116             delete [] old_color_table;
1117         }
1118     }
1119 }
1120 
1121 ///////////////////////////////////////////////////////////////////////////////
InstallFontTable(int DisplayIndex,GX_DISPLAY * display)1122 void resource_view::InstallFontTable(int DisplayIndex, GX_DISPLAY *display)
1123 {
1124     VALID_PROJECT
1125     font_table table;
1126 
1127     if (DisplayIndex < 0)
1128     {
1129         return;
1130     }
1131 
1132     int ThemeIndex = GetOpenProject()->mDisplays[DisplayIndex].active_theme;
1133 
1134     BuildFontTable(DisplayIndex, ThemeIndex, &table);
1135 
1136     if (!display)
1137     {
1138         display = get_target_view_display();
1139     }
1140     if (display)
1141     {
1142         GX_FONT **old_font_table = display->gx_display_font_table;
1143         gx_display_font_table_set(display, table.fonts, table.num_fonts);
1144         if (old_font_table)
1145         {
1146             delete [] old_font_table;
1147         }
1148     }
1149 }
1150 
1151 ///////////////////////////////////////////////////////////////////////////////
InstallPixelmapTable(int DisplayIndex,GX_DISPLAY * display)1152 void resource_view::InstallPixelmapTable(int DisplayIndex, GX_DISPLAY *display)
1153 {
1154     VALID_PROJECT
1155     pixelmap_table table;
1156 
1157     if (DisplayIndex < 0)
1158     {
1159         return;
1160     }
1161 
1162     if (!display)
1163     {
1164         display = get_target_view_display();
1165     }
1166 
1167     int ThemeIndex = GetOpenProject()->mDisplays[DisplayIndex].active_theme;
1168 
1169     if (display)
1170     {
1171         CheckInstallPalette(DisplayIndex, display);
1172 
1173         GX_PIXELMAP **old_map_table = display->gx_display_pixelmap_table;
1174         BuildPixelmapTable(DisplayIndex, ThemeIndex, &table);
1175         gx_display_pixelmap_table_set(display, table.maps, table.num_maps);
1176 
1177         if (old_map_table)
1178         {
1179             delete [] old_map_table;
1180         }
1181     }
1182 }
1183 
1184 /////////////////////////////////////////////////////////////////////////////
BuildResourceTables(int DisplayIndex,GX_DISPLAY * display,BOOL update_resource_view)1185 void resource_view::BuildResourceTables(int DisplayIndex, GX_DISPLAY *display, BOOL update_resource_view)
1186 {
1187     VALID_PROJECT
1188 
1189     // Install these resources with GUIX:
1190     InstallColorTable(DisplayIndex, display);
1191     InstallFontTable(DisplayIndex, display);
1192     InstallPixelmapTable(DisplayIndex, display);
1193 
1194     string_table *table = project->mDisplays[DisplayIndex].stable;
1195     if (table)
1196     {
1197         table->UpdateGuixLanguageTable(display, update_resource_view);
1198     }
1199 }
1200 
1201 /////////////////////////////////////////////////////////////////////////////
InstallResourcesThreadEntry(LPVOID thread_input)1202 static DWORD WINAPI InstallResourcesThreadEntry(LPVOID thread_input)
1203 {
1204     resource_view *res_view = (resource_view*)GetResourceView();
1205 
1206     if (res_view)
1207     {
1208         int display_index = (int)thread_input;
1209         res_view->BuildResourceTables(display_index, NULL);
1210     }
1211 
1212     EndBusyMsg();
1213 
1214     return TRUE;
1215 }
1216 
1217 /////////////////////////////////////////////////////////////////////////////
InstallResources(int DisplayIndex)1218 void resource_view::InstallResources(int DisplayIndex)
1219 {
1220     VALID_PROJECT
1221 
1222     int ThemeIndex = GetOpenProject()->mDisplays[DisplayIndex].active_theme;
1223 
1224     // Delete resource tree
1225     mpTree->DeleteAllItems();
1226 
1227     // populate the tree with the selected display's resources
1228     res_info *info = project->mDisplays[DisplayIndex].themes[ThemeIndex].GetFirstResourceInfo();
1229     InsertTreeResources(NULL, info);
1230 
1231     resource_item *root = mpTree->GetRoot();
1232     if (root)
1233     {
1234         // Set current item
1235         SetCurrentItem(root->First());
1236     }
1237 
1238     StartWorkThread(InstallResourcesThreadEntry, (LPVOID)DisplayIndex, "Installing Resources.", TRUE);
1239 }
1240 
1241 /////////////////////////////////////////////////////////////////////////////
CreateUniqueResourceName(res_info * info)1242 void resource_view::CreateUniqueResourceName(res_info *info)
1243 {
1244     CString base_name = info->name;
1245     CString name;
1246     CString num;
1247     int val = 1;
1248 
1249     while (1)
1250     {
1251         num.Format(_T("%d"), val);
1252 
1253         name = base_name + num;
1254         if (!NameExists(mDisplayIndex, info->type, name))
1255         {
1256             info->name = name;
1257             return;
1258         }
1259         val++;
1260     }
1261 }
1262 
1263 /////////////////////////////////////////////////////////////////////////////
OnDisplaySelect(int DisplayIndex,BOOL bReload)1264 void resource_view::OnDisplaySelect(int DisplayIndex, BOOL bReload)
1265 {
1266     VALID_PROJECT
1267     if (mDisplayIndex != DisplayIndex || bReload)
1268     {
1269         mNewResourcePasted = FALSE;
1270         mpTree->DeleteAllItems();
1271         mDisplayIndex = DisplayIndex;
1272 
1273         if (DisplayIndex >= 0)
1274         {
1275             InstallResources(DisplayIndex);
1276         }
1277 
1278         mpTree->PositionItems();
1279     }
1280 }
1281 
1282 /////////////////////////////////////////////////////////////////////////////
InitializeThemePixelmapsThreadEntry(LPVOID thread_input)1283 static DWORD WINAPI InitializeThemePixelmapsThreadEntry(LPVOID thread_input)
1284 {
1285     studiox_project *project = GetOpenProject();
1286 
1287     if (project)
1288     {
1289         int display_index = (int)thread_input;
1290         project->InitializeThemePixelmaps(display_index, project->mDisplays[display_index].active_theme);
1291     }
1292 
1293     EndBusyMsg();
1294 
1295     return TRUE;
1296 }
1297 
1298 /////////////////////////////////////////////////////////////////////////////
FinalizePasteResources()1299 void resource_view::FinalizePasteResources()
1300 {
1301     studiox_project *project = GetOpenProject();
1302 
1303     if (mNewResourcePasted && project)
1304     {
1305         string_table *table = project->mDisplays[mDisplayIndex].stable;
1306         if (table)
1307         {
1308             table->Sort();
1309         }
1310 
1311         if (project->IsPaletteMode(mDisplayIndex))
1312         {
1313             StartWorkThread(InitializeThemePixelmapsThreadEntry, (LPVOID)mDisplayIndex, "Creating Optimal Palette.", TRUE);
1314         }
1315 
1316         OnDisplaySelect(mDisplayIndex, TRUE);
1317         mNewResourcePasted = FALSE;
1318     }
1319 }
1320 
CleanupDisplayResources(GX_DISPLAY * display)1321 void resource_view::CleanupDisplayResources(GX_DISPLAY *display)
1322 {
1323     GX_PIXELMAP **old_map_table;
1324     GX_COLOR    *old_color_table;
1325     GX_FONT     **old_font_table;
1326 
1327     old_map_table = display->gx_display_pixelmap_table;
1328     gx_display_pixelmap_table_set(display, NULL, 0);
1329 
1330     old_font_table = display->gx_display_font_table;
1331     gx_display_font_table_set(display, NULL, 0);
1332 
1333     old_color_table = display->gx_display_color_table;
1334     gx_display_color_table_set(display, NULL, 0);
1335 
1336     if (old_map_table)
1337     {
1338         delete [] old_map_table;
1339     }
1340 
1341     if (old_font_table)
1342     {
1343         delete [] old_font_table;
1344     }
1345 
1346     if (old_color_table)
1347     {
1348         delete [] old_color_table;
1349     }
1350 
1351     // if we installed a string table with GUIX, delete it now:
1352     GX_STRING **pOldTable = NULL;
1353     GX_UBYTE language_count = 0;
1354     UINT string_count = 0;
1355     gx_display_language_table_get_ext(display, &pOldTable, &language_count, &string_count);
1356 
1357     string_table::DeleteGuixLanguageDirectionTable(display);
1358 
1359     if (pOldTable)
1360     {
1361         string_table::DeleteGuixLanguageTable(pOldTable, language_count, string_count);
1362         gx_display_language_table_set_ext(display, NULL, 0, 0);
1363     }
1364 }
1365 
1366 ///////////////////////////////////////////////////////////////////////////////
OnCloseProject()1367 void resource_view::OnCloseProject()
1368 {
1369     mpTree->DeleteAllItems();
1370 
1371     CleanupDisplayResources(get_target_view_display());
1372 
1373     Invalidate();
1374     mDisplayIndex = -1;
1375 }
1376 
1377 ///////////////////////////////////////////////////////////////////////////////
OnTreeSizeChange()1378 void resource_view::OnTreeSizeChange()
1379 {
1380     if (mpTree)
1381     {
1382         CRect childsize;
1383         GetClientRect(&childsize);
1384         childsize.bottom = childsize.top + mpTree->GetHeight();
1385         childsize.right = childsize.left + mpTree->GetWidth();
1386 
1387         SIZE total;
1388         total.cx = childsize.Width();
1389         total.cy = childsize.Height() + 20;
1390 
1391         SetScrollSizes(MM_TEXT, total);
1392         Invalidate();
1393     }
1394 }
1395 
1396 ///////////////////////////////////////////////////////////////////////////////
OnAddCustomColor()1397 void resource_view::OnAddCustomColor()
1398 {
1399     VALID_PROJECT
1400     if (!mpCurrentItem)
1401     {
1402         return;
1403     }
1404 
1405     resource_item *parent;
1406 
1407     if (mpCurrentItem->GetResType() == RES_TYPE_ADD_COLOR)
1408     {
1409         parent = mpCurrentItem->Parent();
1410     }
1411     else
1412     {
1413         parent = mpCurrentItem;
1414     }
1415 
1416 
1417     // double check to insure we have the correct parent:
1418     if (mDisplayIndex == -1)
1419     {
1420         return;
1421     }
1422     if (parent->mpRes->name != "Custom")
1423     {
1424         return;
1425     }
1426 
1427     color_edit_dialog dlg(mDisplayIndex, this);
1428 
1429     if (dlg.DoModal() == IDOK)
1430     {
1431         GX_COLOR color = dlg.GetColor();
1432         CString name = dlg.GetName();
1433 
1434         // Add a res_info element to the project:
1435         AddColor(color, name, parent);
1436     }
1437 }
1438 
1439 ///////////////////////////////////////////////////////////////////////////////
1440 // KGM Note:
1441 // This function does NOT update the GUIX tables, because we could be adding
1442 // several resources so just update the tables once. The copy/paste engine will
1443 // force a table update after all resources are added.
1444 ///////////////////////////////////////////////////////////////////////////////
1445 
PasteResource(res_info * info,int conflict_option)1446 int resource_view::PasteResource(res_info *info, int conflict_option)
1447 {
1448     studiox_project *project = GetOpenProject();
1449     if (!project || !info)
1450     {
1451         return conflict_option;
1452     }
1453     resource_item *parent;
1454     resource_item *existing;
1455     res_info *new_info;
1456     display_info *display;
1457     int rgb_color = 0;
1458 
1459     switch(info->type)
1460     {
1461     case RES_TYPE_COLOR:
1462         parent = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_FOLDER, CUSTOM_COLOR_FOLDER);
1463         existing = mpTree->FindItem(parent, RES_TYPE_COLOR, info->name);
1464 
1465         display = &project->mDisplays[mDisplayIndex];
1466 
1467         if (display)
1468         {
1469             int active_theme = display->active_theme;
1470 
1471             //color convert
1472             info->colorval = ProjectConfigDlg::GetColorVal(info->colorval,
1473                 display->themes[active_theme].palette,
1474                 display->themes[active_theme].palette_predefined,
1475                 display->colorformat);
1476 
1477             rgb_color = ProjectConfigDlg::GetRGBColor(info->colorval,
1478                 display->themes[active_theme].palette,
1479                 display->themes[active_theme].palette_total_size,
1480                 display->colorformat);
1481         }
1482 
1483         if (existing)
1484         {
1485             if (existing->GetRGBColor() != rgb_color)
1486             {
1487                 //conflict
1488                 if (conflict_option == 0)
1489                 {
1490                     CString msg;
1491                     msg.Format(_T("Source and Destination projects have duplicate Color IDs \"%s\"."), info->name);
1492 
1493                     options_dialog dlg(_T("Warning"), msg, paste_conflict_options, this);
1494                     if (dlg.DoModal() == IDOK)
1495                     {
1496                         conflict_option = dlg.GetSelectedOption();
1497                     }
1498                 }
1499 
1500                 switch (conflict_option)
1501                 {
1502                 case PASTE_CONFLICT_OPTION_USE_SOURCE:
1503                     //Use string from source
1504                     existing->SetColorValue(info->colorval);
1505                     mNewResourcePasted = TRUE;
1506                     break;
1507 
1508                 case PASTE_CONFLICT_OPTION_RENAME:
1509                     //Rename pasted string id
1510                     CreateUniqueResourceName(info);
1511 
1512                     AddColor(info->colorval, info->name, parent);
1513                     mNewResourcePasted = TRUE;
1514                     break;
1515 
1516                 case PASTE_CONFLICT_OPTION_USE_DESTINATION:
1517                 case PASTE_CONFLICT_OPTION_ABORT:
1518                 default:
1519                     break;
1520                 }
1521             }
1522         }
1523         else
1524         {
1525             mNewResourcePasted = TRUE;
1526             AddColor(info->colorval, info->name, parent);
1527         }
1528         break;
1529 
1530     case RES_TYPE_FONT:
1531         parent = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_FOLDER, CUSTOM_FONT_FOLDER);
1532         existing = mpTree->FindItem(parent, RES_TYPE_FONT, info->name);
1533 
1534         if (!existing)
1535         {
1536             mNewResourcePasted = TRUE;
1537             new_info = new res_info(parent->mpRes, *info, FALSE);
1538             AddFont(parent, new_info);
1539         }
1540         break;
1541 
1542     case RES_TYPE_PIXELMAP:
1543         parent = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_FOLDER, CUSTOM_PIXELMAP_FOLDER);
1544 
1545         if (!parent)
1546         {
1547             // create a custom pixelmap folder
1548             parent = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_GROUP, PIXELMAP_GROUP);
1549 
1550             if (!parent)
1551             {
1552                 // this should NOT happen, but just in case
1553                 return conflict_option;
1554             }
1555             res_info *info = new res_info(RES_TYPE_FOLDER);
1556             info->name = _T("Custom");
1557             info->folder_id = CUSTOM_PIXELMAP_FOLDER;
1558             mpTree->CreateUniqueFolderName(info->name, info->folder_id);
1559 
1560             // insert new folder into project:
1561             parent->mpRes->Attach(info);
1562             InsertTreeResources(parent, info);
1563 
1564             SyncResourceAdd(info);
1565 
1566             // we created custom pixelmap folder, so now find it again:
1567             parent = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_FOLDER, CUSTOM_PIXELMAP_FOLDER);
1568 
1569             if (!parent)
1570             {
1571                 // This should NOT happen
1572                 return conflict_option;
1573             }
1574         }
1575 
1576         existing = mpTree->FindItem(parent, RES_TYPE_PIXELMAP, info->name);
1577 
1578         if (!existing)
1579         {
1580             mNewResourcePasted = TRUE;
1581             new_info = new res_info(parent->mpRes, *info, FALSE);
1582             int display_format = project->mDisplays[mDisplayIndex].colorformat;
1583             if (!edit_pixelmap_dlg::IsOutputFormatSupported(display_format, new_info->output_color_format) || new_info->raw)
1584             {
1585                 //if the output pixelmap format is not supported, reset output color format as default
1586                 new_info->output_color_format = 0;
1587             }
1588             if (display_format == GX_COLOR_FORMAT_8BIT_PALETTE)
1589             {
1590                 new_info->palette_type = PALETTE_TYPE_SHARED;
1591             }
1592 
1593             AddPixelmap(parent, new_info, project->IsPaletteMode(mDisplayIndex));
1594 
1595             for (int theme = 0; theme < project->mDisplays[mDisplayIndex].num_themes; theme++)
1596             {
1597 
1598                 if (project->GetDisplayColorFormat(new_info) == GX_COLOR_FORMAT_8BIT_PALETTE ||
1599                     project->TestForPixelmapsUsingGlobalPalette(project->mDisplays[mDisplayIndex].themes[theme].GetFirstResourceInfo()))
1600                 {
1601                     project->InitializeThemePixelmaps(mDisplayIndex, theme);
1602                 }
1603             }
1604         }
1605         break;
1606     }
1607     return conflict_option;
1608 }
1609 
1610 ///////////////////////////////////////////////////////////////////////////////
1611 // KGM Note:
1612 // This function does NOT update the GUIX tables, because we could be adding
1613 // several resources so just update the tables once. The copy/paste engine will
1614 // force a table update after all resources are added.
1615 ///////////////////////////////////////////////////////////////////////////////
1616 
PasteResource(string_table_record & record,int conflict_option)1617 int resource_view::PasteResource(string_table_record &record, int conflict_option)
1618 {
1619     int language;
1620     BOOL conflict_string_content = FALSE;
1621 
1622     studiox_project *project = GetOpenProject();
1623     if (!project || mDisplayIndex < 0)
1624     {
1625         return PASTE_CONFLICT_OPTION_ABORT;
1626     }
1627 
1628     string_table *table = project->mDisplays[mDisplayIndex].stable;
1629 
1630     if (table)
1631     {
1632         int string_index = table->FindStringIndex(record.id_name);
1633 
1634         if (string_index)
1635         {
1636             for (language = 0; language < table->CountLanguages(); language++)
1637             {
1638                 if (table->GetString(string_index, language) != record.strings[language])
1639                 {
1640                     conflict_string_content = TRUE;
1641                     break;
1642                 }
1643             }
1644 
1645             if (conflict_string_content)
1646             {
1647                 if (conflict_option == 0)
1648                 {
1649                     CString msg;
1650                     msg.Format(_T("Source and Destination projects have duplicate String IDs \"%s\"."), record.id_name);
1651 
1652                     options_dialog dlg(_T("Warning"), msg, paste_conflict_options, this);
1653                     if (dlg.DoModal() == IDOK)
1654                     {
1655                         conflict_option = dlg.GetSelectedOption();
1656                     }
1657                 }
1658 
1659                 switch (conflict_option)
1660                 {
1661                 case PASTE_CONFLICT_OPTION_USE_SOURCE:
1662                     //Use string from source
1663                     for (language = 0; language < table->CountLanguages(); language++)
1664                     {
1665                         table->SetString(string_index, language, record.strings[language], FALSE);
1666                     }
1667                     mNewResourcePasted = TRUE;
1668                     break;
1669 
1670                 case PASTE_CONFLICT_OPTION_USE_DESTINATION:
1671                     //use string from destination
1672                     break;
1673 
1674                 case PASTE_CONFLICT_OPTION_RENAME:
1675                     //Rename pasted string id
1676                     for (language = 0; language < table->CountLanguages(); language++)
1677                     {
1678                         int index = table->CheckAddString(record.strings[language], record.id_name);
1679                         record.id_name = table->GetResourceIdName(index);
1680                     }
1681                     mNewResourcePasted = TRUE;
1682                     break;
1683 
1684                 case PASTE_CONFLICT_OPTION_ABORT:
1685                 default:
1686                     //abort pasting
1687                     break;
1688                 }
1689             }
1690         }
1691         else
1692         {
1693             string_index = table->AddString(record.id_name, record.strings[0]);
1694             for (language = 0; language < table->CountLanguages(); language++)
1695             {
1696                 table->SetString(string_index, language, record.strings[language], FALSE);
1697             }
1698             mNewResourcePasted = TRUE;
1699         }
1700     }
1701     return conflict_option;
1702 }
1703 
1704 
1705 ///////////////////////////////////////////////////////////////////////////////
OnEditSystemColor()1706 void resource_view::OnEditSystemColor()
1707 {
1708     VALID_PROJECT
1709 
1710     if (!mpCurrentItem)
1711     {
1712         return;
1713     }
1714     resource_item *item = mpCurrentItem;
1715     GX_DISPLAY *display = get_target_view_display();
1716 
1717     color_edit_dialog dlg(item, mDisplayIndex, this);
1718 
1719     if (project && dlg.DoModal() == IDOK)
1720     {
1721         GX_COLOR color = dlg.GetColor();
1722 
1723         item->SetColorValue(color);
1724         project->SetModified();
1725         Invalidate();
1726         InstallColorTable(mDisplayIndex);
1727     }
1728 }
1729 
1730 
1731 ///////////////////////////////////////////////////////////////////////////////
OnEditCustomColor()1732 void resource_view::OnEditCustomColor()
1733 {
1734     VALID_PROJECT
1735     resource_item *item = mpCurrentItem;
1736     GX_DISPLAY *display = get_target_view_display();
1737 
1738     GX_COLOR color;
1739 
1740     if (!item || !item->mpRes)
1741     {
1742         return;
1743     }
1744 
1745     CString old_color_name = item->mpRes->name;
1746 
1747     color_edit_dialog dlg(item, mDisplayIndex, this);
1748 
1749     if (dlg.DoModal() == IDOK)
1750     {
1751         color = dlg.GetColor();
1752 
1753         item->SetColorValue(color);
1754         item->mpRes->name = dlg.GetName();
1755 
1756         if (old_color_name != item->mpRes->name)
1757         {
1758             SyncResourceName(old_color_name, item->mpRes);
1759 
1760             project->UpdateDictionaryResourceName(mDisplayIndex, old_color_name, item->mpRes);
1761             GetPropsWin()->ResourcesChanged();
1762 
1763             if (project->mDisplays[mDisplayIndex].stable)
1764             {
1765                 project->mDisplays[mDisplayIndex].stable->UpdateStringTableRichTextResourceName(RES_TYPE_COLOR, old_color_name, item->mpRes->name);
1766             }
1767         }
1768 
1769         InstallColorTable(mDisplayIndex);
1770         project->SetModified();
1771         Invalidate();
1772     }
1773 }
1774 
1775 ///////////////////////////////////////////////////////////////////////////////
OnAddFont()1776 void resource_view::OnAddFont()
1777 {
1778     VALID_PROJECT
1779     resource_item *parent;
1780 
1781     if (!mpCurrentItem)
1782     {
1783         return;
1784     }
1785 
1786     if (mpCurrentItem->GetResType() == RES_TYPE_ADD_FONT)
1787     {
1788         parent = mpCurrentItem->Parent();
1789     }
1790     else
1791     {
1792         parent = mpCurrentItem;
1793     }
1794 
1795     if (!parent || !parent->mpRes)
1796     {
1797         return;
1798     }
1799 
1800     res_info * info = InitFontInfo();
1801 
1802     font_path_dialog dlg(mDisplayIndex, project->mDisplays[mDisplayIndex].colorformat, info, this);
1803 
1804     if (dlg.DoModal() == IDOK)
1805     {
1806         AddFont(parent,info);
1807     }
1808     else
1809 	{
1810         delete info;
1811     }
1812 }
1813 ///////////////////////////////////////////////////////////////////////////////
InitFontInfo()1814 res_info * resource_view::InitFontInfo()
1815 {
1816     studiox_project *project = GetOpenProject();
1817     if (!project)
1818     {
1819         return NULL;
1820     }
1821     res_info *info = new res_info(RES_TYPE_FONT);
1822     info->pathinfo.pathname = _T("");
1823     info->pathinfo.pathtype = PATH_TYPE_PROJECT_RELATIVE;
1824     info->name = _T("NewFont");
1825     info->font_height = 16;
1826     info->font_pages = font_path_dialog::CreateDefaultFontPages();
1827     info->font_bits = 1;
1828     info->compress = FALSE;
1829     info->font_kerning = FALSE;
1830 
1831     return info;
1832 }
1833 
1834 ///////////////////////////////////////////////////////////////////////////////
AddFont(resource_item * parent,res_info * info)1835 void resource_view::AddFont(resource_item *parent, res_info *info)
1836 {
1837     VALID_PROJECT
1838     BOOL kerning = info->font_kerning;
1839     GX_FONT *font = MakeFont(info, mDisplayIndex, TRUE);
1840 
1841     info->font = font;
1842     if (kerning)
1843     {
1844         if (font)
1845         {
1846             if ((font->gx_font_format & GX_FONT_FORMAT_KERNING) == 0)
1847             {
1848                 info->font_kerning = GX_FALSE;
1849 
1850                 Notify("The selected font file doesn't have kerning info. The kerning checkbox will be set to false.");
1851             }
1852         }
1853     }
1854 
1855     parent->mpRes->Attach(info);
1856     project->AddToResourceDictionary(mDisplayIndex, info);
1857 
1858     /* Get output font size. */
1859     info->storage_size = GetFontStorage(info, project, mDisplayIndex);
1860 
1861     // insert this item into the display tree:
1862     InsertTreeResources(parent, info);
1863     if (!parent->IsOpen())
1864     {
1865         parent->Open();
1866     }
1867     mpTree->PositionItems();
1868 
1869     SyncResourceAdd(info);
1870 
1871     InstallFontTable(mDisplayIndex);
1872     project->SetModified();
1873     GetPropsWin()->ResourcesChanged();
1874 }
1875 
1876 ///////////////////////////////////////////////////////////////////////////////
OnEditFont()1877 void resource_view::OnEditFont()
1878 {
1879     VALID_PROJECT
1880 
1881     if (!mpCurrentItem)
1882     {
1883         return;
1884     }
1885 
1886     resource_item *item = mpCurrentItem;
1887     res_info *info = item->mpRes;
1888 
1889     if (!info || info->type != RES_TYPE_FONT)
1890     {
1891         return;
1892     }
1893 
1894     CString old_font_name = info->name;
1895     CString old_font_path = info->pathinfo.pathname;
1896     font_path_dialog dlg(mDisplayIndex, project->mDisplays[mDisplayIndex].colorformat, info, this);
1897 
1898     if (dlg.DoModal() == IDOK)
1899     {
1900         if (old_font_name != info->name)
1901         {
1902             // Reset font name in all active themes
1903             SyncResourceName(old_font_name, info);
1904 
1905             project->UpdateDictionaryResourceName(mDisplayIndex, old_font_name, info);
1906 
1907             if (project->mDisplays[mDisplayIndex].stable)
1908             {
1909                 project->mDisplays[mDisplayIndex].stable->UpdateStringTableRichTextResourceName(RES_TYPE_FONT, old_font_name, info->name);
1910             }
1911         }
1912 
1913         EditFont(item, old_font_path);
1914     }
1915 }
1916 
1917 ///////////////////////////////////////////////////////////////////////////////
EditFont(resource_item * item,CString & old_font_path)1918 void resource_view::EditFont(resource_item *item, CString &old_font_path)
1919 {
1920     VALID_PROJECT
1921     res_info *info = item->mpRes;
1922     BOOL     kerning = info->font_kerning;
1923     if (info->font && (!info->is_default || !old_font_path.IsEmpty()))
1924     {
1925         DestroyFont(info->font);
1926         info->font = NULL;
1927     }
1928 
1929     GX_FONT *font = NULL;
1930 
1931     if (info->is_default && info->pathinfo.pathname.IsEmpty())
1932     {
1933         studiox_project::ConfigureDefaultFont(info, mDisplayIndex);
1934     }
1935     else
1936     {
1937         font = MakeFont(info, mDisplayIndex, TRUE);
1938         if (font)
1939         {
1940             if (kerning)
1941             {
1942                 if ((font->gx_font_format & GX_FONT_FORMAT_KERNING) == 0)
1943                 {
1944                     info->font_kerning = GX_FALSE;
1945                     Notify("The selected font file doesn't have kerning info. The kerning checkbox will be set to false.");
1946                 }
1947             }
1948 
1949             info->font = font;
1950 
1951             /* Get output font size. */
1952             info->storage_size = GetFontStorage(info, project, mDisplayIndex);
1953         }
1954     }
1955 
1956     project->SetModified();
1957     InstallFontTable(mDisplayIndex);
1958     GetPropsWin()->ResourcesChanged();
1959     item->RebuildPreview();
1960     mpTree->PositionItems();
1961 }
1962 
1963 ///////////////////////////////////////////////////////////////////////////////
Scroll(int delta,BOOL redraw)1964 void resource_view::Scroll(int delta, BOOL redraw)
1965 {
1966     SetScrollPos(SB_VERT, GetScrollPos(SB_VERT) + delta, redraw);
1967     Invalidate();
1968 }
1969 
1970 ///////////////////////////////////////////////////////////////////////////////
ScrollIntoView(resource_item * item)1971 void resource_view::ScrollIntoView(resource_item *item)
1972 {
1973     if (item)
1974     {
1975         int scrollpos = GetScrollPos(SB_VERT);
1976 
1977         CRect client;
1978         GetClientRect(client);
1979 
1980         CRect rect = item->GetPos();
1981         rect.top -= scrollpos;
1982         rect.bottom -= scrollpos;
1983 
1984         if (rect.top < client.top)
1985         {
1986             Scroll(rect.top - client.top);
1987         }
1988         else if (rect.bottom > client.bottom)
1989         {
1990             Scroll(rect.bottom - client.bottom);
1991         }
1992     }
1993 }
1994 
1995 ///////////////////////////////////////////////////////////////////////////////
SetCurrentItem(resource_item * item)1996 void resource_view::SetCurrentItem(resource_item* item)
1997 {
1998     CRect rect;
1999     int scrollpos = GetScrollPos(SB_VERT);
2000 
2001 
2002     if (mpCurrentItem)
2003     {
2004         rect = mpCurrentItem->GetPos();
2005         rect.top -= scrollpos;
2006         rect.bottom -= scrollpos;
2007 
2008         InvalidateRect(rect);
2009     }
2010 
2011     mpCurrentItem = item;
2012 
2013     if (mpCurrentItem)
2014     {
2015         rect = mpCurrentItem->GetPos();
2016         rect.top -= scrollpos;
2017         rect.bottom -= scrollpos;
2018 
2019         InvalidateRect(rect);
2020 
2021         ScrollIntoView(mpCurrentItem);
2022 
2023         // Raise UI Automation event.
2024         resource_item_provider* itemProvider = mpCurrentItem->GetResItemProvider();
2025         if (itemProvider)
2026         {
2027             itemProvider->RaiseSelectElementEvent();
2028             itemProvider->RaiseChangeFocusEvent();
2029         }
2030     }
2031 }
2032 
2033 
2034 ///////////////////////////////////////////////////////////////////////////////
UpdateStringTableFonts(FontCharMap * map,res_info * start)2035 void resource_view::UpdateStringTableFonts(FontCharMap *map, res_info *start)
2036 {
2037     VALID_PROJECT
2038 
2039     if (!start)
2040     {
2041         int active_theme = project->mDisplays[mDisplayIndex].active_theme;
2042         start = project->mDisplays[mDisplayIndex].themes[active_theme].GetFirstResourceInfo();
2043     }
2044 
2045     while(start)
2046     {
2047         if (start->type == RES_TYPE_FONT)
2048         {
2049             if (start->font_charset_include_string_table)
2050             {
2051                 if (start->font)
2052                 {
2053                     if (!start->is_default || !start->pathinfo.pathname.IsEmpty())
2054                     {
2055                         // try to just add needed glyphs. If that doesn't work,
2056                         // then we have to re-make the font
2057                         if (!InsertStringTableGlyphs(map, start, mDisplayIndex))
2058                         {
2059                             DestroyFont(start->font);
2060                             start->font = MakeFont(start, mDisplayIndex, FALSE);
2061                             start->storage_size = GetFontStorage(start, project, mDisplayIndex);
2062                         }
2063                         else
2064                         {
2065                             if (start->font_charset_include_string_table)
2066                             {
2067                                 start->storage_size = GetFontStorage(start, project, mDisplayIndex);
2068                             }
2069                         }
2070                     }
2071                 }
2072                 else
2073                 {
2074                     start->font = MakeFont(start, mDisplayIndex, FALSE);
2075                     start->storage_size = GetFontStorage(start, project, mDisplayIndex);
2076                 }
2077             }
2078         }
2079 
2080         if (start->child)
2081         {
2082             UpdateStringTableFonts(map, start->child);
2083         }
2084         start = start->next;
2085     }
2086     InstallFontTable(mDisplayIndex);
2087 }
2088 
2089 ///////////////////////////////////////////////////////////////////////////////
OnDeleteCustomColor()2090 void resource_view::OnDeleteCustomColor()
2091 {
2092     VALID_PROJECT
2093     resource_item *pItem = mpCurrentItem;
2094 
2095     if (pItem && pItem->mpRes)
2096     {
2097         if (pItem->mpRes->type == RES_TYPE_COLOR)
2098         {
2099             if (pItem->mpRes->is_default == FALSE)
2100             {
2101                 int res_id = project->GetResourceId(mDisplayIndex, pItem->mpRes);
2102 
2103                 //select next item
2104                 SelectNextItem();
2105 
2106                 SyncResourceDelete(pItem->mpRes);
2107 
2108                 project->DeleteResource(pItem->mpRes);
2109                 pItem->mpRes = NULL;
2110                 mpTree->DeleteItem(pItem);
2111                 InstallColorTable(mDisplayIndex);
2112 
2113                 // clean up all widget references to this resource
2114                 folder_info *info = project->mDisplays[mDisplayIndex].GetFirstChildFolder();
2115                 widget_factory::DecrementWidgetResourceIds(RES_TYPE_COLOR, info, res_id);
2116                 Invalidate();
2117                 GetPropsWin()->ResourcesChanged();
2118                 project->SetModified();
2119 
2120 
2121                 if (project->mDisplays[mDisplayIndex].stable)
2122                 {
2123                     // update string table.
2124                     project->mDisplays[mDisplayIndex].stable->UpdateGuixLanguageTable();
2125                 }
2126             }
2127         }
2128     }
2129 }
2130 
2131 ///////////////////////////////////////////////////////////////////////////////
OnDeleteFont()2132 void resource_view::OnDeleteFont()
2133 {
2134     VALID_PROJECT
2135 
2136     if (!mpCurrentItem)
2137     {
2138         return;
2139     }
2140 
2141     resource_item *item = mpCurrentItem;
2142 
2143     res_info *info = item->mpRes;
2144 
2145     if (!info || info->type != RES_TYPE_FONT ||
2146         info->is_default)
2147     {
2148         return;
2149     }
2150     int res_id = project->GetResourceId(mDisplayIndex, info);
2151 
2152     //select next item
2153     SelectNextItem();
2154 
2155     SyncResourceDelete(info);
2156 
2157     project->DeleteResource(info);
2158     item->mpRes = NULL;
2159     mpTree->DeleteItem(item);
2160     InstallFontTable(mDisplayIndex);
2161 
2162     // clean up all widget references to this resource
2163     folder_info *finfo = project->mDisplays[mDisplayIndex].GetFirstChildFolder();
2164     widget_factory::DecrementWidgetResourceIds(RES_TYPE_FONT, finfo, res_id);
2165     GetPropsWin()->ResourcesChanged();
2166 
2167     if (project->mDisplays[mDisplayIndex].stable)
2168     {
2169         // update string table.
2170         project->mDisplays[mDisplayIndex].stable->UpdateGuixLanguageTable();
2171     }
2172 
2173     Invalidate();
2174 }
2175 
2176 ///////////////////////////////////////////////////////////////////////////////
OnAddPixelmaps()2177 void resource_view::OnAddPixelmaps()
2178 {
2179     TCHAR *path;
2180     TCHAR *name;
2181     TCHAR *pGet;
2182     CString pathname;
2183     VALID_PROJECT
2184     BOOL warn_on_error = TRUE;
2185 
2186     int NameLen;
2187     resource_item *parent;
2188 
2189     if (!mpCurrentItem)
2190     {
2191         return;
2192     }
2193 
2194     if (mpCurrentItem->GetResType() == RES_TYPE_ADD_PIXELMAP)
2195     {
2196         parent = mpCurrentItem->Parent();
2197     }
2198     else
2199     {
2200         parent = mpCurrentItem;
2201     }
2202 
2203     if (!parent || !parent->mpRes)
2204     {
2205         return;
2206     }
2207 
2208     project->mHeader.warn_missing_image = TRUE;
2209 
2210     int filecount = BrowseForMultipleFiles(_T("Select Image File(s)"),
2211                                            _T("Image Files\0*.png;*.jpg;*.bmp;*.gif\0"), NULL,
2212                                            &path, &name, this);
2213 
2214     CStringArray patharray;
2215 
2216     if (filecount > 0)
2217     {
2218         pGet = name;
2219 
2220         while(*pGet)
2221         {
2222             if (filecount > 1)
2223             {
2224                 pathname = CString(path) + CString("\\") + CString(pGet);
2225             }
2226             else
2227             {
2228                 pathname = CString(path);
2229             }
2230 
2231             patharray.Add(pathname);
2232 
2233             NameLen = (int)_tcslen(pGet) + 1;
2234             pGet += NameLen;
2235         }
2236         delete [] path;
2237     }
2238 
2239     AddPixelmaps(parent, &patharray);
2240 }
2241 
2242 ///////////////////////////////////////////////////////////////////////////////
OnEditPixelmaps()2243 void resource_view::OnEditPixelmaps()
2244 {
2245     if (!mpCurrentItem)
2246     {
2247         return;
2248     }
2249 
2250     edit_pixelmap_dlg dlg(mpCurrentItem->mpRes, this);
2251 
2252     if (dlg.DoModal() == IDOK)
2253     {
2254         EditPixelmaps(mpCurrentItem);
2255     }
2256 }
2257 
2258 ///////////////////////////////////////////////////////////////////////////////
OnAddPixelmapFolder()2259 void resource_view::OnAddPixelmapFolder()
2260 {
2261     VALID_PROJECT
2262     if (!mpCurrentItem)
2263     {
2264         return;
2265     }
2266 
2267     resource_item *parent = mpCurrentItem;
2268 
2269     if (!parent->mpRes)
2270     {
2271         return;
2272     }
2273 
2274     res_info *info = new res_info(RES_TYPE_FOLDER);
2275     info->name = _T("New Folder");
2276     info->folder_id = CUSTOM_PIXELMAP_FOLDER;
2277 
2278     mpTree->CreateUniqueFolderName(info->name, info->folder_id);
2279 
2280     res_info* add = new res_info(RES_TYPE_ADD_PIXELMAP);
2281     info->Attach(add);
2282 
2283     // insert new folder into project:
2284     parent->mpRes->Attach(info);
2285 
2286     // insert this item into the display tree:
2287     InsertTreeResources(parent, info);
2288 
2289     SyncResourceAdd(info);
2290 
2291     if (!parent->IsOpen())
2292     {
2293         parent->Open();
2294     }
2295     else
2296     {
2297         mpTree->PositionItems();
2298     }
2299 
2300     resource_item *child = parent->First();
2301     while(child->Next())
2302     {
2303         child = child->Next();
2304     }
2305     SetCurrentItem(child);
2306     OnRenamePixelmapFolder();
2307 }
2308 
2309 ///////////////////////////////////////////////////////////////////////////////
OnRemovePixelmapFolder()2310 void resource_view::OnRemovePixelmapFolder()
2311 {
2312     VALID_PROJECT
2313     if (mpCurrentItem && mpCurrentItem->mpRes)
2314     {
2315         if (mpCurrentItem->mpRes->type == RES_TYPE_FOLDER)
2316         {
2317             // remove child resources under the folder
2318             res_info *child;
2319             res_info *next;
2320             resource_item *childItem;
2321             resource_item *delItem = mpCurrentItem;
2322             int res_id;
2323             child = delItem->mpRes->child;
2324 
2325             delItem->Close();
2326 
2327             //select next item
2328             SelectNextItem();
2329 
2330             if (mpCurrentItem && mpCurrentItem->GetResType() != RES_TYPE_FOLDER)
2331             {
2332                 //select previous item
2333                 SetCurrentItem(delItem);
2334                 SelectPreviousItem();
2335             }
2336 
2337             CArray<GX_RESOURCE_ID> res_id_array;
2338 
2339             while (child)
2340             {
2341                 next = child->next;
2342 
2343                 if (child->type == RES_TYPE_PIXELMAP)
2344                 {
2345                     res_id = project->GetResourceId(GetProjectView()->GetActiveDisplay(), child);
2346 
2347                     if (res_id)
2348                     {
2349                         res_id_array.Add(res_id);
2350                     }
2351                 }
2352 
2353                 child = next;
2354             }
2355 
2356             child = delItem->mpRes->child;
2357 
2358             while(child)
2359             {
2360                 next = child->next;
2361 
2362                 childItem = mpTree->FindItem(delItem, child->type, child->name);
2363 
2364                 project->DeleteResource(child);
2365                 mpTree->DeleteItem(childItem);
2366 
2367                 child = next;
2368             }
2369 
2370             if (project->IsPaletteMode(mDisplayIndex))
2371             {
2372                 StartWorkThread(InitializeThemePixelmapsThreadEntry, (LPVOID)mDisplayIndex, "Creating Optimal Palette.", TRUE);
2373             }
2374             InstallPixelmapTable(mDisplayIndex);
2375 
2376             SyncResourceDelete(delItem->mpRes);
2377 
2378             // remove this resource from project:
2379             project->DeleteResource(delItem->mpRes);
2380             delItem->mpRes = NULL;
2381 
2382             // remove this item from display tree:
2383             mpTree->DeleteItem(delItem);
2384 
2385             // clean up all widget references to this resource
2386             folder_info* finfo = project->mDisplays[mDisplayIndex].GetFirstChildFolder();
2387             widget_factory::DecrementWidgetResourceIds(RES_TYPE_PIXELMAP, finfo, res_id_array);
2388 
2389             GetPropsWin()->ResourcesChanged();
2390             Invalidate();
2391         }
2392     }
2393 }
2394 
2395 ///////////////////////////////////////////////////////////////////////////////
OnRenamePixelmapFolder()2396 void resource_view::OnRenamePixelmapFolder()
2397 {
2398     VALID_PROJECT
2399     resource_item *item = mpCurrentItem;
2400 
2401     if (!mpCurrentItem)
2402     {
2403         return;
2404     }
2405 
2406     res_info *info = item->mpRes;
2407 
2408     if (!info || info->type != RES_TYPE_FOLDER)
2409     {
2410         return;
2411     }
2412 
2413     CString old_folder_name = info->name;
2414 
2415     folder_name_dlg dlg(info, this);
2416 
2417     if (dlg.DoModal() == IDOK)
2418     {
2419         dlg.GetEditFolderName(info->name);
2420 
2421         SyncResourceName(old_folder_name, info);
2422 
2423         Invalidate();
2424         project->SetModified();
2425     }
2426 }
2427 
2428 ///////////////////////////////////////////////////////////////////////////////
OnEnablePixelmapFolder()2429 void resource_view::OnEnablePixelmapFolder()
2430 {
2431     VALID_PROJECT
2432     resource_item* item = mpCurrentItem;
2433 
2434     if (!mpCurrentItem)
2435     {
2436         return;
2437     }
2438 
2439     res_info* info = item->mpRes;
2440 
2441     info->enabled = TRUE;
2442 
2443     //Sychronous child properties with parent group. If pixelmap folder is enabled, its child should be all enabled.
2444     EnableDisableChild(info, RES_TYPE_PIXELMAP, info->enabled);
2445 }
2446 
2447 ///////////////////////////////////////////////////////////////////////////////
OnDisablePixelmapFolder()2448 void resource_view::OnDisablePixelmapFolder()
2449 {
2450     VALID_PROJECT
2451     resource_item *item = mpCurrentItem;
2452 
2453     if (!mpCurrentItem)
2454     {
2455         return;
2456     }
2457 
2458     res_info *info = item->mpRes;
2459 
2460     info->enabled = FALSE;
2461 
2462     //Sychronous child properties with parent group. If pixelmap folder is enabled, its child should be all enabled.
2463     EnableDisableChild(info, RES_TYPE_PIXELMAP, info->enabled);
2464 }
2465 
2466 ///////////////////////////////////////////////////////////////////////////////
EnableDisableChild(res_info * parent,int target_child_type,GX_BOOL enable)2467 void resource_view::EnableDisableChild(res_info *parent, int target_child_type, GX_BOOL enable)
2468 {
2469     res_info *child = parent->child;
2470 
2471     while (child)
2472     {
2473         if (child->type == target_child_type)
2474         {
2475             child->enabled = enable;
2476         }
2477 
2478         if (child->child)
2479         {
2480             EnableDisableChild(child, target_child_type, enable);
2481         }
2482 
2483         child = child->next;
2484     }
2485 }
2486 
2487 ///////////////////////////////////////////////////////////////////////////////
GetFolderEnableDisableState(res_info * parent)2488 int resource_view::GetFolderEnableDisableState(res_info *parent)
2489 {
2490     int current_state = parent->enabled;
2491     BOOL first_child = TRUE;
2492 
2493     if (parent->type == RES_TYPE_GROUP ||
2494         parent->type == RES_TYPE_FOLDER)
2495     {
2496         int next_state;
2497         res_info* child = parent->child;
2498 
2499         while (child)
2500         {
2501             if (child->type == RES_TYPE_GROUP ||
2502                 child->type == RES_TYPE_FOLDER ||
2503                 child->type == RES_TYPE_PIXELMAP)
2504             {
2505                 if (child->type == RES_TYPE_PIXELMAP)
2506                 {
2507                     next_state = child->enabled;
2508                 }
2509                 else
2510                 {
2511                     next_state = GetFolderEnableDisableState(child);
2512                 }
2513 
2514                 if (first_child)
2515                 {
2516                     current_state = next_state;
2517                     first_child = FALSE;
2518                 }
2519 
2520                 if (current_state != next_state)
2521                 {
2522                     return RES_STATE_UNDETERMINED;
2523                 }
2524             }
2525 
2526             child = child->next;
2527         }
2528     }
2529 
2530     return current_state;
2531 }
2532 
2533 ///////////////////////////////////////////////////////////////////////////////
OnEditPixelmap()2534 void resource_view::OnEditPixelmap()
2535 {
2536     VALID_PROJECT
2537     if (!mpCurrentItem)
2538     {
2539         return;
2540     }
2541 
2542     resource_item *item = mpCurrentItem;
2543     res_info *info = item->mpRes;
2544 
2545     if (!info || info->type != RES_TYPE_PIXELMAP)
2546     {
2547         return;
2548     }
2549 
2550     CString old_pixelmap_name = info->name;
2551     int old_frame_count = info->GetPixelmapFrameCount();
2552 
2553     edit_pixelmap_dlg dlg(info, this);
2554 
2555     if (dlg.DoModal() == IDOK)
2556     {
2557         if (old_pixelmap_name != info->name)
2558         {
2559             // Reset pixelmap name in all active themes
2560             SyncResourceName(old_pixelmap_name, info);
2561 
2562             project->UpdateDictionaryResourceName(mDisplayIndex, old_pixelmap_name, info);
2563         }
2564 
2565         EditPixelmaps(item);
2566 
2567         if (old_frame_count != info->GetPixelmapFrameCount())
2568         {
2569             // Need to update frame information of the sprite that reference this pixemlap.
2570             folder_info* finfo = project->mDisplays[mDisplayIndex].GetFirstChildFolder();
2571 
2572             if (finfo)
2573             {
2574                 widget_factory::UpdateSpriteFrameInfos(finfo, project->GetResourceId(mDisplayIndex, RES_TYPE_PIXELMAP, info->name));
2575             }
2576 
2577             SyncResourcePath(info);
2578         }
2579     }
2580 }
2581 
2582 ///////////////////////////////////////////////////////////////////////////////
OnDeletePixelmap()2583 void resource_view::OnDeletePixelmap()
2584 {
2585     VALID_PROJECT
2586 
2587     if (!mpCurrentItem)
2588     {
2589         return;
2590     }
2591     resource_item *item = mpCurrentItem;
2592     res_info *info = item->mpRes;
2593 
2594     if (!info || info->type != RES_TYPE_PIXELMAP ||
2595         info->is_default)
2596     {
2597         return;
2598     }
2599     int res_id = project->GetResourceId(mDisplayIndex, info);
2600 
2601     //select next item
2602     SelectNextItem();
2603 
2604     SyncResourceDelete(info);
2605 
2606     project->DeleteResource(info);
2607     item->mpRes = NULL;
2608     mpTree->DeleteItem(item);
2609 
2610     if (project->IsPaletteMode(mDisplayIndex))
2611     {
2612         StartWorkThread(InitializeThemePixelmapsThreadEntry, (LPVOID)mDisplayIndex, "Creating Optimal Palette.", TRUE);
2613     }
2614     InstallPixelmapTable(mDisplayIndex);
2615 
2616     // clean up all widget references to this resource
2617     folder_info *finfo = project->mDisplays[mDisplayIndex].GetFirstChildFolder();
2618     widget_factory::DecrementWidgetResourceIds(RES_TYPE_PIXELMAP, finfo, res_id);
2619     GetPropsWin()->ResourcesChanged();
2620     Invalidate();
2621 }
2622 
2623 ////////////////////////////////////////////////////////////////////////////////
OnEnablePixelmap()2624 void resource_view::OnEnablePixelmap()
2625 {
2626     VALID_PROJECT
2627 
2628     if (!mpCurrentItem)
2629     {
2630         return;
2631     }
2632 
2633     resource_item *item = mpCurrentItem;
2634     res_info *info;
2635     res_info *parent;
2636 
2637     for (int theme = 0; theme < project->mDisplays[mDisplayIndex].num_themes; theme++)
2638     {
2639         if (theme == project->mDisplays[mDisplayIndex].active_theme)
2640         {
2641             info = item->mpRes;
2642         }
2643         else
2644         {
2645             info = project->FindResource(mDisplayIndex, theme, item->mpRes->type, item->mpRes->name);
2646         }
2647 
2648         if (info)
2649         {
2650             info->enabled = TRUE;
2651 
2652             parent = info->parent;
2653             if (parent->type == RES_TYPE_FOLDER && parent->folder_id == CUSTOM_PIXELMAP_FOLDER)
2654             {
2655                 //enable the folder
2656                 parent->enabled = TRUE;
2657             }
2658         }
2659     }
2660 }
2661 
2662 ////////////////////////////////////////////////////////////////////////////////
OnDisablePixelmap()2663 void resource_view::OnDisablePixelmap()
2664 {
2665     VALID_PROJECT
2666     if (!mpCurrentItem)
2667     {
2668         return;
2669     }
2670 
2671     resource_item *item = mpCurrentItem;
2672     res_info *info;
2673 
2674     for (int theme = 0; theme < project->mDisplays[mDisplayIndex].num_themes; theme++)
2675     {
2676         if (theme == project->mDisplays[mDisplayIndex].active_theme)
2677         {
2678             info = item->mpRes;
2679         }
2680         else
2681         {
2682             info = project->FindResource(mDisplayIndex, theme, item->mpRes->type, item->mpRes->name);
2683         }
2684 
2685         if (info)
2686         {
2687             info->enabled = FALSE;
2688         }
2689     }
2690 }
2691 
2692 ////////////////////////////////////////////////////////////////////////////////
OnGenerateXML()2693 void resource_view::OnGenerateXML()
2694 {
2695     VALID_PROJECT
2696     if (!mpCurrentItem)
2697     {
2698         return;
2699     }
2700 
2701     if (mpCurrentItem->mpRes)
2702     {
2703         CFileDialog dlg(FALSE, _T(".xml"), mpCurrentItem->mpRes->name,
2704             OFN_SHOWHELP | OFN_OVERWRITEPROMPT,
2705             _T("XML Files|*.xml||"),
2706             this);
2707 
2708         if (dlg.DoModal() == IDOK)
2709         {
2710             CString filename = dlg.GetFileName();
2711             int index = filename.ReverseFind('.');
2712             if (index >= 0)
2713             {
2714                 // Remove extension.
2715                 filename = filename.Left(index);
2716             }
2717             project->GenerateResourceXml(dlg.GetPathName(), filename, mpCurrentItem->mpRes);
2718         }
2719     }
2720 }
2721 
2722 ////////////////////////////////////////////////////////////////////////////////
RestoreStringIdsFromBackup(folder_info * write,folder_info * read)2723 void resource_view::RestoreStringIdsFromBackup(folder_info *write, folder_info *read)
2724 {
2725     while (write && read)
2726     {
2727         RestoreStringIdsFromBackup(write->GetFirstChildWidget(), read->GetFirstChildWidget());
2728         write = write->GetNextFolder();
2729         read = read->GetNextFolder();
2730     }
2731 }
2732 
2733 ////////////////////////////////////////////////////////////////////////////////
RestoreStringIdsFromBackup(widget_info * write,widget_info * read)2734 void resource_view::RestoreStringIdsFromBackup(widget_info *write, widget_info *read)
2735 {
2736     widget_service_provider *provider;
2737     GX_RESOURCE_ID *read_id_list;
2738     GX_RESOURCE_ID *write_id_list;
2739     int count;
2740     int index;
2741 
2742     while(write && read)
2743     {
2744         if (write->GetChildWidgetInfo() && read->GetChildWidgetInfo())
2745         {
2746             RestoreStringIdsFromBackup(write->GetChildWidgetInfo(), read->GetChildWidgetInfo());
2747         }
2748 
2749         if (read->basetype == GX_TYPE_STRING_SCROLL_WHEEL)
2750         {
2751             read_id_list = read->ewi.string_scroll_wheel.string_id_list;
2752             write_id_list = write->ewi.string_scroll_wheel.string_id_list;
2753             count = read->ewi.string_scroll_wheel.base.total_rows;
2754         }
2755         else
2756         {
2757             read_id_list = read->string_id;
2758             write_id_list = write->string_id;
2759             count = NUM_WIDGET_STRINGS;
2760         }
2761 
2762         if (write_id_list && read_id_list)
2763         {
2764             provider = widget_factory::GetServiceProvider(write->basetype);
2765             if (provider)
2766             {
2767                 for (index = 0; index < count; index++)
2768                 {
2769                     if (write_id_list[index] != read_id_list[index])
2770                     {
2771                         provider->AssignText(write, index, read_id_list[index]);
2772                     }
2773                 }
2774             }
2775         }
2776 
2777         write = write->GetNextWidgetInfo();
2778         read = read->GetNextWidgetInfo();
2779     }
2780 }
2781 
2782 ///////////////////////////////////////////////////////////////////////////////
OnEditStringTable()2783 void resource_view::OnEditStringTable()
2784 {
2785     VALID_PROJECT
2786     folder_info *widget_backup = NULL;
2787 
2788     // clone the string table and the widget information in case the user cancels:
2789     string_table *table = project->mDisplays[mDisplayIndex].stable;
2790 
2791     if (!table)
2792     {
2793         return;
2794     }
2795     string_table *clone_table = new string_table(*table);
2796 
2797     // clone the widget info
2798     if (project->mDisplays[mDisplayIndex].GetFirstChildFolder())
2799     {
2800         widget_backup = new folder_info(*project->mDisplays[mDisplayIndex].GetFirstChildFolder(), TRUE);
2801     }
2802 
2803     CRect size;
2804 
2805     string_table_edit_dlg dlg(table, this);
2806 
2807     if (dlg.DoModal() == IDOK)
2808     {
2809         delete clone_table;     // delete the table backup
2810         delete widget_backup;   // delete backup widget info
2811         GetPropsWin()->ResourcesChanged();
2812         project->SetModified();
2813     }
2814     else
2815     {
2816         // delete the modified project and replace it with our backup and reload the resource tree
2817         delete project->mDisplays[mDisplayIndex].stable;
2818         project->mDisplays[mDisplayIndex].stable = clone_table;
2819         project->mHeader.num_languages = clone_table->CountLanguages();
2820         RebuildStringItems();
2821         RestoreStringIdsFromBackup(project->mDisplays[mDisplayIndex].GetFirstChildFolder(), widget_backup);
2822         delete widget_backup;
2823 
2824         widget_factory::UpdateInputWidgetText(project);
2825 
2826         GetProjectView()->DeSelect();
2827         GetPropsWin()->ResourcesChanged();
2828     }
2829 
2830     string_table::EnableDisableRuntimeBidiText(project->mDisplays[mDisplayIndex].stable->GetActiveLanguage());
2831 }
2832 
2833 ///////////////////////////////////////////////////////////////////////////////
OnEditLanguages()2834 void resource_view::OnEditLanguages()
2835 {
2836     VALID_PROJECT
2837     config_languages_dlg dlg;
2838     dlg.DoModal();
2839 }
2840 
2841 ///////////////////////////////////////////////////////////////////////////////
OnSetActiveLanguage(int delta)2842 void resource_view::OnSetActiveLanguage(int delta)
2843 {
2844     VALID_PROJECT
2845 
2846     string_table *table = project->mDisplays[mDisplayIndex].stable;
2847 
2848     int num_languages = table->CountLanguages();
2849     int current_language = table->GetActiveLanguage();
2850 
2851     if (delta == 1)
2852     {
2853         if (current_language + 1 < num_languages)
2854         {
2855             table->SetActiveLanguage(current_language + 1);
2856             RebuildStringItems(FALSE);
2857         }
2858     }
2859     else
2860     {
2861         if (current_language > 0)
2862         {
2863             table->SetActiveLanguage(current_language - 1);
2864             RebuildStringItems(FALSE);
2865         }
2866     }
2867 }
2868 
2869 ///////////////////////////////////////////////////////////////////////////////
OnSetActiveTheme(int delta)2870 void resource_view::OnSetActiveTheme(int delta)
2871 {
2872     VALID_PROJECT
2873 
2874     int total_themes = project->mDisplays[mDisplayIndex].num_themes;
2875     int active_theme = project->mDisplays[mDisplayIndex].active_theme;
2876 
2877     active_theme += delta;
2878 
2879     if ((active_theme >= 0) && (active_theme < total_themes))
2880     {
2881         project->mDisplays[mDisplayIndex].active_theme = active_theme;
2882 
2883         /* Font resource can be different for different theme,
2884            clear string table char_map so font with include_string_table_c style can be recalculate. */
2885         project->mDisplays[mDisplayIndex].stable->ClearStringTableCharMap();
2886 
2887         // install active theme resources
2888         InstallResources(mDisplayIndex);
2889     }
2890 }
2891 
2892 
2893 ///////////////////////////////////////////////////////////////////////////////
IsOpen(int folder_id)2894 BOOL resource_view::IsOpen(int folder_id)
2895 {
2896     resource_item *item = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_GROUP, folder_id);
2897 
2898     if (item)
2899     {
2900         return item->IsOpen();
2901     }
2902     else
2903     {
2904         return FALSE;
2905     }
2906 }
2907 
2908 //////////////////////////////////////////////////////////////////////////////
SetResFolderStatus(int folder_id,int open_status)2909 void resource_view::SetResFolderStatus(int folder_id, int open_status)
2910 {
2911     resource_item *item = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_GROUP, folder_id);
2912 
2913     if (!item)
2914     {
2915         return;
2916     }
2917 
2918     if (open_status)
2919     {
2920         if (!item->IsOpen())
2921         {
2922             item->Open();
2923         }
2924     }
2925     else
2926     {
2927         if (item->IsOpen())
2928         {
2929             item->Close();
2930         }
2931     }
2932 }
2933 
2934 //////////////////////////////////////////////////////////////////////////////
OnTimer(UINT_PTR nIDEvent)2935 void resource_view::OnTimer(UINT_PTR nIDEvent)
2936 {
2937     // TODO: Add your message handler code here and/or call default
2938 
2939     mTimerTicks++;
2940 
2941     if (nIDEvent != DRAG_MOVE_TIMER_ID)
2942     {
2943         CScrollView::OnTimer(nIDEvent);
2944     }
2945 
2946     POINT pt;
2947     GetCursorPos(&pt);
2948     RECT rect;
2949     GetClientRect(&rect);
2950     ClientToScreen(&rect);
2951 
2952     if (pt.y < rect.top + 10)
2953     {
2954         //scroll up
2955         int slowscroll = 6 - (rect.top + 10 - pt.y) / 10;
2956         if (0 == (mTimerTicks % (slowscroll > 0 ? slowscroll : 1)))
2957         {
2958             SendMessage(WM_VSCROLL, SB_LINEUP);
2959         }
2960     }
2961     else if (pt.y > rect.bottom - 10)
2962     {
2963         //scroll down
2964         int slowscroll = 6 - (pt.y - rect.bottom + 10) / 10;
2965         if (0 == (mTimerTicks % (slowscroll > 0 ? slowscroll : 1)))
2966         {
2967             SendMessage(WM_VSCROLL, SB_LINEDOWN);
2968         }
2969     }
2970 }
2971 
2972 //////////////////////////////////////////////////////////////////////////////
AddColor(GX_COLOR color,CString name,resource_item * parent)2973 void resource_view::AddColor(GX_COLOR color, CString name, resource_item *parent)
2974 {
2975     // Add a res_info element to the project:
2976     VALID_PROJECT
2977 
2978     res_info *info = project->AddCustomColor(color, name, parent->mpRes);
2979 
2980     // insert this item into the display tree:
2981     InsertTreeResources(parent, info);
2982 
2983     SyncResourceAdd(info);
2984 
2985     if (!parent->IsOpen())
2986     {
2987         parent->Open();
2988     }
2989     mpTree->PositionItems();
2990 
2991     // make a new color table for GUIX:
2992     InstallColorTable(mDisplayIndex);
2993     GetPropsWin()->ResourcesChanged();
2994 }
2995 
2996 //////////////////////////////////////////////////////////////////////////////
AddPixelmap(resource_item * parent,res_info * info,BOOL palette_mode)2997 void resource_view::AddPixelmap(resource_item *parent, res_info *info, BOOL palette_mode)
2998 {
2999     VALID_PROJECT
3000 
3001     //palette_info *pal = NULL;
3002     parent->mpRes->Attach(info);
3003     project->AddToResourceDictionary(mDisplayIndex, info);
3004 
3005     if (!palette_mode)
3006     {
3007         project->InitializeOnePixelmap(info, NULL);
3008     }
3009 
3010     // insert this item into the display tree:
3011     InsertTreeResources(parent, info);
3012     SyncResourceAdd(info);
3013 }
3014 
3015 //////////////////////////////////////////////////////////////////////////////
TaskAddPixelmaps(resource_item * parent,CStringArray * patharray)3016 void resource_view::TaskAddPixelmaps(resource_item *parent, CStringArray *patharray)
3017 {
3018     VALID_PROJECT
3019     CString pathname;
3020     BOOL    add_pixelmap;
3021     BOOL  palette_mode = FALSE;
3022 
3023     int count = patharray->GetCount();
3024 
3025     palette_mode = project->IsPaletteMode(mDisplayIndex);
3026 
3027     while (count--)
3028     {
3029         add_pixelmap = FALSE;
3030 
3031         pathname = patharray->GetAt(count);
3032 
3033         FormatPath(pathname);
3034 
3035         CString res_name;
3036         int index = pathname.ReverseFind('\\');
3037 
3038         if (index >= 0)
3039         {
3040             res_name = pathname.Mid(index + 1);
3041         }
3042         else
3043         {
3044             res_name = pathname;
3045         }
3046 
3047         res_name = RemoveFileExtension(res_name);
3048 
3049         /*Check file exists in all pixelmaps forlder?*/
3050         if (!FileExists(mDisplayIndex, RES_TYPE_PIXELMAP, pathname))
3051         {
3052             add_pixelmap = TRUE;
3053         }
3054         else
3055         {
3056             CString message;
3057             CString temp_str("already exists. Do you still want to add it?");
3058             message = res_name + " " + temp_str;
3059             if (AskUser(CW2A(message)) == TRUE)
3060             {
3061                 add_pixelmap = TRUE;
3062             }
3063         }
3064 
3065         if (add_pixelmap)
3066         {
3067             res_name.MakeUpper();
3068             /*Set available Id name for import pixelmap file.*/
3069             SetImportIdName(mDisplayIndex, res_name);
3070 
3071             res_info *info = new res_info(RES_TYPE_PIXELMAP);
3072             info->name = res_name;
3073             info->pathinfo.pathtype = PATH_TYPE_PROJECT_RELATIVE;
3074             SaveToPathInfo(info->pathinfo, pathname);
3075 
3076             if (!parent->mpRes->enabled)
3077             {
3078                 info->enabled = GX_FALSE;
3079             }
3080 
3081             if (palette_mode)
3082             {
3083                 info->palette_type = PALETTE_TYPE_SHARED;
3084             }
3085 
3086             // if the source has an alpha channel, default to keeping it
3087             CString abspath = MakeAbsolutePathname(info->pathinfo);
3088             image_reader* pReader = image_reader::CreateProperReader(abspath);
3089 
3090             if (pReader)
3091             {
3092                 info->keep_alpha = pReader->CheckImageHasAlphaChannel(abspath);
3093                 delete pReader;
3094             }
3095 
3096             if ((image_reader::GetImageType(abspath) == IMAGE_TYPE_GIF) &&
3097                 (project->mDisplays[mDisplayIndex].colorformat > GX_COLOR_FORMAT_8BIT_PALETTE))
3098             {
3099                 info->output_color_format = GX_COLOR_FORMAT_8BIT_PALETTE;
3100                 info->palette_type = PALETTE_TYPE_PRIVATE;
3101             }
3102 
3103             AddPixelmap(parent, info, palette_mode);
3104         }
3105     }
3106 
3107     if (!parent->IsOpen())
3108     {
3109         this->SendMessage(USR_MSG_OPEN_RESOURCE_ITEM, (WPARAM)parent, 0);
3110     }
3111 
3112     if (palette_mode)
3113     {
3114         project->InitializeThemePixelmaps(mDisplayIndex, project->mDisplays[mDisplayIndex].active_theme);
3115     }
3116 }
3117 
TaskAddPixelmapsThreadEntry(LPVOID thread_input)3118 static DWORD WINAPI TaskAddPixelmapsThreadEntry(LPVOID thread_input)
3119 {
3120     resource_view *res_view = (resource_view *) GetResourceView();
3121 
3122     if (res_view)
3123     {
3124         void **pointer_array = (void **)thread_input;
3125         resource_item *parent = (resource_item *) pointer_array[0];
3126         CStringArray *patharray = (CStringArray *) pointer_array[1];
3127 
3128         res_view->TaskAddPixelmaps(parent, patharray);
3129     }
3130 
3131     EndBusyMsg();
3132 
3133     return TRUE;
3134 }
3135 
3136 //////////////////////////////////////////////////////////////////////////////
AddPixelmaps(resource_item * parent,CStringArray * patharray)3137 void resource_view::AddPixelmaps(resource_item *parent, CStringArray *patharray)
3138 {
3139     VALID_PROJECT
3140 
3141     void *param_array[2] = { (void*)parent, (void*)patharray };
3142     StartWorkThread(TaskAddPixelmapsThreadEntry, param_array, "Initializing Pixelmaps.", TRUE);
3143 
3144     mpTree->PositionItems();
3145     InstallPixelmapTable(mDisplayIndex);
3146     GetPropsWin()->ResourcesChanged();
3147     project->SetModified();
3148 }
3149 
3150 //////////////////////////////////////////////////////////////////////////////
InitializePixelmaps(resource_item * item)3151 void resource_view::InitializePixelmaps(resource_item *item)
3152 {
3153     VALID_PROJECT
3154 
3155     resource_item *child = item;
3156     res_info *info;
3157 
3158     info = child->mpRes;
3159 
3160     if (!info)
3161     {
3162         return;
3163     }
3164 
3165     switch (info->type)
3166     {
3167     case RES_TYPE_GROUP:
3168     case RES_TYPE_FOLDER:
3169         child = child->First();
3170         while (child)
3171         {
3172             InitializePixelmaps(child);
3173 
3174             child = child->Next();
3175         }
3176         break;
3177 
3178     case RES_TYPE_PIXELMAP:
3179         if (info && info->type == RES_TYPE_PIXELMAP && info->is_modified)
3180         {
3181             int display = project->GetDisplayIndex(info);
3182             int theme = project->mDisplays[display].active_theme;
3183 
3184             if (project->GetDisplayColorFormat(info) == GX_COLOR_FORMAT_8BIT_PALETTE ||
3185                 project->TestForPixelmapsUsingGlobalPalette(project->mDisplays[display].themes[theme].GetFirstResourceInfo()))
3186             {
3187                 project->InitializeThemePixelmaps(display, theme);
3188             }
3189             else
3190             {
3191                 project->InitializeOnePixelmap(info, NULL);
3192             }
3193 
3194             // Rebuild preview
3195             child->RebuildPreview();
3196             info->is_modified = FALSE;
3197         }
3198     }
3199 }
3200 
3201 //////////////////////////////////////////////////////////////////////////////
TaskInitializePixelmaps(resource_item * item)3202 void resource_view::TaskInitializePixelmaps(resource_item *item)
3203 {
3204     InitializePixelmaps(item);
3205     InstallPixelmapTable(mDisplayIndex);
3206 }
3207 
3208 //////////////////////////////////////////////////////////////////////////////
InitializePixelmapsThreadEntry(LPVOID thread_input)3209 static DWORD WINAPI InitializePixelmapsThreadEntry(LPVOID thread_input)
3210 {
3211     resource_view *res_view = GetResourceView();
3212 
3213     if (res_view)
3214     {
3215         res_view->TaskInitializePixelmaps((resource_item *)thread_input);
3216     }
3217 
3218     EndBusyMsg();
3219 
3220     return TRUE;
3221 }
3222 
3223 //////////////////////////////////////////////////////////////////////////////
EditPixelmaps(resource_item * item)3224 void resource_view::EditPixelmaps(resource_item *item)
3225 {
3226     VALID_PROJECT
3227 
3228     StartWorkThread(InitializePixelmapsThreadEntry, (LPVOID)item, "Initializing Pixelmap.", TRUE);
3229 
3230     mpTree->PositionItems();
3231     project->SetModified();
3232     GetPropsWin()->ResourcesChanged();
3233 }
3234 
3235 //////////////////////////////////////////////////////////////////////////////
SyncResourceName(CString & old_name,res_info * info)3236 void resource_view::SyncResourceName(CString &old_name, res_info *info)
3237 {
3238     VALID_PROJECT
3239 
3240     res_info *current_info;
3241     for (int theme = 0; theme < project->mDisplays[mDisplayIndex].num_themes; theme++)
3242     {
3243         if (theme == project->mDisplays[mDisplayIndex].active_theme)
3244         {
3245             continue;
3246         }
3247 
3248         current_info = project->FindResource(mDisplayIndex, theme, info->type, old_name);
3249 
3250         if (current_info)
3251         {
3252             current_info->name = info->name;
3253         }
3254         else
3255         {
3256             CString msg;
3257 
3258             msg.Format(_T("Internal Error: resource item \"%s\" in theme \"%s\" not found"),info->name,
3259                 project->mDisplays[mDisplayIndex].themes[theme].theme_name);
3260             ErrorMsg(msg);
3261         }
3262     }
3263 }
3264 
3265 //////////////////////////////////////////////////////////////////////////////
SyncResourceAdd(res_info * info)3266 void resource_view::SyncResourceAdd(res_info *info)
3267 {
3268     VALID_PROJECT
3269 
3270     res_info *parent;
3271     res_info *current_info;
3272 
3273     for (int theme = 0; theme < project->mDisplays[mDisplayIndex].num_themes; theme++)
3274     {
3275         if (theme == project->mDisplays[mDisplayIndex].active_theme)
3276         {
3277             continue;
3278         }
3279         else
3280         {
3281             if (info->parent)
3282             {
3283                 if (info->parent->type == RES_TYPE_FOLDER)
3284                 {
3285                     parent = project->FindResourceFolder(mDisplayIndex, theme, info->parent->type, info->parent->folder_id, info->parent->name);
3286                 }
3287                 else
3288                 {
3289                     parent = project->FindResource(mDisplayIndex, theme, info->parent->type, info->parent->name);
3290                 }
3291             }
3292             else
3293             {
3294                 parent = NULL;
3295             }
3296         }
3297 
3298         if (parent)
3299         {
3300             current_info = new res_info(NULL, *info, TRUE);
3301             parent->Attach(current_info);
3302 
3303             switch (current_info->type)
3304             {
3305             case RES_TYPE_FONT:
3306             {
3307                 GX_FONT *font = MakeFont(current_info, mDisplayIndex, TRUE);
3308 
3309                 if (font)
3310                 {
3311                     current_info->font = font;
3312 
3313                     /* Get output font size. */
3314                     current_info->storage_size = GetFontStorage(current_info, project, mDisplayIndex);
3315                 }
3316 
3317                 break;
3318             }
3319 
3320             case RES_TYPE_PIXELMAP:
3321                 /* KGM_PALETTE_MODE
3322                    Need to update theme palette if running in
3323                    8bit palette mode
3324                 */
3325                 project->InitializeOnePixelmap(current_info, NULL);
3326                 break;
3327             }
3328         }
3329         else
3330         {
3331             CString msg;
3332             msg.Format(_T("Internal Error: the parent of resource item \"%s\" in theme \"%s\" not found"), info->name,
3333                 project->mDisplays[mDisplayIndex].themes[theme].theme_name);
3334             ErrorMsg(msg);
3335         }
3336     }
3337 }
3338 
3339 //////////////////////////////////////////////////////////////////////////////
SyncResourcePath(res_info * info)3340 void resource_view::SyncResourcePath(res_info* info)
3341 {
3342     VALID_PROJECT
3343 
3344     res_info* current_info;
3345     for (int theme = 0; theme < project->mDisplays[mDisplayIndex].num_themes; theme++)
3346     {
3347         if (theme == project->mDisplays[mDisplayIndex].active_theme)
3348         {
3349             continue;
3350         }
3351 
3352         current_info = project->FindResource(mDisplayIndex, theme, info->type, info->name);
3353 
3354         if (current_info)
3355         {
3356             current_info->pathinfo = info->pathinfo;
3357 
3358             int theme = project->mDisplays[mDisplayIndex].active_theme;
3359 
3360             if (project->GetDisplayColorFormat(info) == GX_COLOR_FORMAT_8BIT_PALETTE ||
3361                 project->TestForPixelmapsUsingGlobalPalette(project->mDisplays[mDisplayIndex].themes[theme].GetFirstResourceInfo()))
3362             {
3363                 project->InitializeThemePixelmaps(mDisplayIndex, theme);
3364             }
3365             else
3366             {
3367                 project->InitializeOnePixelmap(current_info, NULL);
3368             }
3369         }
3370         else
3371         {
3372             CString msg;
3373 
3374             msg.Format(_T("Internal Error: resource item \"%s\" in theme \"%s\" not found"), info->name,
3375                 project->mDisplays[mDisplayIndex].themes[theme].theme_name);
3376             ErrorMsg(msg);
3377         }
3378     }
3379 }
3380 
3381 //////////////////////////////////////////////////////////////////////////////
DeleteResourceChildren(res_info * parent)3382 void resource_view::DeleteResourceChildren(res_info* parent)
3383 {
3384     VALID_PROJECT
3385 
3386     res_info *child = parent->child;
3387     res_info *next;
3388 
3389     while (child)
3390     {
3391         next = child->next;
3392 
3393         project->DeleteResource(child);
3394 
3395         child = next;
3396     }
3397 }
3398 
3399 //////////////////////////////////////////////////////////////////////////////
SyncResourceDelete(res_info * info)3400 void resource_view::SyncResourceDelete(res_info *info)
3401 {
3402     VALID_PROJECT
3403 
3404     res_info *current_info;
3405 
3406     for (int theme = 0; theme < project->mDisplays[mDisplayIndex].num_themes; theme++)
3407     {
3408         if (theme == project->mDisplays[mDisplayIndex].active_theme)
3409         {
3410             continue;
3411         }
3412         else
3413         {
3414             if (info->type == RES_TYPE_FOLDER)
3415             {
3416                 current_info = project->FindResourceFolder(mDisplayIndex, theme, info->type, info->folder_id, info->name);
3417 
3418                 if (current_info)
3419                 {
3420                     DeleteResourceChildren(current_info);
3421                 }
3422             }
3423             else
3424             {
3425                 current_info = project->FindResource(mDisplayIndex, theme, info->type, info->name);
3426             }
3427         }
3428 
3429         if (current_info)
3430         {
3431             project->DeleteResource(current_info);
3432         }
3433         else
3434         {
3435             CString msg;
3436 
3437             msg.Format(_T("Internal Error: resource item \"%s\" in theme \"%s\" not found"), info->name,
3438                 project->mDisplays[mDisplayIndex].themes[theme].theme_name);
3439             ErrorMsg(msg);
3440         }
3441     }
3442 }
3443 
3444 //////////////////////////////////////////////////////////////////////////////
ChangeItemParent(resource_item * item,resource_item * new_parent)3445 void resource_view::ChangeItemParent(resource_item *item, resource_item *new_parent)
3446 {
3447     VALID_PROJECT
3448 
3449     res_info *info;
3450     res_info *parent_info;
3451 
3452     for (int theme = 0; theme < project->mDisplays[mDisplayIndex].num_themes; theme++)
3453     {
3454         if (theme == project->mDisplays[mDisplayIndex].active_theme)
3455         {
3456             info = item->mpRes;
3457             parent_info = new_parent->mpRes;
3458 
3459             item->Detach();
3460             new_parent->Attach(item);
3461             item->SetPos(CRect(0, 0, 0, 0));
3462             mpTree->PositionItems();
3463         }
3464         else
3465         {
3466             info = project->FindResource(mDisplayIndex, theme, item->mpRes->type, item->mpRes->name);
3467             parent_info = project->FindResource(mDisplayIndex, theme, new_parent->mpRes->type, new_parent->mpRes->name);
3468         }
3469 
3470         info->Detach();
3471         parent_info->Attach(info);
3472     }
3473 }
3474 
3475 //////////////////////////////////////////////////////////////////////////////
OnRebuildStringItems(WPARAM wParam,LPARAM lParam)3476 LRESULT resource_view::OnRebuildStringItems(WPARAM wParam, LPARAM lParam)
3477 {
3478     RebuildStringItems((BOOL)wParam);
3479 
3480     return 0;
3481 }
3482 
3483 //////////////////////////////////////////////////////////////////////////////
OnUpdateStringTableFonts(WPARAM wParam,LPARAM lParam)3484 LRESULT resource_view::OnUpdateStringTableFonts(WPARAM wParam, LPARAM lParam)
3485 {
3486     FontCharMap *charmap = (FontCharMap *)wParam;
3487     UpdateStringTableFonts(charmap);
3488 
3489     return 0;
3490 }
3491 
3492 //////////////////////////////////////////////////////////////////////////////
OnOpenResourceItem(WPARAM wParam,LPARAM lParam)3493 LRESULT resource_view::OnOpenResourceItem(WPARAM wParam, LPARAM lParam)
3494 {
3495     resource_item *res_item = (resource_item *)wParam;
3496     if (!res_item->IsOpen())
3497     {
3498         res_item->Open();
3499     }
3500 
3501     return 0;
3502 }
3503 
3504 //////////////////////////////////////////////////////////////////////////////
OnTestMessage(WPARAM wParam,LPARAM lParam)3505 LRESULT resource_view::OnTestMessage(WPARAM wParam, LPARAM lParam)
3506 {
3507     resource_item *item;
3508     res_info *info = NULL;
3509     int index;
3510     CStringArray param;
3511     CStringArray path_array;
3512     CString folder_name;
3513     CString path;
3514     CString name;
3515     int res_type;
3516     int res_id;
3517     studiox_project *project;
3518 
3519     switch (wParam)
3520     {
3521     case TEST_ADD_PIXELMAPS:
3522         //parameter = folder_name,path,name1,name2,...
3523         SplitString(GetTestingParam(1), ',', &param);
3524 
3525         folder_name = param.GetAt(0);
3526         path = param.GetAt(1);
3527 
3528         for (index = 2; index < param.GetCount(); index++)
3529         {
3530             path_array.Add(path + param.GetAt(index));
3531         }
3532 
3533         // Find parent item
3534         item = mpTree->FindFolderNamed(mpTree->GetRoot(), RES_TYPE_FOLDER, CUSTOM_PIXELMAP_FOLDER, folder_name);
3535 
3536         if (item)
3537         {
3538             // for testing, don't flag missing image file
3539             project = GetOpenProject();
3540             project->mHeader.warn_missing_image = FALSE;
3541 
3542             // Add pixelmaps to parent
3543             AddPixelmaps(item, &path_array);
3544         }
3545         break;
3546 
3547     case TEST_CLICK_RESOURCE_GROUP:
3548         item = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_GROUP, lParam);
3549         if (item)
3550         {
3551             SetCurrentItem(item);
3552 
3553             if (item->IsOpen())
3554             {
3555                 item->Close();
3556             }
3557             else
3558             {
3559                 item->Open();
3560             }
3561         }
3562         break;
3563 
3564     case TEST_CLICK_PIXELMAP_FOLDER:
3565         SplitString(GetTestingParam(0), ',', &param);
3566 
3567         res_id = _tstoi(param.GetAt(0));
3568         name = param.GetAt(1);
3569 
3570         item = mpTree->FindFolderNamed(mpTree->GetRoot(), RES_TYPE_FOLDER, res_id, name);
3571 
3572         if (item)
3573         {
3574             SetCurrentItem(item);
3575 
3576             if (item->IsOpen())
3577             {
3578                 item->Close();
3579             }
3580             else
3581             {
3582                 item->Open();
3583             }
3584         }
3585         break;
3586 
3587     case TEST_CLICK_RESOURCE_ITEM:
3588         project = GetOpenProject();
3589         SplitString(GetTestingParam(0), ',', &param);
3590 
3591         res_type = _tstoi(param.GetAt(0));
3592         name = param.GetAt(1);
3593 
3594         item = mpTree->FindItem(mpTree->GetRoot(), res_type, name);
3595 
3596         if (item)
3597         {
3598             SetCurrentItem(item);
3599         }
3600         break;
3601 
3602     case TEST_ADD_COLOR:
3603         name = _T("Add New Color");
3604         item = mpTree->FindItem(mpTree->GetRoot(), RES_TYPE_ADD_COLOR, name);
3605         if (item)
3606         {
3607             SetCurrentItem(item);
3608             OnAddCustomColor();
3609         }
3610         break;
3611 
3612     case TEST_EDIT_COLOR:
3613         OnEditCustomColor();
3614         break;
3615 
3616     case TEST_DELETE_COLOR:
3617         OnDeleteCustomColor();
3618         break;
3619 
3620     case TEST_ADD_FONT:
3621         name = _T("Add New Font");
3622         item = mpTree->FindItem(mpTree->GetRoot(), RES_TYPE_ADD_FONT, name);
3623         if (item)
3624         {
3625             SetCurrentItem(item);
3626             OnAddFont();
3627         }
3628         break;
3629 
3630     case TEST_EDIT_FONT:
3631         OnEditFont();
3632         break;
3633 
3634     case TEST_DELETE_FONT:
3635         OnDeleteFont();
3636         break;
3637 
3638     case TEST_EDIT_STRING:
3639         OnEditStringTable();
3640         break;
3641 
3642     case TEST_EDIT_PIXELMAP:
3643         OnEditPixelmap();
3644         break;
3645 
3646     case TEST_EDIT_PIXELMAPS:
3647         OnEditPixelmaps();
3648         break;
3649 
3650     case TEST_DELETE_PIXELMAP:
3651         OnDeletePixelmap();
3652         break;
3653 
3654     case TEST_ENABLE_PIXELMAP:
3655         OnEnablePixelmap();
3656         break;
3657 
3658     case TEST_DISABLE_PIXELMAP:
3659         OnDisablePixelmap();
3660         break;
3661 
3662     case TEST_ADD_PIXELMAP_FOLDER:
3663         OnAddPixelmapFolder();
3664         break;
3665 
3666     case TEST_REMOVE_PIXELMAP_FOLDER:
3667         OnRemovePixelmapFolder();
3668         break;
3669 
3670     case TEST_ENABLE_PIXELMAP_FOLDER:
3671         OnEnablePixelmapFolder();
3672         break;
3673 
3674     case TEST_DISABLE_PIXELMAP_FOLDER:
3675         OnDisablePixelmapFolder();
3676         break;
3677 
3678     case TEST_INCREMENT_ACTIVE_LANGUAGE_INDEX:
3679         OnSetActiveLanguage(1);
3680         break;
3681 
3682     case TEST_DECREMENT_ACTIVE_LANGUAGE_INDEX:
3683         OnSetActiveLanguage(-1);
3684         break;
3685 
3686     case TEST_GENERATE_XML:
3687         project = GetOpenProject();
3688         if (project && mpCurrentItem)
3689         {
3690             path = GetTestingParam(0);
3691             index = path.ReverseFind('\\');
3692             if (index < 0)
3693             {
3694                 index = path.ReverseFind('/');
3695             }
3696 
3697             if (index >= 0)
3698             {
3699                 name = path.Mid(index + 1);
3700                 name = RemoveFileExtension(name);
3701             }
3702             project->GenerateResourceXml(path, name, mpCurrentItem->mpRes);
3703         }
3704         break;
3705     }
3706 
3707     return 0;
3708 }
3709 
3710 
3711 ///////////////////////////////////////////////////////////////////////////////
OnSetFocus(CWnd * pOldWnd)3712 void resource_view::OnSetFocus(CWnd* pOldWnd)
3713 {
3714     CScrollView::OnSetFocus(pOldWnd);
3715 
3716     // TODO: Add your message handler code here
3717     if (mpCurrentItem)
3718     {
3719         CRect rect = mpCurrentItem->GetPos();
3720         int scrollpos = GetScrollPos(SB_VERT);
3721         rect.top -= scrollpos;
3722         rect.bottom -= scrollpos;
3723         InvalidateRect(rect);
3724 
3725         if (mpCurrentItem->GetResItemProvider())
3726         {
3727             mpCurrentItem->GetResItemProvider()->RaiseChangeFocusEvent();
3728         }
3729     }
3730 }
3731 
3732 ///////////////////////////////////////////////////////////////////////////////
OnKillFocus(CWnd * pNewWnd)3733 void resource_view::OnKillFocus(CWnd* pNewWnd)
3734 {
3735     CScrollView::OnKillFocus(pNewWnd);
3736 
3737     // TODO: Add your message handler code here
3738     if (mpCurrentItem)
3739     {
3740         CRect rect = mpCurrentItem->GetPos();
3741         int scrollpos = GetScrollPos(SB_VERT);
3742         rect.top -= scrollpos;
3743         rect.bottom -= scrollpos;
3744         InvalidateRect(rect);
3745     }
3746 }
3747 
3748 ///////////////////////////////////////////////////////////////////////////////
GetResViewProvider()3749 resource_view_provider* resource_view::GetResViewProvider()
3750 {
3751     if (m_pResViewProvider == NULL)
3752     {
3753         m_pResViewProvider = new resource_view_provider(this);
3754     }
3755     return m_pResViewProvider;
3756 }
3757 
3758 ///////////////////////////////////////////////////////////////////////////////
CreateUniqueId()3759 int resource_view::CreateUniqueId()
3760 {
3761     static int uniqueId;
3762     return uniqueId++;
3763 }
3764 
3765 ///////////////////////////////////////////////////////////////////////////////
SelectNextItem()3766 void resource_view::SelectNextItem()
3767 {
3768     if (!mpCurrentItem)
3769     {
3770         return;
3771     }
3772 
3773     CRect size = mpCurrentItem->GetPos();
3774     CPoint cp(size.left, size.bottom + (mpCurrentItem->GetItemHeight() / 2));
3775 
3776     resource_item *next = mpTree->FindItem(mpTree->GetRoot(), cp);
3777 
3778     if (next)
3779     {
3780         SetCurrentItem(next);
3781     }
3782 }
3783 
3784 ///////////////////////////////////////////////////////////////////////////////
SelectPreviousItem()3785 void resource_view::SelectPreviousItem()
3786 {
3787     if (!mpCurrentItem)
3788     {
3789         return;
3790     }
3791 
3792     CRect size = mpCurrentItem->GetPos();
3793     CPoint cp(size.left, size.top - (mpCurrentItem->GetItemHeight() / 2));
3794 
3795     resource_item *previous = mpTree->FindItem(mpTree->GetRoot(), cp);
3796 
3797     if (previous)
3798     {
3799         SetCurrentItem(previous);
3800     }
3801 }
3802 
3803 ///////////////////////////////////////////////////////////////////////////////
OnReturnKey(int item_type)3804 BOOL resource_view::OnReturnKey(int item_type)
3805 {
3806     switch (item_type)
3807     {
3808     case RES_TYPE_COLOR:
3809     {
3810         if (!GetCurrentItem())
3811         {
3812             return FALSE;
3813         }
3814 
3815         resource_item* parent = GetCurrentItem()->Parent();
3816 
3817         if (parent && (parent->GetResType() == RES_TYPE_FOLDER))
3818         {
3819             if (parent->mpRes->folder_id == DEFAULT_COLOR_FOLDER)
3820             {
3821                 OnEditSystemColor();
3822             }
3823             else
3824             {
3825                 OnEditCustomColor();
3826             }
3827 
3828             return TRUE;
3829         }
3830     }
3831         break;
3832 
3833     case RES_TYPE_ADD_COLOR:
3834         OnAddCustomColor();
3835         return TRUE;
3836 
3837     case RES_TYPE_FONT:
3838         OnEditFont();
3839         return TRUE;
3840 
3841     case RES_TYPE_ADD_FONT:
3842         OnAddFont();
3843         return TRUE;
3844 
3845     case RES_TYPE_PIXELMAP:
3846         OnEditPixelmap();
3847         return TRUE;
3848 
3849     case RES_TYPE_ADD_PIXELMAP:
3850         OnAddPixelmaps();
3851         return TRUE;
3852 
3853     case RES_TYPE_ADD_STRING:
3854     case RES_TYPE_STRING:
3855         OnEditStringTable();
3856         return TRUE;
3857 
3858     default:
3859         break;
3860     }
3861 
3862     return FALSE;
3863 }
3864 
3865 ///////////////////////////////////////////////////////////////////////////////
OnTabKey(int item_type)3866 BOOL resource_view::OnTabKey(int item_type)
3867 {
3868     int nShiftKey = GetKeyState(VK_SHIFT);
3869 
3870     switch (item_type)
3871     {
3872     case RES_TYPE_HEADER:
3873     case RES_TYPE_GROUP:
3874         if (nShiftKey & KEY_STATE_DOWN)
3875         {
3876             if (mpCurrentItem->Previous())
3877             {
3878                 SetCurrentItem(mpCurrentItem->Previous());
3879             }
3880         }
3881         else
3882         {
3883             if (mpCurrentItem->Next())
3884             {
3885                 SetCurrentItem(mpCurrentItem->Next());
3886             }
3887         }
3888         return TRUE;
3889 
3890     default:
3891         break;
3892     }
3893 
3894     return FALSE;
3895 }
3896 
3897 ///////////////////////////////////////////////////////////////////////////////
OnDirectionKey(int item_type,int key)3898 BOOL resource_view::OnDirectionKey(int item_type, int key)
3899 {
3900     switch (key)
3901     {
3902     case VK_DOWN:
3903         SelectNextItem();
3904         return TRUE;
3905 
3906     case VK_UP:
3907         SelectPreviousItem();
3908         return TRUE;
3909 
3910     default:
3911         break;
3912     }
3913 
3914     switch (item_type)
3915     {
3916     case RES_TYPE_HEADER:
3917         if (key == VK_LEFT)
3918         {
3919             OnSetActiveTheme(-1);
3920         }
3921         else if (key == VK_RIGHT)
3922         {
3923             OnSetActiveTheme(1);
3924         }
3925         return TRUE;
3926 
3927     case RES_TYPE_GROUP:
3928     case RES_TYPE_FOLDER:
3929         if (key == VK_LEFT)
3930         {
3931             if (mpCurrentItem->IsOpen())
3932             {
3933                 //collapse group or folder
3934                 mpCurrentItem->Close();
3935                 mpTree->PositionItems();
3936             }
3937         }
3938         else if (key == VK_RIGHT)
3939         {
3940             if (!mpCurrentItem->IsOpen())
3941             {
3942                 //expand group or folder
3943                 mpCurrentItem->Open();
3944                 mpTree->PositionItems();
3945             }
3946         }
3947         return TRUE;
3948 
3949     case RES_TYPE_STRING:
3950         if (key == VK_LEFT)
3951         {
3952             OnSetActiveLanguage(-1);
3953         }
3954         else if (key == VK_RIGHT)
3955         {
3956             OnSetActiveLanguage(1);
3957         }
3958         return TRUE;
3959 
3960     default:
3961         break;
3962     }
3963 
3964     return FALSE;
3965 }
3966 
3967 ///////////////////////////////////////////////////////////////////////////////
OnPageDonw(int item_type)3968 void resource_view::OnPageDonw(int item_type)
3969 {
3970     CRect client;
3971     CRect size = mpCurrentItem->GetPos();
3972 
3973     GetClientRect(&client);
3974     CPoint cp(size.left, size.top + client.Height());
3975 
3976     Scroll(client.Height());
3977 
3978     resource_item* next = mpTree->FindItem(mpTree->GetRoot(), cp);
3979 
3980     if (next)
3981     {
3982         SetCurrentItem(next);
3983     }
3984 }
3985 
3986 ///////////////////////////////////////////////////////////////////////////////
OnPageUp(int item_type)3987 void resource_view::OnPageUp(int item_type)
3988 {
3989     CRect client;
3990     CRect size = mpCurrentItem->GetPos();
3991 
3992     GetClientRect(&client);
3993     CPoint cp(size.left, size.top - client.Height());
3994 
3995     resource_item* previous = mpTree->FindItem(mpTree->GetRoot(), cp);
3996 
3997     Scroll(-client.Height());
3998 
3999     if (previous)
4000     {
4001         SetCurrentItem(previous);
4002     }
4003 }
4004 
4005 ///////////////////////////////////////////////////////////////////////////////
OnHome(int item_type)4006 void resource_view::OnHome(int item_type)
4007 {
4008     resource_item *item = mpTree->GetRoot()->First();
4009     if (item)
4010     {
4011         SetCurrentItem(item);
4012     }
4013 }
4014 
4015 ///////////////////////////////////////////////////////////////////////////////
OnEnd(int item_type)4016 void resource_view::OnEnd(int item_type)
4017 {
4018     resource_item *item;
4019 
4020 
4021     item = mpTree->FindFolder(mpTree->GetRoot(), RES_TYPE_GROUP, STRING_GROUP);
4022 
4023     if (item && item->IsOpen())
4024     {
4025         CString res_name("Add New String");
4026 
4027         item = mpTree->FindItem(item, RES_TYPE_ADD_STRING, res_name);
4028     }
4029 
4030     if (item)
4031     {
4032         SetCurrentItem(item);
4033     }
4034 }
4035 
4036 ///////////////////////////////////////////////////////////////////////////////
PreTranslateMessage(MSG * pMsg)4037 BOOL resource_view::PreTranslateMessage(MSG* pMsg)
4038 {
4039     // TODO: Add your specialized code here and/or call the base class
4040     if (pMsg->message == WM_SYSKEYDOWN)
4041     {
4042         int nAltKey = GetKeyState(VK_MENU);
4043 
4044         switch (pMsg->wParam)
4045         {
4046         case VK_UP:
4047         case VK_LEFT:
4048             if (nAltKey & KEY_STATE_DOWN)
4049             {
4050                 //move focus to target view
4051                 target_view* view = GetTargetView();
4052                 if (view)
4053                 {
4054                     CMainFrame* frame = (CMainFrame*)GetParentFrame();
4055                     frame->SetActiveView(view);
4056                     return TRUE;
4057                 }
4058             }
4059             break;
4060 
4061         default:
4062             break;
4063         }
4064     }
4065     else if (pMsg->message == WM_KEYDOWN)
4066     {
4067         int item_type = -1;
4068         int key = pMsg->wParam;
4069 
4070         if (mpCurrentItem)
4071         {
4072             item_type = mpCurrentItem->GetResType();
4073         }
4074 
4075         switch (key)
4076         {
4077         case VK_TAB:
4078             if (OnTabKey(item_type))
4079             {
4080                 return TRUE;
4081             }
4082             break;
4083 
4084         case VK_RETURN:
4085             if (OnReturnKey(item_type))
4086             {
4087                 return TRUE;
4088             }
4089             break;
4090 
4091         case VK_LEFT:
4092         case VK_RIGHT:
4093         case VK_DOWN:
4094         case VK_UP:
4095             if (OnDirectionKey(item_type, key))
4096             {
4097                 return TRUE;
4098             }
4099             break;
4100 
4101         case VK_PRIOR:
4102             OnPageUp(item_type);
4103             return TRUE;
4104 
4105         case VK_NEXT:
4106             OnPageDonw(item_type);
4107             return TRUE;
4108 
4109         case VK_HOME:
4110             OnHome(item_type);
4111             return TRUE;
4112 
4113         case VK_END:
4114             OnEnd(item_type);
4115             return TRUE;
4116 
4117         default:
4118             break;
4119         }
4120     }
4121 
4122     return CScrollView::PreTranslateMessage(pMsg);
4123 }
4124 
4125 ///////////////////////////////////////////////////////////////////////////////
WindowProc(UINT message,WPARAM wParam,LPARAM lParam)4126 LRESULT resource_view::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
4127 {
4128     switch (message)
4129     {
4130     case WM_GETOBJECT:
4131         // Register the control with UI Automation.
4132         // If the lParam matches the RootObjectId, send back the tree view provider.
4133         if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId))
4134         {
4135             // Return its associated UI Automation provider.
4136             LRESULT lresult = UiaReturnRawElementProvider(
4137                 GetSafeHwnd(), wParam, lParam, GetResViewProvider());
4138             return lresult;
4139         }
4140         return 0;
4141 
4142     case SBM_GETSCROLLINFO:
4143     {
4144         SCROLLINFO* si = (SCROLLINFO*)lParam;
4145         if (si->fMask == SIF_POS)
4146         {
4147             si->nPos = GetScrollPos(SB_VERT);
4148         }
4149         return 0;
4150     }
4151 
4152     default:
4153         // Do nothing.
4154         break;
4155     }
4156 
4157     return CScrollView::WindowProc(message, wParam, lParam);
4158 }
4159 
4160 ///////////////////////////////////////////////////////////////////////////////
OnSettingChange(UINT uFlags,LPCTSTR lpszSection)4161 void resource_view::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
4162 {
4163     CScrollView::OnSettingChange(uFlags, lpszSection);
4164 
4165     if (mDisplayIndex >= 0)
4166     {
4167         InstallResources(mDisplayIndex);
4168     }
4169 }
4170