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 menu = projectView.popupMenu.menu.FindItem(ProjectView::FileCompile, 0); if(menu) menu.disabled = unavailable;
1647 projectView.popupMenu.Update(null);
1651 void AdjustDebugMenus()
1653 bool unavailable = !project || project.GetTargetType(project.config) != executable ||
1654 projectView.buildInProgress == buildingMainProject;
1655 bool active = ide.debugger.isActive;
1656 bool executing = ide.debugger.state == running;
1657 //bool holding = ide.debugger.state == stopped;
1659 debugStartResumeItem.disabled = unavailable || executing;
1660 debugStartResumeItem.text = active ? $"Resume" : $"Start";
1661 debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart;
1664 toolBar.buttonDebugStartResume.disabled = unavailable || executing;
1665 toolBar.buttonDebugStartResume.toolTip = active ? $"Resume" : $"Start";
1668 debugBreakItem.disabled = unavailable || !executing;
1669 debugStopItem.disabled = unavailable || !active;
1670 debugRestartItem.disabled = unavailable || !active;
1673 toolBar.buttonDebugPause.disabled = unavailable || !executing;
1674 toolBar.buttonDebugStop.disabled = unavailable || !active;
1675 toolBar.buttonDebugRestart.disabled = unavailable || !active;
1678 debugStepIntoItem.disabled = unavailable || executing;
1679 debugStepOverItem.disabled = unavailable || executing;
1680 debugStepOutItem.disabled = unavailable || executing || !active;
1681 debugSkipStepOverItem.disabled = unavailable || executing;
1682 debugSkipStepOutItem.disabled = unavailable || executing || !active;
1685 toolBar.buttonDebugStepInto.disabled = unavailable || executing;
1686 toolBar.buttonDebugStepOver.disabled = unavailable || executing;
1687 toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active;
1688 toolBar.buttonDebugSkipStepOver.disabled = unavailable || executing;
1689 // toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing;
1691 if((Designer)GetActiveDesigner())
1693 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1696 codeEditor.debugRunToCursor.disabled = unavailable || executing;
1697 codeEditor.debugSkipRunToCursor.disabled = unavailable || executing;
1702 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1704 char tempString[MAX_LOCATION];
1705 strcpy(tempString, directory);
1706 if(saveSettings && !projectView)
1708 ideSettings.ideFileDialogLocation = directory;
1709 settingsContainer.Save();
1712 ideFileDialog.currentDirectory = tempString;
1713 codeEditorFileDialog.currentDirectory = tempString;
1714 codeEditorFormFileDialog.currentDirectory = tempString;
1717 void ChangeProjectFileDialogDirectory(char * directory)
1719 ideSettings.ideProjectFileDialogLocation = directory;
1720 settingsContainer.Save();
1723 Window FindWindow(char * filePath)
1725 Window document = null;
1727 // TOCHECK: Do we need to change slashes here?
1728 for(document = firstChild; document; document = document.next)
1730 char * fileName = document.fileName;
1731 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1733 document.visible = true;
1734 document.Activate();
1741 bool DontTerminateDebugSession(char * title)
1743 if(debugger.isActive)
1745 if(MessageBox { type = yesNo, master = ide,
1746 contents = $"Do you want to terminate the debugging session in progress?",
1747 text = title }.Modal() == no)
1750 MessageBox msg { type = yesNo, master = ide,
1751 contents = "Do you want to terminate the debugging session in progress?",
1753 if(msg.Modal() == no)
1765 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1767 char extension[MAX_EXTENSION] = "";
1768 Window document = null;
1769 bool isProject = false;
1770 bool needFileModified = true;
1771 char winFilePath[MAX_LOCATION];
1772 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1776 GetExtension(filePath, extension);
1780 strcpy(extension, type);
1782 if(strcmp(extension, ProjectExtension))
1784 for(document = firstChild; document; document = document.next)
1786 char * fileName = document.fileName;
1787 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1789 document.visible = true;
1791 document.Activate();
1797 if(createIfFails == whatever)
1799 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1801 needFileModified = false;
1802 if(openMethod == normal)
1804 if(DontTerminateDebugSession($"Open Project"))
1807 if(MenuWindowCloseAll(null, 0))
1811 projectView.visible = false;
1812 projectView.Destroy(0);
1813 // Where did this come from? projectView = null;
1820 Workspace workspace = null;
1822 if(FileExists(filePath))
1824 if(!strcmp(extension, ProjectExtension))
1826 char workspaceFile[MAX_LOCATION];
1827 strcpy(workspaceFile, filePath);
1828 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1829 workspace = LoadWorkspace(workspaceFile, filePath);
1831 else if(!strcmp(extension, WorkspaceExtension))
1832 workspace = LoadWorkspace(filePath, null);
1835 //project = LoadProject(filePath);
1840 char absolutePath[MAX_LOCATION];
1841 CreateProjectView(workspace, filePath);
1842 document = projectView;
1844 workspace.DropInvalidBreakpoints();
1847 ide.projectView.ShowOutputBuildLog(true);
1849 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
1850 ide.projectView.DisplayCompiler(compiler, false);
1853 UpdateCompilerConfigs();
1856 char newWorkingDir[MAX_LOCATION];
1857 StripLastDirectory(filePath, newWorkingDir);
1858 ChangeFileDialogsDirectory(newWorkingDir, false);
1861 document.fileName = filePath;
1863 ideMainFrame.SetText("%s - %s", filePath, titleECEREIDE);
1865 // this crashes on starting ide with epj file, solution please?
1866 // app.UpdateDisplay();
1868 workspace.holdTracking = true;
1869 for(ofi : workspace.openedFiles)
1871 if(ofi.state != closed)
1873 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1876 char fileName[MAX_LOCATION];
1878 GetLastDirectory(ofi.path, fileName);
1879 node = projectView.project.topNode.Find(fileName, true);
1881 node.EnsureVisible();
1885 workspace.holdTracking = false;
1887 workspace.timer.Start();
1889 findInFilesDialog.mode = FindInFilesMode::project;
1890 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1893 char location[MAX_LOCATION];
1894 StripLastDirectory(ide.project.topNode.path, location);
1895 ChangeProjectFileDialogDirectory(location);
1899 if(projectView.debugger)
1900 projectView.debugger.EvaluateWatches();
1907 if(MessageBox { type = yesNo, master = this, text = $"Error opening project", contents = $"Open a different project?" }.Modal() == yes)
1909 ideProjectFileDialog.text = openProjectFileDialogTitle;
1910 if(ideProjectFileDialog.Modal() == cancel)
1912 filePath = ideProjectFileDialog.filePath;
1913 GetExtension(filePath, extension);
1924 else if(openMethod == add)
1929 char slashFilePath[MAX_LOCATION];
1930 GetSlashPathBuffer(slashFilePath, filePath);
1931 for(p : workspace.projects)
1933 if(!fstrcmp(p.filePath, slashFilePath))
1941 MessageBox { type = ok, parent = parent, master = this, text = $"Same Project",
1942 contents = $"This project is already present in workspace." }.Modal();
1946 prj = LoadProject(filePath);
1949 CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler);
1950 prj.StartMonitoring();
1951 workspace.projects.Add(prj);
1953 projectView.AddNode(prj.topNode, null);
1954 workspace.modified = true;
1956 findInFilesDialog.AddProjectItem(prj);
1957 projectView.ShowOutputBuildLog(true);
1958 projectView.DisplayCompiler(compiler, false);
1959 projectView.ProjectUpdateMakefileForAllConfigs(prj);
1963 char location[MAX_LOCATION];
1964 StripLastDirectory(prj.topNode.path, location);
1965 ChangeProjectFileDialogDirectory(location);
1968 // projectView is associated with the main project and not with the one just added but
1969 return projectView; // just to let the caller know something was opened
1977 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1978 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1979 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1981 if(FileExists(filePath))
1982 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1983 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1984 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1987 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
1990 else if(!strcmp(extension, "3ds"))
1992 if(FileExists(filePath))
1993 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1994 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1995 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1999 MessageBox { type = ok, master = this, text = filePath, contents = $"File doesn't exist." }.Modal();
2002 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
2003 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
2004 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
2005 !strcmp(extension, "css") || !strcmp(extension, "php") ||
2006 !strcmp(extension, "js"))
2008 CodeEditor editor { parent = this, state = state, visible = false };
2009 editor.updatingCode = true;
2010 if(editor.LoadFile(filePath))
2013 editor.visible = true;
2017 needFileModified = false;
2021 CodeEditor editor { parent = this, state = state, visible = false };
2022 if(editor.LoadFile(filePath))
2025 editor.visible = true;
2029 needFileModified = false;
2032 if(document && (document._class == class(PictureEdit) ||
2033 document._class == class(ModelView)))
2038 document.fileName = filePath;
2039 if(workspace && !workspace.holdTracking)
2040 workspace.UpdateOpenedFileInfo(filePath, opened);
2044 if(!document && createIfFails != no)
2046 if(createIfFails != yes && !needFileModified &&
2047 MessageBox { type = yesNo, master = this, text = filePath, contents = $"File doesn't exist. Create?" }.Modal() == yes)
2048 createIfFails = yes;
2049 if(createIfFails == yes || createIfFails == whatever)
2051 document = (Window)NewCodeEditor(this, state, true);
2053 document.fileName = filePath;
2059 if(projectView && document._class == class(CodeEditor) && workspace)
2061 int lineNumber, position;
2063 CodeEditor editor = (CodeEditor)document;
2064 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
2065 editor.openedFileInfo.holdTracking = true;
2066 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
2067 position = Max(editor.openedFileInfo.position - 1, 0);
2068 editor.editBox.GoToLineNum(lineNumber);
2069 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
2070 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
2071 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
2072 editor.editBox.scroll = scroll;
2073 editor.openedFileInfo.holdTracking = false;
2076 if(needFileModified)
2077 document.OnFileModified = OnFileModified;
2078 document.NotifySaved = DocumentSaved;
2081 ideSettings.AddRecentProject(document.fileName);
2083 ideSettings.AddRecentFile(document.fileName);
2084 ide.UpdateRecentMenus();
2085 ide.AdjustFileMenus();
2086 settingsContainer.Save();
2094 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
2095 /*bool Window::GenericDocumentOnClose(bool parentClosing)
2097 if(!parentClosing && ide.workspace)
2098 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2101 bool ModelView::ModelViewOnClose(bool parentClosing)
2103 if(!parentClosing && ide.workspace)
2104 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2107 bool PictureEdit::PictureEditOnClose(bool parentClosing)
2109 if(!parentClosing && ide.workspace)
2110 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
2115 void OnUnloadGraphics(Window window)
2117 display.ClearMaterials();
2118 display.ClearTextures();
2119 display.ClearMeshes();
2123 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
2125 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2126 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2130 bool OnKeyDown(Key key, unichar ch)
2135 projectView.Update(null);
2138 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
2141 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
2147 void GoToError(const char * line)
2150 projectView.GoToError(line);
2153 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
2156 char *colon = strchr(text, ':');
2157 char filePath[MAX_LOCATION];
2158 char completePath[MAX_LOCATION];
2159 int line = 0, col = 0;
2164 char * close = strchr(text, ')');
2168 strncpy(name, &text[4], close - text - 4);
2169 name[close - text - 4] = '\0';
2170 for(p : ide.workspace.projects)
2172 if(!strcmp(p.name, name))
2182 prj = project ? project : (dir ? null : ide.project);
2183 if(colon && (colon[1] == '/' || colon[1] == '\\'))
2185 path = (colon - 1 > path) ? colon - 1 : path;
2186 colon = strstr(colon + 1, ":");
2188 while(isspace(*path)) path++;
2191 strncpy(filePath, path, colon - path);
2192 filePath[colon - path] = '\0';
2193 line = atoi(colon + 1);
2194 colon = strstr(colon + 1, ":");
2196 col = atoi(colon + 1);
2198 else if(path - 1 >= path && *(path - 1) == '\"')
2200 colon = strchr(path, '\"');
2203 strncpy(filePath, path, colon - path);
2204 filePath[colon - path] = '\0';
2209 strcpy(completePath, prj.topNode.path);
2210 else if(dir && dir[0])
2211 strcpy(completePath, dir);
2213 completePath[0] = '\0';
2214 PathCat(completePath, filePath);
2216 if(FileExists(completePath).isFile)
2218 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
2219 if(codeEditor && line)
2221 EditBox editBox = codeEditor.editBox;
2222 editBox.GoToLineNum(line - 1);
2223 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
2228 void OnRedraw(Surface surface)
2230 Bitmap bitmap = back.bitmap;
2232 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
2235 void SheetSelected(SheetType sheetSelected)
2237 if(activeChild == sheet)
2239 if(sheetSelected == methods)
2241 viewPropertiesItem.accelerator = f4;
2242 viewPropertiesItem.parent = viewMenu;
2243 viewMethodsItem.parent = null;
2247 viewMethodsItem.accelerator = f4;
2248 viewMethodsItem.parent = viewMenu;
2249 viewPropertiesItem.parent = null;
2254 viewMethodsItem.parent = viewMenu;
2255 viewPropertiesItem.parent = viewMenu;
2256 if(sheetSelected == methods)
2258 viewMethodsItem.accelerator = f4;
2259 viewPropertiesItem.accelerator = 0;
2263 viewMethodsItem.accelerator = 0;
2264 viewPropertiesItem.accelerator = f4;
2269 void OnActivateClient(Window client, Window previous)
2271 //if(!client || client != previous)
2274 if(!client || client != previous)
2277 dataType = previous._class;
2278 if(previous && !strcmp(dataType.name, "CodeEditor"))
2280 ((CodeEditor)previous).UpdateFormCode();
2282 else if(previous && !strcmp(dataType.name, "Designer"))
2284 ((Designer)previous).codeEditor.UpdateFormCode();
2289 dataType = client._class;
2290 if(client && !strcmp(dataType.name, "CodeEditor"))
2292 CodeEditor codeEditor = (CodeEditor)client;
2293 SetPrivateModule(codeEditor.privateModule);
2294 SetCurrentContext(codeEditor.globalContext);
2295 SetTopContext(codeEditor.globalContext);
2296 SetGlobalContext(codeEditor.globalContext);
2298 SetDefines(&codeEditor.defines);
2299 SetImports(&codeEditor.imports);
2301 SetActiveDesigner(codeEditor.designer);
2303 sheet.codeEditor = codeEditor;
2304 toolBox.codeEditor = codeEditor;
2306 viewDesignerItem.parent = viewMenu;
2307 if(activeChild != codeEditor)
2309 viewCodeItem.parent = viewMenu;
2310 viewDesignerItem.accelerator = 0;
2311 viewCodeItem.accelerator = f8;
2315 viewCodeItem.parent = null;
2316 viewDesignerItem.accelerator = f8;
2319 else if(client && !strcmp(dataType.name, "Designer"))
2321 CodeEditor codeEditor = ((Designer)client).codeEditor;
2324 SetPrivateModule(codeEditor.privateModule);
2325 SetCurrentContext(codeEditor.globalContext);
2326 SetTopContext(codeEditor.globalContext);
2327 SetGlobalContext(codeEditor.globalContext);
2328 SetDefines(&codeEditor.defines);
2329 SetImports(&codeEditor.imports);
2333 SetPrivateModule(null);
2334 SetCurrentContext(null);
2335 SetTopContext(null);
2336 SetGlobalContext(null);
2341 SetActiveDesigner((Designer)client);
2343 sheet.codeEditor = codeEditor;
2344 toolBox.codeEditor = codeEditor;
2346 viewCodeItem.parent = viewMenu;
2347 if(activeChild != client)
2349 viewDesignerItem.parent = viewMenu;
2350 viewDesignerItem.accelerator = f8;
2351 viewCodeItem.accelerator = 0;
2355 viewDesignerItem.parent = null;
2356 viewCodeItem.accelerator = f8;
2362 sheet.codeEditor = null;
2363 toolBox.codeEditor = null;
2364 SetActiveDesigner(null);
2366 viewDesignerItem.parent = null;
2367 viewCodeItem.parent = null;
2370 SheetSelected(sheet.sheetSelected);
2373 projectCompileItem = null;
2378 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2380 CodeEditor codeEditor = (CodeEditor)client;
2381 EditBox editBox = codeEditor.editBox;
2383 statusBar.AddField(pos);
2385 caps = { width = 40, text = $"CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2386 statusBar.AddField(caps);
2388 ovr = { width = 30, text = $"OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2389 statusBar.AddField(ovr);
2391 num = { width = 30, text = $"NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2392 statusBar.AddField(num);
2394 //statusBar.text = "Ready";
2396 if(projectView && projectView.project)
2398 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2402 sprintf(name, $"Compile %s", node.name);
2403 projectCompileItem =
2405 copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress;
2407 bool NotifySelect(MenuItem selection, Modifiers mods)
2411 bool result = false;
2412 ProjectNode node = null;
2413 for(p : ide.workspace.projects)
2415 node = projectView.GetNodeFromWindow(activeClient, p);
2416 if(node && projectView.Compile(node))
2423 ide.outputView.buildBox.Logf($"File %s is excluded from current build configuration.\n", node.name);
2428 projectMenu.AddDynamic(projectCompileItem, ide, false);
2434 caps = ovr = num = null;
2439 bool OnClose(bool parentClosing)
2441 //return !projectView.buildInProgress;
2442 if(projectView && projectView.buildInProgress)
2444 if(DontTerminateDebugSession($"Close IDE"))
2446 if(findInFilesDialog)
2447 findInFilesDialog.SearchStop();
2450 workspace.timer.Stop();
2453 ideMainFrame.Destroy(0);
2460 for(c = 1; c<app.argc; c++)
2462 char fullPath[MAX_LOCATION];
2463 char parentPath[MAX_LOCATION];
2464 char ext[MAX_EXTENSION];
2466 FileAttribs dirAttribs;
2467 GetWorkingDir(fullPath, MAX_LOCATION);
2468 PathCat(fullPath, app.argv[c]);
2469 StripLastDirectory(fullPath, parentPath);
2470 GetExtension(app.argv[c], ext);
2471 isProject = !strcmpi(ext, "epj");
2473 if(isProject && c > 1) continue;
2475 // Create directory for projects (only)
2476 if(((dirAttribs = FileExists(parentPath)) && dirAttribs.isDirectory) || isProject)
2478 if(isProject && !FileExists(fullPath))
2480 // The NewProject will handle directory creation
2481 /*if(!dirAttribs.isDirectory)
2483 MakeDir(parentPath);
2484 dirAttribs = FileExists(parentPath);
2486 if(dirAttribs.isDirectory)*/
2488 char name[MAX_LOCATION];
2489 NewProjectDialog newProjectDialog;
2493 projectView.visible = false;
2494 if(!projectView.Destroy(0))
2498 newProjectDialog = { master = this };
2500 strcpy(name, app.argv[c]);
2501 StripExtension(name);
2502 GetLastDirectory(name, name);
2503 newProjectDialog.projectName.contents = name;
2504 newProjectDialog.projectName.NotifyModified(newProjectDialog, newProjectDialog.projectName);
2505 newProjectDialog.locationEditBox.path = parentPath;
2506 newProjectDialog.NotifyModifiedLocation(newProjectDialog.locationEditBox);
2508 newProjectDialog.Modal();
2511 ideSettings.AddRecentProject(projectView.fileName);
2512 ide.UpdateRecentMenus();
2513 settingsContainer.Save();
2516 // Open only one project
2520 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2528 // IS THIS NEEDED? WASN'T HERE BEFORE... Crashes on getting node's projectView otherwise
2531 projectView.visible = false;
2532 projectView.Destroy(0);
2535 #ifdef GDB_DEBUG_GUI
2536 gdbDialog.Destroy(0);
2541 void SetPath(bool projectsDirs, CompilerConfig compiler, ProjectConfig config)
2545 char * oldPaths[128];
2546 String oldList = new char[maxPathLen];
2547 Array<String> newExePaths { };
2548 //Map<String, bool> exePathExists { };
2550 #if defined(__unix__) || defined(__APPLE__)
2551 Array<String> newLibPaths { };
2552 Map<String, bool> libPathExists { };
2557 for(prj : workspace.projects)
2559 DirExpression targetDirExp;
2561 // SKIP FIRST PROJECT...
2562 if(prj == workspace.projects.firstIterator.data) continue;
2564 // NOTE: Right now the additional project config dir will be
2565 // obtained when the debugger is started, so toggling it
2566 // while building will change which library gets used.
2567 // To go with the initial state, e.g. when F5 was pressed,
2568 // we nould need to keep a list of all project's active
2569 // config upon startup.
2570 targetDirExp = prj.GetTargetDir(compiler, prj.config);
2572 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2576 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2577 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2581 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2582 if(cfg.targetType == sharedLibrary && cfg.debug)
2586 if(targetDirExp.dir)
2588 char buffer[MAX_LOCATION];
2589 #if defined(__WIN32__)
2590 Array<String> paths = newExePaths;
2592 Array<String> paths = newLibPaths;
2594 GetSystemPathBuffer(buffer, prj.topNode.path);
2595 PathCat(buffer, targetDirExp.dir);
2598 if(!fstrcmp(p, buffer))
2605 paths.Add(CopyString(buffer));
2607 delete targetDirExp;
2611 for(item : compiler.executableDirs)
2614 for(p : newExePaths)
2616 if(!fstrcmp(p, item))
2623 newExePaths.Add(CopySystemPath(item));
2626 GetEnvironment("PATH", oldList, maxPathLen);
2628 printf("Old value of PATH: %s\n", oldList);
2630 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2631 for(c = 0; c < count; c++)
2634 for(p : newExePaths)
2636 if(!fstrcmp(p, oldPaths[c]))
2643 newExePaths.Add(CopySystemPath(oldPaths[c]));
2647 for(path : newExePaths)
2648 len += strlen(path) + 1;
2649 newList = new char[len + 1];
2651 for(path : newExePaths)
2653 strcat(newList, path);
2654 strcat(newList, pathListSep);
2656 newList[len - 1] = '\0';
2657 SetEnvironment("PATH", newList);
2659 printf("New value of PATH: %s\n", newList);
2666 #if defined(__unix__) || defined(__APPLE__)
2668 for(item : compiler.libraryDirs)
2670 if(!libPathExists[item]) // fstrcmp should be used
2672 newLibPaths.Add(item);
2673 libPathExists[item] = true;
2677 #if defined(__APPLE__)
2678 GetEnvironment("DYLD_LIBRARY_PATH", oldList, maxPathLen);
2680 GetEnvironment("LD_LIBRARY_PATH", oldList, maxPathLen);
2683 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2685 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2686 for(c = 0; c < count; c++)
2688 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2690 newLibPaths.Add(oldPaths[c]);
2691 libPathExists[oldPaths[c]] = true;
2696 for(path : newLibPaths)
2697 len += strlen(path) + 1;
2698 newList = new char[len + 1];
2700 for(path : newLibPaths)
2702 strcat(newList, path);
2703 strcat(newList, pathListSep);
2705 newList[len - 1] = '\0';
2706 #if defined(__APPLE__)
2707 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2709 SetEnvironment("LD_LIBRARY_PATH", newList);
2712 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2717 delete libPathExists;
2720 if(compiler.distccEnabled && compiler.distccHosts)
2721 SetEnvironment("DISTCC_HOSTS", compiler.distccHosts);
2726 void DestroyTemporaryProjectDir()
2728 if(tmpPrjDir && tmpPrjDir[0])
2730 if(FileExists(tmpPrjDir).isDirectory)
2731 DestroyDir(tmpPrjDir);
2732 property::tmpPrjDir = null;
2738 // Graphics Driver Menu
2742 app.currentSkin.selectionColor = selectionColor;
2743 app.currentSkin.selectionText = selectionText;
2747 driverItems = new MenuItem[app.numDrivers];
2748 for(c = 0; c < app.numDrivers; c++)
2750 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2751 driverItems[c].id = c;
2752 driverItems[c].isRadio = true;
2755 driverItems = new MenuItem[2];
2756 #if defined(__unix__)
2757 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2758 driverItems[0].id = 0;
2759 driverItems[0].isRadio = true;
2761 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2762 driverItems[0].id = 0;
2763 driverItems[0].isRadio = true;
2765 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2766 driverItems[1].id = 1;
2767 driverItems[1].isRadio = true;
2769 /* skinItems = new MenuItem[app.numSkins];
2770 for(c = 0; c < app.numSkins; c++)
2772 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2773 skinItems[c].id = c;
2774 skinItems[c].isRadio = true;
2777 ideFileDialog.master = this;
2778 ideProjectFileDialog.master = this;
2780 //SetDriverAndSkin();
2784 void UpdateRecentMenus()
2787 Menu fileMenu = menu.FindMenu($"File");
2788 Menu recentFiles = fileMenu.FindMenu($"Recent Files");
2789 Menu recentProjects = fileMenu.FindMenu($"Recent Projects");
2790 char itemName[MAX_LOCATION + 4];
2793 recentFiles.Clear();
2796 for(recent : ideSettings.recentFiles)
2798 sprintf(itemName, "%d %s", 1 + c, recent);
2799 MakeSystemPath(itemName);
2800 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, ide, true);
2804 recentProjects.Clear();
2806 for(recent : ideSettings.recentProjects)
2808 sprintf(itemName, "%d %s", 1 + c, recent);
2809 MakeSystemPath(itemName);
2810 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, ide, true);
2823 void DestroyDir(char * path)
2825 RecursiveDeleteFolderFSI fsi { };
2830 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2832 bool preserveRootFolder;
2834 void OutFolder(char * folderPath, bool isRoot)
2836 if(!(preserveRootFolder && isRoot))
2837 RemoveDir(folderPath);
2840 bool OnFile(char * filePath)
2842 DeleteFile(filePath);
2847 class IDEApp : GuiApplication
2849 //driver = "Win32Console";
2850 // driver = "OpenGL";
2855 SetLoggingMode(stdOut, null);
2856 //SetLoggingMode(debug, null);
2858 settingsContainer.Load();
2859 #if defined(__unix__) || defined(__APPLE__)
2860 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2862 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2864 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2868 desktop.text = titleECEREIDE;
2871 for(c = 1; c<app.argc; c++)
2873 char fullPath[MAX_LOCATION];
2874 GetWorkingDir(fullPath, MAX_LOCATION);
2875 PathCat(fullPath, app.argv[c]);
2876 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2883 IDEMainFrame ideMainFrame { };
2885 define app = ((IDEApp)__thisModule);
2887 define titleECEREIDE = $"ECERE IDE (Debug)";
2889 define titleECEREIDE = $"ECERE IDE";