Compare Projects.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. /******************************************************************************/
  4. CompareProjects CompareProjs;
  5. /******************************************************************************/
  6. /******************************************************************************/
  7. void CompareProjects::ElmListElm::setElm(C Project &proj, C Elm &elm)
  8. {
  9. T.name=proj.elmFullName(&elm);
  10. T.type=elm.type;
  11. T.type_name=ElmTypeName[elm.type];
  12. T.id=elm.id;
  13. }
  14. void CompareProjects::Changed(C Property &prop) {CompareProjs.refresh();}
  15. void CompareProjects::SelectSel(CompareProjects &cp)
  16. {
  17. Memt<UID> ids; FREPA(cp.list.sel)if(ElmListElm *elml=cp.list.absToData(cp.list.sel[i]))ids.add(elml->id); Proj.elmSelect(ids);
  18. }
  19. void CompareProjects::SelectAll(CompareProjects &cp)
  20. {
  21. Memt<UID> ids; FREPA(cp.data)ids.add(cp.data[i].id); Proj.elmSelect(ids);
  22. }
  23. void CompareProjects::release()
  24. {
  25. projects.clear();
  26. list.clear();
  27. data.clear();
  28. }
  29. CompareProjects& CompareProjects::del(){release(); ::EE::Window::del (); return T;}
  30. CompareProjects& CompareProjects::hide(){release(); ::PropWin::hide(); return T;}
  31. CompareProjects& CompareProjects::rect(C Rect &rect)
  32. {
  33. ::EE::Window::rect(rect);
  34. flt p=0.02f;
  35. region.rect(Rect(p, -clientHeight()+p, clientWidth()-p, prop_min_y-p));
  36. return T;
  37. }
  38. void CompareProjects::create()
  39. {
  40. add("Detect Data Differences" , MEMBER(CompareProjects, test_data));
  41. add("Detect Name Differences" , MEMBER(CompareProjects, test_name));
  42. add("Detect Parent Differences" , MEMBER(CompareProjects, test_parent));
  43. add("Detect Publish Differences", MEMBER(CompareProjects, test_publish));
  44. add("Display New Elements" , MEMBER(CompareProjects, display_new)).desc("This will display all elements that exist in one project, but don't exist in the other one.");
  45. Rect r=::PropWin::create("Project Comparison"); prop_min_y=r.min.y; autoData(this); ::PropWin::changed(Changed); flag|=WIN_RESIZABLE; button[1].show(); button[2].show();
  46. ListColumn lc[]=
  47. {
  48. ListColumn(MEMBER(ElmListElm, name), 1.00f, "Name"), // 0
  49. ListColumn(MEMBER(ElmListElm, type_name), 0.22f, "Type"), // 1
  50. };
  51. T+=select_selected.create(Rect_L( r .right()+Vec2(0.05f, 0), 0.3f, 0.06f), "Select Picked").func(SelectSel, T).desc("This option will select the Project Elements which are picked on this list");
  52. T+=select_all .create(Rect_L(select_selected.rect().right()+Vec2(0.05f, 0), 0.3f, 0.06f), "Select All" ).func(SelectAll, T).desc("This option will select all Project Elements which are visible on this list");
  53. T+=region.create();
  54. region+=list.create(lc, Elms(lc)).elmHeight(0.038f).textSize(0, 1); list.flag|=LIST_RESIZABLE_COLUMNS|LIST_MULTI_SEL; list.cur_mode=LCM_ALWAYS;
  55. list.sort_column[0]=0;
  56. rect(Rect_C(0, 0, 1.22f+0.02f*2+region.slidebarSize(), 1.8f));
  57. }
  58. bool CompareProjects::DiffElm(C Project &proj_a, C Elm &elm_a, C Project &proj_b, C Elm &elm_b)
  59. {
  60. if(elm_a.newerData(elm_b) || elm_a.newerFile(elm_b)
  61. || elm_b.newerData(elm_a) || elm_b.newerFile(elm_a))return true;
  62. if(!FEqual(proj_a.editPath(elm_a), proj_b.editPath(elm_b))
  63. || !FEqual(proj_a.gamePath(elm_a), proj_b.gamePath(elm_b)))return true;
  64. return false;
  65. }
  66. void CompareProjects::refresh()
  67. {
  68. data.clear();
  69. if(projects.elms()>=2)
  70. {
  71. Memc<UID> different;
  72. FREPAD(pa, projects) // start from the beginning to list elements preferrably with pathnames from the first project
  73. {
  74. C Project &proj_a=projects[pa];
  75. FREPAD(ea, proj_a.elms) // start from the beginning to minimize 'binaryInclude' time
  76. {
  77. C Elm &elm_a=proj_a.elms[ea];
  78. if(elm_a.finalExists())
  79. REPAD(pb, projects) // compare all projects (and not only those before 'proj_a', something like "REP(ea)" because we need to check all elements of both projects compared to others in case 'display_new' is selected)
  80. if(pb!=pa) // don't compare the same project
  81. {
  82. C Project &proj_b=projects[pb];
  83. C Elm * elm_b=proj_b.findElm(elm_a.id, elm_a.type);
  84. if(elm_b && elm_b->finalExists())
  85. {
  86. if(test_data && (elm_a.data ? elm_a.data->ver.ver : 0)!=(elm_b->data ? elm_b->data->ver.ver : 0) && DiffElm(proj_a, elm_a, proj_b, *elm_b)
  87. || test_name && elm_a. name_time!=elm_b-> name_time && !Equal(elm_a.name, elm_b->name, true)
  88. || test_parent && elm_a.parent_time!=elm_b->parent_time && elm_a.parent_id!=elm_b->parent_id
  89. || test_publish && elm_a.noPublish()!=elm_b->noPublish())
  90. if(different.binaryInclude(elm_a.id, Compare))
  91. data.New().setElm(proj_a, elm_a);
  92. }else
  93. if(display_new)
  94. if(different.binaryInclude(elm_a.id, Compare))
  95. data.New().setElm(proj_a, elm_a);
  96. }
  97. }
  98. }
  99. }
  100. list.setData(data);
  101. }
  102. void CompareProjects::changed(C UID &proj_id)
  103. {
  104. if(visible())REPA(projects)
  105. {
  106. Project &proj=projects[i]; if(proj.id==proj_id)
  107. {
  108. if(proj_id==Proj.id)proj=Proj;else
  109. {
  110. Str path=proj.path;
  111. int ver; Str error; proj.load3(path, ver, error);
  112. proj.setIDPath(proj_id, path);
  113. }
  114. refresh(); break;
  115. }
  116. }
  117. }
  118. void CompareProjects::compare(C MemPtr<UID> &proj_ids)
  119. {
  120. release(); hide();
  121. FREPA(proj_ids) // process in order
  122. {
  123. C Projects::Elm *proj=Projs.findProj(proj_ids[i]); if(!proj){Gui.msgBox(S, S+"Project \""+proj_ids[i].asFileName()+"\" was not found"); return;}
  124. if(!proj->path.is()){Gui.msgBox(S, S+"Project \""+proj->name+"\" has no path"); return;}
  125. Project temp; int ver; Str error; LOAD_RESULT result=temp.load3(proj->path, ver, error);
  126. if(LoadOK(result))
  127. {
  128. temp.setIDPath(proj->id, proj->path);
  129. Swap(projects.New(), temp);
  130. }else switch(result)
  131. {
  132. case LOAD_NEWER : Gui.msgBox(S, S+"Project \""+proj->name+"\" requires newer engine version."); return;
  133. case LOAD_ERROR : Gui.msgBox(S, S+"Project \""+proj->name+"\" failed to load."+(error.is() ? '\n' : '\0')+error); return;
  134. case LOAD_LOCKED: Gui.msgBox(S, S+"Project \""+proj->name+"\" is locked."); return;
  135. }
  136. }
  137. refresh();
  138. activate();
  139. }
  140. void CompareProjects::update(C GuiPC &gpc)
  141. {
  142. ::EE::ClosableWindow::update(gpc);
  143. if(visible() && gpc.visible)
  144. {
  145. select_selected.visible(Proj.valid());
  146. select_all .visible(Proj.valid());
  147. if(Ms.bd( 0) && Gui.ms()==&list
  148. || Kb.k (KB_ENTER) && Gui.kb()==&list)
  149. if(ElmListElm *list_elm=list())
  150. if(Elm *elm=Proj.findElm(list_elm->id))
  151. {
  152. if(!ElmVisible(elm->type))elm=Proj.firstVisibleParent(elm);
  153. if(elm)
  154. {
  155. if(elm->type==ELM_FOLDER)Proj.elmOpenParents(elm->id);
  156. else Proj.elmToggle (elm->id); // call this first because it may open parents
  157. Proj.elmLocate(list_elm->id, true); // call this next once parents are opened
  158. }
  159. }
  160. }
  161. }
  162. CompareProjects::CompareProjects() : test_data(true), test_name(true), test_parent(false), test_publish(false), display_new(false), prop_min_y(0) {}
  163. CompareProjects::ElmListElm::ElmListElm() : type_name(null), id(UIDZero), type(ELM_NONE) {}
  164. /******************************************************************************/