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), ',', ¶m_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