1 
2 #include "studiox_includes.h"
3 #include "copy_paste_engine.h"
4 #include "app_runner.h"
5 #include "folder_name_dlg.h"
6 #include "gx_win32_studio_display_driver.h"
7 
8 #ifdef _DEBUG
9 #define new DEBUG_NEW
10 #endif
11 
12 extern INI_INFO        StudioXIni;
13 extern CString         studiox_version_string;
14 extern CArray<WIDGET_SELECT_ENTRY> SelectedWidgets;
15 
16 IMPLEMENT_DYNCREATE(project_view, CTreeView)
17 
18 enum project_view_test_commands{
19     TEST_OPEN_PROJECT = 1,
20     TEST_CLOSE_PROJECT,
21     TEST_IMPORT_PROJECT,
22     TEST_SELECT_PROJECT_TREE_NODE,
23     TEST_SELECT_PROJECT_FOLDER,
24     TEST_SELECT_CHILD_WIDGET,
25     TEST_SELECT_MULTI_WIDGETS,
26     TEST_DELETE_WIDGET,
27     TEST_GET_WIDGET_LEFT,
28     TEST_GET_WIDGET_TOP,
29     TEST_GET_WIDGET_RIGHT,
30     TEST_GET_WIDGET_BOTTOM,
31     TEST_INSERT_FOLDER,
32     TEST_EDIT_FOLDER_PROPERTIES,
33     TEST_DELETE_FOLDER,
34     TEST_TERMINATE_APP_EXECUTION
35 };
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 BEGIN_MESSAGE_MAP(project_view, CTreeView)
39     ON_WM_PAINT()
40     ON_WM_ERASEBKGND()
41     ON_WM_CONTEXTMENU()
42     ON_NOTIFY_REFLECT(NM_RCLICK, OnRClick)
43     ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnNodeSelect)
44     ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemExpanded)
45     ON_COMMAND(ID_EDIT_FOLDER_PROPERTIES, OnEditFolderProperties)
46     ON_COMMAND(ID_LOCK_WIDGET_POSITIONS, OnLockUlockWidgetPositions)
47     ON_MESSAGE(STUDIO_TEST, OnTestMessage)
48 END_MESSAGE_MAP()
49 
50 typedef struct {
51     int widget_type;
52     int bmp_id;
53 } WIDGET_TYPE_IMAGE_MAP ;
54 
55 WIDGET_TYPE_IMAGE_MAP ProjectViewImageMap[] = {
56     { -1,   IDB_PROJECT},
57     { -1,   IDB_DISPLAY},
58     { -1,   IDB_FOLDER_CLOSE},
59     { -1,   IDB_FOLDER_OPEN},
60     { GX_TYPE_WINDOW, IDB_WINDOW},
61     { GX_TYPE_DIALOG, IDB_DIALOG},
62     { GX_TYPE_HORIZONTAL_LIST, IDB_HORZ_LIST},
63     { GX_TYPE_VERTICAL_LIST,   IDB_VERT_LIST},
64     { GX_TYPE_DROP_LIST,       IDB_DROP_LIST},
65     { GX_TYPE_BUTTON, IDB_BUTTON},
66     { GX_TYPE_CHECKBOX, IDB_CHECKBOX},
67     { GX_TYPE_RADIO_BUTTON, IDB_RADIO_BUTTON},
68     { GX_TYPE_ICON, IDB_ICON },
69     { GX_TYPE_ICON_BUTTON, IDB_ICON_BUTTON},
70     { GX_TYPE_TEXT_BUTTON, IDB_TEXT_BUTTON},
71     { GX_TYPE_MULTI_LINE_TEXT_BUTTON, IDB_MULTI_LINE_TEXT_BUTTON},
72     { GX_TYPE_PIXELMAP_BUTTON, IDB_PIXELMAP_BUTTON},
73     { GX_TYPE_SHADOW_BUTTON, IDB_SHADOW_BUTTON},
74     { GX_TYPE_SPRITE, IDB_SPRITE },
75     { GX_TYPE_PROMPT, IDB_PROMPT},
76     { GX_TYPE_MULTI_LINE_TEXT_VIEW, IDB_MULTILINE_PROMPT},
77     { GX_TYPE_MULTI_LINE_TEXT_INPUT, IDB_MULTILINE_TEXT_INPUT },
78     { GX_TYPE_PIXELMAP_PROMPT, IDB_PIXELMAP_PROMPT},
79     { GX_TYPE_PIXELMAP_TEXT_INPUT, IDB_PIXELMAP_TEXT_INPUT},
80     { GX_TYPE_SINGLE_LINE_TEXT_INPUT, IDB_TEXT_INPUT},
81     { GX_TYPE_HORIZONTAL_SCROLL, IDB_HORZ_SCROLL},
82     { GX_TYPE_VERTICAL_SCROLL, IDB_VERT_SCROLL},
83     { GX_TYPE_SLIDER, IDB_SLIDER},
84     { GX_TYPE_PIXELMAP_SLIDER, IDB_PIXELMAP_SLIDER},
85     { GX_TYPE_PROGRESS_BAR, IDB_PROGRESS_BAR},
86     { GX_TYPE_RADIAL_PROGRESS_BAR, IDB_RADIAL_PROGRESS_BAR},
87     { GX_TYPE_CIRCULAR_GAUGE, IDB_GAUGE},
88     { 0, 0}
89 };
90 
91 ///////////////////////////////////////////////////////////////////////////////
project_view()92 project_view::project_view()
93 {
94     mpImageList = NULL;
95     m_active_display = -1;
96     m_widget_copy = NULL;
97 }
98 
99 ///////////////////////////////////////////////////////////////////////////////
~project_view()100 project_view::~project_view()
101 {
102     studiox_project *project = GetOpenProject();
103     if (project)
104     {
105         delete project;
106         SetOpenProject(NULL);
107     }
108 
109 
110     if (mpImageList)
111     {
112         delete mpImageList;
113     }
114 
115     if (m_widget_copy)
116     {
117         delete m_widget_copy;
118     }
119 }
120 
121 ///////////////////////////////////////////////////////////////////////////////
PreCreateWindow(CREATESTRUCT & cs)122 BOOL project_view::PreCreateWindow(CREATESTRUCT& cs)
123 {
124 
125     if( !CTreeView::PreCreateWindow(cs) )
126         return FALSE;
127     // TODO: Modify the Window class or styles here by modifying
128     //  the CREATESTRUCT cs
129 
130     return TRUE;
131 }
132 
133 ///////////////////////////////////////////////////////////////////////////////
AddTreeRoot(CString & rootname)134 HTREEITEM project_view::AddTreeRoot(CString &rootname)
135 {
136    /* setup initial tree view */
137 
138     TVINSERTSTRUCT tvInsert;
139     CString fullname = rootname;
140     TCHAR *ps = fullname.GetBuffer(1);
141 
142     tvInsert.hParent = NULL;
143     tvInsert.hInsertAfter = NULL;
144     tvInsert.item.mask = TVIF_TEXT;
145     tvInsert.item.pszText = ps;
146     tvInsert.item.iImage = 0;
147     HTREEITEM hroot = mpTree->InsertItem(&tvInsert);
148     fullname.ReleaseBuffer();
149     return hroot;
150 }
151 
152 ///////////////////////////////////////////////////////////////////////////////
CreateImageList(int width,int height)153 CImageList *CreateImageList(int width, int height)
154 {
155     CImageList *list = new CImageList();
156     list->Create(width, height, ILC_COLOR24, 0, 0);
157 
158     WIDGET_TYPE_IMAGE_MAP *entry = ProjectViewImageMap;
159 
160     while(entry->bmp_id)
161     {
162         CBitmap *bmp = new CBitmap();
163         bmp->LoadBitmap(entry->bmp_id);
164         list->Add(bmp, (CBitmap *) NULL);
165         delete bmp;
166         entry++;
167     }
168     return list;
169 }
170 
171 ///////////////////////////////////////////////////////////////////////////////
OnInitialUpdate()172 void project_view::OnInitialUpdate()
173 {
174     /* inform the parent frame of my instance for later access */
175     CMainFrame *frame = (CMainFrame *) GetParentFrame();
176     frame ->SetProjectView(this);
177     frame->SetActiveView(this);
178     SetWindowText(_T("Project View"));
179 
180     mpTree = &GetTreeCtrl();
181     mpTree->DeleteAllItems();
182 
183     SetControlAccessibleName(mpTree->GetSafeHwnd(), _T("project_view"));
184 
185     SetFrameTitle(CString(_T("No Project")));
186     HTREEITEM hroot = AddTreeRoot(CString(_T("No Project")));
187 //    mpTree->ModifyStyle(0, TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS);
188     mpTree->ModifyStyle(0, TVS_HASLINES|TVS_HASBUTTONS|TVS_SHOWSELALWAYS);
189 
190     // create an image list:
191     if (mpImageList)
192     {
193         delete mpImageList;
194         mpImageList = NULL;
195     }
196     mpImageList = CreateImageList(16, 16);
197     mpTree->SetImageList(mpImageList, TVSIL_NORMAL);
198     mpTree->SetIndent(0);
199 }
200 
201 ///////////////////////////////////////////////////////////////////////////////
AssignTreeImage(HTREEITEM item,widget_info * info)202 void project_view::AssignTreeImage(HTREEITEM item, widget_info *info)
203 {
204     WIDGET_TYPE_IMAGE_MAP *entry = ProjectViewImageMap;
205     int index = 0;
206 
207     while(entry->bmp_id)
208     {
209         if (entry->widget_type == info->basetype)
210         {
211             mpTree->SetItemImage(item, index, index);
212             break;
213         }
214         index++;
215         entry++;
216     }
217 }
218 
219 
220 ///////////////////////////////////////////////////////////////////////////////
AssignTreeImage(HTREEITEM item,folder_info * info,BOOL expaned)221 void project_view::AssignTreeImage(HTREEITEM item, folder_info *info , BOOL expaned)
222 {
223     WIDGET_TYPE_IMAGE_MAP *entry = ProjectViewImageMap;
224     int index = 0;
225     if (expaned)
226     {
227         while (entry->bmp_id)
228         {
229             if (entry->bmp_id == IDB_FOLDER_OPEN)
230             {
231                 mpTree->SetItemImage(item, index, index);
232                 break;
233             }
234             index++;
235             entry++;
236         }
237     }
238     else
239     {
240         while (entry->bmp_id)
241         {
242             if (entry->bmp_id == IDB_FOLDER_CLOSE)
243             {
244                 mpTree->SetItemImage(item, index, index);
245                 break;
246             }
247 
248             index++;
249             entry++;
250         }
251     }
252 
253 }
254 
255 ///////////////////////////////////////////////////////////////////////////////
AddTreeFolders(HTREEITEM hParent,folder_info * start)256 void project_view::AddTreeFolders(HTREEITEM hParent, folder_info *start)
257 {
258     while (start)
259     {
260         HTREEITEM hCurrent = mpTree->InsertItem(start->folder_name,
261             hParent, TVI_SORT);
262         mpTree->SetItemData(hCurrent, (DWORD_PTR)start);
263         AssignTreeImage(hCurrent, start);
264 
265         AddTreeWidgets(hCurrent, start->GetFirstChildWidget());
266 
267         start = start->GetNextFolder();
268     }
269 }
270 
271 
272 ///////////////////////////////////////////////////////////////////////////////
AddTreeWidgets(HTREEITEM hParent,widget_info * start)273 void project_view::AddTreeWidgets(HTREEITEM hParent, widget_info *start)
274 {
275     CString tree_name;
276 
277     while (start)
278     {
279         if (!start->app_name.IsEmpty())
280         {
281             tree_name = start->app_name;
282         }
283         else
284         {
285             tree_name = start->base_name;
286         }
287         HTREEITEM hCurrent = mpTree->InsertItem(tree_name,
288             hParent, TVI_SORT);
289         mpTree->SetItemData(hCurrent, (DWORD_PTR) start);
290         AssignTreeImage(hCurrent, start);
291 
292         if (start->GetChildWidgetInfo())
293         {
294             AddTreeWidgets(hCurrent, start->GetChildWidgetInfo());
295         }
296         start = start->GetNextWidgetInfo();
297     }
298 }
299 
300 ///////////////////////////////////////////////////////////////////////////////
SelectFirstScreen()301 void project_view::SelectFirstScreen()
302 {
303     HTREEITEM hroot = mpTree->GetRootItem();
304 
305     if (hroot)
306     {
307         // Select the first display:
308         HTREEITEM hdisplay = mpTree->GetChildItem(hroot);
309 
310         if (hdisplay)
311         {
312             HTREEITEM hfolder = mpTree->GetChildItem(hdisplay);
313             if (hfolder)
314             {
315                 HTREEITEM hscreen = mpTree->GetChildItem(hfolder);
316                 if (hscreen)
317                 {
318                     mpTree->SelectItem(hscreen);
319                 }
320                 else
321                 {
322                     mpTree->SelectItem(hfolder);
323                 }
324             }
325             else
326             {
327                 mpTree->SelectItem(hdisplay);
328             }
329         }
330     }
331 }
332 
333 ///////////////////////////////////////////////////////////////////////////////
RunApplication(CWnd * parent)334 void project_view::RunApplication(CWnd *parent)
335 {
336     studiox_project *project = GetOpenProject();
337     display_info *display;
338 
339     if (project)
340     {
341         int display_index = GetActiveDisplay();
342         display = &project->mDisplays[display_index];
343         if (display->screenflow)
344         {
345             app_runner runner;
346             runner.RunApplication(display_index, parent);
347         }
348         else
349         {
350             ErrorMsg("Screen flow diagram is not been configured, cannot run application", parent);
351             return;
352         }
353     }
354 }
355 
356 ///////////////////////////////////////////////////////////////////////////////
SelectDisplay(int display)357 void project_view::SelectDisplay(int display)
358 {
359     HTREEITEM hroot = mpTree->GetRootItem();
360 
361     if (hroot)
362     {
363         // Select the first display:
364         HTREEITEM hdisplay = mpTree->GetChildItem(hroot);
365 
366         while (hdisplay)
367         {
368             int index = mpTree->GetItemData(hdisplay);
369 
370             if (index == display)
371             {
372                 mpTree->SelectItem(hdisplay);
373                 break;
374             }
375             hdisplay = mpTree->GetNextSiblingItem(hdisplay);
376         }
377     }
378 }
379 
380 ///////////////////////////////////////////////////////////////////////////////
PopulateProjectTree(studiox_project * pProj)381 void project_view::PopulateProjectTree(studiox_project *pProj)
382 {
383     HTREEITEM hCurrent;
384     int DisplayIndex = 0;
385     mpTree->DeleteAllItems();
386 
387     if (pProj == NULL)
388     {
389         return;
390     }
391 
392     for (DisplayIndex = 0; DisplayIndex < pProj->mHeader.max_displays; DisplayIndex++)
393     {
394         widget_factory::CleanupWidgets(pProj->mDisplays[DisplayIndex].GetFirstChildFolder());
395     }
396 
397     // Add the root node:
398     HTREEITEM hroot = AddTreeRoot(pProj->mHeader.project_name);
399 
400     // Add the display nodes:
401 
402     for (DisplayIndex = 0; DisplayIndex < pProj->mHeader.num_displays; DisplayIndex++)
403     {
404         hCurrent = mpTree->InsertItem(pProj->mDisplays[DisplayIndex].name,
405             hroot, TVI_SORT);
406         mpTree->SetItemData(hCurrent, DisplayIndex);
407         mpTree->SetItemImage(hCurrent, 1, 1);
408 
409         AddTreeFolders(hCurrent, pProj->mDisplays[DisplayIndex].GetFirstChildFolder());
410         //widget_factory::GenerateWidgets(pProj->mDisplays[DisplayIndex].GetFirstChildFolder());
411     }
412     mpTree->Expand(hroot, TVE_EXPAND);
413 }
414 
415 ///////////////////////////////////////////////////////////////////////////////
OnPaint()416 void project_view::OnPaint()
417 {
418     CTreeView::OnPaint();
419 }
420 
421 ///////////////////////////////////////////////////////////////////////////////
OnEraseBkgnd(CDC * pDC)422 BOOL project_view::OnEraseBkgnd(CDC *pDC)
423 {
424      return CTreeView::OnEraseBkgnd(pDC);
425 }
426 template <class T>
427 ///////////////////////////////////////////////////////////////////////////////
check_set_active_display(T * info)428 BOOL project_view::check_set_active_display(T *info)
429 {
430     studiox_project *project = GetOpenProject();
431 
432     if (project)
433     {
434         int display_index = project->GetDisplayIndex(info);
435 
436         if (display_index >= 0)
437         {
438             if (display_index != m_active_display)
439             {
440                 //Cleanup current display resources
441                 GetResourceView()->CleanupDisplayResources(get_target_view_display());
442 
443                 m_active_display = display_index;
444                 GetTargetScreen()->ConfigureDisplay(display_index);
445                 GetResourceView()->OnDisplaySelect(display_index);
446                 return TRUE;
447             }
448         }
449     }
450     return FALSE;
451 }
452 
453 ///////////////////////////////////////////////////////////////////////////////
OnItemExpanded(NMHDR * pNotifyStruct,LRESULT * pr)454 void project_view::OnItemExpanded(NMHDR *pNotifyStruct, LRESULT *pr)
455 {
456     NM_TREEVIEW *pTree = (NM_TREEVIEW *)pNotifyStruct;
457     TV_ITEM tItem = pTree->itemNew;
458     HTREEITEM hItem = tItem.hItem;
459 
460     if (hItem)
461     {
462         if (GetTreeNodeLevel(hItem) == FOLDER_NODE_LEVEL)
463         {
464             folder_info *folder = (folder_info *)mpTree->GetItemData(hItem);
465             UINT style = mpTree->GetItemState(hItem, TVIS_EXPANDED);
466             /* */
467             if (style & TVIS_EXPANDED)
468             {
469                 AssignTreeImage(hItem, folder, TRUE);
470             }
471             else
472             {
473                 AssignTreeImage(hItem, folder);
474             }
475 
476             /* Force project view to redraw here to make the "+" shown.
477             Sometime the "+" isn't shown when generally running,
478             but it is shown when debug. So force it redraw here.*/
479             Invalidate();
480             UpdateWindow();
481         }
482     }
483 }
484 
485 ///////////////////////////////////////////////////////////////////////////////
OnNodeSelect(NMHDR * ph,LRESULT * pr)486 void project_view::OnNodeSelect(NMHDR *ph, LRESULT *pr)
487 {
488     studiox_project *project = GetOpenProject();
489     if (!project)
490     {
491         return;
492     }
493     HTREEITEM hItem = mpTree->GetSelectedItem();
494     widget_info *info;
495     folder_info *folder;
496     GX_WINDOW_ROOT *root;
497     int display_index;
498 
499     switch(GetTreeNodeLevel(hItem))
500     {
501     case PROJECT_NODE_LEVEL:
502         GetTargetScreen()->SelectWidget(NULL, FALSE, FALSE);
503         GetPropsWin()->OnWidgetSelect(NULL);
504         break;
505 
506     case DISPLAY_NODE_LEVEL:
507         GetTargetScreen()->SelectWidget(NULL, FALSE, FALSE);
508         GetPropsWin()->OnWidgetSelect(NULL);
509         display_index = (int) mpTree->GetItemData(hItem);
510         if (display_index != m_active_display)
511         {
512             m_active_display = display_index;
513             GetResourceView()->CleanupDisplayResources(get_target_view_display());
514             GetTargetScreen()->ConfigureDisplay(display_index);
515             GetResourceView()->OnDisplaySelect(display_index);
516         }
517         break;
518 
519     case FOLDER_NODE_LEVEL:
520         folder = (folder_info *)mpTree->GetItemData(hItem);
521         check_set_active_display<folder_info>(folder);
522         root = get_root_window();
523         info = folder->GetFirstChildWidget();
524         if (root && !root->gx_widget_first_child && info)
525         {
526             GetTargetScreen()->SelectWidget(info, FALSE, FALSE);
527             GetPropsWin()->OnWidgetSelect(info);
528         }
529         else
530         {
531             GetTargetScreen()->SelectWidget(NULL, FALSE, FALSE);
532             GetPropsWin()->OnWidgetSelect(NULL);
533         }
534 
535         if (root)
536         {
537             gx_widget_show((GX_WIDGET *)get_root_window());
538         }
539         break;
540 
541     case SCREEN_NODE_LEVEL:
542         info = (widget_info *) mpTree->GetItemData(hItem);
543         check_set_active_display<widget_info>(info);
544         GetTargetScreen()->SwitchTopWidget(info);
545         GetTargetScreen()->SelectWidget(info, FALSE, FALSE);
546         GetPropsWin()->OnWidgetSelect(info);
547         if (get_root_window())
548         {
549             gx_widget_show((GX_WIDGET *)get_root_window());
550         }
551         break;
552 
553     default:
554         info = (widget_info *) mpTree->GetItemData(hItem);
555         check_set_active_display(info);
556         GetTargetScreen()->SelectWidget(info, FALSE, FALSE);
557         GetPropsWin()->OnWidgetSelect(info);
558         break;
559     }
560 }
561 
562 ///////////////////////////////////////////////////////////////////////////////
OnRClick(NMHDR * pNMHDR,LRESULT * pResult)563 void project_view::OnRClick(NMHDR *pNMHDR, LRESULT *pResult)
564 {
565     SendMessage(WM_CONTEXTMENU, (WPARAM) m_hWnd, GetMessagePos());
566     *pResult = 1;
567 }
568 
569 ///////////////////////////////////////////////////////////////////////////////
OnContextMenu(CWnd * pWnd,CPoint pos)570 void project_view::OnContextMenu(CWnd *pWnd, CPoint pos)
571 {
572     HTREEITEM htItem;
573 
574     if (pos.x == -1 && pos.y == -1)
575     {
576         // The contet menu is generated from the keyboard, for example the user types Shift+F10
577         // Pop up menu under selected item
578         htItem = mpTree->GetSelectedItem();
579 
580         if (htItem == NULL)
581             return;
582 
583         CRect rect;
584         mpTree->GetItemRect(htItem, &rect, TRUE);
585         pos.x = rect.left;
586         pos.y = rect.bottom;
587     }
588     else
589     {
590         ScreenToClient(&pos);
591 
592         UINT uFlags;
593 
594         htItem = mpTree->HitTest(pos, &uFlags);
595 
596         if (htItem == NULL)
597             return;
598 
599         if (htItem != mpTree->GetSelectedItem())
600         {
601             mpTree->Select(htItem, TVGN_CARET);
602         }
603     }
604 
605     //m_hActiveItem = htItem;
606 
607     CMenu       menu;
608     CMenu       insert_menu;
609     CMenu       base_menu;
610     CMenu      *pPopup;
611     CMenu      *pInsertMenu = GX_NULL;
612     INT         node_level;
613 
614     node_level = GetTreeNodeLevel(htItem);
615 
616     switch(node_level)
617     {
618     case PROJECT_NODE_LEVEL:
619     {
620         menu.LoadMenu(IDR_PROJECT_OPTIONS);
621         pPopup = menu.GetSubMenu(0);
622 
623         studiox_project *project = GetOpenProject();
624 
625         if (project)
626         {
627             if (project->IsWidgetPositionLocked())
628             {
629                 pPopup->CheckMenuItem(ID_LOCK_WIDGET_POSITIONS, MF_CHECKED);
630             }
631             else
632             {
633                 pPopup->CheckMenuItem(ID_LOCK_WIDGET_POSITIONS, MF_UNCHECKED);
634             }
635 
636             ClientToScreen(&pos);
637             pPopup->TrackPopupMenu(TPM_LEFTALIGN, pos.x, pos.y, (CMainFrame*)AfxGetMainWnd());
638         }
639     }
640         break;
641 
642     case DISPLAY_NODE_LEVEL:
643         menu.LoadMenu(IDR_DISPLAY_MENU);
644         pPopup = menu.GetSubMenu(0);
645 
646         insert_menu.LoadMenu(IDR_INSERT_MENU);
647         pInsertMenu = insert_menu.GetSubMenu(0);
648 
649         if (pInsertMenu)
650         {
651             if (CreateBaseMenu(&base_menu))
652             {
653                 pInsertMenu->AppendMenu(MF_POPUP, (UINT)base_menu.m_hMenu, _T("Template"));
654             }
655             pPopup->AppendMenu(MF_POPUP, (UINT)pInsertMenu->m_hMenu, _T("Insert"));
656 
657             /* Disable items except folder. Only folder can be added to display node. */
658             int count = pInsertMenu->GetMenuItemCount();
659             int id;
660             for (int pos = 0; pos < count; pos++)
661             {
662                 id = pInsertMenu->GetMenuItemID(pos);
663 
664                 if (id != ID_INSERT_FOLDER)
665                 {
666                     pInsertMenu->EnableMenuItem(pos, MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
667                 }
668             }
669         }
670 
671         ClientToScreen(&pos);
672         pPopup->TrackPopupMenu(TPM_LEFTALIGN, pos.x, pos.y, (CMainFrame *)AfxGetMainWnd());
673         break;
674 
675     case FOLDER_NODE_LEVEL:
676     case SCREEN_NODE_LEVEL:
677     default:
678         menu.LoadMenu(IDR_WIDGET_MENU);
679         pPopup = menu.GetSubMenu(0);
680 
681         insert_menu.LoadMenu(IDR_INSERT_MENU);
682         pInsertMenu = insert_menu.GetSubMenu(0);
683 
684         if (pInsertMenu)
685         {
686             if (node_level == FOLDER_NODE_LEVEL)
687             {
688                 /* Insert rename item to rename folder. */
689                 pPopup->InsertMenu(0, MF_BYPOSITION, ID_EDIT_FOLDER_PROPERTIES, _T("Edit Folder Properties"));
690             }
691 
692             if (CreateBaseMenu(&base_menu))
693             {
694                 pInsertMenu->AppendMenu(MF_POPUP, (UINT)base_menu.m_hMenu, _T("Template"));
695             }
696 
697             pPopup->AppendMenu(MF_POPUP, (UINT)pInsertMenu->m_hMenu, _T("Insert"));
698 
699             /* Disable "folder" item */
700             pInsertMenu->EnableMenuItem(0, MF_BYPOSITION | MF_DISABLED | MF_GRAYED);
701         }
702 
703         ClientToScreen(&pos);
704         pPopup->TrackPopupMenu(TPM_LEFTALIGN, pos.x, pos.y, (CMainFrame *)AfxGetMainWnd());
705         break;
706     }
707 }
708 
709 
710 ///////////////////////////////////////////////////////////////////////////////
711 // This function MUST be called when the active project pointer is changed,
712 // like if it is backed up (cloned) and restored
DeSelect()713 void project_view::DeSelect()
714 {
715     mpTree->SelectItem(mpTree->GetRootItem());
716 
717     GetTargetScreen()->SelectWidget(NULL, FALSE, FALSE);
718     GetPropsWin()->OnWidgetSelect(NULL);
719 }
720 
721 ///////////////////////////////////////////////////////////////////////////////
OnProjectReset()722 void project_view::OnProjectReset()
723 {
724     GetTargetScreen()->SwitchTopWidget(NULL);
725     GetTargetScreen()->ConfigureDisplay(m_active_display);
726     PopulateProjectTree(GetOpenProject());
727 }
728 
729 ///////////////////////////////////////////////////////////////////////////////
OnConfigureDisplays()730 void project_view::OnConfigureDisplays()
731 {
732     studiox_project *project = GetOpenProject();
733 
734     if (!project)
735     {
736         return;
737     }
738 
739     CString name;
740     BOOL is_root_selected = FALSE;
741 
742     HTREEITEM item = mpTree->GetSelectedItem();
743     int selected_node_level = 0;
744 
745     name = mpTree->GetItemText(item);
746     selected_node_level = GetTreeNodeLevel(item);
747 
748     GetProjectView()->DeSelect();
749     GetTargetScreen()->SwitchTopWidget(NULL);
750     GetTargetScreen()->ConfigureDisplay(-1);
751 
752     ProjectConfigDlg dlg(NULL, m_active_display);
753     dlg.SetOwner(AfxGetMainWnd());
754     if (dlg.DoModal() == IDOK)
755     {
756         if (project)
757         {
758             project->mHeader.guix_version = dlg.GetGuixVersion();
759             project->SetModified();
760             project->InitializeAllPixelmaps();
761             project->InitializeFonts();
762             PopulateProjectTree(project);
763         }
764     }
765     GetResourceView()->CleanupDisplayResources(get_target_view_display());
766     GetTargetScreen()->ConfigureDisplay(m_active_display, TRUE);
767     GetResourceView()->OnDisplaySelect(m_active_display, TRUE);
768 
769     switch (selected_node_level)
770     {
771     case PROJECT_NODE_LEVEL:
772         item = mpTree->GetRootItem();
773         break;
774 
775     case DISPLAY_NODE_LEVEL:
776         item = FindProjectTreeNode(mpTree->GetRootItem(), name, DISPLAY_NODE_LEVEL);
777         break;
778 
779     default:
780         if (m_active_display >= 0)
781         {
782             item = FindProjectTreeNode(name, project->mDisplays[m_active_display].name);
783         }
784         break;
785     }
786 
787     if (item)
788     {
789         mpTree->SelectItem(item);
790     }
791     else
792     {
793         SelectFirstScreen();
794     }
795 
796 }
797 
798 ///////////////////////////////////////////////////////////////////////////////
TerminateAppExecutions()799 void project_view::TerminateAppExecutions()
800 {
801     GX_WIN32_DISPLAY_DRIVER_DATA *data = gx_win32_get_data_instance_head();
802     for (int index = 0; index < GX_MAX_WIN32_DISPLAYS; index++)
803     {
804         if (data->win32_driver_type && data->win32_guix_ThreadId)
805         {
806             /* Send window close message. */
807             ::SendMessage(data->win32_driver_winhandle, WM_CLOSE, 0, 0);
808 
809             HANDLE guix_thread = OpenThread(SYNCHRONIZE, FALSE, data->win32_guix_ThreadId);
810             WaitForSingleObject(guix_thread, INFINITE);
811             CloseHandle(guix_thread);
812         }
813         data++;
814     }
815 }
816 
817 ///////////////////////////////////////////////////////////////////////////////
CloseProject(BOOL DisplayRecent,BOOL CheckSaveChanges)818 void project_view::CloseProject(BOOL DisplayRecent, BOOL CheckSaveChanges)
819 {
820     /* Destory app execution window. */
821     TerminateAppExecutions();
822 
823     GetResourceView()->OnCloseProject();
824     GetTargetScreen()->OnCloseProject();
825     m_active_display = -1;
826     GetPropsWin()->OnWidgetSelect(NULL);
827     widget_factory::ResetServiceProviders();
828 
829     studiox_project *project = GetOpenProject();
830 
831     if (project)
832     {
833         if (CheckSaveChanges && project->IsModified())
834         {
835             if (AskUser("The current project has been modified. Do you want to save your changes?"))
836             {
837                 project->Save();
838             }
839         }
840         delete project;
841         SetOpenProject(NULL);
842     }
843     mpTree->DeleteAllItems();
844     SetFrameTitle(CString(_T("No Project")));
845     AddTreeRoot(CString(_T("No Project")));
846 
847     if (DisplayRecent)
848     {
849         GetTargetView()->DisplayRecentProjects();
850     }
851 
852     ((CMainFrame *)AfxGetMainWnd())->DisableMenus();
853 }
854 
855 ///////////////////////////////////////////////////////////////////////////////
SetFrameTitle(CString & title)856 void project_view::SetFrameTitle(CString &title)
857 {
858     CString fulltitle = _T("Azure RTOS GUIX Studio ");
859     fulltitle += studiox_version_string;
860     fulltitle += " - ";
861     fulltitle += title;
862     AfxGetMainWnd()->SetWindowText(fulltitle);
863 }
864 
865 ///////////////////////////////////////////////////////////////////////////////
NewProject(CWnd * parent)866 void project_view::NewProject(CWnd *parent)
867 {
868     if (parent == NULL)
869     {
870         parent = AfxGetMainWnd();
871     }
872 
873     CString title;
874     CString pathname;
875     NewProjectDlg dlg(parent);
876 
877     if (dlg.DoModal() == IDOK)
878     {
879         CloseProject();
880 
881         title = dlg.Getproject_name();
882         pathname = dlg.Getproject_path();
883         SetProjectDirectory(pathname);
884 
885         studiox_project *project = new studiox_project(pathname, title, TRUE);
886         SetOpenProject(project);
887 
888         if (project->Save())
889         {
890             pathname += '\\';
891             pathname += title;
892             pathname += ".gxp";
893             AddRecentProject(pathname);
894             SetFrameTitle(title);
895             AddTreeRoot(project->mHeader.project_name);
896             OnConfigureDisplays();
897             PopulateProjectTree(project);
898             GetTargetView()->DisplayTarget();
899             GetResourceView()->OnOpenProject();
900 
901             GetTargetScreen()->ConfigureDisplay(0);
902             GetResourceView()->OnDisplaySelect(0, TRUE);
903 
904             //Add default folder and default window to project to help user start in Studio when create new project
905             SelectDisplay(0);
906             /* Add default folder to display 0*/
907             OnInsertFolder();
908             /* Add default window */
909             GetTargetScreen()->OnAddWidget(GX_TYPE_WINDOW);
910             /* Show notify message. */
911             Notify("To begin, right click in the target view and begin inserting child widgets.");
912 
913             project->mHeader.b_new_project = FALSE;
914         }
915         else
916         {
917             CloseProject();
918         }
919 
920         ((CMainFrame *)AfxGetMainWnd())->EnableMenus();
921     }
922 }
923 
924 ///////////////////////////////////////////////////////////////////////////////
ProjectRenamed()925 void project_view::ProjectRenamed()
926 {
927     // this function is called when the user uses "Save As". We have to reset
928     // the title and reset the root tree node:
929     studiox_project *project = GetOpenProject();
930     if (project)
931     {
932         SetFrameTitle(project->mHeader.project_name);
933         mpTree->SetItemText(mpTree->GetRootItem(), project->mHeader.project_name);
934     }
935 }
936 
937 ///////////////////////////////////////////////////////////////////////////////
938 
OpenProject(CString & path,CString & name)939 BOOL project_view::OpenProject(CString &path, CString &name)
940 {
941     CMainFrame *pMain = (CMainFrame *) AfxGetMainWnd();
942     CWnd* pCwnd = AfxGetApp()->m_pMainWnd;
943     CCommandInfo *pCmdInfo = pMain->GetCmdInfo();
944     BOOL failure = FALSE;
945 
946     if (path == ".")
947     {
948         TCHAR tpath[MAX_PATH];
949         GetCurrentDirectory(MAX_PATH, tpath);
950         path = tpath;
951     }
952 
953     studiox_project *project = new studiox_project(path, name, FALSE);
954     SetOpenProject(project);
955 
956     CString pathname = path;
957     pathname += '\\';
958     pathname += name;
959     SetProjectDirectory(path);
960     GotoProjectDirectory();
961 
962     if (pCmdInfo->IsXmlMode())
963     {
964         if (!project->ReadXMLFile(pathname))
965         {
966             failure = TRUE;
967         }
968     }
969     else if (project->Read(pathname))
970     {
971         SetFrameTitle(name);
972         AddRecentProject(pathname);
973         PopulateProjectTree(project);
974         GetTargetView()->DisplayTarget();
975         GetResourceView()->OnOpenProject();
976 
977         m_active_display = 0;
978 
979         if (GetTargetScreen()->ConfigureDisplay(0))
980         {
981             GetResourceView()->OnDisplaySelect(0, TRUE);
982             SelectFirstScreen();
983             ((CMainFrame *)AfxGetMainWnd())->EnableMenus();
984         }
985         else
986         {
987             failure = TRUE;
988         }
989     }
990     else
991     {
992         failure = TRUE;
993     }
994 
995     if (failure)
996     {
997         CloseProject();
998 
999         return FALSE;
1000     }
1001 
1002     return TRUE;
1003 }
1004 
1005 ///////////////////////////////////////////////////////////////////////////////
OpenProject()1006 void project_view::OpenProject()
1007 {
1008     CFileDialog dlg(TRUE, _T(".gxp"), NULL,
1009         OFN_FILEMUSTEXIST|OFN_NOREADONLYRETURN|OFN_PATHMUSTEXIST,
1010         _T("GUIX project files|*.gxp||"),
1011         this);
1012 
1013     if (dlg.DoModal() == IDOK)
1014     {
1015         CloseProject();
1016 
1017         CString pathname = dlg.GetPathName();
1018         CString name = dlg.GetFileName();
1019 
1020         CString path = pathname.Left(pathname.GetLength() - name.GetLength() - 1);
1021         OpenProject(path, name);
1022     }
1023 }
1024 
1025 ///////////////////////////////////////////////////////////////////////////////
MergeProject()1026 void project_view::MergeProject()
1027 {
1028     studiox_project *current = GetOpenProject();
1029 
1030     if (current)
1031     {
1032         CFileDialog dlg(TRUE, _T(".gxp"), NULL,
1033             OFN_FILEMUSTEXIST|OFN_NOREADONLYRETURN|OFN_PATHMUSTEXIST,
1034             _T("GUIX project files|*.gxp||"),
1035             this);
1036 
1037         if (dlg.DoModal() == IDOK)
1038         {
1039             CString pathname = dlg.GetPathName();
1040             CString name = dlg.GetFileName();
1041 
1042             CString path = pathname.Left(pathname.GetLength() - name.GetLength() - 1);
1043             MergeProject(path, name);
1044         }
1045     }
1046 }
1047 
1048 ///////////////////////////////////////////////////////////////////////////////
MergeProject(CString & path,CString & name)1049 void project_view::MergeProject(CString &path, CString &name)
1050 {
1051     extern CString gOpenProjectDir;
1052 
1053     studiox_project *merge_project = new studiox_project(path, name, FALSE);
1054 
1055     CString oldpathname = gOpenProjectDir;
1056     SetProjectDirectory(path);
1057 
1058     CString pathname;
1059     pathname.Format(_T("%s\\%s"), path, name);
1060 
1061     if (merge_project->Read(pathname))
1062     {
1063         SetProjectDirectory(oldpathname);
1064 
1065         import_project_dlg import(merge_project, path, this);
1066 
1067         import.DoModal();
1068     }
1069     delete merge_project;
1070 }
1071 
1072 ///////////////////////////////////////////////////////////////////////////////
OpenHistoryProject(int index)1073 void project_view::OpenHistoryProject(int index)
1074 {
1075     CloseProject();
1076     CString pathname = StudioXIni.recent_project_paths[index];
1077     if (pathname.IsEmpty())
1078     {
1079         return;
1080     }
1081     CString path = pathname;
1082     CString name = path.Mid(path.ReverseFind('\\') + 1);
1083     path = path.Left(path.GetLength() - name.GetLength() - 1);
1084     OpenProject(path, name);
1085 }
1086 
1087 ///////////////////////////////////////////////////////////////////////////////
GetTreeNodeLevel(HTREEITEM item)1088 int project_view::GetTreeNodeLevel(HTREEITEM item)
1089 {
1090     if (!item)
1091     {
1092         return -1;
1093     }
1094 
1095     int Level = PROJECT_NODE_LEVEL;
1096     HTREEITEM root = mpTree->GetRootItem();
1097 
1098     while (item != root)
1099     {
1100         Level++;
1101         item = mpTree->GetParentItem(item);
1102     }
1103     return Level;
1104 }
1105 
1106 
1107 ///////////////////////////////////////////////////////////////////////////////
OnConfigureThemes()1108 void project_view::OnConfigureThemes()
1109 {
1110     studiox_project *project = GetOpenProject();
1111     if (project)
1112     {
1113         int old_theme = project->mDisplays[m_active_display].active_theme;
1114 
1115         configure_theme_dlg dlg(m_active_display);
1116         dlg.DoModal();
1117         project->SetModified();
1118     }
1119 }
1120 
1121 
1122 ///////////////////////////////////////////////////////////////////////////////
IsDisplaySelected()1123 BOOL project_view::IsDisplaySelected()
1124 {
1125     studiox_project *project = GetOpenProject();
1126 
1127     if (project)
1128     {
1129         HTREEITEM hItem = mpTree->GetSelectedItem();
1130 
1131         if (GetTreeNodeLevel(hItem) == DISPLAY_NODE_LEVEL)
1132         {
1133             LONG data = (LONG) mpTree->GetItemData(hItem);
1134 
1135             // this should be a display index, 0 to MAX_DISPLAYS
1136 
1137             if (data >= 0 && data < MAX_DISPLAYS)
1138             {
1139                 return TRUE;
1140             }
1141         }
1142     }
1143     return FALSE;
1144 }
1145 
1146 ///////////////////////////////////////////////////////////////////////////////
IsFolderSelected()1147 BOOL project_view::IsFolderSelected()
1148 {
1149     studiox_project *project = GetOpenProject();
1150 
1151     if (project)
1152     {
1153         HTREEITEM hItem = mpTree->GetSelectedItem();
1154 
1155         if (GetTreeNodeLevel(hItem) == FOLDER_NODE_LEVEL)
1156         {
1157             return TRUE;
1158         }
1159     }
1160     return FALSE;
1161 }
1162 
1163 ///////////////////////////////////////////////////////////////////////////////
GetSelectedNodeLevel()1164 INT project_view::GetSelectedNodeLevel()
1165 {
1166     studiox_project *project = GetOpenProject();
1167 
1168     if (project)
1169     {
1170         HTREEITEM hItem = mpTree->GetSelectedItem();
1171 
1172         return GetTreeNodeLevel(hItem);
1173     }
1174     return PROJECT_NODE_LEVEL;
1175 }
1176 
1177 ///////////////////////////////////////////////////////////////////////////////
GetSelectedFolder()1178 folder_info *project_view::GetSelectedFolder()
1179 {
1180     if (IsFolderSelected())
1181     {
1182         HTREEITEM hItem = mpTree->GetSelectedItem();
1183         if (hItem)
1184         {
1185             return ((folder_info *)mpTree->GetItemData(hItem));
1186         }
1187     }
1188     return GX_NULL;
1189 }
1190 
1191 ///////////////////////////////////////////////////////////////////////////////
GetRootFolder()1192 folder_info *project_view::GetRootFolder()
1193 {
1194     folder_info *root = NULL;
1195     studiox_project *project = GetOpenProject();
1196 
1197     if (project && m_active_display >= 0)
1198     {
1199         root = project->mDisplays[m_active_display].GetFirstChildFolder();
1200     }
1201     return root;
1202 }
1203 
1204 ///////////////////////////////////////////////////////////////////////////////
UpdateChildPositions(widget_info * parent)1205 void project_view::UpdateChildPositions(widget_info *parent)
1206 {
1207     if (parent)
1208     {
1209         widget_info *child = parent->GetChildWidgetInfo();
1210 
1211         while(child)
1212         {
1213             if (child->widget)
1214             {
1215                 child->size = child->widget->gx_widget_size;
1216             }
1217             UpdateChildPositions(child);
1218             child = child->GetNextWidgetInfo();
1219         }
1220     }
1221 }
1222 
1223 ///////////////////////////////////////////////////////////////////////////////
CheckParentRefresh(GX_WIDGET * parent)1224 void project_view::CheckParentRefresh(GX_WIDGET *parent)
1225 {
1226     studiox_project *project = GetOpenProject();
1227     if (project && parent)
1228     {
1229         if (parent->gx_widget_type == GX_TYPE_MENU_LIST)
1230         {
1231             parent = ((GX_MENU_LIST *)parent)->gx_menu_list_owner;
1232         }
1233 
1234         widget_info *info = project->FindWidgetInfo(parent);
1235         CheckParentRefresh(info);
1236     }
1237 }
1238 
1239 ///////////////////////////////////////////////////////////////////////////////
CheckParentRefresh(widget_info * parent_info)1240 void project_view::CheckParentRefresh(widget_info *parent_info)
1241 {
1242     BOOL update_positions = FALSE;
1243     GX_WIDGET *parent;
1244     studiox_project *project = GetOpenProject();
1245 
1246     if (parent_info && project)
1247     {
1248         switch(parent_info->basetype)
1249         {
1250         case GX_TYPE_VERTICAL_LIST:
1251             {
1252             GX_VERTICAL_LIST *list = (GX_VERTICAL_LIST *) parent_info->widget;
1253             gx_vertical_list_children_position(list);
1254             update_positions = TRUE;
1255             }
1256             break;
1257 
1258         case GX_TYPE_HORIZONTAL_LIST:
1259             {
1260             GX_HORIZONTAL_LIST *list = (GX_HORIZONTAL_LIST *) parent_info->widget;
1261             gx_horizontal_list_children_position(list);
1262             update_positions = TRUE;
1263             }
1264             break;
1265 
1266         case GX_TYPE_ACCORDION_MENU:
1267             parent = menu_service_provider::TopLevelMenuContainerFind(parent_info->widget);
1268             if (parent && parent->gx_widget_type == GX_TYPE_ACCORDION_MENU)
1269             {
1270                 parent_info = project->FindWidgetInfo(parent);
1271                 gx_accordion_menu_position((GX_ACCORDION_MENU *)parent);
1272                 memcpy_s(&parent_info->size, sizeof(parent_info->size), &parent_info->widget->gx_widget_size, sizeof(GX_RECTANGLE));
1273                 update_positions = TRUE;
1274             }
1275             break;
1276 
1277         case GX_TYPE_MENU:
1278             parent = parent_info->widget->gx_widget_parent;
1279             parent = menu_service_provider::TopLevelMenuContainerFind(parent);
1280 
1281             if (parent)
1282             {
1283                 parent_info = project->FindWidgetInfo(parent);
1284 
1285                 if (parent->gx_widget_type == GX_TYPE_ACCORDION_MENU)
1286                 {
1287                     gx_accordion_menu_position((GX_ACCORDION_MENU *)parent);
1288                 }
1289                 else if (parent->gx_widget_type == GX_TYPE_TREE_VIEW)
1290                 {
1291                     gx_tree_view_position((GX_TREE_VIEW *)parent);
1292                 }
1293                 update_positions = TRUE;
1294             }
1295             break;
1296 
1297         case GX_TYPE_TREE_VIEW:
1298             gx_tree_view_position((GX_TREE_VIEW *)parent_info->widget);
1299             update_positions = TRUE;
1300             break;
1301 
1302         case GX_TYPE_GENERIC_SCROLL_WHEEL:
1303             gx_generic_scroll_wheel_children_position((GX_GENERIC_SCROLL_WHEEL *)parent_info->widget);
1304             update_positions = TRUE;
1305             break;
1306 
1307         default:
1308             break;
1309         }
1310 
1311         if (update_positions)
1312         {
1313             UpdateChildPositions(parent_info);
1314         }
1315     }
1316 
1317 }
1318 
1319 ///////////////////////////////////////////////////////////////////////////////
OnDeleteWidget()1320 void project_view::OnDeleteWidget()
1321 {
1322     studiox_project *project = GetOpenProject();
1323     if (project)
1324     {
1325         HTREEITEM hItem = mpTree->GetSelectedItem();
1326         int       node_level = GetTreeNodeLevel(hItem);
1327 
1328         if (node_level >= SCREEN_NODE_LEVEL)
1329         {
1330             widget_info *info = (widget_info *) mpTree->GetItemData(hItem);
1331 
1332             DeleteWidget(info);
1333         }
1334         else if (node_level == FOLDER_NODE_LEVEL)
1335         {
1336             folder_info *folder = (folder_info *)mpTree->GetItemData(hItem);
1337 
1338             DeleteFolder(folder);
1339         }
1340     }
1341 }
1342 
1343 ///////////////////////////////////////////////////////////////////////////////
1344 // called when user do delete (and also by Undo manager)
DeleteFolder(folder_info * folder)1345 void project_view::DeleteFolder(folder_info *folder)
1346 {
1347     studiox_project *project = GetOpenProject();
1348     if (project)
1349     {
1350         int display_index = project->GetDisplayIndex(folder);
1351 
1352         /* Check all derived widgets of template (if there's one) are removed before delete any item. */
1353         if (!template_service_provider::CheckExternalTemplateDerivations(folder))
1354         {
1355             Notify("At least one template within this folder is referenced outside this folder. This folder cannot be deleted until all template references are first removed.");
1356             return;
1357         }
1358 
1359         screen_flow *screenflow = project->mDisplays[display_index].screenflow;
1360         widget_info *info = folder->GetFirstChildWidget();
1361 
1362         /* delete screen flow*/
1363         while (info)
1364         {
1365             if (screenflow)
1366             {
1367                 flow_item *item = screenflow->GetFlowItem(info->app_name);
1368                 if (item && item->trigger_list)
1369                 {
1370                     CString msg;
1371                     msg.Format(_T("Triggers that defined for \"%s\" will be deleted as well, continue?"), info->app_name);
1372                     if (!AskUser(CT2A(msg)))
1373                     {
1374                         return;
1375                     }
1376                 }
1377                 screenflow->DeleteFlowItem(info->app_name, display_index);
1378             }
1379 
1380             info = info->GetNextWidgetInfo();
1381         }
1382 
1383         HTREEITEM hItem = FindProjectTreeNode(folder->folder_name, project->mDisplays[display_index].name);
1384 
1385         UndoManager()->AddEntry(UNDO_TYPE_DELETE_FOLDER, folder, display_index);
1386 
1387         GetTargetScreen()->SelectWidget(NULL, FALSE, FALSE);
1388         GetPropsWin()->OnWidgetSelect(NULL);
1389 
1390         project->DeleteFolder(folder);
1391 
1392         if (hItem)
1393         {
1394             mpTree->DeleteItem(hItem);
1395         }
1396     }
1397 }
1398 
1399 ///////////////////////////////////////////////////////////////////////////////
FindWidgetIdName(widget_info * start,widget_info * except,CString id_name)1400 BOOL project_view::FindWidgetIdName(widget_info *start, widget_info *except, CString id_name)
1401 {
1402     //search widget id name under "start" info
1403     //do not search under "except" info
1404     if (start != except)
1405     {
1406         if (start->id_name == id_name)
1407         {
1408             return TRUE;
1409         }
1410 
1411         widget_info *child = start->GetChildWidgetInfo();
1412         while (child)
1413         {
1414             if (FindWidgetIdName(child, except, id_name))
1415             {
1416                 return TRUE;
1417             }
1418             child = child->GetNextWidgetInfo();
1419         }
1420     }
1421 
1422     return FALSE;
1423 }
1424 
1425 ///////////////////////////////////////////////////////////////////////////////
CheckTriggerReference(screen_flow * flow,flow_item * item,widget_info * screen_info,widget_info * info,widget_info * search)1426 BOOL project_view::CheckTriggerReference(screen_flow *flow, flow_item *item, widget_info *screen_info, widget_info *info, widget_info *search)
1427 {
1428     if (item)
1429     {
1430         if (!search->id_name.IsEmpty())
1431         {
1432             // check if the id name is referenced by a trigger
1433             // if yes, check if there are duplicate ID name under the same top level widget
1434             if (flow->FindTrigger(item, search->id_name) && !FindWidgetIdName(screen_info, info, search->id_name))
1435             {
1436                 CString  msg;
1437                 msg.Format(_T("ID name \"%s\" is referenced by a trigger, remove the id name will invalid the trigger, continue?"), search->id_name);
1438                 if (!AskUser(CT2A(msg)))
1439                 {
1440                     return FALSE;
1441                 }
1442             }
1443         }
1444 
1445         widget_info *child = search->GetChildWidgetInfo();
1446         while (child)
1447         {
1448             if (!CheckTriggerReference(flow, item, screen_info, info, child))
1449             {
1450                 return FALSE;
1451             }
1452 
1453             child = child->GetNextWidgetInfo();
1454         }
1455     }
1456     return TRUE;
1457 }
1458 
1459 ///////////////////////////////////////////////////////////////////////////////
RemoveWidgetIdFromDictionary(studiox_project * project,int display,widget_info * info)1460 VOID project_view::RemoveWidgetIdFromDictionary(studiox_project *project, int display, widget_info *info)
1461 {
1462     screen_flow *flow = project->mDisplays[display].screenflow;
1463 
1464     if (!info->id_name.IsEmpty())
1465     {
1466         project->RemoveFromIdDictionary(display, ID_TYPE_WIDGET, info->id_name);
1467     }
1468 
1469     widget_info *child = info->GetChildWidgetInfo();
1470 
1471     while (child)
1472     {
1473         RemoveWidgetIdFromDictionary(project, display, child);
1474         child = child->GetNextWidgetInfo();
1475     }
1476 }
1477 
1478 ///////////////////////////////////////////////////////////////////////////////
CheckRemoveWidget(studiox_project * project,int display,widget_info * info)1479 BOOL project_view::CheckRemoveWidget(studiox_project *project, int display, widget_info *info)
1480 {
1481     screen_flow *flow = project->mDisplays[display].screenflow;
1482     widget_info *screen_info = NULL;
1483     flow_item *item = NULL;
1484 
1485     if (flow)
1486     {
1487         screen_info = GetProjectView()->FindTopLevelWidget(info);
1488 
1489         if (screen_info)
1490         {
1491             item = flow->GetFlowItem(screen_info->app_name);
1492         }
1493 
1494         if (item)
1495         {
1496             if (item->screen_name == info->app_name)
1497             {
1498                 CString  msg;
1499                 msg.Format(_T("Triggers that defined for \"%s\" will be deleted as well, continue?"), info->app_name);
1500                 if (!AskUser(CT2A(msg)))
1501                 {
1502                     return FALSE;
1503                 }
1504             }
1505             else if (!CheckTriggerReference(flow, item, screen_info, info, info))
1506             {
1507                 return FALSE;
1508             }
1509         }
1510     }
1511 
1512     RemoveWidgetIdFromDictionary(project, display, info);
1513 
1514     return TRUE;
1515 }
1516 
1517 ///////////////////////////////////////////////////////////////////////////////
1518 // called when user delete, and also by Undo manager
DeleteWidget(widget_info * info)1519 void project_view::DeleteWidget(widget_info *info)
1520 {
1521     HTREEITEM hItem = 0;
1522     GX_WIDGET *parent = NULL;
1523     studiox_project *project = GetOpenProject();
1524 
1525     if (!info)
1526     {
1527         return;
1528     }
1529 
1530     if (project)
1531     {
1532         if (info->is_template)
1533         {
1534             if (template_service_provider::CountDerivedWidgets(info))
1535             {
1536                 Notify("This template cannot be deleted until all references are first removed.");
1537                 return;
1538             }
1539         }
1540 
1541         int display_index = project->GetDisplayIndex(info);
1542 
1543         if (!CheckRemoveWidget(project, display_index, info))
1544         {
1545             return;
1546         }
1547 
1548         if (IsTopLevelWidget(info))
1549         {
1550             screen_flow *screenflow = project->mDisplays[m_active_display].screenflow;
1551 
1552             if (screenflow)
1553             {
1554                 screenflow->DeleteFlowItem(info->app_name, m_active_display);
1555             }
1556         }
1557 
1558         UndoManager()->AddEntry(UNDO_TYPE_DELETE_WIDGET, info, display_index);
1559 
1560         GetTargetScreen()->SelectWidget(NULL, FALSE, FALSE);
1561         GetPropsWin()->OnWidgetSelect(NULL);
1562 
1563         if (info->widget)
1564         {
1565             parent = info->widget->gx_widget_parent;
1566         }
1567 
1568         hItem = FindWidget(info);
1569         project->DeleteWidget(info);
1570 
1571         if (hItem)
1572         {
1573             mpTree->DeleteItem(hItem);
1574         }
1575 
1576         if (parent)
1577         {
1578             CheckParentRefresh(parent);
1579 
1580             if (parent->gx_widget_type == GX_TYPE_MENU_LIST)
1581             {
1582                 //deleted widget is a child of menu list, decrease the list count
1583                 widget_info *parent_info = project->FindWidgetInfo(parent);
1584                 if (parent_info)
1585                 {
1586                     parent_info->ewi.menu.list_total_count--;
1587                 }
1588             }
1589         }
1590     }
1591 }
1592 
1593 
1594 ///////////////////////////////////////////////////////////////////////////////
OnCutWidget()1595 void project_view::OnCutWidget()
1596 {
1597     OnCopyWidget();
1598     OnDeleteWidget();
1599 }
1600 
1601 ///////////////////////////////////////////////////////////////////////////////
OnCopyWidget()1602 void project_view::OnCopyWidget()
1603 {
1604     studiox_project *project = GetOpenProject();
1605     if (project)
1606     {
1607         HTREEITEM hItem = mpTree->GetSelectedItem();
1608         int selected_level = GetTreeNodeLevel(hItem);
1609         if (selected_level == FOLDER_NODE_LEVEL)
1610         {
1611             folder_info *folder = (folder_info *)mpTree->GetItemData(hItem);
1612 
1613             /* Copy Folder. */
1614             copy_paste_engine cpe;
1615             cpe.CopyToClipboard(folder, m_hWnd);
1616         }
1617         else if (selected_level >= SCREEN_NODE_LEVEL)
1618         {
1619             //GetTargetScreen()->SelectWidget(NULL);
1620             widget_info *info = (widget_info *) mpTree->GetItemData(hItem);
1621 
1622             if (info)
1623             {
1624                 copy_paste_engine cpe;
1625                 cpe.CopyToClipboard(info, m_hWnd);
1626             }
1627         }
1628         else
1629         {
1630             //There maybe more than one widgets been selected
1631             if (GetTargetScreen())
1632             {
1633                 GetTargetScreen()->CopySelectedWidgets();
1634             }
1635         }
1636     }
1637 }
1638 
1639 ///////////////////////////////////////////////////////////////////////////////
CheckRemoveDuplicateTemplates(folder_info * start,folder_info * search_start,BOOL notify_duplicates)1640 BOOL project_view::CheckRemoveDuplicateTemplates(folder_info *start, folder_info *search_start, BOOL notify_duplicates)
1641 {
1642     studiox_project *project = GetOpenProject();
1643 
1644     if (!project)
1645     {
1646         return FALSE;
1647     }
1648 
1649     if (!search_start)
1650     {
1651         search_start = project->mDisplays[m_active_display].GetFirstChildFolder();
1652     }
1653 
1654     widget_info *info = start->GetFirstChildWidget();
1655     widget_info *find;
1656     widget_info *pre = NULL;
1657     widget_info *next;
1658     while (info)
1659     {
1660         next = info->GetNextWidgetInfo();
1661 
1662         if (info->is_template)
1663         {
1664             find = project->FindWidgetInfo(search_start, info->app_name, FALSE);
1665 
1666             if (find)
1667             {
1668                 if (!find->is_template)
1669                 {
1670                     CString msg;
1671                     msg.Format(L"Template name \"%s\" already exists! Aborting.", info->app_name);
1672                     Notify(CT2A(msg));
1673                     return FALSE;
1674                 }
1675 
1676                 if (notify_duplicates)
1677                 {
1678                     CString msg;
1679                     msg.Format(L"Template \"%s\" already exists! Skipping.", info->app_name);
1680                     Notify(CT2A(msg));
1681                 }
1682 
1683                 if (pre)
1684                 {
1685                     pre->SetNextWidgetInfo(info->GetNextWidgetInfo());
1686                 }
1687                 else
1688                 {
1689                     start->SetFirstChildWidget(info->GetNextWidgetInfo());
1690                 }
1691                 info->SetNextWidgetInfo(NULL);
1692                 delete info;
1693             }
1694             else
1695             {
1696                 pre = info;
1697             }
1698         }
1699         else
1700         {
1701             pre = info;
1702         }
1703         info = next;
1704     }
1705 
1706     return TRUE;
1707 }
1708 
1709 ///////////////////////////////////////////////////////////////////////////////
AddWidgetsToFolder(folder_info * target_folder,folder_info * src_folder)1710 void project_view::AddWidgetsToFolder(folder_info *target_folder, folder_info *src_folder)
1711 {
1712     widget_info *child = src_folder->GetFirstChildWidget();
1713     widget_info *next;
1714 
1715     if (!child)
1716     {
1717         return;
1718     }
1719 
1720     next = child->GetNextWidgetInfo();
1721 
1722     while (next)
1723     {
1724         child = next;
1725         next = child->GetNextWidgetInfo();
1726     }
1727 
1728     child->SetNextWidgetInfo(target_folder->GetFirstChildWidget());
1729     target_folder->SetFirstChildWidget(src_folder->GetFirstChildWidget());
1730 }
1731 
1732 
1733 ///////////////////////////////////////////////////////////////////////////////
CombineCopyPasteWidgets(copy_paste_info * pasted_info)1734 folder_info *project_view::CombineCopyPasteWidgets(copy_paste_info *pasted_info)
1735 {
1736     folder_info *copied_widgets = pasted_info->copied_widgets;
1737     folder_info *template_dependencies = pasted_info->template_dependencies;
1738 
1739     if (template_dependencies)
1740     {
1741         // Remove templates that duplicate the target project template.
1742         if (!CheckRemoveDuplicateTemplates(template_dependencies))
1743         {
1744             delete pasted_info;
1745             return NULL;
1746         }
1747 
1748         // Remove copied widgets that duplicate template dependencies.
1749         CheckRemoveDuplicateTemplates(copied_widgets, template_dependencies);
1750 
1751         // Add the remaining template widgets to copied widgets fodler.
1752         AddWidgetsToFolder(copied_widgets, template_dependencies);
1753         template_dependencies->SetFirstChildWidget(NULL);
1754     }
1755 
1756     if (!CheckRemoveDuplicateTemplates(copied_widgets, NULL, TRUE))
1757     {
1758         delete pasted_info;
1759         return NULL;
1760     }
1761 
1762     pasted_info->copied_widgets = NULL;
1763     delete pasted_info;
1764 
1765     return copied_widgets;
1766 }
1767 
1768 ///////////////////////////////////////////////////////////////////////////////
PasteFolder(copy_paste_info * pasted_info)1769 void project_view::PasteFolder(copy_paste_info *pasted_info)
1770 {
1771     studiox_project *project = GetOpenProject();
1772 
1773     if (!project || !pasted_info)
1774     {
1775         return;
1776     }
1777 
1778     folder_info *copied_widgets = CombineCopyPasteWidgets(pasted_info);
1779     if (!copied_widgets)
1780     {
1781         return;
1782     }
1783 
1784     //create uniqute folder name
1785     CreateUniqeFolderName(copied_widgets);
1786 
1787     widget_factory::CreateUniqueAppNames(copied_widgets->GetFirstChildWidget(), copied_widgets->GetFirstChildWidget(), NULL, TRUE);
1788 
1789     //add folder to active display
1790     project->AddFolderToDisplay(m_active_display, copied_widgets);
1791 
1792     if (copied_widgets->GetFirstChildWidget())
1793     {
1794         //select the first widget of the folder
1795         HTREEITEM select = FindWidget(copied_widgets->GetFirstChildWidget());
1796         if (select)
1797         {
1798             mpTree->SelectItem(select);
1799         }
1800     }
1801 }
1802 
1803 ///////////////////////////////////////////////////////////////////////////////
PasteWidgets(folder_info * parent_folder,copy_paste_info * pasted_info)1804 void project_view::PasteWidgets(folder_info *parent_folder, copy_paste_info *pasted_info)
1805 {
1806     studiox_project *project = GetOpenProject();
1807 
1808     if (!project || !pasted_info)
1809     {
1810         return;
1811     }
1812 
1813     folder_info *copied_widgets = CombineCopyPasteWidgets(pasted_info);
1814     if (!copied_widgets)
1815     {
1816         return;
1817     }
1818 
1819     if (copied_widgets->GetFirstChildWidget())
1820     {
1821         // Find last child of the copied widgets.
1822         widget_info* last_child = copied_widgets->GetFirstChildWidget();
1823         while (last_child && last_child->GetNextWidgetInfo())
1824         {
1825             last_child = last_child->GetNextWidgetInfo();
1826         }
1827 
1828         copied_widgets->folder_name = parent_folder->folder_name;
1829 
1830         widget_factory::CreateUniqueAppNames(copied_widgets->GetFirstChildWidget(), copied_widgets->GetFirstChildWidget(), NULL, TRUE);
1831 
1832         UndoManager()->AddEntry(UNDO_TYPE_INSERT_TOP_LEVEL_WIDGETS, copied_widgets, m_active_display);
1833 
1834         project->AddWidgetToFolder(parent_folder, copied_widgets->GetFirstChildWidget());
1835 
1836         //select the last widget of the folder
1837         HTREEITEM select = FindWidget(last_child);
1838         if (select)
1839         {
1840             mpTree->SelectItem(select);
1841         }
1842     }
1843 
1844     copied_widgets->SetFirstChildWidget(NULL);
1845     delete copied_widgets;
1846 }
1847 
1848 ///////////////////////////////////////////////////////////////////////////////
PasteWidgets(widget_info * parent_info,copy_paste_info * pasted_info)1849 void project_view::PasteWidgets(widget_info *parent_info, copy_paste_info *pasted_info)
1850 {
1851     studiox_project *project = GetOpenProject();
1852 
1853     if (!project || !pasted_info)
1854     {
1855         return;
1856     }
1857 
1858     folder_info *copied_widgets = pasted_info->copied_widgets;
1859 
1860     if (!copied_widgets)
1861     {
1862         return;
1863     }
1864 
1865     widget_info* pasted_widget = copied_widgets->GetFirstChildWidget();
1866 
1867     // Check if copied widgets contain templates.
1868     while (pasted_widget)
1869     {
1870         if (pasted_widget->is_template)
1871         {
1872             // Template is not allowed to be pasted to widget node.
1873             CString msg;
1874             msg.Format(L"Template \"%s\" must be pasted to folder node.", pasted_widget->app_name);
1875             Notify(CT2A(msg));
1876             delete pasted_info;
1877             return;
1878         }
1879 
1880         pasted_widget = pasted_widget->GetNextWidgetInfo();
1881     }
1882 
1883     folder_info *template_dependencies = pasted_info->template_dependencies;
1884     int display = GetActiveDisplay();
1885 
1886     if (template_dependencies)
1887     {
1888         // Remove templates that duplicate the target project template.
1889         if (!CheckRemoveDuplicateTemplates(template_dependencies))
1890         {
1891             delete pasted_info;
1892             return;
1893         }
1894 
1895         // Paste templates to top level folder.
1896         if (template_dependencies->GetFirstChildWidget())
1897         {
1898             folder_info *parent_folder = project->FindParentFolderInfo(parent_info);
1899 
1900             template_dependencies->folder_name = parent_folder->folder_name;
1901             UndoManager()->AddEntry(UNDO_TYPE_INSERT_TOP_LEVEL_WIDGETS, template_dependencies, display);
1902 
1903             project->AddWidgetToFolder(parent_folder, template_dependencies->GetFirstChildWidget());
1904             template_dependencies->SetFirstChildWidget(NULL);
1905 
1906             HTREEITEM select = FindWidget(parent_info);
1907             if (select)
1908             {
1909                 mpTree->SelectItem(select);
1910             }
1911         }
1912     }
1913 
1914     const widget_info *pasted_widget_tail;
1915     HTREEITEM hItem = mpTree->GetSelectedItem();
1916 
1917     GX_RECTANGLE combine_size;
1918     GX_RECTANGLE newsize;
1919     int x_shift, y_shift;
1920 
1921     pasted_widget = copied_widgets->GetFirstChildWidget();
1922 
1923     if (!pasted_widget)
1924     {
1925         delete pasted_info;
1926         return;
1927     }
1928 
1929     combine_size = pasted_widget->size;
1930     while (pasted_widget)
1931     {
1932         gx_utility_rectangle_combine(&combine_size, &pasted_widget->size);
1933         pasted_widget = pasted_widget->GetNextWidgetInfo();
1934     }
1935     newsize = combine_size;
1936     gx_utility_rectangle_center(&newsize, &parent_info->size);
1937 
1938     x_shift = newsize.gx_rectangle_left - combine_size.gx_rectangle_left;
1939     y_shift = newsize.gx_rectangle_top - combine_size.gx_rectangle_top;
1940 
1941     widget_info *search_start = GetProjectView()->FindTopLevelWidget(parent_info);
1942 
1943     widget_factory::CreateUniqueAppNames(copied_widgets->GetFirstChildWidget(),
1944         copied_widgets->GetFirstChildWidget(), search_start->GetChildWidgetInfo(), FALSE);
1945 
1946     if (parent_info->widget)
1947     {
1948         widget_factory::GenerateWidgets(parent_info->widget, copied_widgets->GetFirstChildWidget());
1949     }
1950 
1951     pasted_widget = copied_widgets->GetFirstChildWidget();
1952     while (pasted_widget)
1953     {
1954         //adjust size to center pasted widgets within the selected parent:
1955         newsize = pasted_widget->size;
1956         gx_utility_rectangle_shift(&newsize, x_shift, y_shift);
1957         widget_factory::MoveWidget(pasted_widget, newsize);
1958 
1959         pasted_widget = pasted_widget->GetNextWidgetInfo();
1960     }
1961 
1962     pasted_widget_tail = project->GetTailInfo(copied_widgets->GetFirstChildWidget());
1963     project->AddWidgetToParent(parent_info, copied_widgets->GetFirstChildWidget());
1964 
1965     // now make the widget visible:
1966     CheckParentRefresh(parent_info);
1967 
1968     GetTargetScreen()->DeSelect();
1969     pasted_widget = copied_widgets->GetFirstChildWidget();
1970     while(pasted_widget)
1971     {
1972         if (pasted_widget->basetype == GX_TYPE_ACCORDION_MENU ||
1973             pasted_widget->basetype == GX_TYPE_TREE_VIEW ||
1974             pasted_widget->basetype == GX_TYPE_GENERIC_SCROLL_WHEEL)
1975         {
1976             CheckParentRefresh(pasted_widget);
1977         }
1978 
1979         GetTargetScreen()->SelectWidget(pasted_widget, TRUE, TRUE);
1980 
1981         if (pasted_widget == pasted_widget_tail)
1982         {
1983             break;
1984         }
1985 
1986         pasted_widget = pasted_widget->GetNextWidgetInfo();
1987     }
1988 
1989     UndoManager()->AddEntry(UNDO_TYPE_INSERT_WIDGET, SelectedWidgets);
1990 
1991     copied_widgets->SetFirstChildWidget(NULL);
1992     delete pasted_info;
1993 }
1994 
1995 ///////////////////////////////////////////////////////////////////////////////
OnPasteWidget()1996 void project_view::OnPasteWidget()
1997 {
1998     studiox_project *project = GetOpenProject();
1999     widget_info *parent_widget_info = NULL;
2000     folder_info *parent_folder_info = NULL;
2001     copy_paste_info *pasted_info = NULL;
2002     int display;
2003 
2004     if (project)
2005     {
2006         HTREEITEM hItem = mpTree->GetSelectedItem();
2007         UINT selected_item_level = GetTreeNodeLevel(hItem);
2008         display = GetActiveDisplay();
2009 
2010         copy_paste_engine cpe;
2011         pasted_info = cpe.PasteFromClipboard(m_hWnd, display);
2012 
2013         if (!pasted_info || !pasted_info->copied_widgets)
2014         {
2015             Notify("Failed to read clipboard data.");
2016         }
2017         else
2018         {
2019             if (pasted_info->copied_widgets->folder_name.IsEmpty())
2020             {
2021                 //copy widgets
2022                 if (selected_item_level < FOLDER_NODE_LEVEL)
2023                 {
2024                     Notify("Copied widgets must be pasted to folder or widgets node.");
2025                     delete pasted_info;
2026                 }
2027                 else
2028                 {
2029                     if (selected_item_level == FOLDER_NODE_LEVEL)
2030                     {
2031                         //copy widgets to a folder
2032                         parent_folder_info = (folder_info *)mpTree->GetItemData(hItem);
2033                         PasteWidgets(parent_folder_info, pasted_info);
2034                     }
2035                     else
2036                     {
2037                         //copy widgets to a widget
2038                         parent_widget_info = (widget_info *)mpTree->GetItemData(hItem);
2039                         PasteWidgets(parent_widget_info, pasted_info);
2040                     }
2041                 }
2042                 return;
2043             }
2044             else
2045             {
2046                 //copy folder
2047                 if (selected_item_level != DISPLAY_NODE_LEVEL)
2048                 {
2049                     Notify("Screen folder must be pasted to display node.");
2050                     delete pasted_info;
2051                 }
2052                 else
2053                 {
2054                     PasteFolder(pasted_info);
2055                 }
2056             }
2057         }
2058     }
2059 }
2060 
2061 ///////////////////////////////////////////////////////////////////////////////
OnInsertFolder()2062 void project_view::OnInsertFolder()
2063 {
2064     studiox_project *project = GetOpenProject();
2065 
2066     folder_info *folder = new folder_info(_T("default_folder"));
2067     CreateUniqeFolderName(folder);
2068     project->AddFolderToDisplay(m_active_display, folder);
2069 }
2070 
2071 ///////////////////////////////////////////////////////////////////////////////
OnEditFolderProperties()2072 void project_view::OnEditFolderProperties()
2073 {
2074     HTREEITEM hItem = mpTree->GetSelectedItem();
2075     folder_info *folder = (folder_info *)mpTree->GetItemData(hItem);
2076 
2077     folder_name_dlg dlg(folder, this);
2078     if (dlg.DoModal() == IDOK)
2079     {
2080         CString new_folder_name;
2081         dlg.GetEditFolderName(new_folder_name);
2082 
2083         /* Set output file name. */
2084         dlg.GetSpecifiedOutputFileName(folder->output_filename);
2085 
2086         if (new_folder_name != folder->folder_name)
2087         {
2088             if (IsFolderNameExist(new_folder_name))
2089             {
2090                 Notify("Folder name already exists. Please check it.");
2091                 return;
2092             }
2093 
2094             folder->folder_name = new_folder_name;
2095             mpTree->SetItemText(hItem, folder->folder_name);
2096             HTREEITEM parent = mpTree->GetParentItem(hItem);
2097             if (parent)
2098             {
2099                 mpTree->SortChildren(parent);
2100             }
2101         }
2102     }
2103 }
2104 
2105 ///////////////////////////////////////////////////////////////////////////////
IsFolderNameExist(folder_info * folder,CString name)2106 GX_BOOL project_view::IsFolderNameExist(folder_info *folder, CString name)
2107 {
2108     while (folder)
2109     {
2110         if (folder->folder_name == name)
2111         {
2112             return TRUE;
2113         }
2114 
2115         folder = folder->GetNextFolder();
2116     }
2117     return FALSE;
2118 }
2119 
2120 ///////////////////////////////////////////////////////////////////////////////
IsFolderNameExist(CString name)2121 GX_BOOL project_view::IsFolderNameExist(CString name)
2122 {
2123     int display = GetActiveDisplay();
2124     studiox_project *project = GetOpenProject();
2125 
2126     folder_info  *info = project->mDisplays[display].GetFirstChildFolder();
2127 
2128     return IsFolderNameExist(info, name);
2129 }
2130 
2131 ///////////////////////////////////////////////////////////////////////////////
CreateUniqeFolderName(folder_info * folder)2132 void project_view::CreateUniqeFolderName(folder_info *folder)
2133 {
2134     CString name = folder->folder_name;
2135     if (IsFolderNameExist(name))
2136     {
2137         /* Create unique folder name. */
2138         CString seed = name;
2139         int underscore = seed.ReverseFind('_');
2140 
2141         if (underscore > 0 && underscore > (seed.GetLength() - 3))
2142         {
2143             if (seed.GetAt(underscore + 1) >= '0' &&
2144                 seed.GetAt(underscore + 1) <= '9')
2145             {
2146                 seed = seed.Left(underscore);
2147             }
2148         }
2149 
2150         int index = 1;
2151         name.Format(seed + _T("_%d"), index++);
2152         while (IsFolderNameExist(name))
2153         {
2154             name.Format(seed + _T("_%d"), index++);
2155         }
2156         folder->folder_name = name;
2157     }
2158 }
2159 
2160 ///////////////////////////////////////////////////////////////////////////////
GetTemplateInfo(int menu_index)2161 widget_info *project_view::GetTemplateInfo(int menu_index)
2162 {
2163     studiox_project *project = GetOpenProject();
2164 
2165     if (project)
2166     {
2167         HTREEITEM     root = mpTree->GetRootItem();
2168         HTREEITEM     hItem = mpTree->GetChildItem(root);
2169         HTREEITEM     folder;
2170         CString       name;
2171         widget_info  *info;
2172 
2173         // Get first item under screen node
2174         folder = mpTree->GetChildItem(hItem);
2175         while (folder)
2176         {
2177             hItem = mpTree->GetChildItem(folder);
2178             while (hItem)
2179             {
2180                 info = (widget_info  *)mpTree->GetItemData(hItem);
2181 
2182                 if (info->is_template)
2183                 {
2184                     if (menu_index == 0)
2185                     {
2186                         return info;
2187                     }
2188                     menu_index--;
2189                 }
2190                 hItem = mpTree->GetNextSiblingItem(hItem);
2191             }
2192             folder = mpTree->GetNextSiblingItem(folder);
2193         }
2194     }
2195     return NULL;
2196 }
2197 
2198 ///////////////////////////////////////////////////////////////////////////////
MoveSelectedToFront()2199 void project_view::MoveSelectedToFront()
2200 {
2201     studiox_project *project = GetOpenProject();
2202 
2203     if (project)
2204     {
2205         widget_info *selected_info = GetTargetScreen()->GetSingleSelect();
2206 
2207         if (!selected_info)
2208         {
2209             return;
2210         }
2211         HTREEITEM hItem = mpTree->GetSelectedItem();
2212 
2213         if (GetTreeNodeLevel(hItem) < DISPLAY_NODE_LEVEL)
2214         {
2215             return;
2216         }
2217         widget_info *info = (widget_info *) mpTree->GetItemData(hItem);
2218 
2219         // sanity check
2220         if (!info || info != selected_info)
2221         {
2222             return;
2223         }
2224 
2225         // if we get to here, we have a valid widget and valid widget_info
2226 
2227         project->MoveInfoToFront(info);
2228         gx_widget_front_move(selected_info->widget, NULL);
2229         CheckParentRefresh(selected_info->widget->gx_widget_parent);
2230     }
2231 }
2232 
2233 ///////////////////////////////////////////////////////////////////////////////
MoveSelectedToBack()2234 void project_view::MoveSelectedToBack()
2235 {
2236     studiox_project *project = GetOpenProject();
2237 
2238     if (project)
2239     {
2240         widget_info *selected_info = GetTargetScreen()->GetSingleSelect();
2241         if (!selected_info)
2242         {
2243             return;
2244         }
2245         HTREEITEM hItem = mpTree->GetSelectedItem();
2246 
2247         if (GetTreeNodeLevel(hItem) < DISPLAY_NODE_LEVEL)
2248         {
2249             return;
2250         }
2251         widget_info *info = (widget_info *) mpTree->GetItemData(hItem);
2252 
2253         // sanity check
2254         if (!info || info != selected_info)
2255         {
2256             return;
2257         }
2258 
2259         // if we get to here, we have a valid widget and valid widget_info
2260 
2261         project->MoveInfoToBack(info);
2262         gx_widget_back_move(selected_info->widget, NULL);
2263         CheckParentRefresh(selected_info->widget->gx_widget_parent);
2264     }
2265 }
2266 
2267 ///////////////////////////////////////////////////////////////////////////////
OnGenerateAll()2268 void project_view::OnGenerateAll()
2269 {
2270     studiox_project *project = GetOpenProject();
2271     BOOL result;
2272 
2273     if (project)
2274     {
2275         if (project->mHeader.gen_binary)
2276         {
2277             result = OnGenBinary(FALSE);
2278         }
2279         else
2280         {
2281             result = OnGenResources(FALSE);
2282         }
2283 
2284         if (result == TRUE)
2285         {
2286             OnGenApplication(FALSE);
2287 
2288             Notify("All Output files have been updated.");
2289         }
2290     }
2291 }
2292 
2293 /////////////////////////////////////////////////////////////////////////////
GenerateResourceFileThreadEntry(LPVOID thread_input)2294 static DWORD WINAPI GenerateResourceFileThreadEntry(LPVOID thread_input)
2295 {
2296     studiox_project* project = GetOpenProject();
2297     BOOL result = TRUE;
2298 
2299     if (project)
2300     {
2301         resource_gen generator(project);
2302         CCommandInfo* pCmdInfo = GetCmdInfo();
2303 
2304         for (int display = 0; display < project->mHeader.num_displays; display++)
2305         {
2306             BOOL enabled;
2307 
2308             if (pCmdInfo->IsNoGui())
2309             {
2310                 enabled = pCmdInfo->IsDisplayEnabled(project->mDisplays[display].name);
2311             }
2312             else
2313             {
2314                 enabled = project->mDisplays[display].enabled;
2315             }
2316 
2317             if (enabled)
2318             {
2319                 project->mDisplays[display].stable->MakeMLViewReferenceRecord(display);
2320                 if (generator.GenerateResourceFile(display) == FALSE)
2321                 {
2322                     /* Should return if generation fail.*/
2323                     result = FALSE;
2324                     break;
2325                 }
2326             }
2327         }
2328     }
2329 
2330     EndBusyMsg();
2331 
2332     return result;
2333 }
2334 
2335 /////////////////////////////////////////////////////////////////////////////
OnGenResources(GX_BOOL show_notify)2336 BOOL project_view::OnGenResources(GX_BOOL show_notify)
2337 {
2338     if (!StartWorkThread(GenerateResourceFileThreadEntry, 0, "Generating Resource File."))
2339     {
2340         return FALSE;
2341     }
2342 
2343     if (show_notify)
2344     {
2345         Notify("Resource File Generation Completed.");
2346     }
2347 
2348     return TRUE;
2349 }
2350 
GenerateScreensThreadEntry(LPVOID thread_input)2351 static DWORD WINAPI GenerateScreensThreadEntry(LPVOID thread_input)
2352 {
2353     studiox_project* project = GetOpenProject();
2354     BOOL result = FALSE;
2355 
2356     if (project)
2357     {
2358         screen_generator generator(project);
2359 
2360         result = generator.GenerateScreens(0);
2361     }
2362 
2363     EndBusyMsg();
2364 
2365     return result;
2366 }
2367 
2368 ///////////////////////////////////////////////////////////////////////////////
OnGenApplication(GX_BOOL show_notify)2369 void project_view::OnGenApplication(GX_BOOL show_notify)
2370 {
2371     if (!StartWorkThread(GenerateScreensThreadEntry, 0, "Generating Specifications File."))
2372     {
2373         return;
2374     }
2375 
2376     if (show_notify)
2377     {
2378         Notify("Application Screen Generation Completed.");
2379     }
2380 }
2381 
2382 ///////////////////////////////////////////////////////////////////////////////
GenerateBinaryFileThreadEntry(LPVOID thread_input)2383 static DWORD WINAPI GenerateBinaryFileThreadEntry(LPVOID thread_input)
2384 {
2385     studiox_project* project = GetOpenProject();
2386     BOOL result = TRUE;
2387 
2388     if (project)
2389     {
2390         binary_resource_gen generator(project, project->mHeader.binary_file_format);
2391         CCommandInfo *pCmdInfo = GetCmdInfo();
2392 
2393         for (int display = 0; display < project->mHeader.num_displays; display++)
2394         {
2395             BOOL enabled;
2396 
2397             if (pCmdInfo->IsNoGui())
2398             {
2399                 enabled = pCmdInfo->IsDisplayEnabled(project->mDisplays[display].name);
2400             }
2401             else
2402             {
2403                 enabled = project->mDisplays[display].enabled;
2404             }
2405 
2406             if (enabled)
2407             {
2408                 project->mDisplays[display].stable->MakeMLViewReferenceRecord(display);
2409                 result = generator.GenerateBinaryFile(display);
2410 
2411                 if(result == FALSE)
2412                 {
2413                     break;
2414                 }
2415             }
2416         }
2417     }
2418 
2419     EndBusyMsg();
2420 
2421     return result;
2422 }
2423 
2424 ///////////////////////////////////////////////////////////////////////////////
OnGenBinary(GX_BOOL show_notify)2425 BOOL project_view::OnGenBinary(GX_BOOL show_notify)
2426 {
2427     studiox_project *project = GetOpenProject();
2428 
2429     if (project)
2430     {
2431         if (!StartWorkThread(GenerateBinaryFileThreadEntry, 0, "Generating Binary Resource File."))
2432         {
2433             return FALSE;
2434         }
2435 
2436         if (show_notify)
2437         {
2438             Notify("Binary Resource File Generation Completed.");
2439         }
2440 
2441         return TRUE;
2442     }
2443 
2444     return FALSE;
2445 }
2446 
2447 
2448 ///////////////////////////////////////////////////////////////////////////////
2449 // add a child widget to the selected screen tree node:
InsertTopLevelWidget(widget_info * info)2450 void project_view::InsertTopLevelWidget(widget_info *info)
2451 {
2452     // KGM- this needs to be fixed. We can't use the tree view selected item
2453     // to determine where to insert a top level widget when we are doing an Undo.
2454     // this causes breakage......
2455 
2456     // we should locate the widget root window, and use that to find the
2457     // tree root.
2458 
2459     HTREEITEM hParent = mpTree->GetSelectedItem();
2460 
2461     while(GetTreeNodeLevel(hParent) > FOLDER_NODE_LEVEL)
2462     {
2463         hParent = mpTree->GetParentItem(hParent);
2464     }
2465 
2466     HTREEITEM hCurrent = mpTree->InsertItem(info->app_name,
2467             hParent, TVI_SORT);
2468     mpTree->SetItemData(hCurrent, (DWORD_PTR) info);
2469     AssignTreeImage(hCurrent, info);
2470 
2471     /* Insert child widgets.  */
2472     if (info->GetChildWidgetInfo())
2473     {
2474         InsertTreeChild(hCurrent, info->GetChildWidgetInfo());
2475     }
2476 
2477     mpTree->SelectItem(hCurrent);
2478     GetPropsWin()->OnWidgetSelect(info);
2479 }
2480 
2481 ///////////////////////////////////////////////////////////////////////////////
2482 // add a folder to display:
InsertFolder(folder_info * info)2483 void project_view::InsertFolder(folder_info *info)
2484 {
2485     HTREEITEM hItem = mpTree->GetSelectedItem();
2486 
2487     HTREEITEM hCurrent = mpTree->InsertItem(info->folder_name,
2488         hItem, TVI_SORT);
2489     mpTree->SetItemData(hCurrent, (DWORD_PTR)info);
2490     AssignTreeImage(hCurrent, info);
2491 
2492     UndoManager()->AddEntry(UNDO_TYPE_INSERT_FOLDER, info, m_active_display);
2493 
2494     /* Insert child widgets.  */
2495     mpTree->SelectItem(hCurrent);
2496 
2497     if (info->GetFirstChildWidget())
2498     {
2499         InsertTreeChild(hCurrent, info->GetFirstChildWidget());
2500         GetPropsWin()->OnWidgetSelect(info->GetFirstChildWidget());
2501     }
2502 
2503     /* Force project view to redraw here to make the "+" shown.
2504        Sometime the "+" isn't shown when generally running,
2505        but it is shown when debug. So force it redraw here.*/
2506     Invalidate();
2507     UpdateWindow();
2508 }
2509 
2510 ///////////////////////////////////////////////////////////////////////////////
2511 // add a child widget to the indicated parent:
InsertTreeChild(HTREEITEM hParent,widget_info * info,BOOL do_siblings)2512 widget_info *project_view::InsertTreeChild(HTREEITEM hParent, widget_info *info, BOOL do_siblings)
2513 {
2514     widget_info *parent_info = (widget_info *)mpTree->GetItemData(hParent);
2515     widget_info *sib;
2516 
2517     HTREEITEM hCurrent = mpTree->InsertItem(info->app_name,
2518         hParent, TVI_SORT);
2519     AssignTreeImage(hCurrent, info);
2520     mpTree->SetItemData(hCurrent, (DWORD_PTR)info);
2521 
2522     if (info->GetChildWidgetInfo())
2523     {
2524         InsertTreeChild(hCurrent, info->GetChildWidgetInfo());
2525     }
2526 
2527     if (do_siblings)
2528     {
2529         sib = info->GetNextWidgetInfo();
2530 
2531         while (sib)
2532         {
2533             InsertTreeChild(hParent, sib, FALSE);
2534             sib = sib->GetNextWidgetInfo();
2535         }
2536     }
2537 
2538     return parent_info;
2539 }
2540 
2541 ///////////////////////////////////////////////////////////////////////////////
2542 // add a child widget to the selected tree node:
InsertTreeChild(widget_info * parent,widget_info * info,BOOL do_siblings)2543 widget_info *project_view::InsertTreeChild(widget_info *parent, widget_info *info, BOOL do_siblings)
2544 {
2545     HTREEITEM hParent = mpTree->GetSelectedItem();
2546     widget_info *parent_info = (widget_info *) mpTree->GetItemData(hParent);
2547     widget_info *sib;
2548 
2549     // make sure we are in sync
2550     if (parent_info == parent)
2551     {
2552         HTREEITEM hCurrent = mpTree->InsertItem(info->app_name,
2553             hParent, TVI_SORT);
2554         AssignTreeImage(hCurrent, info);
2555         mpTree->SetItemData(hCurrent, (DWORD_PTR) info);
2556 
2557         if (info->GetChildWidgetInfo())
2558         {
2559             InsertTreeChild(hCurrent, info->GetChildWidgetInfo());
2560         }
2561 
2562         if (do_siblings)
2563         {
2564             sib = info->GetNextWidgetInfo();
2565 
2566             while(sib)
2567             {
2568                 InsertTreeChild(hParent, sib, FALSE);
2569                 sib = sib->GetNextWidgetInfo();
2570             }
2571         }
2572 
2573         mpTree->SelectItem(hCurrent);
2574         GetPropsWin()->OnWidgetSelect(info);
2575         return parent_info;
2576     }
2577     return NULL;
2578 }
2579 
2580 ///////////////////////////////////////////////////////////////////////////////
InsertTreeChild(folder_info * folder,widget_info * info,BOOL do_siblings)2581 folder_info *project_view::InsertTreeChild(folder_info *folder, widget_info *info, BOOL do_siblings)
2582 {
2583     HTREEITEM hParent = mpTree->GetSelectedItem();
2584     folder_info *parent_folder = (folder_info *)mpTree->GetItemData(hParent);
2585     widget_info *sib;
2586 
2587     // make sure we are in sync
2588     if (parent_folder == folder)
2589     {
2590         HTREEITEM hCurrent = mpTree->InsertItem(info->app_name,
2591             hParent, TVI_SORT);
2592         AssignTreeImage(hCurrent, info);
2593         mpTree->SetItemData(hCurrent, (DWORD_PTR)info);
2594 
2595         if (info->GetChildWidgetInfo())
2596         {
2597             InsertTreeChild(hCurrent, info->GetChildWidgetInfo());
2598         }
2599 
2600         if (do_siblings)
2601         {
2602             sib = info->GetNextWidgetInfo();
2603 
2604             while (sib)
2605             {
2606                 InsertTreeChild(hParent, sib, FALSE);
2607                 sib = sib->GetNextWidgetInfo();
2608             }
2609         }
2610 
2611         mpTree->SelectItem(hCurrent);
2612         GetPropsWin()->OnWidgetSelect(info);
2613         return parent_folder;
2614     }
2615     return NULL;
2616 }
2617 
2618 ///////////////////////////////////////////////////////////////////////////////
FindWidget(HTREEITEM start,widget_info * widget)2619 HTREEITEM project_view::FindWidget(HTREEITEM start, widget_info *widget)
2620 {
2621     HTREEITEM result;
2622 
2623     while(start)
2624     {
2625         widget_info *info = (widget_info *) mpTree->GetItemData(start);
2626         if (info == widget)
2627         {
2628             return start;
2629         }
2630 
2631         HTREEITEM child = mpTree->GetChildItem(start);
2632         if (child)
2633         {
2634             result = FindWidget(child, widget);
2635             if (result)
2636             {
2637                 return result;
2638             }
2639         }
2640         start = mpTree->GetNextSiblingItem(start);
2641     }
2642     return 0;
2643 }
2644 
2645 ///////////////////////////////////////////////////////////////////////////////
FindWidget(widget_info * widget)2646 HTREEITEM project_view::FindWidget(widget_info *widget)
2647 {
2648     HTREEITEM root = mpTree->GetRootItem();
2649     HTREEITEM display = mpTree->GetChildItem(root); //display node
2650     HTREEITEM found;
2651     while (display)
2652     {
2653         HTREEITEM folder = mpTree->GetChildItem(display); //folder item
2654         while (folder)
2655         {
2656             HTREEITEM child = mpTree->GetChildItem(folder); //screen item
2657             found = FindWidget(child, widget);
2658             if (found)
2659             {
2660                 return found;
2661             }
2662             folder = mpTree->GetNextSiblingItem(folder);
2663         }
2664         display = mpTree->GetNextSiblingItem(display);
2665     }
2666 
2667     return 0;
2668 }
2669 
2670 ///////////////////////////////////////////////////////////////////////////////
FindProjectTreeNode(HTREEITEM start,CString name,int search_depth)2671 HTREEITEM project_view::FindProjectTreeNode(HTREEITEM start, CString name, int search_depth)
2672 {
2673     HTREEITEM result;
2674     HTREEITEM child;
2675     CString   text;
2676 
2677     while (start)
2678     {
2679         text = mpTree->GetItemText(start);
2680         if (text.Compare(name) == 0)
2681         {
2682             return start;
2683         }
2684 
2685         child = mpTree->GetChildItem(start);
2686         if (child && search_depth)
2687         {
2688             search_depth--;
2689             result = FindProjectTreeNode(child, name, search_depth);
2690             if (result)
2691             {
2692                 return result;
2693             }
2694         }
2695 
2696         start = mpTree->GetNextSiblingItem(start);
2697     }
2698     return 0;
2699 }
2700 
2701 ///////////////////////////////////////////////////////////////////////////////
FindProjectTreeNode(CString name,CString display_name,CString screen_name)2702 HTREEITEM project_view::FindProjectTreeNode(CString name, CString display_name, CString screen_name)
2703 {
2704     if (!name)
2705     {
2706         return 0;
2707     }
2708     HTREEITEM root = mpTree->GetRootItem();
2709     HTREEITEM start = mpTree->GetChildItem(root); //display level
2710     HTREEITEM screen;
2711     BOOL found = FALSE;
2712 
2713     if (!display_name.IsEmpty())
2714     {
2715         while (start)
2716         {
2717             if (display_name == mpTree->GetItemText(start))
2718             {
2719                 start = mpTree->GetChildItem(start);
2720                 break;
2721             }
2722             start = mpTree->GetNextSiblingItem(start);
2723         }
2724     }
2725 
2726     if (start && !screen_name.IsEmpty())
2727     {
2728         while (start)
2729         {
2730             //loop through folders
2731             screen = mpTree->GetChildItem(start);
2732             while (screen)
2733             {
2734                 //loop through screens
2735                 if (screen_name == mpTree->GetItemText(screen))
2736                 {
2737                     start = mpTree->GetChildItem(screen);
2738                     found = TRUE;
2739                     break;
2740                 }
2741                 screen = mpTree->GetNextSiblingItem(screen);
2742             }
2743 
2744             if (found)
2745             {
2746                 break;
2747             }
2748             start = mpTree->GetNextSiblingItem(start);
2749         }
2750     }
2751 
2752     return FindProjectTreeNode(start, name);
2753 }
2754 
2755 ///////////////////////////////////////////////////////////////////////////////
2756 // this is called by WidgetSelected, when the target widget is NULl. This
2757 // means the user clicked on the root window.
DisplaySelected()2758 void project_view::DisplaySelected()
2759 {
2760     if (m_active_display < 0)
2761     {
2762         return;
2763     }
2764     HTREEITEM root = mpTree->GetRootItem();
2765     HTREEITEM display = mpTree->GetChildItem(root);
2766     int index = 0;
2767 
2768     while(display && index < m_active_display)
2769     {
2770         display = mpTree->GetNextSiblingItem(display);
2771         index++;
2772     }
2773     mpTree->SelectItem(display);
2774 }
2775 
2776 
2777 ///////////////////////////////////////////////////////////////////////////////
2778 // this is called by target screen when the user clicks on a widget.
2779 // update tree view to match
WidgetSelected(widget_info * info)2780 void project_view::WidgetSelected(widget_info *info)
2781 {
2782     if (info && info->widget && info->widget->gx_widget_type != GX_TYPE_ROOT_WINDOW)
2783     {
2784         HTREEITEM hSelected;
2785         hSelected = FindWidget(info);
2786 
2787         if (hSelected)
2788         {
2789             mpTree->SelectItem(hSelected);
2790             GetPropsWin()->OnWidgetSelect(info);
2791         }
2792     }
2793     else
2794     {
2795         GetPropsWin()->OnWidgetSelect(NULL);
2796         DisplaySelected();
2797     }
2798 }
2799 
2800 ///////////////////////////////////////////////////////////////////////////////
FolderSelected(INT display_index,CString folder_name)2801 void project_view::FolderSelected(INT display_index, CString folder_name)
2802 {
2803     HTREEITEM item = mpTree->GetRootItem(); //root
2804     HTREEITEM display = mpTree->GetChildItem(item); //display
2805 
2806     int index = 0;
2807     /* Get target display. */
2808     while (display && index < display_index)
2809     {
2810         display = mpTree->GetNextSiblingItem(display);
2811         index++;
2812     }
2813     mpTree->SelectItem(display);
2814 
2815     /* Select target folder. */
2816     HTREEITEM folder = mpTree->GetChildItem(display); //folder
2817     while (folder)
2818     {
2819         if (mpTree->GetItemText(folder) == folder_name)
2820         {
2821             mpTree->SelectItem(folder);
2822             return;
2823         }
2824         folder = mpTree->GetNextSiblingItem(folder);
2825     }
2826 
2827 }
2828 
2829 ///////////////////////////////////////////////////////////////////////////////
FolderSelected(folder_info * folder)2830 void project_view::FolderSelected(folder_info * folder)
2831 {
2832     if (folder)
2833     {
2834         int display_index = GetOpenProject()->GetDisplayIndex(folder);
2835         FolderSelected(display_index, folder->folder_name);
2836     }
2837     else
2838     {
2839         GetPropsWin()->OnWidgetSelect(NULL);
2840         DisplaySelected();
2841     }
2842 }
2843 
2844 ///////////////////////////////////////////////////////////////////////////////
NotifyNameChange(widget_info * info)2845 void project_view::NotifyNameChange(widget_info *info)
2846 {
2847     HTREEITEM hitem = mpTree->GetSelectedItem();
2848     widget_info *selinfo = (widget_info *) mpTree->GetItemData(hitem);
2849     CString name;
2850 
2851     if (info == selinfo)
2852     {
2853         if (!info->app_name.IsEmpty())
2854         {
2855             mpTree->SetItemText(hitem, info->app_name);
2856             name = info->app_name;
2857         }
2858         else
2859         {
2860             mpTree -> SetItemText(hitem, info->base_name);
2861             name = info->base_name;
2862         }
2863 
2864         HTREEITEM hParent = mpTree->GetParentItem(hitem);
2865         if (hParent)
2866         {
2867             /* Sort child to be alphabetly displayed. */
2868             mpTree->SortChildren(hParent);
2869         }
2870     }
2871 }
2872 
2873 /////////////////////////////////////////////////////////////////////////////
GetTreeState(CArray<int> * state_array)2874 void project_view::GetTreeState(CArray<int> *state_array)
2875 {
2876     HTREEITEM root = mpTree->GetRootItem();
2877     HTREEITEM screen = mpTree->GetChildItem(root); // display node
2878     UINT      state = 0;
2879 
2880     while (screen)
2881     {
2882         HTREEITEM child = mpTree->GetChildItem(screen);
2883 
2884         state = mpTree->GetItemState(screen, TVIS_EXPANDED);
2885 
2886         state_array->Add(state);
2887 
2888         if(child)
2889         {
2890             GetTreeState(child, state_array);
2891         }
2892 
2893         screen = mpTree->GetNextSiblingItem(screen);
2894     }
2895 }
2896 
2897 ///////////////////////////////////////////////////////////////////////////
GetTreeState(HTREEITEM hParent,CArray<int> * state_array)2898 void project_view::GetTreeState(HTREEITEM hParent, CArray<int> *state_array)
2899 {
2900     UINT      state = 0;
2901 
2902     while (hParent)
2903     {
2904         HTREEITEM child = mpTree->GetChildItem(hParent);
2905 
2906         state = mpTree->GetItemState(hParent, TVIS_EXPANDED);
2907 
2908         state_array->Add(state);
2909 
2910         if (child)
2911         {
2912             GetTreeState(child, state_array);
2913         }
2914 
2915         hParent = mpTree->GetNextSiblingItem(hParent);
2916     }
2917 }
2918 
2919 
2920 /////////////////////////////////////////////////////////////////////////////
SetTreeState(CArray<int> * state_array)2921 void project_view::SetTreeState(CArray<int> *state_array)
2922 {
2923     HTREEITEM root = mpTree->GetRootItem();
2924     HTREEITEM screen = mpTree->GetChildItem(root); // display node
2925 
2926     if (!state_array)
2927     {
2928         return;
2929     }
2930 
2931     while (screen)
2932     {
2933         if (state_array->GetCount() == 0)
2934         {
2935             break;
2936         }
2937 
2938         HTREEITEM child = mpTree->GetChildItem(screen);
2939 
2940         if (state_array->GetAt(0))
2941         {
2942             mpTree->Expand(screen, TVE_EXPAND);
2943         }
2944         else
2945         {
2946             mpTree->Expand(screen, TVE_COLLAPSE);
2947         }
2948 
2949         state_array->RemoveAt(0);
2950 
2951         if (state_array->GetCount() && child)
2952         {
2953             SetTreeState(child, state_array);
2954         }
2955 
2956         screen = mpTree->GetNextSiblingItem(screen);
2957     }
2958 }
2959 
2960 ///////////////////////////////////////////////////////////////////////////
SetTreeState(HTREEITEM hParent,CArray<int> * state_array)2961 void project_view::SetTreeState(HTREEITEM hParent, CArray<int> *state_array)
2962 {
2963     if (!state_array)
2964     {
2965         return;
2966     }
2967 
2968     while (hParent)
2969     {
2970         if (state_array->GetCount() == 0)
2971         {
2972             break;
2973         }
2974 
2975         HTREEITEM child = mpTree->GetChildItem(hParent);
2976 
2977         if (state_array->GetAt(0))
2978         {
2979             mpTree->Expand(hParent, TVE_EXPAND);
2980         }
2981         else
2982         {
2983             mpTree->Expand(hParent, TVE_COLLAPSE);
2984         }
2985 
2986         state_array->RemoveAt(0);
2987 
2988         if (state_array->GetCount() && child)
2989         {
2990             SetTreeState(child, state_array);
2991         }
2992 
2993         hParent = mpTree->GetNextSiblingItem(hParent);
2994     }
2995 }
2996 
2997 ///////////////////////////////////////////////////////////////////////////////
OnTestMessage(WPARAM wParam,LPARAM lParam)2998 LRESULT project_view::OnTestMessage(WPARAM wParam, LPARAM lParam)
2999 {
3000     CStringArray param_list;
3001     LRESULT result = 0;
3002     CString pathname;
3003     CString filename;
3004     HTREEITEM select;
3005     CString path;
3006     CString title;
3007     widget_info *info;
3008 
3009     switch(wParam)
3010     {
3011     case TEST_OPEN_PROJECT:
3012         CloseProject(FALSE, FALSE);
3013         pathname = GetTestingParam(0);
3014         filename = pathname.Right(pathname.GetLength() - pathname.ReverseFind('\\') - 1);
3015         pathname = pathname.Left(pathname.GetLength() - filename.GetLength() - 1);
3016         OpenProject(pathname, filename);
3017         break;
3018 
3019     case TEST_CLOSE_PROJECT:
3020         CloseProject(TRUE, lParam);
3021         break;
3022 
3023     case TEST_IMPORT_PROJECT:
3024         pathname = GetTestingParam(1);
3025         filename = pathname.Right(pathname.GetLength() - pathname.ReverseFind('\\') - 1);
3026         pathname = pathname.Left(pathname.GetLength() - filename.GetLength() - 1);
3027         MergeProject(pathname, filename);
3028         break;
3029 
3030     case TEST_SELECT_PROJECT_TREE_NODE:
3031         select = FindProjectTreeNode(GetTestingParam(0));
3032         if (select)
3033         {
3034             mpTree->SelectItem(select);
3035             result = 1;
3036         }
3037         else
3038         {
3039             result = 0;
3040         }
3041         break;
3042 
3043     case TEST_SELECT_PROJECT_FOLDER:
3044         // parameters are display name, folder name:
3045         SplitString(GetTestingParam(0), ',', &param_list);
3046         select = FindProjectTreeNode(param_list[1], param_list[0]);
3047         if (select)
3048         {
3049             mpTree->SelectItem(select);
3050             result = 1;
3051         }
3052         else
3053         {
3054             result = 0;
3055         }
3056         break;
3057 
3058     case TEST_SELECT_CHILD_WIDGET:
3059         select = mpTree->GetSelectedItem();
3060 
3061         if (select)
3062         {
3063             mpTree->SelectItem(mpTree->GetChildItem(select));
3064             result = 1;
3065         }
3066         else
3067         {
3068             result = 0;
3069         }
3070         break;
3071 
3072 
3073     case TEST_SELECT_MULTI_WIDGETS:
3074         select = FindProjectTreeNode(GetTestingParam(0));
3075         if (select)
3076         {
3077             info = (widget_info *)mpTree->GetItemData(select);
3078 
3079             if (info)
3080             {
3081                 GetTargetScreen()->MakeTopWindowVisible(info);
3082                 GetTargetScreen()->SelectWidget(info, TRUE, TRUE);
3083             }
3084         }
3085         break;
3086 
3087     case TEST_DELETE_FOLDER:
3088     case TEST_DELETE_WIDGET:
3089         OnDeleteWidget();
3090         break;
3091 
3092     case TEST_GET_WIDGET_LEFT:
3093         select = FindProjectTreeNode(GetTestingParam(0));
3094         if (select)
3095         {
3096             info = (widget_info *)mpTree->GetItemData(select);
3097 
3098             if (info)
3099             {
3100                 return info->size.gx_rectangle_left;
3101             }
3102         }
3103         break;
3104 
3105     case TEST_GET_WIDGET_TOP:
3106         select = FindProjectTreeNode(GetTestingParam(0));
3107         if (select)
3108         {
3109             info = (widget_info *)mpTree->GetItemData(select);
3110 
3111             if (info)
3112             {
3113                 return info->size.gx_rectangle_top;
3114             }
3115         }
3116         break;
3117 
3118     case TEST_GET_WIDGET_RIGHT:
3119         select = FindProjectTreeNode(GetTestingParam(0));
3120         if (select)
3121         {
3122             info = (widget_info *)mpTree->GetItemData(select);
3123 
3124             if (info)
3125             {
3126                 return info->size.gx_rectangle_right;
3127             }
3128         }
3129         break;
3130 
3131     case TEST_GET_WIDGET_BOTTOM:
3132         select = FindProjectTreeNode(GetTestingParam(0));
3133         if (select)
3134         {
3135             info = (widget_info *)mpTree->GetItemData(select);
3136 
3137             if (info)
3138             {
3139                 return info->size.gx_rectangle_bottom;
3140             }
3141         }
3142         break;
3143 
3144     case TEST_INSERT_FOLDER:
3145         OnInsertFolder();
3146         break;
3147 
3148     case TEST_EDIT_FOLDER_PROPERTIES:
3149         select = mpTree->GetSelectedItem();
3150         if (GetTreeNodeLevel(select) == FOLDER_NODE_LEVEL)
3151         {
3152             OnEditFolderProperties();
3153         }
3154         break;
3155 
3156     case TEST_TERMINATE_APP_EXECUTION:
3157         TerminateAppExecutions();
3158         break;
3159     }
3160 
3161     return result;
3162 }
3163 
3164 ///////////////////////////////////////////////////////////////////////////
UpdateBaseMenu(CMenu * parent)3165 void project_view::UpdateBaseMenu(CMenu *parent)
3166 {
3167     HTREEITEM    root = mpTree->GetRootItem();
3168     HTREEITEM    display = mpTree->GetChildItem(root);
3169     HTREEITEM    folder;
3170     HTREEITEM    child;
3171     widget_info *info;
3172 
3173     CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd();
3174     CMenu      *pBaseMenu;
3175     CString     screen_name;
3176     int         index = 0;
3177     widget_info *selected = GetTargetScreen()->GetSingleSelect();
3178     int          flags;
3179     int          template_menu_pos = -1;
3180 
3181     pBaseMenu = pMain->GetBaseMenu();
3182 
3183     index = pBaseMenu->GetMenuItemCount();
3184 
3185     // clear menu items of container menu
3186     if (index)
3187     {
3188         template_menu_pos = parent->GetSubMenu(0)->GetMenuItemCount() - 1;
3189 
3190         while (index)
3191         {
3192             pBaseMenu->RemoveMenu(index - 1, MF_BYPOSITION);
3193             index--;
3194         }
3195     }
3196 
3197     index = m_active_display;
3198     while (index)
3199     {
3200         display = mpTree->GetNextSiblingItem(display);
3201         index--;
3202     }
3203 
3204     folder = mpTree->GetChildItem(display);
3205     while (folder)
3206     {
3207         child = mpTree->GetChildItem(folder);
3208         while (child)
3209         {
3210             info = (widget_info *)mpTree->GetItemData(child);
3211 
3212             if (info && info->is_template)
3213             {
3214                 flags = MF_STRING;
3215                 if (selected == info)
3216                 {
3217                     flags |= MF_DISABLED;
3218                 }
3219                 pBaseMenu->AppendMenu(flags, ID_ADD_TEMPLATE_BASE + index, info->app_name);
3220                 index++;
3221             }
3222 
3223             child = mpTree->GetNextSiblingItem(child);
3224         }
3225         folder = mpTree->GetNextSiblingItem(folder);
3226     }
3227 
3228     if (index)
3229     {
3230         if (template_menu_pos < 0)
3231         {
3232             //insert template submebu
3233             parent->GetSubMenu(0)->AppendMenu(MF_POPUP, (UINT)pBaseMenu->m_hMenu, _T("Template"));
3234         }
3235     }
3236     else
3237     {
3238         if (template_menu_pos >= 0)
3239         {
3240             //remove template submenu
3241             parent->GetSubMenu(0)->RemoveMenu(template_menu_pos, MF_BYPOSITION);
3242         }
3243     }
3244 }
3245 
3246 ///////////////////////////////////////////////////////////////////////////
CreateBaseMenu(CMenu * pBaseMenu)3247 BOOL project_view::CreateBaseMenu(CMenu *pBaseMenu)
3248 {
3249     HTREEITEM    root = mpTree->GetRootItem();
3250     HTREEITEM    display = mpTree->GetChildItem(root);
3251     HTREEITEM    folder = mpTree->GetChildItem(display);
3252     HTREEITEM    child;
3253     widget_info *info;
3254     int          index;
3255     widget_info *selected = GetTargetScreen()->GetSingleSelect();
3256     int          flags;
3257 
3258     index = m_active_display;
3259     while (index)
3260     {
3261         display = mpTree->GetNextSiblingItem(display);
3262         index--;
3263     }
3264 
3265     folder = mpTree->GetChildItem(display);
3266     while (folder)
3267     {
3268         child = mpTree->GetChildItem(folder);
3269         while (child)
3270         {
3271             info = (widget_info *)mpTree->GetItemData(child);
3272             if (info->is_template)
3273             {
3274                 if (index == 0)
3275                 {
3276                     pBaseMenu->CreatePopupMenu();
3277                 }
3278 
3279                 flags = MF_STRING;
3280                 if (selected == info)
3281                 {
3282                     flags |= MF_DISABLED;
3283                 }
3284                 pBaseMenu->AppendMenu(flags, ID_ADD_TEMPLATE_BASE + index, info->app_name);
3285                 index++;
3286             }
3287             child = mpTree->GetNextSiblingItem(child);
3288         }
3289 
3290         folder = mpTree->GetNextSiblingItem(folder);
3291     }
3292 
3293     if (index)
3294     {
3295         return TRUE;
3296     }
3297 
3298     return FALSE;
3299 }
3300 
3301 ///////////////////////////////////////////////////////////////////////////
IsTopLevelWidget(widget_info * widgetinfo)3302 GX_BOOL project_view::IsTopLevelWidget(widget_info *widgetinfo)
3303 {
3304     //Check if a widget is in top level
3305     HTREEITEM       root = mpTree->GetRootItem();
3306     HTREEITEM       display = mpTree->GetChildItem(root);
3307     HTREEITEM       child;
3308     HTREEITEM       folder;
3309     widget_info    *info;
3310 
3311     while (display)
3312     {
3313         folder = mpTree->GetChildItem(display);
3314         while (folder)
3315         {
3316             child = mpTree->GetChildItem(folder);
3317             while (child)
3318             {
3319                 info = (widget_info *)mpTree->GetItemData(child);
3320 
3321                 if (info == widgetinfo)
3322                 {
3323                     return TRUE;
3324                 }
3325 
3326                 child = mpTree->GetNextSiblingItem(child);
3327             }
3328             folder = mpTree->GetNextSiblingItem(folder);
3329         }
3330         display = mpTree->GetNextSiblingItem(display);
3331     }
3332 
3333     return FALSE;
3334 }
3335 
3336 ///////////////////////////////////////////////////////////////////////////
GetTopLevelWidgetList(int display_index,CArray<widget_info * > * list)3337 void project_view::GetTopLevelWidgetList(int display_index, CArray<widget_info *> *list)
3338 {
3339     HTREEITEM       root = mpTree->GetRootItem();
3340     HTREEITEM       screen = mpTree->GetChildItem(root); // display level
3341     HTREEITEM       child;
3342     widget_info    *info;
3343 
3344     list->RemoveAll();
3345 
3346     while (display_index)
3347     {
3348         screen = mpTree->GetNextSiblingItem(screen);
3349         display_index--;
3350     }
3351 
3352     screen = mpTree->GetChildItem(screen);  // folder level
3353     while (screen)
3354     {
3355         child = mpTree->GetChildItem(screen);
3356         while (child)
3357         {
3358             info = (widget_info *)mpTree->GetItemData(child);
3359 
3360             list->Add(info);
3361 
3362             child = mpTree->GetNextSiblingItem(child);
3363         }
3364         screen = mpTree->GetNextSiblingItem(screen);
3365     }
3366 
3367 }
3368 
3369 ///////////////////////////////////////////////////////////////////////////
FindTopLevelWidget(widget_info * child)3370 widget_info *project_view::FindTopLevelWidget(widget_info *child)
3371 {
3372     HTREEITEM       root = mpTree->GetRootItem();
3373     HTREEITEM       display = mpTree->GetChildItem(root);
3374     HTREEITEM       folder;
3375     HTREEITEM       screen;
3376     HTREEITEM       child_screen;
3377     widget_info    *found = NULL;
3378     widget_info    *info;
3379 
3380     while(display)
3381     {
3382         folder = mpTree->GetChildItem(display);
3383         while (folder)
3384         {
3385             screen = mpTree->GetChildItem(folder);
3386             while (screen)
3387             {
3388                 info = (widget_info *)mpTree->GetItemData(screen);
3389 
3390                 if (info == child)
3391                 {
3392                     found = info;
3393                     break;
3394                 }
3395 
3396                 child_screen = mpTree->GetChildItem(screen);
3397 
3398                 while (child_screen)
3399                 {
3400                     if (FindWidget(child_screen, child))
3401                     {
3402                         found = info;
3403                         break;
3404                     }
3405 
3406                     child_screen = mpTree->GetNextSiblingItem(child_screen);
3407                 }
3408 
3409                 screen = mpTree->GetNextSiblingItem(screen);
3410             }
3411             if (found)
3412             {
3413                 break;
3414             }
3415             folder = mpTree->GetNextSiblingItem(folder);
3416         }
3417         display = mpTree->GetNextSiblingItem(display);
3418     }
3419     return found;
3420 }
3421 
3422 ///////////////////////////////////////////////////////////////////////////////
OnLockUlockWidgetPositions()3423 VOID project_view::OnLockUlockWidgetPositions()
3424 {
3425     studiox_project *project = GetOpenProject();
3426 
3427     if (project)
3428     {
3429         if (project->IsWidgetPositionLocked())
3430         {
3431             project->LockUlockWidgetPositions(FALSE);
3432         }
3433         else
3434         {
3435             project->LockUlockWidgetPositions(TRUE);
3436         }
3437     }
3438 }
3439 
3440 ///////////////////////////////////////////////////////////////////////////////
PreTranslateMessage(MSG * pMsg)3441 BOOL project_view::PreTranslateMessage(MSG* pMsg)
3442 {
3443     // TODO: Add your specialized code here and/or call the base class
3444     if (pMsg->message == WM_SYSKEYDOWN)
3445     {
3446         int nAltKey = GetKeyState(VK_MENU);
3447 
3448         switch (pMsg->wParam)
3449         {
3450         case VK_DOWN:
3451             if (nAltKey & KEY_STATE_DOWN)
3452             {
3453                 //Move focus to property window
3454                 properties_win* props = GetPropsWin();
3455                 if (props)
3456                 {
3457                     props->SetFocus();
3458                     return TRUE;
3459                 }
3460             }
3461             break;
3462 
3463         case VK_RIGHT:
3464             if (nAltKey & KEY_STATE_DOWN)
3465             {
3466                 target_view* view = GetTargetView();
3467                 if (view)
3468                 {
3469                     CMainFrame* frame = (CMainFrame*)GetParentFrame();
3470                     frame->SetActiveView(view);
3471                     return TRUE;
3472                 }
3473             }
3474             break;
3475 
3476         default:
3477             break;
3478         }
3479     }
3480 
3481     return CTreeView::PreTranslateMessage(pMsg);
3482 }
3483