2 public import static "ecere"
3 public import static "ec"
9 import "GlobalSettingsDialog"
10 import "NewProjectDialog"
11 import "FindInFilesDialog"
12 import "ActiveCompilerDialog"
19 import "ProjectActiveConfig"
20 import "ProjectConfig"
22 import "NodeProperties"
23 import "ProjectSettings"
35 import "BreakpointsView"
36 import "CallStackView"
47 import "FileSystemIterator"
49 #if defined(__WIN32__)
50 define pathListSep = ";";
52 define pathListSep = ":";
55 define maxPathLen = 65 * MAX_LOCATION;
57 class PathBackup : struct
64 oldPath = new char[maxPathLen];
65 oldLDPath = new char[maxPathLen];
67 GetEnvironment("PATH", oldPath, maxPathLen);
68 #if defined(__APPLE__)
69 GetEnvironment("DYLD_LIBRARY_PATH", oldLDPath, maxPathLen);
71 GetEnvironment("LD_LIBRARY_PATH", oldLDPath, maxPathLen);
77 SetEnvironment("PATH", oldPath);
78 #if defined(__APPLE__)
79 SetEnvironment("DYLD_LIBRARY_PATH", oldLDPath);
81 SetEnvironment("LD_LIBRARY_PATH", oldLDPath);
88 enum OpenCreateIfFails { no, yes, something, whatever };
89 enum OpenMethod { normal, add };
91 static Array<FileFilter> fileFilters
93 { $"C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)", "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx" },
94 { $"Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)", "eh, h, hpp, hh, hxx" },
95 { $"C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)", "ec, c, cpp, cc, cxx" },
96 { $"Text files (*.txt, *.text, *.nfo, *.info)", "txt, text, nfo, info" },
97 { $"Web files (*.html, *.htm, *.xhtml, *.css, *.php, *.js, *.jsi, *.rb, *.xml)", "html, htm, xhtml, css, php, js, jsi, rb, xml" },
98 { $"Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)", "jpg, jpeg, bmp, pcx, png, gif" },
99 { $"3D Studio Model Files (*.3ds)", "3ds" },
100 { $"All files", null }
103 static Array<FileType> fileTypes
105 { $"Based on extension", null },
108 { $"3D Studio Model", "3ds" }
111 static Array<FileFilter> projectFilters
113 { $"Project Files (*.epj)", ProjectExtension }
116 static Array<FileType> projectTypes
118 { $"Project File", ProjectExtension }
121 static Array<FileFilter> findInFilesFileFilters
123 { $"eC Files (*.ec, *.eh)", "ec, eh" },
124 { $"C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)", "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx" },
125 { $"Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)", "eh, h, hpp, hh, hxx" },
126 { $"C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)", "ec, c, cpp, cc, cxx" },
127 { $"Text files (*.txt)", "txt" },
128 { $"All files", null }
131 FileDialog ideFileDialog
133 type = multiOpen, text = $"Open";
134 types = fileTypes.array, sizeTypes = fileTypes.count * sizeof(FileType), filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter);
137 define openProjectFileDialogTitle = $"Open Project";
138 define addProjectFileDialogTitle = $"Open Additional Project";
139 FileDialog ideProjectFileDialog
142 types = projectTypes.array, sizeTypes = projectTypes.count * sizeof(FileType), filters = projectFilters.array, sizeFilters = projectFilters.count * sizeof(FileFilter);
145 GlobalSettingsDialog globalSettingsDialog
147 ideSettings = ideSettings;
148 settingsContainer = settingsContainer;
150 void OnGlobalSettingChange(GlobalSettingsChange globalSettingsChange)
152 switch(globalSettingsChange)
157 for(child = ide.firstChild; child; child = child.next)
159 if(child._class == class(CodeEditor))
161 CodeEditor codeEditor = (CodeEditor) child;
162 codeEditor.editBox.freeCaret = ideSettings.useFreeCaret;
163 // codeEditor.editBox.lineNumbers = ideSettings.showLineNumbers;
164 codeEditor.editBox.caretFollowsScrolling = ideSettings.caretFollowsScrolling;
165 codeEditor.OnPostCreate(); // Update editBox margin size
172 case compilerSettings:
174 ide.UpdateCompilerConfigs();
181 void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
186 lineY = (line - 1) * lineH;
187 if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
189 Bitmap bitmap = resource.bitmap;
191 surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
196 #define IDEItem(x) (&((IDEWorkSpace)0).x)
198 class IDEToolbar : ToolBar
202 ToolButton buttonNewFile { this, toolTip = $"New file", menuItemPtr = IDEItem(fileNewItem) };
204 ToolButton buttonOpenFile { this, toolTip = $"Open file", menuItemPtr = IDEItem(fileOpenItem) };
206 // ToolButton buttonCloseFile { this, toolTip = $"Close file", menuItemPtr = IDEItem(fileCloseItem) };
208 ToolButton buttonSaveFile { this, toolTip = $"Save file", menuItemPtr = IDEItem(fileSaveItem) };
210 ToolButton buttonSaveAllFile { this, toolTip = $"Save all", menuItemPtr = IDEItem(fileSaveAllItem) };
212 ToolSeparator separator1 { this };
221 // ToolSeparator separator2 { this };
223 /* Project options */
225 ToolButton buttonNewProject { this, toolTip = $"New project", menuItemPtr = IDEItem(projectNewItem) };
227 ToolButton buttonOpenProject { this, toolTip = $"Open project", menuItemPtr = IDEItem(projectOpenItem) };
228 // Add project to workspace
229 ToolButton buttonAddProject { this, toolTip = $"Add project to workspace", menuItemPtr = IDEItem(projectAddItem), disabled = true; };
231 // ToolButton buttonCloseProject { this, toolTip = $"Close project", menuItemPtr = IDEItem(projectCloseItem), disabled = true; };
233 ToolSeparator separator3 { this };
235 /* Build/Execution options */
237 ToolButton buttonBuild { this, toolTip = $"Build project", menuItemPtr = IDEItem(projectBuildItem), disabled = true; };
239 ToolButton buttonReLink { this, toolTip = $"Relink project", menuItemPtr = IDEItem(projectLinkItem), disabled = true; };
241 ToolButton buttonRebuild { this, toolTip = $"Rebuild project", menuItemPtr = IDEItem(projectRebuildItem), disabled = true; };
243 ToolButton buttonClean { this, toolTip = $"Clean project", menuItemPtr = IDEItem(projectCleanItem), disabled = true; };
245 // ToolButton buttonRealClean { this, toolTip = $"Real clean project", menuItemPtr = IDEItem(projectRealCleanItem), disabled = true; };
246 // Regenerate Makefile
247 ToolButton buttonRegenerateMakefile { this, toolTip = $"Regenerate Makefile", menuItemPtr = IDEItem(projectRegenerateItem), disabled = true; };
248 // Compile actual file
250 ToolButton buttonRun { this, toolTip = $"Run", menuItemPtr = IDEItem(projectRunItem), disabled = true; };
252 ToolSeparator separator4 { this };
256 ToolButton buttonDebugStartResume { this, toolTip = $"Start", menuItemPtr = IDEItem(debugStartResumeItem), disabled = true; };
258 ToolButton buttonDebugRestart { this, toolTip = $"Restart", menuItemPtr = IDEItem(debugRestartItem), disabled = true; };
260 ToolButton buttonDebugPause { this, toolTip = $"Break", menuItemPtr = IDEItem(debugBreakItem), disabled = true; };
262 ToolButton buttonDebugStop { this, toolTip = $"Stop", menuItemPtr = IDEItem(debugStopItem), disabled = true; };
264 //ToolButton buttonRun { this, toolTip = $"Run", menuItemPtr = IDEItem(projectRunItem) };
266 ToolButton buttonDebugStepInto { this, toolTip = $"Step Into", menuItemPtr = IDEItem(debugStepIntoItem), disabled = true; };
268 ToolButton buttonDebugStepOver { this, toolTip = $"Step Over", menuItemPtr = IDEItem(debugStepOverItem), disabled = true; };
270 ToolButton buttonDebugStepOut { this, toolTip = $"Step Out", menuItemPtr = IDEItem(debugStepOutItem), disabled = true; };
272 ToolButton buttonDebugSkipStepOver { this, toolTip = $"Step Over Skipping Breakpoints", menuItemPtr = IDEItem(debugSkipStepOverItem), disabled = true; };
275 class IDEMainFrame : Window
277 background = formColor;
278 borderStyle = sizable;
282 minClientSize = { 600, 300 };
284 icon = { ":icon.png" };
285 text = titleECEREIDE;
289 anchor = { top = 0, right = 0, bottom = 0 };
292 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
299 isActiveClient = true;
301 direction = vertical;
302 background = formColor;
303 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
311 ((IDEWorkSpace)master).toolBar = null;
314 IDEWorkSpace ideWorkSpace { stack, this, toolBar = toolBar };
317 define ide = ideMainFrame.ideWorkSpace;
319 class IDEWorkSpace : Window
321 background = Color { 85, 85, 85 };
324 hasVertScroll = true;
325 hasHorzScroll = true;
327 isActiveClient = true;
328 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
332 MenuItem * driverItems, * skinItems;
333 StatusField pos { width = 150 };
334 StatusField ovr, caps, num;
336 BitmapResource back { ":ecereBack.jpg", window = this };
337 BitmapResource bmpBp { ":codeMarks/breakpoint.png", window = this };
338 BitmapResource bmpBpDisabled { ":codeMarks/breakpointDisabled.png", window = this };
339 BitmapResource bmpBpHalf { ":codeMarks/breakpointHalf.png", window = this };
340 BitmapResource bmpBpHalfDisabled { ":codeMarks/breakpointHalfDisabled.png", window = this };
341 BitmapResource bmpCursor { ":codeMarks/cursor.png", window = this };
342 BitmapResource bmpCursorError { ":codeMarks/cursorError.png", window = this };
343 BitmapResource bmpTopFrame { ":codeMarks/topFrame.png", window = this };
344 BitmapResource bmpTopFrameError { ":codeMarks/topFrameError.png", window = this };
345 BitmapResource bmpTopFrameHalf { ":codeMarks/topFrameHalf.png", window = this };
346 BitmapResource bmpTopFrameHalfError { ":codeMarks/topFrameHalfError.png", window = this };
348 Debugger debugger { };
350 ProjectView projectView;
352 OutputView outputView
356 void OnGotoError(char * line)
361 void OnCodeLocationParseAndGoTo(char * line)
363 ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir);
366 bool OnKeyDown(Key key, unichar ch)
371 if(!ide.findInFilesDialog || !ide.findInFilesDialog.SearchAbort())
372 ide.ShowCodeEditor();
375 ide.projectView.stopBuild = true;
379 OutputView::OnKeyDown(key, ch);
386 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
389 ide.RepositionWindows(false);
393 bool OnClose(bool parentClosing)
397 ide.RepositionWindows(false);
398 return parentClosing;
402 CallStackView callStackView
404 parent = this, font = { panelFont.faceName, panelFont.size };
406 void OnGotoLine(char * line)
409 stackLvl = atoi(line);
410 ide.debugger.GoToStackFrameLine(stackLvl, true);
413 void OnSelectFrame(int lineNumber)
415 ide.debugger.SelectFrame(lineNumber);
418 void OnToggleBreakpoint()
420 Debugger debugger = ide.debugger;
421 if(debugger.activeFrame && debugger.activeFrame.absoluteFile)
423 int line = debugger.activeFrame.line;
424 char name[MAX_LOCATION];
426 // TOFIX: Improve on this, don't use only filename, make a function
427 GetLastDirectory(debugger.activeFrame.absoluteFile, name);
428 if(ide && ide.workspace)
430 for(p : ide.workspace.projects)
432 if(p.topNode.Find(name, false))
440 for(p : ide.workspace.projects)
442 if(IsPathInsideOf(debugger.activeFrame.absoluteFile, p.topNode.path))
450 debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line, prj);
453 CodeEditor codeEditor = (CodeEditor)ide.FindWindow(debugger.activeFrame.absoluteFile);
454 if(codeEditor) { codeEditor.Update(null); Activate(); }
459 bool OnKeyDown(Key key, unichar ch)
463 case escape: ide.ShowCodeEditor(); break;
468 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
471 ide.RepositionWindows(false);
475 bool OnClose(bool parentClosing)
479 ide.RepositionWindows(false);
480 return parentClosing;
483 void OnRedraw(Surface surface)
486 int lineCursor, lineTopFrame, activeThread, hitThread;
487 int lineH, scrollY, boxH;
489 Breakpoint bp = null;
490 Debugger debugger = ide.debugger;
491 Frame activeFrame = debugger.activeFrame;
494 scrollY = editBox.scroll.y;
495 displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
497 activeThread = debugger.activeThread;
498 hitThread = debugger.hitThread;
499 debugger.GetCallStackCursorLine(&error, &lineCursor, &lineTopFrame);
501 if(activeFrame && activeFrame.absoluteFile)
503 for(i : ide.workspace.breakpoints; i.type == user)
505 if(i.absoluteFilePath && i.absoluteFilePath[0] &&
506 !fstrcmp(i.absoluteFilePath, activeFrame.absoluteFile) &&
507 activeFrame.line == i.line)
516 DrawLineMarginIcon(surface,
517 /*(lineCursor == 1 || lineTopFrame == 1) ? */ide.bmpBpHalf/* : ide.bmpBp*/,
518 lineCursor /*1*/, lineH, scrollY, boxH);
521 if(activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
522 DrawLineMarginIcon(surface,
523 (lineCursor == 1 || lineTopFrame == 1) ? ide.bmpBpHalf : ide.bmpBp,
524 1, lineH, scrollY, boxH);
526 DrawLineMarginIcon(surface, error ? ide.bmpCursorError : ide.bmpCursor, lineCursor, lineH, scrollY, boxH);
527 if(bp && lineCursor == 1) //activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
528 bmp = error ? ide.bmpTopFrameHalfError : ide.bmpTopFrameHalf;
530 bmp = error ? ide.bmpTopFrameError : ide.bmpTopFrame;
531 DrawLineMarginIcon(surface, bmp, lineTopFrame, lineH, scrollY, boxH);
532 if(editBox.horzScroll && editBox.horzScroll.visible)
534 surface.SetBackground(control);
535 surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
540 WatchesView watchesView { parent = this };
541 ThreadsView threadsView
543 parent = this, font = { panelFont.faceName, panelFont.size };
545 bool OnKeyDown(Key key, unichar ch)
549 case escape: ide.ShowCodeEditor(); break;
554 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
557 ide.RepositionWindows(false);
561 bool OnClose(bool parentClosing)
565 ide.RepositionWindows(false);
566 return parentClosing;
569 void OnSelectThread(int threadId)
572 ide.debugger.SelectThread(threadId);
575 bool OnGetThreadsInfo(int * activeThread, int * hitThread, int * signalThread)
578 Debugger debugger = ide.debugger;
579 *activeThread = debugger.activeThread;
580 *hitThread = debugger.hitThread;
581 *signalThread = debugger.signalThread;
586 BreakpointsView breakpointsView { parent = this };
588 ToolBox toolBox { parent = this };
589 Sheet sheet { parent = this };
592 property char * tmpPrjDir { set { delete tmpPrjDir; if(value) tmpPrjDir = CopyString(value); } get { return tmpPrjDir; } };
594 Menu fileMenu { menu, $"File", f, hasMargin = true };
597 fileMenu, $"New", n, ctrlN;
598 bitmap = { ":actions/docNew.png" };
599 bool NotifySelect(MenuItem selection, Modifiers mods)
601 Window document = (Window)NewCodeEditor(this, normal, false);
602 document.NotifySaved = DocumentSaved;
606 MenuItem fileOpenItem
608 fileMenu, $"Open...", o, ctrlO;
609 bitmap = { ":actions/docOpen.png" };
610 bool NotifySelect(MenuItem selection, Modifiers mods)
612 if(!projectView && ideSettings.ideFileDialogLocation)
613 ideFileDialog.currentDirectory = ideSettings.ideFileDialogLocation;
616 if(ideFileDialog.Modal() == ok)
618 bool gotWhatWeWant = false;
620 int numSelections = ideFileDialog.numSelections;
621 char ** multiFilePaths = ideFileDialog.multiFilePaths;
623 for(c = 0; c < numSelections; c++)
625 if(OpenFile(multiFilePaths[c], normal, true, fileTypes[ideFileDialog.fileType].typeExtension, no, normal))
626 gotWhatWeWant = true;
629 MessageBox { type = yesNo, master = this, text = $"Error opening file",
630 contents = $"Open a different file?" }.Modal() == no)
632 if(!projectView && gotWhatWeWant)
633 ChangeFileDialogsDirectory(ideFileDialog.currentDirectory, true);
643 MenuItem fileCloseItem { fileMenu, $"Close", c, ctrlF4, NotifySelect = MenuFileClose };
644 MenuDivider { fileMenu };
645 MenuItem fileSaveItem
647 fileMenu, $"Save", s, ctrlS, bitmap = { ":actions/docSave.png" };
649 // For the toolbar button; clients can still override that for the menu item
650 bool Window::NotifySelect(MenuItem selection, Modifiers mods)
652 Window w = activeClient;
654 w.MenuFileSave(null, 0);
658 MenuItem fileSaveAsItem { fileMenu, $"Save As...", a };
659 MenuItem fileSaveAllItem { fileMenu, $"Save All", l, NotifySelect = MenuFileSaveAll, bitmap = { ":actions/docSaveAll.png" } };
660 MenuDivider { fileMenu };
663 fileMenu, $"Find In Files...", f, Key { f, ctrl = true , shift = true };
664 bool NotifySelect(MenuItem selection, Modifiers mods)
666 findInFilesDialog.replaceMode = false;
667 findInFilesDialog.Show();
671 MenuItem replaceInFiles
673 fileMenu, $"Replace In Files...", e, Key { r, ctrl = true , shift = true };
674 bool NotifySelect(MenuItem selection, Modifiers mods)
676 findInFilesDialog.replaceMode = true;
677 findInFilesDialog.Show();
681 MenuDivider { fileMenu };
682 MenuItem globalSettingsItem
684 fileMenu, $"Global Settings...", g;
685 bool NotifySelect(MenuItem selection, Modifiers mods)
687 globalSettingsDialog.master = this;
688 if(ide.workspace && ide.workspace.compiler)
689 globalSettingsDialog.workspaceActiveCompiler = ide.workspace.compiler;
690 else if(ideSettings.defaultCompiler)
691 globalSettingsDialog.workspaceActiveCompiler = ideSettings.defaultCompiler;
692 globalSettingsDialog.Modal();
696 MenuDivider { fileMenu };
697 Menu recentFiles { fileMenu, $"Recent Files", r };
698 Menu recentProjects { fileMenu, $"Recent Projects", p };
699 MenuDivider { fileMenu };
702 fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit;
704 bool NotifySelect(MenuItem selection, Modifiers mods)
706 ideMainFrame.Destroy(0);
711 bool FileRecentFile(MenuItem selection, Modifiers mods)
714 for(file : ideSettings.recentFiles)
716 if(id == selection.id)
718 OpenFile(file, normal, true, null, no, normal);
726 bool FileRecentProject(MenuItem selection, Modifiers mods)
729 for(file : ideSettings.recentProjects)
731 if(id == selection.id)
733 OpenFile(file, normal, true, null, no, normal);
741 MenuPlacement editMenu { menu, $"Edit", e };
743 Menu projectMenu { menu, $"Menu"."Project", p, hasMargin = true };
744 MenuItem projectNewItem
746 projectMenu, $"New...", n, Key { n, true, true };
747 bitmap = { ":actions/projNew.png" };
748 bool NotifySelect(MenuItem selection, Modifiers mods)
750 if(!DontTerminateDebugSession($"New Project"))
751 if(MenuWindowCloseAll(null, 0))
753 NewProjectDialog newProjectDialog;
757 projectView.visible = false;
758 if(!projectView.Destroy(0))
762 newProjectDialog = { master = this };
763 newProjectDialog.Modal();
766 ideSettings.AddRecentProject(projectView.fileName);
767 ide.UpdateRecentMenus();
768 settingsContainer.Save();
774 MenuItem projectOpenItem
776 projectMenu, $"Open...", o, Key { o, true, true };
777 bitmap = { ":actions/projOpen.png" };
778 bool NotifySelect(MenuItem selection, Modifiers mods)
780 if(ideSettings.ideProjectFileDialogLocation)
781 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
783 ideProjectFileDialog.text = openProjectFileDialogTitle;
784 if(ideProjectFileDialog.Modal() == ok)
786 OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal);
787 //ChangeProjectFileDialogDirectory(ideProjectFileDialog.currentDirectory);
792 MenuItem projectQuickItem
794 projectMenu, $"Quick...", q, f7, disabled = true;
795 bool NotifySelect(MenuItem selection, Modifiers mods)
798 QuickProjectDialog{ this }.Modal();
802 MenuItem projectAddItem
804 projectMenu, $"Add project to workspace...", a, Key { a, true, true };
805 bitmap = { ":actions/projAdd.png" };
807 bool NotifySelect(MenuItem selection, Modifiers mods)
809 if(ideSettings.ideProjectFileDialogLocation)
810 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
812 ideProjectFileDialog.text = addProjectFileDialogTitle;
815 if(ideProjectFileDialog.Modal() == ok)
817 if(OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add))
819 if(MessageBox { type = yesNo, master = this, text = $"Error opening project file",
820 contents = $"Add a different project?" }.Modal() == no)
831 MenuItem projectCloseItem
833 projectMenu, $"Close", c, disabled = true;
834 bool NotifySelect(MenuItem selection, Modifiers mods)
838 if(!ide.DontTerminateDebugSession($"Project Close"))
840 if(findInFilesDialog)
841 findInFilesDialog.SearchStop();
842 projectView.visible = false;
843 if(projectView.Destroy(0))
844 MenuWindowCloseAll(null, 0);
846 char workingDir[MAX_LOCATION];
847 GetWorkingDir(workingDir, MAX_LOCATION);
848 findInFilesDialog.currentDirectory = workingDir;
849 ideMainFrame.text = titleECEREIDE;
856 MenuDivider { projectMenu };
857 MenuItem activeCompilerItem
859 projectMenu, $"Active Compiler...", g, /*altF5, */disabled = true;
860 bool NotifySelect(MenuItem selection, Modifiers mods)
862 projectView.MenuCompiler(null, mods);
866 MenuItem projectActiveConfigItem
868 projectMenu, $"Active Configuration...", g, altF5, disabled = true;
869 bool NotifySelect(MenuItem selection, Modifiers mods)
871 projectView.MenuConfig(projectView.active ? selection : null, mods);
875 MenuItem projectSettingsItem
877 projectMenu, $"Settings...", s, altF7, disabled = true;
878 bool NotifySelect(MenuItem selection, Modifiers mods)
880 projectView.MenuSettings(projectView.active ? selection : null, mods);
884 MenuDivider { projectMenu };
885 MenuItem projectBrowseFolderItem
887 projectMenu, $"Browse Project Folder", p, disabled = true;
888 bool NotifySelect(MenuItem selection, Modifiers mods)
891 projectView.MenuBrowseFolder(null, mods);
895 MenuDivider { projectMenu };
896 MenuItem projectRunItem
898 projectMenu, $"Run", r, ctrlF5, disabled = true;
899 bitmap = { ":actions/run.png" };
900 bool NotifySelect(MenuItem selection, Modifiers mods)
903 projectView.Run(null, mods);
907 MenuItem projectBuildItem
909 projectMenu, $"Build", b, f7, disabled = true;
910 bitmap = { ":actions/build.png" };
911 bool NotifySelect(MenuItem selection, Modifiers mods)
914 projectView.ProjectBuild(projectView.active ? selection : null, mods);
918 MenuItem projectLinkItem
920 projectMenu, $"Relink", l, disabled = true;
921 bitmap = { ":actions/relink.png" };
922 bool NotifySelect(MenuItem selection, Modifiers mods)
925 projectView.ProjectLink(projectView.active ? selection : null, mods);
929 MenuItem projectRebuildItem
931 projectMenu, $"Rebuild", d, shiftF7, disabled = true;
932 bitmap = { ":actions/rebuild.png" };
933 bool NotifySelect(MenuItem selection, Modifiers mods)
936 projectView.ProjectRebuild(projectView.active ? selection : null, mods);
940 MenuItem projectCleanItem
942 projectMenu, $"Clean", e, disabled = true;
943 bitmap = { ":actions/clean.png" };
944 bool NotifySelect(MenuItem selection, Modifiers mods)
949 projectView.ProjectClean(projectView.active ? selection : null, mods);
954 MenuItem projectRealCleanItem
956 projectMenu, $"Real Clean", disabled = true;
957 bitmap = { ":actions/clean.png" };
958 bool NotifySelect(MenuItem selection, Modifiers mods)
963 projectView.ProjectRealClean(projectView.active ? selection : null, mods);
968 MenuItem projectRegenerateItem
970 projectMenu, $"Regenerate Makefile", m, disabled = true;
971 bitmap = { ":actions/regMakefile.png" };
972 bool NotifySelect(MenuItem selection, Modifiers mods)
975 projectView.ProjectRegenerate(projectView.active ? selection : null, mods);
979 MenuItem projectCompileItem;
980 Menu debugMenu { menu, $"Debug", d, hasMargin = true };
981 MenuItem debugStartResumeItem
983 debugMenu, $"Start", s, f5, disabled = true;
984 bitmap = { ":actions/debug.png" };
985 NotifySelect = MenuDebugStart;
987 bool MenuDebugStart(MenuItem selection, Modifiers mods)
991 debugStartResumeItem.disabled = true; // a very rare exception to calling AdjustDebugMenus
992 if(!projectView.DebugStart())
993 debugStartResumeItem.disabled = false; // same exception
997 bool MenuDebugResume(MenuItem selection, Modifiers mods)
1000 projectView.DebugResume();
1003 MenuItem debugRestartItem
1005 debugMenu, $"Restart", r, Key { f5, ctrl = true, shift = true }, disabled = true;
1006 bitmap = { ":actions/restart.png" };
1007 bool NotifySelect(MenuItem selection, Modifiers mods)
1010 projectView.DebugRestart();
1014 MenuItem debugBreakItem
1016 debugMenu, $"Break", b, Key { pauseBreak, ctrl = true }, disabled = true;
1017 bitmap = { ":actions/pause.png" };
1018 bool NotifySelect(MenuItem selection, Modifiers mods)
1021 projectView.DebugBreak();
1025 MenuItem debugStopItem
1027 debugMenu, $"Stop", p, shiftF5, disabled = true;
1028 bitmap = { ":actions/stopDebug.png" };
1029 bool NotifySelect(MenuItem selection, Modifiers mods)
1032 projectView.DebugStop();
1036 MenuDivider { debugMenu };
1037 MenuItem debugStepIntoItem
1039 debugMenu, $"Step Into", i, f11, disabled = true;
1040 bitmap = { ":actions/stepInto.png" };
1041 bool NotifySelect(MenuItem selection, Modifiers mods)
1044 projectView.DebugStepInto();
1048 MenuItem debugStepOverItem
1050 debugMenu, $"Step Over", v, f10, disabled = true;
1051 bitmap = { ":actions/stepOver.png" };
1052 bool NotifySelect(MenuItem selection, Modifiers mods)
1055 projectView.DebugStepOver(false);
1059 MenuItem debugStepOutItem
1061 debugMenu, $"Step Out", o, shiftF11, disabled = true;
1062 bitmap = { ":actions/stepOut.png" };
1063 bool NotifySelect(MenuItem selection, Modifiers mods)
1066 projectView.DebugStepOut(false);
1070 MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c };
1071 MenuItem debugSkipStepOverItem
1073 debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
1074 bool NotifySelect(MenuItem selection, Modifiers mods)
1077 projectView.DebugStepOver(true);
1081 MenuItem debugSkipStepOutItem
1083 debugMenu, $"Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
1084 bitmap = { ":actions/skipBreaks.png" };
1085 bool NotifySelect(MenuItem selection, Modifiers mods)
1088 projectView.DebugStepOut(true);
1092 MenuPlacement debugSkipRunToCursorItem { debugMenu, $"Run To Cursor Skipping Breakpoints", u };
1093 //MenuDivider { debugMenu };
1094 //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
1095 MenuPlacement imageMenu { menu, $"Image", i };
1096 Menu viewMenu { menu, $"View", v };
1097 MenuItem viewProjectItem
1099 viewMenu, $"Project View", j, alt0, disabled = true;
1100 bool NotifySelect(MenuItem selection, Modifiers mods)
1104 projectView.visible = true;
1105 projectView.Activate();
1110 MenuPlacement { viewMenu, $"View Designer" };
1111 MenuPlacement { viewMenu, $"View Code" };
1112 MenuPlacement { viewMenu, $"View Properties" };
1113 MenuPlacement { viewMenu, $"View Methods" };
1114 MenuItem viewDesignerItem
1116 viewMenu, $"View Designer", d, f8;
1117 bool NotifySelect(MenuItem selection, Modifiers mods)
1119 Window client = activeClient;
1120 Class dataType = client._class;
1121 if(!strcmp(dataType.name, "Designer"))
1123 client.visible = true;
1127 ((CodeEditor)client).ViewDesigner();
1131 MenuItem viewCodeItem
1133 viewMenu, $"View Code", c, f8;
1134 bool NotifySelect(MenuItem selection, Modifiers mods)
1136 Window client = activeClient;
1137 Class dataType = client._class;
1138 if(!strcmp(dataType.name, "Designer"))
1139 client = ((Designer)client).codeEditor;
1142 // Do this after so the caret isn't moved yet...
1143 client.visible = true;
1147 MenuItem viewPropertiesItem
1149 viewMenu, $"View Properties", p, f4;
1150 bool NotifySelect(MenuItem selection, Modifiers mods)
1152 sheet.visible = true;
1153 sheet.sheetSelected = properties;
1158 MenuItem viewMethodsItem
1160 viewMenu, $"View Methods", m, f4;
1161 bool NotifySelect(MenuItem selection, Modifiers mods)
1163 sheet.visible = true;
1164 sheet.sheetSelected = methods;
1169 MenuItem viewToolBoxItem
1171 viewMenu, $"View Toolbox", x, f12;
1172 bool NotifySelect(MenuItem selection, Modifiers mods)
1174 toolBox.visible = true;
1179 MenuItem viewOutputItem
1181 viewMenu, $"Output", o, alt2;
1182 bool NotifySelect(MenuItem selection, Modifiers mods)
1188 MenuItem viewWatchesItem
1190 viewMenu, $"Watches", w, alt3;
1191 bool NotifySelect(MenuItem selection, Modifiers mods)
1197 MenuItem viewThreadsItem
1199 viewMenu, $"Threads", t, alt4;
1200 bool NotifySelect(MenuItem selection, Modifiers mods)
1206 MenuItem viewBreakpointsItem
1208 viewMenu, $"Breakpoints", b, alt5;
1209 bool NotifySelect(MenuItem selection, Modifiers mods)
1211 breakpointsView.Show();
1215 MenuItem viewCallStackItem
1217 viewMenu, $"Call Stack", s, alt7;
1218 bool NotifySelect(MenuItem selection, Modifiers mods)
1220 callStackView.Show();
1224 MenuItem viewAllDebugViews
1226 viewMenu, $"All Debug Views", a, alt9;
1227 bool NotifySelect(MenuItem selection, Modifiers mods)
1232 callStackView.Show();
1233 breakpointsView.Show();
1237 #ifdef GDB_DEBUG_GUI
1238 MenuDivider { viewMenu };
1239 MenuItem viewGDBItem
1241 viewMenu, $"GDB Dialog", g, Key { f9, shift = true, ctrl = true };
1242 bool NotifySelect(MenuItem selection, Modifiers mods)
1249 MenuDivider { viewMenu };
1250 MenuItem viewColorPicker
1252 viewMenu, $"Color Picker...", c, Key { c, ctrl = true , shift = true };
1253 bool NotifySelect(MenuItem selection, Modifiers mods)
1255 ColorPicker colorPicker { master = this, parent = this, stayOnTop = true };
1256 colorPicker.Create();
1260 MenuDivider { viewMenu };
1264 viewMenu, "Full Screen", f, checkable = true;
1266 bool NotifySelect(MenuItem selection, Modifiers mods)
1268 app.fullScreen ^= true;
1270 anchor = { 0, 0, 0, 0 };
1275 Menu driversMenu { viewMenu, $"Graphics Driver", v };
1276 //Menu skinsMenu { viewMenu, "GUI Skins", k };
1277 Menu windowMenu { menu, $"Window", w };
1278 MenuItem { windowMenu, $"Close All", l, NotifySelect = MenuWindowCloseAll };
1279 MenuDivider { windowMenu };
1280 MenuItem { windowMenu, $"Next", n, f6, NotifySelect = MenuWindowNext };
1281 MenuItem { windowMenu, $"Previous", p, shiftF6, NotifySelect = MenuWindowPrevious };
1282 MenuDivider { windowMenu };
1283 MenuItem { windowMenu, $"Cascade", c, NotifySelect = MenuWindowCascade };
1284 MenuItem { windowMenu, $"Tile Horizontally", h, NotifySelect = MenuWindowTileHorz };
1285 MenuItem { windowMenu, $"Tile Vertically", v, NotifySelect = MenuWindowTileVert };
1286 MenuItem { windowMenu, $"Arrange Icons", a, NotifySelect = MenuWindowArrangeIcons };
1287 MenuDivider { windowMenu };
1288 MenuItem { windowMenu, $"Windows...", w, NotifySelect = MenuWindowWindows };
1289 Menu helpMenu { menu, $"Help", h };
1292 helpMenu, $"API Reference", r, f1;
1293 bool NotifySelect(MenuItem selection, Modifiers mods)
1295 Execute("documentor");
1299 MenuDivider { helpMenu };
1302 helpMenu, $"About...", a;
1303 bool NotifySelect(MenuItem selection, Modifiers mods)
1305 AboutIDE { master = this }.Modal();
1310 property ToolBox toolBox
1312 get { return toolBox; }
1315 property Sheet sheet
1317 get { return sheet; }
1320 property Project project
1322 get { return projectView ? projectView.project : null; }
1325 property Workspace workspace
1327 get { return projectView ? projectView.workspace : null; }
1330 FindInFilesDialog findInFilesDialog
1332 master = this, parent = this;
1333 filters = findInFilesFileFilters.array, sizeFilters = findInFilesFileFilters.count * sizeof(FileFilter);
1337 #ifdef GDB_DEBUG_GUI
1340 master = this, parent = this;
1341 anchor = { left = 100, top = 100, right = 100, bottom = 100 };
1343 void OnCommand(char * string)
1346 ide.debugger.SendGDBCommand(string);
1351 bool NotifySelectDisplayDriver(MenuItem selection, Modifiers mods)
1353 //app.driver = app.drivers[selection.id];
1355 app.driver = selection.id ? "OpenGL" : "X";
1357 app.driver = selection.id ? "OpenGL" : "GDI";
1359 delete ideSettings.displayDriver;
1360 ideSettings.displayDriver = CopyString(selection.id ? "OpenGL" : "Default");
1362 settingsContainer.Save();
1363 //SetDriverAndSkin();
1367 bool NotifySelectDisplaySkin(MenuItem selection, Modifiers mods)
1369 app.skin = app.skins[selection.id];
1374 void SetDriverAndSkin()
1377 for(c = 0; c < app.numSkins; c++)
1378 if(!strcmp(app.skins[c], app.skin))
1380 skinItems[c].checked = true;
1383 for(c = 0; c < app.numDrivers; c++)
1384 if(!strcmp(app.drivers[c], app.driver))
1386 driverItems[c].checked = true;
1391 ProjectView CreateProjectView(Workspace workspace, char * fileName)
1393 Project project = workspace.projects.firstIterator.data;
1394 projectView = ProjectView
1397 fileName = fileName;
1399 void NotifyDestroyed(Window window, DialogResult result)
1402 text = titleECEREIDE;
1407 projectView.Create();
1408 RepositionWindows(false);
1410 // Leave it after Create to avoid flicker due to seeing IDE without a project view
1411 projectView.workspace = workspace;
1412 projectView.project = project;
1413 ideMainFrame.SetText("%s - %s", project.topNode.name, titleECEREIDE);
1417 ide.breakpointsView.LoadFromWorkspace();
1418 ide.watchesView.LoadFromWorkspace();
1420 findInFilesDialog.projectNodeField.userData = projectView;
1423 char fileName[MAX_LOCATION];
1424 strcpy(fileName, project.topNode.path);
1425 PathCat(fileName, project.topNode.name);
1430 bool GetDebugMenusDisabled()
1434 Project project = projectView.project;
1436 if(project.GetTargetType(project.config) == executable)
1443 void RepositionWindows(bool expand)
1448 bool inDebugMode = debugger.isActive;
1449 bool callStackVisible = expand ? false : callStackView.visible;
1450 bool threadsVisible = expand ? false : threadsView.visible;
1451 bool watchesVisible = expand ? false : watchesView.visible;
1452 bool breakpointsVisible = expand ? false : breakpointsView.visible;
1453 bool toolBoxVisible = toolBox.visible;
1454 bool outputVisible = expand ? false : outputView.visible;
1455 int topDistance = (callStackVisible || threadsVisible) ? 200 : 0;
1456 int bottomDistance = (outputVisible || watchesVisible || breakpointsVisible) ? 240 : 0;
1458 for(child = firstChild; child; child = child.next)
1460 if(child._class == class(CodeEditor) || child._class == class(Designer) ||
1461 child._class == class(Sheet) || child._class == class(ProjectView))
1463 Anchor anchor = child.anchor;
1464 anchor.top = topDistance;
1465 anchor.bottom = bottomDistance;
1466 if(child._class == class(CodeEditor) || child._class == class(Designer))
1468 anchor.right = toolBoxVisible ? 150 : 0;
1470 child.anchor = anchor;
1474 if(child._class == class(OutputView) || child._class == class(CallStackView) || child._class == class(ThreadsView) || child._class == class(WatchesView) ||
1475 child._class == class(BreakpointsView))
1476 child.visible = false;
1479 // If this is not here, the IDE is not updated when doing Debug/Break then Alt-4 to show call stack (IDE not updated)
1484 bool ShowCodeEditor()
1487 activeClient.Activate();
1488 else if(projectView)
1490 projectView.visible = true;
1491 projectView.Activate();
1495 sheet.visible = true;
1501 bool ShouldStopBuild()
1503 return projectView.stopBuild;
1506 void DocumentSaved(Window document, char * fileName)
1508 ideSettings.AddRecentFile(fileName);
1509 ide.UpdateRecentMenus();
1510 ide.AdjustFileMenus();
1511 settingsContainer.Save();
1514 bool Window::OnFileModified(FileChange fileChange, char * param)
1517 sprintf(temp, $"The document %s was modified by another application.\n"
1518 "Would you like to reload it and lose your changes?", this.fileName);
1519 if(MessageBox { type = yesNo, master = this/*.parent*/,
1520 text = $"Document has been modified", contents = temp }.Modal() == yes)
1522 char * fileName = CopyString(this.fileName);
1523 WindowState state = this.state;
1524 Anchor anchor = this.anchor;
1525 Size size = this.size;
1527 this.modifiedDocument = false;
1529 this = ide.OpenFile(fileName, normal, true, null, no, normal);
1532 this.anchor = anchor;
1534 this.SetState(state, true, 0);
1542 void UpdateMakefiles()
1546 CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler);
1547 for(prj : workspace.projects)
1548 projectView.ProjectUpdateMakefileForAllConfigs(prj);
1553 void UpdateCompilerConfigs()
1557 CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler);
1558 projectView.ShowOutputBuildLog(true);
1559 projectView.DisplayCompiler(compiler, false);
1560 for(prj : workspace.projects)
1561 projectView.ProjectPrepareCompiler(prj, compiler);
1568 bool unavailable = !project;
1570 projectAddItem.disabled = unavailable;
1571 toolBar.buttonAddProject.disabled = unavailable;
1573 activeCompilerItem.disabled = unavailable;
1574 projectActiveConfigItem.disabled = unavailable;
1575 projectSettingsItem.disabled = unavailable;
1577 projectBrowseFolderItem.disabled = unavailable;
1579 viewProjectItem.disabled = unavailable;
1586 property bool hasOpenedCodeEditors
1591 for(w = firstChild; w; w = w.next)
1592 if(w._class == class(CodeEditor) &&
1593 w.isDocument && !w.closing && w.visible && w.created &&
1594 w.fileName && w.fileName[0])
1600 void AdjustFileMenus()
1602 bool unavailable = project != null || !hasOpenedCodeEditors; // are they supported source code (ec, c, cpp, etc) ?
1604 projectQuickItem.disabled = unavailable;
1607 void AdjustBuildMenus()
1609 bool unavailable = project && projectView.buildInProgress;
1611 projectNewItem.disabled = unavailable;
1612 toolBar.buttonNewProject.disabled = unavailable;
1613 projectOpenItem.disabled = unavailable;
1614 toolBar.buttonOpenProject.disabled = unavailable;
1616 unavailable = !project || projectView.buildInProgress;
1618 projectCloseItem.disabled = unavailable;
1619 // toolBar.buttonCloseProject.disabled = unavailable;
1621 projectRunItem.disabled = unavailable || project.GetTargetType(project.config) != executable;
1622 toolBar.buttonRun.disabled = unavailable || project.GetTargetType(project.config) != executable;
1623 projectBuildItem.disabled = unavailable;
1624 toolBar.buttonBuild.disabled = unavailable;
1625 projectLinkItem.disabled = unavailable;
1626 toolBar.buttonReLink.disabled = unavailable;
1627 projectRebuildItem.disabled = unavailable;
1628 toolBar.buttonRebuild.disabled = unavailable;
1629 projectCleanItem.disabled = unavailable;
1630 toolBar.buttonClean.disabled = unavailable;
1631 projectRealCleanItem.disabled = unavailable;
1632 // toolBar.buttonRealClean.disabled = unavailable;
1633 projectRegenerateItem.disabled = unavailable;
1634 toolBar.buttonRegenerateMakefile.disabled = unavailable;
1635 projectCompileItem.disabled = unavailable;
1637 if(projectView && projectView.popupMenu && projectView.popupMenu.menu && projectView.popupMenu.created)
1640 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectBuild, 0); if(menu) menu.disabled = unavailable;
1641 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectLink, 0); if(menu) menu.disabled = unavailable;
1642 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRebuild, 0); if(menu) menu.disabled = unavailable;
1643 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectClean, 0); if(menu) menu.disabled = unavailable;
1644 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRealClean, 0); if(menu) menu.disabled = unavailable;
1645 menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRegenerate, 0); if(menu) menu.disabled = unavailable;
1646 projectView.popupMenu.Update(null);
1650 void AdjustDebugMenus()
1652 bool unavailable = !project || project.GetTargetType(project.config) != executable ||
1653 projectView.buildInProgress == buildingMainProject;
1654 bool active = ide.debugger.isActive;
1655 bool executing = ide.debugger.state == running;
1656 //bool holding = ide.debugger.state == stopped;
1658 debugStartResumeItem.disabled = unavailable || executing;
1659 debugStartResumeItem.text = active ? $"Resume" : $"Start";
1660 debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart;
1663 toolBar.buttonDebugStartResume.disabled = unavailable || executing;
1664 toolBar.buttonDebugStartResume.toolTip = active ? $"Resume" : $"Start";
1667 debugBreakItem.disabled = unavailable || !executing;
1668 debugStopItem.disabled = unavailable || !active;
1669 debugRestartItem.disabled = unavailable || !active;
1672 toolBar.buttonDebugPause.disabled = unavailable || !executing;
1673 toolBar.buttonDebugStop.disabled = unavailable || !active;
1674 toolBar.buttonDebugRestart.disabled = unavailable || !active;
1677 debugStepIntoItem.disabled = unavailable || executing;
1678 debugStepOverItem.disabled = unavailable || executing;
1679 debugStepOutItem.disabled = unavailable || executing || !active;
1680 debugSkipStepOverItem.disabled = unavailable || executing;
1681 debugSkipStepOutItem.disabled = unavailable || executing || !active;
1684 toolBar.buttonDebugStepInto.disabled = unavailable || executing;
1685 toolBar.buttonDebugStepOver.disabled = unavailable || executing;
1686 toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active;
1687 toolBar.buttonDebugSkipStepOver.disabled = unavailable || executing;
1688 // toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing;
1690 if((Designer)GetActiveDesigner())
1692 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1695 codeEditor.debugRunToCursor.disabled = unavailable || executing;
1696 codeEditor.debugSkipRunToCursor.disabled = unavailable || executing;
1701 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1703 char tempString[MAX_LOCATION];
1704 strcpy(tempString, directory);
1705 if(saveSettings && !projectView)
1707 ideSettings.ideFileDialogLocation = directory;
1708 settingsContainer.Save();
1711 ideFileDialog.currentDirectory = tempString;
1712 codeEditorFileDialog.currentDirectory = tempString;
1713 codeEditorFormFileDialog.currentDirectory = tempString;
1716 void ChangeProjectFileDialogDirectory(char * directory)
1718 ideSettings.ideProjectFileDialogLocation = directory;
1719 settingsContainer.Save();
1722 Window FindWindow(char * filePath)
1724 Window document = null;
1726 // TOCHECK: Do we need to change slashes here?
1727 for(document = firstChild; document; document = document.next)
1729 char * fileName = document.fileName;
1730 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1732 document.visible = true;
1733 document.Activate();
1740 bool DontTerminateDebugSession(char * title)
1742 if(debugger.isActive)
1744 if(MessageBox { type = yesNo, master = ide,
1745 contents = $"Do you want to terminate the debugging session in progress?",
1746 text = title }.Modal() == no)
1749 MessageBox msg { type = yesNo, master = ide,
1750 contents = "Do you want to terminate the debugging session in progress?",
1752 if(msg.Modal() == no)
1764 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1766 char extension[MAX_EXTENSION] = "";
1767 Window document = null;
1768 bool isProject = false;
1769 bool needFileModified = true;
1770 char winFilePath[MAX_LOCATION];
1771 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1775 GetExtension(filePath, extension);
1779 strcpy(extension, type);
1781 if(strcmp(extension, ProjectExtension))
1783 for(document = firstChild; document; document = document.next)
1785 char * fileName = document.fileName;
1786 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1788 document.visible = true;
1790 document.Activate();
1796 if(createIfFails == whatever)
1798 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1800 needFileModified = false;
1801 if(openMethod == normal)
1803 if(DontTerminateDebugSession($"Open Project"))
1806 if(MenuWindowCloseAll(null, 0))
1810 projectView.visible = false;
1811 projectView.Destroy(0);
1812 // Where did this come from? projectView = null;
1819 Workspace workspace = null;
1821 if(FileExists(filePath))
1823 if(!strcmp(extension, ProjectExtension))
1825 char workspaceFile[MAX_LOCATION];
1826 strcpy(workspaceFile, filePath);
1827 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1828 workspace = LoadWorkspace(workspaceFile, filePath);
1830 else if(!strcmp(extension, WorkspaceExtension))
1831 workspace = LoadWorkspace(filePath, null);
1834 //project = LoadProject(filePath);
1839 char absolutePath[MAX_LOCATION];
1840 CreateProjectView(workspace, filePath);
1841 document = projectView;
1843 workspace.DropInvalidBreakpoints();
1846 ide.projectView.ShowOutputBuildLog(true);
1848 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
1849 ide.projectView.DisplayCompiler(compiler, false);
1852 UpdateCompilerConfigs();
1855 char newWorkingDir[MAX_LOCATION];
1856 StripLastDirectory(filePath, newWorkingDir);
1857 ChangeFileDialogsDirectory(newWorkingDir, false);
1860 document.fileName = filePath;
1862 ideMainFrame.SetText("%s - %s", filePath, titleECEREIDE);
1864 // this crashes on starting ide with epj file, solution please?
1865 // app.UpdateDisplay();
1867 workspace.holdTracking = true;
1868 for(ofi : workspace.openedFiles)
1870 if(ofi.state != closed)
1872 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1875 char fileName[MAX_LOCATION];
1877 GetLastDirectory(ofi.path, fileName);
1878 node = projectView.project.topNode.Find(fileName, true);
1880 node.EnsureVisible();
1884 workspace.holdTracking = false;
1886 workspace.timer.Start();
1888 findInFilesDialog.mode = FindInFilesMode::project;
1889 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1892 char location[MAX_LOCATION];
1893 StripLastDirectory(ide.project.topNode.path, location);
1894 ChangeProjectFileDialogDirectory(location);
1898 if(projectView.debugger)
1899 projectView.debugger.EvaluateWatches();
1906 if(MessageBox { type = yesNo, master = this, text = $"Error opening project", contents = $"Open a different project?" }.Modal() == yes)
1908 ideProjectFileDialog.text = openProjectFileDialogTitle;
1909 if(ideProjectFileDialog.Modal() == cancel)
1911 filePath = ideProjectFileDialog.filePath;
1912 GetExtension(filePath, extension);
1923 else if(openMethod == add)
1928 char slashFilePath[MAX_LOCATION];
1929 GetSlashPathBuffer(slashFilePath, filePath);
1930 for(p : workspace.projects)
1932 if(!fstrcmp(p.filePath, slashFilePath))
1940 MessageBox { type = ok, parent = parent, master = this, text = $"Same Project",
1941 contents = $"This project is already present in workspace." }.Modal();
1945 prj = LoadProject(filePath);
1948 CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler);
1949 prj.StartMonitoring();
1950 workspace.projects.Add(prj);
1952 projectView.AddNode(prj.topNode, null);
1953 workspace.modified = true;
1955 findInFilesDialog.AddProjectItem(prj);
1956 projectView.ShowOutputBuildLog(true);
1957 projectView.DisplayCompiler(compiler, false);
1958 projectView.ProjectUpdateMakefileForAllConfigs(prj);
1962 char location[MAX_LOCATION];
1963 StripLastDirectory(prj.topNode.path, location);
1964 ChangeProjectFileDialogDirectory(location);
1967 // projectView is associated with the main project and not with the one just added but
1968 return projectView; // just to let the caller know something was opened
1976 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1977 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1978 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1980 if(FileExists(filePath))
1981 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1982 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1983 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1986 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1989 else if(!strcmp(extension, "3ds"))
1991 if(FileExists(filePath))
1992 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1993 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1994 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1998 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
2001 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
2002 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
2003 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
2004 !strcmp(extension, "css") || !strcmp(extension, "php") ||
2005 !strcmp(extension, "js"))
2007 CodeEditor editor { parent = this, state = state, visible = false };
2008 editor.updatingCode = true;
2009 if(editor.LoadFile(filePath))
2012 editor.visible = true;
2016 needFileModified = false;
2020 CodeEditor editor { parent = this, state = state, visible = false };
2021 if(editor.LoadFile(filePath))
2024 editor.visible = true;
2028 needFileModified = false;
2031 if(document && (document._class == class(PictureEdit) ||
2032 document._class == class(ModelView)))
2037 document.fileName = filePath;
2038 if(workspace && !workspace.holdTracking)
2039 workspace.UpdateOpenedFileInfo(filePath, opened);
2043 if(!document && createIfFails != no)
2045 if(createIfFails != yes && !needFileModified &&
2046 MessageBox { type = yesNo, master = this, text = filePath, contents = $"File doesn't exist. Create?" }.Modal() == yes)
2047 createIfFails = yes;
2048 if(createIfFails == yes || createIfFails == whatever)
2050 document = (Window)NewCodeEditor(this, state, true);
2052 document.fileName = filePath;
2058 if(projectView && document._class == class(CodeEditor) && workspace)
2060 int lineNumber, position;
2062 CodeEditor editor = (CodeEditor)document;
2063 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
2064 editor.openedFileInfo.holdTracking = true;
2065 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
2066 position = Max(editor.openedFileInfo.position - 1, 0);
2067 editor.editBox.GoToLineNum(lineNumber);
2068 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
2069 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
2070 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
2071 editor.editBox.scroll = scroll;
2072 editor.openedFileInfo.holdTracking = false;
2075 if(needFileModified)
2076 document.OnFileModified = OnFileModified;
2077 document.NotifySaved = DocumentSaved;
2080 ideSettings.AddRecentProject(document.fileName);
2082 ideSettings.AddRecentFile(document.fileName);
2083 ide.UpdateRecentMenus();
2084 ide.AdjustFileMenus();
2085 settingsContainer.Save();
2093 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
2094 /*bool Window::GenericDocumentOnClose(bool parentClosing)
2096 if(!parentClosing && ide.workspace)
2097 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2100 bool ModelView::ModelViewOnClose(bool parentClosing)
2102 if(!parentClosing && ide.workspace)
2103 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2106 bool PictureEdit::PictureEditOnClose(bool parentClosing)
2108 if(!parentClosing && ide.workspace)
2109 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2114 void OnUnloadGraphics(Window window)
2116 display.ClearMaterials();
2117 display.ClearTextures();
2118 display.ClearMeshes();
2122 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
2124 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2125 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2129 bool OnKeyDown(Key key, unichar ch)
2134 projectView.Update(null);
2137 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2140 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2146 void GoToError(const char * line)
2149 projectView.GoToError(line);
2152 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
2155 char *colon = strchr(text, ':');
2156 char filePath[MAX_LOCATION];
2157 char completePath[MAX_LOCATION];
2158 int line = 0, col = 0;
2163 char * close = strchr(text, ')');
2167 strncpy(name, &text[4], close - text - 4);
2168 name[close - text - 4] = '\0';
2169 for(p : ide.workspace.projects)
2171 if(!strcmp(p.name, name))
2181 prj = project ? project : (dir ? null : ide.project);
2182 if(colon && (colon[1] == '/' || colon[1] == '\\'))
2184 path = (colon - 1 > path) ? colon - 1 : path;
2185 colon = strstr(colon + 1, ":");
2187 while(isspace(*path)) path++;
2190 strncpy(filePath, path, colon - path);
2191 filePath[colon - path] = '\0';
2192 line = atoi(colon + 1);
2193 colon = strstr(colon + 1, ":");
2195 col = atoi(colon + 1);
2197 else if(path - 1 >= path && *(path - 1) == '\"')
2199 colon = strchr(path, '\"');
2202 strncpy(filePath, path, colon - path);
2203 filePath[colon - path] = '\0';
2208 strcpy(completePath, prj.topNode.path);
2209 else if(dir && dir[0])
2210 strcpy(completePath, dir);
2212 completePath[0] = '\0';
2213 PathCat(completePath, filePath);
2215 if(FileExists(completePath).isFile)
2217 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
2218 if(codeEditor && line)
2220 EditBox editBox = codeEditor.editBox;
2221 editBox.GoToLineNum(line - 1);
2222 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
2227 void OnRedraw(Surface surface)
2229 Bitmap bitmap = back.bitmap;
2231 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
2234 void SheetSelected(SheetType sheetSelected)
2236 if(activeChild == sheet)
2238 if(sheetSelected == methods)
2240 viewPropertiesItem.accelerator = f4;
2241 viewPropertiesItem.parent = viewMenu;
2242 viewMethodsItem.parent = null;
2246 viewMethodsItem.accelerator = f4;
2247 viewMethodsItem.parent = viewMenu;
2248 viewPropertiesItem.parent = null;
2253 viewMethodsItem.parent = viewMenu;
2254 viewPropertiesItem.parent = viewMenu;
2255 if(sheetSelected == methods)
2257 viewMethodsItem.accelerator = f4;
2258 viewPropertiesItem.accelerator = 0;
2262 viewMethodsItem.accelerator = 0;
2263 viewPropertiesItem.accelerator = f4;
2268 void OnActivateClient(Window client, Window previous)
2270 //if(!client || client != previous)
2273 if(!client || client != previous)
2276 dataType = previous._class;
2277 if(previous && !strcmp(dataType.name, "CodeEditor"))
2279 ((CodeEditor)previous).UpdateFormCode();
2281 else if(previous && !strcmp(dataType.name, "Designer"))
2283 ((Designer)previous).codeEditor.UpdateFormCode();
2288 dataType = client._class;
2289 if(client && !strcmp(dataType.name, "CodeEditor"))
2291 CodeEditor codeEditor = (CodeEditor)client;
2292 SetPrivateModule(codeEditor.privateModule);
2293 SetCurrentContext(codeEditor.globalContext);
2294 SetTopContext(codeEditor.globalContext);
2295 SetGlobalContext(codeEditor.globalContext);
2297 SetDefines(&codeEditor.defines);
2298 SetImports(&codeEditor.imports);
2300 SetActiveDesigner(codeEditor.designer);
2302 sheet.codeEditor = codeEditor;
2303 toolBox.codeEditor = codeEditor;
2305 viewDesignerItem.parent = viewMenu;
2306 if(activeChild != codeEditor)
2308 viewCodeItem.parent = viewMenu;
2309 viewDesignerItem.accelerator = 0;
2310 viewCodeItem.accelerator = f8;
2314 viewCodeItem.parent = null;
2315 viewDesignerItem.accelerator = f8;
2318 else if(client && !strcmp(dataType.name, "Designer"))
2320 CodeEditor codeEditor = ((Designer)client).codeEditor;
2323 SetPrivateModule(codeEditor.privateModule);
2324 SetCurrentContext(codeEditor.globalContext);
2325 SetTopContext(codeEditor.globalContext);
2326 SetGlobalContext(codeEditor.globalContext);
2327 SetDefines(&codeEditor.defines);
2328 SetImports(&codeEditor.imports);
2332 SetPrivateModule(null);
2333 SetCurrentContext(null);
2334 SetTopContext(null);
2335 SetGlobalContext(null);
2340 SetActiveDesigner((Designer)client);
2342 sheet.codeEditor = codeEditor;
2343 toolBox.codeEditor = codeEditor;
2345 viewCodeItem.parent = viewMenu;
2346 if(activeChild != client)
2348 viewDesignerItem.parent = viewMenu;
2349 viewDesignerItem.accelerator = f8;
2350 viewCodeItem.accelerator = 0;
2354 viewDesignerItem.parent = null;
2355 viewCodeItem.accelerator = f8;
2361 sheet.codeEditor = null;
2362 toolBox.codeEditor = null;
2363 SetActiveDesigner(null);
2365 viewDesignerItem.parent = null;
2366 viewCodeItem.parent = null;
2369 SheetSelected(sheet.sheetSelected);
2372 projectCompileItem = null;
2377 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2379 CodeEditor codeEditor = (CodeEditor)client;
2380 EditBox editBox = codeEditor.editBox;
2382 statusBar.AddField(pos);
2384 caps = { width = 40, text = $"CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2385 statusBar.AddField(caps);
2387 ovr = { width = 30, text = $"OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2388 statusBar.AddField(ovr);
2390 num = { width = 30, text = $"NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2391 statusBar.AddField(num);
2393 //statusBar.text = "Ready";
2395 if(projectView && projectView.project)
2397 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2401 sprintf(name, $"Compile %s", node.name);
2402 projectCompileItem =
2404 copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress;
2406 bool NotifySelect(MenuItem selection, Modifiers mods)
2410 bool result = false;
2411 ProjectNode node = null;
2412 for(p : ide.workspace.projects)
2414 node = projectView.GetNodeFromWindow(activeClient, p);
2415 if(node && projectView.Compile(node))
2422 ide.outputView.buildBox.Logf($"File %s is excluded from current build configuration.\n", node.name);
2427 projectMenu.AddDynamic(projectCompileItem, ide, false);
2433 caps = ovr = num = null;
2438 bool OnClose(bool parentClosing)
2440 //return !projectView.buildInProgress;
2441 if(projectView && projectView.buildInProgress)
2443 if(DontTerminateDebugSession($"Close IDE"))
2445 if(findInFilesDialog)
2446 findInFilesDialog.SearchStop();
2449 workspace.timer.Stop();
2452 ideMainFrame.Destroy(0);
2459 for(c = 1; c<app.argc; c++)
2461 char fullPath[MAX_LOCATION];
2462 char parentPath[MAX_LOCATION];
2463 char ext[MAX_EXTENSION];
2465 FileAttribs dirAttribs;
2466 GetWorkingDir(fullPath, MAX_LOCATION);
2467 PathCat(fullPath, app.argv[c]);
2468 StripLastDirectory(fullPath, parentPath);
2469 GetExtension(app.argv[c], ext);
2470 isProject = !strcmpi(ext, "epj");
2472 if(isProject && c > 1) continue;
2474 // Create directory for projects (only)
2475 if(((dirAttribs = FileExists(parentPath)) && dirAttribs.isDirectory) || isProject)
2477 if(isProject && !FileExists(fullPath))
2479 // The NewProject will handle directory creation
2480 /*if(!dirAttribs.isDirectory)
2482 MakeDir(parentPath);
2483 dirAttribs = FileExists(parentPath);
2485 if(dirAttribs.isDirectory)*/
2487 char name[MAX_LOCATION];
2488 NewProjectDialog newProjectDialog;
2492 projectView.visible = false;
2493 if(!projectView.Destroy(0))
2497 newProjectDialog = { master = this };
2499 strcpy(name, app.argv[c]);
2500 StripExtension(name);
2501 GetLastDirectory(name, name);
2502 newProjectDialog.projectName.contents = name;
2503 newProjectDialog.projectName.NotifyModified(newProjectDialog, newProjectDialog.projectName);
2504 newProjectDialog.locationEditBox.path = parentPath;
2505 newProjectDialog.NotifyModifiedLocation(newProjectDialog.locationEditBox);
2507 newProjectDialog.Modal();
2510 ideSettings.AddRecentProject(projectView.fileName);
2511 ide.UpdateRecentMenus();
2512 settingsContainer.Save();
2515 // Open only one project
2519 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2527 // IS THIS NEEDED? WASN'T HERE BEFORE... Crashes on getting node's projectView otherwise
2530 projectView.visible = false;
2531 projectView.Destroy(0);
2534 #ifdef GDB_DEBUG_GUI
2535 gdbDialog.Destroy(0);
2540 void SetPath(bool projectsDirs, CompilerConfig compiler, ProjectConfig config)
2544 char * oldPaths[128];
2545 String oldList = new char[maxPathLen];
2546 Array<String> newExePaths { };
2547 //Map<String, bool> exePathExists { };
2549 #if defined(__unix__) || defined(__APPLE__)
2550 Array<String> newLibPaths { };
2551 Map<String, bool> libPathExists { };
2556 for(prj : workspace.projects)
2558 DirExpression targetDirExp;
2560 // SKIP FIRST PROJECT...
2561 if(prj == workspace.projects.firstIterator.data) continue;
2563 // NOTE: Right now the additional project config dir will be
2564 // obtained when the debugger is started, so toggling it
2565 // while building will change which library gets used.
2566 // To go with the initial state, e.g. when F5 was pressed,
2567 // we nould need to keep a list of all project's active
2568 // config upon startup.
2569 targetDirExp = prj.GetTargetDir(compiler, prj.config);
2571 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2575 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2576 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2580 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2581 if(cfg.targetType == sharedLibrary && cfg.debug)
2585 if(targetDirExp.dir)
2587 char buffer[MAX_LOCATION];
2588 #if defined(__WIN32__)
2589 Array<String> paths = newExePaths;
2591 Array<String> paths = newLibPaths;
2593 GetSystemPathBuffer(buffer, prj.topNode.path);
2594 PathCat(buffer, targetDirExp.dir);
2597 if(!fstrcmp(p, buffer))
2604 paths.Add(CopyString(buffer));
2606 delete targetDirExp;
2610 for(item : compiler.executableDirs)
2613 for(p : newExePaths)
2615 if(!fstrcmp(p, item))
2622 newExePaths.Add(CopySystemPath(item));
2625 GetEnvironment("PATH", oldList, maxPathLen);
2627 printf("Old value of PATH: %s\n", oldList);
2629 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2630 for(c = 0; c < count; c++)
2633 for(p : newExePaths)
2635 if(!fstrcmp(p, oldPaths[c]))
2642 newExePaths.Add(CopySystemPath(oldPaths[c]));
2646 for(path : newExePaths)
2647 len += strlen(path) + 1;
2648 newList = new char[len + 1];
2650 for(path : newExePaths)
2652 strcat(newList, path);
2653 strcat(newList, pathListSep);
2655 newList[len - 1] = '\0';
2656 SetEnvironment("PATH", newList);
2658 printf("New value of PATH: %s\n", newList);
2665 #if defined(__unix__) || defined(__APPLE__)
2667 for(item : compiler.libraryDirs)
2669 if(!libPathExists[item]) // fstrcmp should be used
2671 newLibPaths.Add(item);
2672 libPathExists[item] = true;
2676 #if defined(__APPLE__)
2677 GetEnvironment("DYLD_LIBRARY_PATH", oldList, maxPathLen);
2679 GetEnvironment("LD_LIBRARY_PATH", oldList, maxPathLen);
2682 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2684 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2685 for(c = 0; c < count; c++)
2687 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2689 newLibPaths.Add(oldPaths[c]);
2690 libPathExists[oldPaths[c]] = true;
2695 for(path : newLibPaths)
2696 len += strlen(path) + 1;
2697 newList = new char[len + 1];
2699 for(path : newLibPaths)
2701 strcat(newList, path);
2702 strcat(newList, pathListSep);
2704 newList[len - 1] = '\0';
2705 #if defined(__APPLE__)
2706 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2708 SetEnvironment("LD_LIBRARY_PATH", newList);
2711 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2716 delete libPathExists;
2719 if(compiler.distccEnabled && compiler.distccHosts)
2720 SetEnvironment("DISTCC_HOSTS", compiler.distccHosts);
2725 void DestroyTemporaryProjectDir()
2727 if(tmpPrjDir && tmpPrjDir[0])
2729 if(FileExists(tmpPrjDir).isDirectory)
2730 DestroyDir(tmpPrjDir);
2731 property::tmpPrjDir = null;
2737 // Graphics Driver Menu
2741 app.currentSkin.selectionColor = selectionColor;
2742 app.currentSkin.selectionText = selectionText;
2746 driverItems = new MenuItem[app.numDrivers];
2747 for(c = 0; c < app.numDrivers; c++)
2749 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2750 driverItems[c].id = c;
2751 driverItems[c].isRadio = true;
2754 driverItems = new MenuItem[2];
2755 #if defined(__unix__)
2756 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2757 driverItems[0].id = 0;
2758 driverItems[0].isRadio = true;
2760 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2761 driverItems[0].id = 0;
2762 driverItems[0].isRadio = true;
2764 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2765 driverItems[1].id = 1;
2766 driverItems[1].isRadio = true;
2768 /* skinItems = new MenuItem[app.numSkins];
2769 for(c = 0; c < app.numSkins; c++)
2771 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2772 skinItems[c].id = c;
2773 skinItems[c].isRadio = true;
2776 ideFileDialog.master = this;
2777 ideProjectFileDialog.master = this;
2779 //SetDriverAndSkin();
2783 void UpdateRecentMenus()
2786 Menu fileMenu = menu.FindMenu($"File");
2787 Menu recentFiles = fileMenu.FindMenu($"Recent Files");
2788 Menu recentProjects = fileMenu.FindMenu($"Recent Projects");
2789 char itemName[MAX_LOCATION + 4];
2792 recentFiles.Clear();
2795 for(recent : ideSettings.recentFiles)
2797 sprintf(itemName, "%d %s", 1 + c, recent);
2798 MakeSystemPath(itemName);
2799 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, ide, true);
2803 recentProjects.Clear();
2805 for(recent : ideSettings.recentProjects)
2807 sprintf(itemName, "%d %s", 1 + c, recent);
2808 MakeSystemPath(itemName);
2809 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, ide, true);
2822 void DestroyDir(char * path)
2824 RecursiveDeleteFolderFSI fsi { };
2829 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2831 bool preserveRootFolder;
2833 void OutFolder(char * folderPath, bool isRoot)
2835 if(!(preserveRootFolder && isRoot))
2836 RemoveDir(folderPath);
2839 bool OnFile(char * filePath)
2841 DeleteFile(filePath);
2846 class IDEApp : GuiApplication
2848 //driver = "Win32Console";
2849 // driver = "OpenGL";
2854 SetLoggingMode(stdOut, null);
2855 //SetLoggingMode(debug, null);
2857 settingsContainer.Load();
2858 #if defined(__unix__) || defined(__APPLE__)
2859 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2861 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2863 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2867 desktop.text = titleECEREIDE;
2870 for(c = 1; c<app.argc; c++)
2872 char fullPath[MAX_LOCATION];
2873 GetWorkingDir(fullPath, MAX_LOCATION);
2874 PathCat(fullPath, app.argv[c]);
2875 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2882 IDEMainFrame ideMainFrame { };
2884 define app = ((IDEApp)__thisModule);
2886 define titleECEREIDE = $"ECERE IDE (Debug)";
2888 define titleECEREIDE = $"ECERE IDE";