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 enum OpenCreateIfFails { no, yes, something, whatever };
56 enum OpenMethod { normal, add };
58 static FileFilter fileFilters[] =
61 "C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)",
62 "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx"
65 "Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)",
69 "C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)",
73 "Text files (*.txt, *.text, *.nfo, *.info)",
74 "txt, text, nfo, info"
77 "Web files (*.html, *.htm, *.xhtml, *.css, *.php, *.js, *.jsi, *.rb, *.xml)",
78 "html, htm, xhtml, css, php, js, jsi, rb, xml"
81 "Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)",
82 "jpg, jpeg, bmp, pcx, png, gif"
85 "3D Studio Model Files (*.3ds)",
91 static FileType fileTypes[] =
93 { "Based on extension", null },
96 { "3D Studio Model", "3ds" }
99 static FileFilter projectFilters[] =
102 "Project Files (*.epj)",
107 static FileType projectTypes[] =
109 { "Project File", ProjectExtension },
112 static FileFilter findInFilesFileFilters[] =
115 "eC Files (*.ec, *.eh)",
119 "C/C++/eC Files (*.ec, *.eh, *.c, *.cpp, *.cc, *.cxx, *.h, *.hpp, *.hh, *.hxx)",
120 "ec, eh, c, cpp, cc, cxx, h, hpp, hh, hxx"
123 "Header Files for eC/C/C++ (*.eh, *.h, *.hpp, *.hh, *.hxx)",
124 "eh, h, hpp, hh, hxx"
127 "C/C++/eC Source Files (*.ec, *.c, *.cpp, *.cc, *.cxx)",
128 "ec, c, cpp, cc, cxx"
131 "Text files (*.txt)",
134 { "All files", null }
137 FileDialog ideFileDialog
139 type = multiOpen, text = "Open";
140 types = fileTypes, sizeTypes = sizeof(fileTypes), filters = fileFilters, sizeFilters = sizeof(fileFilters);
143 FileDialog ideProjectFileDialog
145 type = open, text = "Open Project";
146 types = projectTypes, sizeTypes = sizeof(projectTypes), filters = projectFilters, sizeFilters = sizeof(projectFilters);
149 GlobalSettingsDialog globalSettingsDialog
151 ideSettings = ideSettings;
152 settingsContainer = settingsContainer;
154 void OnGlobalSettingChange(GlobalSettingsChange globalSettingsChange)
156 switch(globalSettingsChange)
161 for(child = ide.firstChild; child; child = child.next)
163 if(child._class == class(CodeEditor))
165 CodeEditor codeEditor = (CodeEditor) child;
166 codeEditor.editBox.freeCaret = ideSettings.useFreeCaret;
167 // codeEditor.editBox.lineNumbers = ideSettings.showLineNumbers;
168 codeEditor.editBox.caretFollowsScrolling = ideSettings.caretFollowsScrolling;
169 codeEditor.OnPostCreate(); // Update editBox margin size
176 case compilerSettings:
178 ide.UpdateMakefiles();
185 void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int lineH, int scrollY, int boxH)
190 lineY = (line - 1) * lineH;
191 if(lineY + lineH > scrollY && lineY + lineH < scrollY + boxH)
193 Bitmap bitmap = resource.bitmap;
195 surface.Blit(bitmap, 0, lineY - scrollY + (lineH - bitmap.height) / 2 + 1, 0, 0, bitmap.width, bitmap.height);
202 //nativeDecorations = true;
203 icon = { ":icon.png" };
204 text = titleECEREIDE;
205 background = Color { 85, 85, 85 };
206 borderStyle = sizable;
211 hasVertScroll = true;
212 hasHorzScroll = true;
218 anchor = { top = 0, right = 0, bottom = 0 };
221 anchor = { left = 0, top = 0, right = 0, bottom = 0 };
225 MenuItem * driverItems, * skinItems;
226 StatusField pos { width = 150 };
227 StatusField ovr, caps, num;
229 BitmapResource back { ":ecereBack.jpg", window = this };
230 BitmapResource bmpBp { ":codeMarks/breakpoint.png", window = this };
231 BitmapResource bmpBpDisabled { ":codeMarks/breakpointDisabled.png", window = this };
232 BitmapResource bmpBpHalf { ":codeMarks/breakpointHalf.png", window = this };
233 BitmapResource bmpBpHalfDisabled { ":codeMarks/breakpointHalfDisabled.png", window = this };
234 BitmapResource bmpCursor { ":codeMarks/cursor.png", window = this };
235 BitmapResource bmpCursorError { ":codeMarks/cursorError.png", window = this };
236 BitmapResource bmpTopFrame { ":codeMarks/topFrame.png", window = this };
237 BitmapResource bmpTopFrameError { ":codeMarks/topFrameError.png", window = this };
238 BitmapResource bmpTopFrameHalf { ":codeMarks/topFrameHalf.png", window = this };
239 BitmapResource bmpTopFrameHalfError { ":codeMarks/topFrameHalfError.png", window = this };
241 FontResource font { "Courier New", 10 };
243 Debugger debugger { };
245 ProjectView projectView;
247 OutputView outputView
251 void OnGotoError(char * line)
256 void OnCodeLocationParseAndGoTo(char * line)
258 ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir);
261 bool OnKeyDown(Key key, unichar ch)
266 if(!ide.findInFilesDialog || !ide.findInFilesDialog.SearchAbort())
267 ide.ShowCodeEditor();
270 ide.projectView.stopBuild = true;
274 OutputView::OnKeyDown(key, ch);
281 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
284 ide.RepositionWindows(false);
288 bool OnClose(bool parentClosing)
292 ide.RepositionWindows(false);
293 return parentClosing;
297 CallStackView callStackView
299 parent = this, font = font;
301 void OnGotoLine(char * line)
304 stackLvl = atoi(line);
305 ide.debugger.GoToStackFrameLine(stackLvl, true);
308 void OnSelectFrame(int lineNumber)
310 ide.debugger.SelectFrame(lineNumber);
313 void OnToggleBreakpoint()
315 Debugger debugger = ide.debugger;
316 if(debugger.activeFrame && debugger.activeFrame.absoluteFile)
318 int line = debugger.activeFrame.line;
319 char name[MAX_LOCATION];
321 // TOFIX: Improve on this, don't use only filename, make a function
322 GetLastDirectory(debugger.activeFrame.absoluteFile, name);
323 if(ide && ide.workspace)
325 for(p : ide.workspace.projects)
327 if(p.topNode.Find(name, false))
335 for(p : ide.workspace.projects)
337 if(eString_PathInsideOf(debugger.activeFrame.absoluteFile, p.topNode.path))
345 debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line, prj);
348 CodeEditor codeEditor = (CodeEditor)ide.FindWindow(debugger.activeFrame.absoluteFile);
349 if(codeEditor) { codeEditor.Update(null); Activate(); }
354 bool OnKeyDown(Key key, unichar ch)
358 case escape: ide.ShowCodeEditor(); break;
363 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
366 ide.RepositionWindows(false);
370 bool OnClose(bool parentClosing)
374 ide.RepositionWindows(false);
375 return parentClosing;
378 void OnRedraw(Surface surface)
381 int lineCursor, lineTopFrame, activeThread, hitThread;
382 int lineH, scrollY, boxH;
384 Breakpoint bp = null;
385 Debugger debugger = ide.debugger;
386 Frame activeFrame = debugger.activeFrame;
389 scrollY = editBox.scroll.y;
390 displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
392 activeThread = debugger.activeThread;
393 hitThread = debugger.hitThread;
394 debugger.GetCallStackCursorLine(&error, &lineCursor, &lineTopFrame);
396 if(activeFrame && activeFrame.absoluteFile)
398 for(i : ide.workspace.breakpoints; i.type == user)
400 if(i.absoluteFilePath && i.absoluteFilePath[0] &&
401 !fstrcmp(i.absoluteFilePath, activeFrame.absoluteFile) &&
402 activeFrame.line == i.line)
411 DrawLineMarginIcon(surface,
412 /*(lineCursor == 1 || lineTopFrame == 1) ? */ide.bmpBpHalf/* : ide.bmpBp*/,
413 lineCursor /*1*/, lineH, scrollY, boxH);
416 if(activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
417 DrawLineMarginIcon(surface,
418 (lineCursor == 1 || lineTopFrame == 1) ? ide.bmpBpHalf : ide.bmpBp,
419 1, lineH, scrollY, boxH);
421 DrawLineMarginIcon(surface, error ? ide.bmpCursorError : ide.bmpCursor, lineCursor, lineH, scrollY, boxH);
422 if(bp && lineCursor == 1) //activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
423 bmp = error ? ide.bmpTopFrameHalfError : ide.bmpTopFrameHalf;
425 bmp = error ? ide.bmpTopFrameError : ide.bmpTopFrame;
426 DrawLineMarginIcon(surface, bmp, lineTopFrame, lineH, scrollY, boxH);
427 if(editBox.horzScroll && editBox.horzScroll.visible)
429 surface.SetBackground(control);
430 surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
435 WatchesView watchesView { parent = this };
436 ThreadsView threadsView
438 parent = this, font = font;
440 bool OnKeyDown(Key key, unichar ch)
444 case escape: ide.ShowCodeEditor(); break;
449 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
452 ide.RepositionWindows(false);
456 bool OnClose(bool parentClosing)
460 ide.RepositionWindows(false);
461 return parentClosing;
464 void OnSelectThread(int threadId)
467 ide.debugger.SelectThread(threadId);
470 bool OnGetThreadsInfo(int * activeThread, int * hitThread, int * signalThread)
473 Debugger debugger = ide.debugger;
474 *activeThread = debugger.activeThread;
475 *hitThread = debugger.hitThread;
476 *signalThread = debugger.signalThread;
481 BreakpointsView breakpointsView { parent = this };
483 ToolBox toolBox { parent = this };
484 Sheet sheet { parent = this };
487 property char * tmpPrjDir { set { delete tmpPrjDir; if(value) tmpPrjDir = CopyString(value); } get { return tmpPrjDir; } };
489 Menu fileMenu { menu, "File", f };
492 fileMenu, "New", n, ctrlN;
493 bool NotifySelect(MenuItem selection, Modifiers mods)
495 Window document = (Window)NewCodeEditor(this, normal, false);
496 document.NotifySaved = DocumentSaved;
500 MenuItem fileOpenItem
502 fileMenu, "Open...", o, ctrlO;
503 bool NotifySelect(MenuItem selection, Modifiers mods)
505 if(!projectView && ideSettings.ideFileDialogLocation)
506 ideFileDialog.currentDirectory = ideSettings.ideFileDialogLocation;
509 if(ideFileDialog.Modal() == ok)
511 bool gotWhatWeWant = false;
513 int numSelections = ideFileDialog.numSelections;
514 char ** multiFilePaths = ideFileDialog.multiFilePaths;
516 for(c = 0; c < numSelections; c++)
518 if(OpenFile(multiFilePaths[c], normal, true, fileTypes[ideFileDialog.fileType].typeExtension, no, normal))
519 gotWhatWeWant = true;
522 MessageBox { type = yesNo, master = this, text = "Error opening file",
523 contents = "Open a different file?" }.Modal() == no)
525 if(!projectView && gotWhatWeWant)
526 ChangeFileDialogsDirectory(ideFileDialog.currentDirectory, true);
536 MenuItem fileCloseItem { fileMenu, "Close", c, ctrlF4, NotifySelect = MenuFileClose };
537 MenuDivider { fileMenu };
538 MenuItem fileSaveItem { fileMenu, "Save", s, ctrlS };
539 MenuItem fileSaveAsItem { fileMenu, "Save As...", a };
540 MenuItem fileSaveAllItem { fileMenu, "Save All", l, NotifySelect = MenuFileSaveAll };
541 MenuDivider { fileMenu };
544 fileMenu, "Find In Files...", f, Key { f, ctrl = true , shift = true };
545 bool NotifySelect(MenuItem selection, Modifiers mods)
547 findInFilesDialog.replaceMode = false;
548 findInFilesDialog.Show();
552 MenuItem replaceInFiles
554 fileMenu, "Replace In Files...", e, Key { r, ctrl = true , shift = true };
555 bool NotifySelect(MenuItem selection, Modifiers mods)
557 findInFilesDialog.replaceMode = true;
558 findInFilesDialog.Show();
562 MenuDivider { fileMenu };
563 MenuItem globalSettingsItem
565 fileMenu, "Global Settings...", g;
566 bool NotifySelect(MenuItem selection, Modifiers mods)
568 globalSettingsDialog.master = this;
569 if(ide.workspace && ide.workspace.compiler)
570 globalSettingsDialog.workspaceActiveCompiler = ide.workspace.compiler;
571 else if(ideSettings.defaultCompiler)
572 globalSettingsDialog.workspaceActiveCompiler = ideSettings.defaultCompiler;
573 globalSettingsDialog.Modal();
577 MenuDivider { fileMenu };
578 Menu recentFiles { fileMenu, "Recent Files", r };
579 Menu recentProjects { fileMenu, "Recent Projects", p };
580 MenuDivider { fileMenu };
581 MenuItem exitItem { fileMenu, "Exit", x, altF4, NotifySelect = MenuFileExit };
583 bool FileRecentFile(MenuItem selection, Modifiers mods)
586 for(file : ideSettings.recentFiles)
588 if(id == selection.id)
590 OpenFile(file, normal, true, null, no, normal);
598 bool FileRecentProject(MenuItem selection, Modifiers mods)
601 for(file : ideSettings.recentProjects)
603 if(id == selection.id)
605 OpenFile(file, normal, true, null, no, normal);
613 MenuPlacement editMenu { menu, "Edit", e };
615 Menu projectMenu { menu, "Project", p };
616 MenuItem projectNewItem
618 projectMenu, "New...", n, Key { n, true, true };
619 bool NotifySelect(MenuItem selection, Modifiers mods)
621 if(!DontTerminateDebugSession("New Project"))
622 if(MenuWindowCloseAll(null, 0))
624 NewProjectDialog newProjectDialog;
628 projectView.visible = false;
629 if(!projectView.Destroy(0))
633 newProjectDialog = { master = this };
634 newProjectDialog.Modal();
637 ideSettings.AddRecentProject(projectView.fileName);
638 ide.UpdateRecentMenus();
639 settingsContainer.Save();
645 MenuItem projectOpenItem
647 projectMenu, "Open...", o, Key { o, true, true };
648 bool NotifySelect(MenuItem selection, Modifiers mods)
650 if(ideSettings.ideProjectFileDialogLocation)
651 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
653 if(ideProjectFileDialog.Modal() == ok)
655 OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal);
656 //ChangeProjectFileDialogDirectory(ideProjectFileDialog.currentDirectory);
661 MenuItem projectQuickItem
663 projectMenu, "Quick...", q, f7;
664 bool NotifySelect(MenuItem selection, Modifiers mods)
667 QuickProjectDialog{ this }.Modal();
671 MenuItem projectAddItem
673 projectMenu, "Add project to workspace...", a, Key { a, true, true };
675 bool NotifySelect(MenuItem selection, Modifiers mods)
677 if(ideSettings.ideProjectFileDialogLocation)
678 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
682 if(ideProjectFileDialog.Modal() == ok)
684 if(OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add))
686 if(MessageBox { type = yesNo, master = this, text = "Error opening project file",
687 contents = "Add a different project?" }.Modal() == no)
698 MenuItem projectCloseItem
700 projectMenu, "Close", c, disabled = true;
701 bool NotifySelect(MenuItem selection, Modifiers mods)
705 if(!ide.DontTerminateDebugSession("Project Close"))
707 if(findInFilesDialog)
708 findInFilesDialog.SearchStop();
709 projectView.visible = false;
710 if(projectView.Destroy(0))
711 MenuWindowCloseAll(null, 0);
713 char workingDir[MAX_LOCATION];
714 GetWorkingDir(workingDir, MAX_LOCATION);
715 findInFilesDialog.currentDirectory = workingDir;
722 MenuDivider { projectMenu };
723 MenuItem activeCompilerItem
725 projectMenu, "Active Compiler...", g, /*altF5, */disabled = true;
726 bool NotifySelect(MenuItem selection, Modifiers mods)
728 projectView.MenuCompiler(null, mods);
732 MenuItem projectActiveConfigItem
734 projectMenu, "Active Configuration...", g, altF5, disabled = true;
735 bool NotifySelect(MenuItem selection, Modifiers mods)
737 projectView.MenuConfig(projectView.active ? selection : null, mods);
741 MenuItem projectSettingsItem
743 projectMenu, "Settings...", s, altF7, disabled = true;
744 bool NotifySelect(MenuItem selection, Modifiers mods)
746 projectView.MenuSettings(projectView.active ? selection : null, mods);
750 MenuDivider { projectMenu };
751 MenuItem projectBrowseFolderItem
753 projectMenu, "Browse Project Folder", p, disabled = true;
754 bool NotifySelect(MenuItem selection, Modifiers mods)
757 projectView.MenuBrowseFolder(null, mods);
761 MenuDivider { projectMenu };
762 MenuItem projectRunItem
764 projectMenu, "Run", r, ctrlF5, disabled = true;
765 bool NotifySelect(MenuItem selection, Modifiers mods)
768 projectView.Run(null, mods);
772 MenuItem projectBuildItem
774 projectMenu, "Build", b, f7, disabled = true;
775 bool NotifySelect(MenuItem selection, Modifiers mods)
778 projectView.ProjectBuild(projectView.active ? selection : null, mods);
782 MenuItem projectLinkItem
784 projectMenu, "Relink", l, disabled = true;
785 bool NotifySelect(MenuItem selection, Modifiers mods)
788 projectView.ProjectLink(projectView.active ? selection : null, mods);
792 MenuItem projectRebuildItem
794 projectMenu, "Rebuild", d, shiftF7, disabled = true;
795 bool NotifySelect(MenuItem selection, Modifiers mods)
798 projectView.ProjectRebuild(projectView.active ? selection : null, mods);
802 MenuItem projectCleanItem
804 projectMenu, "Clean", e, disabled = true;
805 bool NotifySelect(MenuItem selection, Modifiers mods)
810 projectView.ProjectClean(projectView.active ? selection : null, mods);
815 MenuItem projectRegenerateItem
817 projectMenu, "Regenerate Makefile", m, disabled = true;
818 bool NotifySelect(MenuItem selection, Modifiers mods)
821 projectView.ProjectRegenerate(projectView.active ? selection : null, mods);
825 MenuItem projectCompileItem;
826 Menu debugMenu { menu, "Debug", d };
827 MenuItem debugStartResumeItem
829 debugMenu, "Start", s, f5, disabled = true;
830 NotifySelect = MenuDebugStart;
832 bool MenuDebugStart(MenuItem selection, Modifiers mods)
836 debugStartResumeItem.disabled = true; // a very rare exception to calling AdjustDebugMenus
837 if(!projectView.DebugStart())
838 debugStartResumeItem.disabled = false; // same exception
842 bool MenuDebugResume(MenuItem selection, Modifiers mods)
845 projectView.DebugResume();
848 MenuItem debugRestartItem
850 debugMenu, "Restart", r, Key { f5, ctrl = true, shift = true }, disabled = true;
851 bool NotifySelect(MenuItem selection, Modifiers mods)
854 projectView.DebugRestart();
858 MenuItem debugBreakItem
860 debugMenu, "Break", b, Key { pauseBreak, ctrl = true }, disabled = true;
861 bool NotifySelect(MenuItem selection, Modifiers mods)
864 projectView.DebugBreak();
868 MenuItem debugStopItem
870 debugMenu, "Stop", p, shiftF5, disabled = true;
871 bool NotifySelect(MenuItem selection, Modifiers mods)
874 projectView.DebugStop();
878 MenuDivider { debugMenu };
879 MenuItem debugStepIntoItem
881 debugMenu, "Step Into", i, f11, disabled = true;
882 bool NotifySelect(MenuItem selection, Modifiers mods)
885 projectView.DebugStepInto();
889 MenuItem debugStepOverItem
891 debugMenu, "Step Over", v, f10, disabled = true;
892 bool NotifySelect(MenuItem selection, Modifiers mods)
895 projectView.DebugStepOver(false);
899 MenuItem debugStepOutItem
901 debugMenu, "Step Out", o, shiftF11, disabled = true;
902 bool NotifySelect(MenuItem selection, Modifiers mods)
905 projectView.DebugStepOut(false);
909 MenuPlacement debugRunToCursorItem { debugMenu, "Run To Cursor", c };
910 MenuItem debugSkipStepOverItem
912 debugMenu, "Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
913 bool NotifySelect(MenuItem selection, Modifiers mods)
916 projectView.DebugStepOver(true);
920 MenuItem debugSkipStepOutItem
922 debugMenu, "Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
923 bool NotifySelect(MenuItem selection, Modifiers mods)
926 projectView.DebugStepOut(true);
930 MenuPlacement debugSkipRunToCursorItem { debugMenu, "Run To Cursor Skipping Breakpoints", u };
931 //MenuDivider { debugMenu };
932 //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
933 MenuPlacement imageMenu { menu, "Image", i };
934 Menu viewMenu { menu, "View", v };
935 MenuItem viewProjectItem
937 viewMenu, "Project", j, alt0, disabled = true;
938 bool NotifySelect(MenuItem selection, Modifiers mods)
942 projectView.visible = true;
943 projectView.Activate();
948 MenuPlacement { viewMenu, "View Designer" };
949 MenuPlacement { viewMenu, "View Code" };
950 MenuPlacement { viewMenu, "View Properties" };
951 MenuPlacement { viewMenu, "View Methods" };
952 MenuItem viewDesignerItem
954 viewMenu, "View Designer", d, f8;
955 bool NotifySelect(MenuItem selection, Modifiers mods)
957 Window client = activeClient;
958 Class dataType = client._class;
959 if(!strcmp(dataType.name, "Designer"))
961 client.visible = true;
965 ((CodeEditor)client).ViewDesigner();
969 MenuItem viewCodeItem
971 viewMenu, "View Code", c, f8;
972 bool NotifySelect(MenuItem selection, Modifiers mods)
974 Window client = activeClient;
975 Class dataType = client._class;
976 if(!strcmp(dataType.name, "Designer"))
977 client = ((Designer)client).codeEditor;
980 // Do this after so the caret isn't moved yet...
981 client.visible = true;
985 MenuItem viewPropertiesItem
987 viewMenu, "View Properties", p, f4;
988 bool NotifySelect(MenuItem selection, Modifiers mods)
990 sheet.visible = true;
991 sheet.sheetSelected = properties;
996 MenuItem viewMethodsItem
998 viewMenu, "View Methods", m, f4;
999 bool NotifySelect(MenuItem selection, Modifiers mods)
1001 sheet.visible = true;
1002 sheet.sheetSelected = methods;
1007 MenuItem viewToolBoxItem
1009 viewMenu, "View Toolbox", x, f12;
1010 bool NotifySelect(MenuItem selection, Modifiers mods)
1012 toolBox.visible = true;
1017 MenuItem viewOutputItem
1019 viewMenu, "Output", o, alt2;
1020 bool NotifySelect(MenuItem selection, Modifiers mods)
1026 MenuItem viewWatchesItem
1028 viewMenu, "Watches", w, alt3;
1029 bool NotifySelect(MenuItem selection, Modifiers mods)
1035 MenuItem viewThreadsItem
1037 viewMenu, "Threads", t, alt4;
1038 bool NotifySelect(MenuItem selection, Modifiers mods)
1044 MenuItem viewBreakpointsItem
1046 viewMenu, "Breakpoints", b, alt5;
1047 bool NotifySelect(MenuItem selection, Modifiers mods)
1049 breakpointsView.Show();
1053 MenuItem viewCallStackItem
1055 viewMenu, "Call Stack", s, alt7;
1056 bool NotifySelect(MenuItem selection, Modifiers mods)
1058 callStackView.Show();
1062 MenuItem viewAllDebugViews
1064 viewMenu, "All Debug Views", a, alt9;
1065 bool NotifySelect(MenuItem selection, Modifiers mods)
1070 callStackView.Show();
1071 breakpointsView.Show();
1075 #ifdef GDB_DEBUG_GUI
1076 MenuDivider { viewMenu };
1077 MenuItem viewGDBItem
1079 viewMenu, "GDB Dialog", g, Key { f9, shift = true, ctrl = true };
1080 bool NotifySelect(MenuItem selection, Modifiers mods)
1087 MenuDivider { viewMenu };
1088 MenuItem viewColorPicker
1090 viewMenu, "Color Picker...", c, Key { c, ctrl = true , shift = true };
1091 bool NotifySelect(MenuItem selection, Modifiers mods)
1093 ColorPicker colorPicker { master = this, parent = this, stayOnTop = true };
1094 colorPicker.Create();
1098 MenuDivider { viewMenu };
1102 viewMenu, "Full Screen", f, checkable = true;
1104 bool NotifySelect(MenuItem selection, Modifiers mods)
1106 app.fullScreen ^= true;
1108 anchor = { 0, 0, 0, 0 };
1113 Menu driversMenu { viewMenu, "Graphics Driver", v };
1114 //Menu skinsMenu { viewMenu, "GUI Skins", k };
1115 Menu windowMenu { menu, "Window", w };
1116 MenuItem { windowMenu, "Close All", l, NotifySelect = MenuWindowCloseAll };
1117 MenuDivider { windowMenu };
1118 MenuItem { windowMenu, "Next", n, f6, NotifySelect = MenuWindowNext };
1119 MenuItem { windowMenu, "Previous", p, shiftF6, NotifySelect = MenuWindowPrevious };
1120 MenuDivider { windowMenu };
1121 MenuItem { windowMenu, "Cascade", c, NotifySelect = MenuWindowCascade };
1122 MenuItem { windowMenu, "Tile Horizontally", h, NotifySelect = MenuWindowTileHorz };
1123 MenuItem { windowMenu, "Tile Vertically", v, NotifySelect = MenuWindowTileVert };
1124 MenuItem { windowMenu, "Arrange Icons", a, NotifySelect = MenuWindowArrangeIcons };
1125 MenuDivider { windowMenu };
1126 MenuItem { windowMenu, "Windows...", w, NotifySelect = MenuWindowWindows };
1127 Menu helpMenu { menu, "Help", h };
1130 helpMenu, "API Reference", r, f1;
1131 bool NotifySelect(MenuItem selection, Modifiers mods)
1133 Execute("documentor");
1137 MenuDivider { helpMenu };
1140 helpMenu, "About...", a;
1141 bool NotifySelect(MenuItem selection, Modifiers mods)
1143 AboutIDE { master = this }.Modal();
1148 property ToolBox toolBox
1150 get { return toolBox; }
1153 property Sheet sheet
1155 get { return sheet; }
1158 property Project project
1160 get { return projectView ? projectView.project : null; }
1163 property Workspace workspace
1165 get { return projectView ? projectView.workspace : null; }
1168 FindInFilesDialog findInFilesDialog
1170 master = this, parent = this;
1171 filters = findInFilesFileFilters, sizeFilters = sizeof(findInFilesFileFilters);
1175 #ifdef GDB_DEBUG_GUI
1178 master = this, parent = this;
1179 anchor = { left = 100, top = 100, right = 100, bottom = 100 };
1181 void OnCommand(char * string)
1184 ide.debugger.SendGDBCommand(string);
1189 bool NotifySelectDisplayDriver(MenuItem selection, Modifiers mods)
1191 //app.driver = app.drivers[selection.id];
1193 app.driver = selection.id ? "OpenGL" : "X";
1195 app.driver = selection.id ? "OpenGL" : "GDI";
1197 delete ideSettings.displayDriver;
1198 ideSettings.displayDriver = CopyString(selection.id ? "OpenGL" : "Default");
1200 settingsContainer.Save();
1201 //SetDriverAndSkin();
1205 bool NotifySelectDisplaySkin(MenuItem selection, Modifiers mods)
1207 app.skin = app.skins[selection.id];
1212 void SetDriverAndSkin()
1215 for(c = 0; c < app.numSkins; c++)
1216 if(!strcmp(app.skins[c], app.skin))
1218 skinItems[c].checked = true;
1221 for(c = 0; c < app.numDrivers; c++)
1222 if(!strcmp(app.drivers[c], app.driver))
1224 driverItems[c].checked = true;
1229 ProjectView CreateProjectView(Workspace workspace, char * fileName)
1231 Project project = workspace.projects.firstIterator.data;
1232 projectView = ProjectView
1235 fileName = fileName;
1237 void NotifyDestroyed(Window window, DialogResult result)
1240 text = titleECEREIDE;
1245 projectView.Create();
1246 RepositionWindows(false);
1248 // Leave it after Create to avoid flicker due to seeing IDE without a project view
1249 projectView.workspace = workspace;
1250 projectView.project = project;
1251 SetText("%s - %s", project.topNode.name, titleECEREIDE);
1255 ide.breakpointsView.LoadFromWorkspace();
1256 ide.watchesView.LoadFromWorkspace();
1259 char fileName[MAX_LOCATION];
1260 strcpy(fileName, project.topNode.path);
1261 PathCat(fileName, project.topNode.name);
1266 bool GetDebugMenusDisabled()
1270 Project project = projectView.project;
1272 if(project.targetType == executable)
1279 void RepositionWindows(bool expand)
1284 bool inDebugMode = debugger.isActive;
1285 bool callStackVisible = expand ? false : callStackView.visible;
1286 bool threadsVisible = expand ? false : threadsView.visible;
1287 bool watchesVisible = expand ? false : watchesView.visible;
1288 bool breakpointsVisible = expand ? false : breakpointsView.visible;
1289 bool toolBoxVisible = toolBox.visible;
1290 bool outputVisible = expand ? false : outputView.visible;
1291 int topDistance = (callStackVisible || threadsVisible) ? 200 : 0;
1292 int bottomDistance = (outputVisible || watchesVisible || breakpointsVisible) ? 240 : 0;
1294 for(child = firstChild; child; child = child.next)
1296 if(child._class == class(CodeEditor) || child._class == class(Designer) ||
1297 child._class == class(Sheet) || child._class == class(ProjectView))
1299 Anchor anchor = child.anchor;
1300 anchor.top = topDistance;
1301 anchor.bottom = bottomDistance;
1302 if(child._class == class(CodeEditor) || child._class == class(Designer))
1304 anchor.right = toolBoxVisible ? 150 : 0;
1306 child.anchor = anchor;
1310 if(child._class == class(OutputView) || child._class == class(CallStackView) || child._class == class(ThreadsView) || child._class == class(WatchesView) ||
1311 child._class == class(BreakpointsView))
1312 child.visible = false;
1315 // If this is not here, the IDE is not updated when doing Debug/Break then Alt-4 to show call stack (IDE not updated)
1320 bool ShowCodeEditor()
1323 activeClient.Activate();
1324 else if(projectView)
1326 projectView.visible = true;
1327 projectView.Activate();
1331 sheet.visible = true;
1337 bool ShouldStopBuild()
1339 return projectView.stopBuild;
1342 void DocumentSaved(Window document, char * fileName)
1344 ideSettings.AddRecentFile(fileName);
1345 ide.UpdateRecentMenus();
1346 settingsContainer.Save();
1349 bool Window::OnFileModified(FileChange fileChange, char * param)
1352 sprintf(temp, "The document %s was modified by another application.\n"
1353 "Would you like to reload it and lose your changes?", this.fileName);
1354 if(MessageBox { type = yesNo, master = this/*.parent*/,
1355 text = "Document has been modified", contents = temp }.Modal() == yes)
1357 char * fileName = CopyString(this.fileName);
1358 WindowState state = this.state;
1359 Anchor anchor = this.anchor;
1360 Size size = this.size;
1362 this.modifiedDocument = false;
1364 this = ide.OpenFile(fileName, normal, true, null, no, normal);
1367 this.anchor = anchor;
1369 this.SetState(state, true, 0);
1377 void UpdateMakefiles()
1381 for(prj : workspace.projects)
1383 bool first = prj == workspace.projects.firstIterator.data;
1384 projectView.ProjectUpdateMakefileForAllConfigs(prj, first, first);
1391 bool unavailable = !project;
1393 projectQuickItem.disabled = !unavailable;
1395 projectAddItem.disabled = unavailable;
1397 activeCompilerItem.disabled = unavailable;
1398 projectActiveConfigItem.disabled = unavailable;
1399 projectSettingsItem.disabled = unavailable;
1401 projectBrowseFolderItem.disabled = unavailable;
1403 viewProjectItem.disabled = unavailable;
1409 void AdjustBuildMenus()
1411 bool unavailable = project && projectView.buildInProgress;
1413 projectNewItem.disabled = unavailable;
1414 projectOpenItem.disabled = unavailable;
1416 unavailable = !project || projectView.buildInProgress;
1418 projectCloseItem.disabled = unavailable;
1420 projectRunItem.disabled = unavailable || project.targetType != executable;
1421 projectBuildItem.disabled = unavailable;
1422 projectLinkItem.disabled = unavailable;
1423 projectRebuildItem.disabled = unavailable;
1424 projectCleanItem.disabled = unavailable;
1425 projectRegenerateItem.disabled = unavailable;
1426 projectCompileItem.disabled = unavailable;
1429 void AdjustDebugMenus()
1431 bool unavailable = !project || project.targetType != executable ||
1432 projectView.buildInProgress == buildingMainProject;
1433 bool active = ide.debugger.isActive;
1434 bool executing = ide.debugger.state == running;
1435 //bool holding = ide.debugger.state == stopped;
1437 debugStartResumeItem.disabled = unavailable || executing;
1439 debugStartResumeItem.text = active ? "Resume" : "Start";
1440 debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart;
1442 debugBreakItem.disabled = unavailable || !executing;
1443 debugStopItem.disabled = unavailable || !active;
1444 debugRestartItem.disabled = unavailable || !active;
1446 debugStepIntoItem.disabled = unavailable || executing;
1447 debugStepOverItem.disabled = unavailable || executing;
1448 debugStepOutItem.disabled = unavailable || executing || !active;
1449 debugSkipStepOverItem.disabled = unavailable || executing;
1450 debugSkipStepOutItem.disabled = unavailable || executing || !active;
1452 if((Designer)GetActiveDesigner())
1454 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1457 codeEditor.debugRunToCursor.disabled = unavailable || executing;
1458 codeEditor.debugSkipRunToCursor.disabled = unavailable || executing;
1463 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1465 char tempString[MAX_LOCATION];
1466 strcpy(tempString, directory);
1467 if(saveSettings && !projectView)
1469 ideSettings.ideFileDialogLocation = directory;
1470 settingsContainer.Save();
1473 ideFileDialog.currentDirectory = tempString;
1474 codeEditorFileDialog.currentDirectory = tempString;
1475 codeEditorFormFileDialog.currentDirectory = tempString;
1478 void ChangeProjectFileDialogDirectory(char * directory)
1480 ideSettings.ideProjectFileDialogLocation = directory;
1481 settingsContainer.Save();
1484 Window FindWindow(char * filePath)
1486 Window document = null;
1488 // TOCHECK: Do we need to change slashes here?
1489 for(document = firstChild; document; document = document.next)
1491 char * fileName = document.fileName;
1492 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1494 document.visible = true;
1495 document.Activate();
1502 bool DontTerminateDebugSession(char * title)
1504 if(debugger.isActive)
1506 if(MessageBox { type = yesNo, master = ide,
1507 contents = "Do you want to terminate the debugging session in progress?",
1508 text = title }.Modal() == no)
1511 MessageBox msg { type = yesNo, master = ide,
1512 contents = "Do you want to terminate the debugging session in progress?",
1514 if(msg.Modal() == no)
1526 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1528 char extension[MAX_EXTENSION] = "";
1529 Window document = null;
1530 bool isProject = false;
1531 bool needFileModified = true;
1532 char winFilePath[MAX_LOCATION];
1533 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1537 GetExtension(filePath, extension);
1541 strcpy(extension, type);
1543 if(strcmp(extension, ProjectExtension))
1545 for(document = firstChild; document; document = document.next)
1547 char * fileName = document.fileName;
1548 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1550 document.visible = true;
1551 document.Activate();
1557 if(createIfFails == whatever)
1559 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1561 if(openMethod == normal)
1563 if(DontTerminateDebugSession("Open Project"))
1566 if(MenuWindowCloseAll(null, 0))
1570 projectView.visible = false;
1571 projectView.Destroy(0);
1572 // Where did this come from? projectView = null;
1579 Workspace workspace = null;
1581 if(FileExists(filePath))
1583 if(!strcmp(extension, ProjectExtension))
1585 char workspaceFile[MAX_LOCATION];
1586 strcpy(workspaceFile, filePath);
1587 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1588 workspace = LoadWorkspace(workspaceFile, filePath);
1590 else if(!strcmp(extension, WorkspaceExtension))
1591 workspace = LoadWorkspace(filePath, null);
1594 //project = LoadProject(filePath);
1599 char absolutePath[MAX_LOCATION];
1600 CreateProjectView(workspace, filePath);
1601 document = projectView;
1603 workspace.DropInvalidBreakpoints();
1606 ide.projectView.ShowOutputBuildLog(true);
1607 ide.projectView.DisplayCompiler(false);
1610 char newWorkingDir[MAX_LOCATION];
1611 StripLastDirectory(filePath, newWorkingDir);
1612 ChangeFileDialogsDirectory(newWorkingDir, false);
1615 document.fileName = filePath;
1617 SetText("%s - %s", filePath, titleECEREIDE);
1619 // this crashes on starting ide with epj file, solution please?
1620 // app.UpdateDisplay();
1622 workspace.holdTracking = true;
1623 for(ofi : workspace.openedFiles)
1625 if(ofi.state != closed)
1627 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1630 char fileName[MAX_LOCATION];
1632 GetLastDirectory(ofi.path, fileName);
1633 node = projectView.project.topNode.Find(fileName, true);
1635 node.EnsureVisible();
1639 workspace.holdTracking = false;
1641 workspace.timer.Start();
1643 findInFilesDialog.mode = FindInFilesMode::project;
1644 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1647 char location[MAX_LOCATION];
1648 StripLastDirectory(ide.project.topNode.path, location);
1649 ChangeProjectFileDialogDirectory(location);
1653 if(projectView.debugger)
1654 projectView.debugger.EvaluateWatches();
1661 if(MessageBox { type = yesNo, parent = this, text = "Error opening project", contents = "Open a different project?" }.Modal() == yes)
1663 if(ideProjectFileDialog.Modal() == cancel)
1665 filePath = ideProjectFileDialog.filePath;
1666 GetExtension(filePath, extension);
1677 else if(openMethod == add)
1682 char slashFilePath[MAX_LOCATION];
1683 GetSlashPathBuffer(slashFilePath, filePath);
1684 for(p : workspace.projects)
1686 if(!fstrcmp(p.filePath, slashFilePath))
1694 MessageBox { type = ok, parent = parent, master = this, text = "Same Project",
1695 contents = "This project is already present in workspace." }.Modal();
1699 prj = LoadProject(filePath);
1702 workspace.projects.Add(prj);
1704 projectView.AddNode(prj.topNode, null);
1705 workspace.modified = true;
1707 findInFilesDialog.AddProjectItem(prj);
1708 projectView.ProjectUpdateMakefileForAllConfigs(prj, true, true);
1709 // projectView is associated with the main project and not with the one just added but
1710 return projectView; // just to let the caller know something was opened
1718 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1719 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1720 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1722 if(FileExists(filePath))
1723 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1724 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1725 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1728 MessageBox { type = ok, parent = this, text = filePath, contents = "File doesn't exist." }.Modal();
1731 else if(!strcmp(extension, "3ds"))
1733 if(FileExists(filePath))
1734 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1735 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1736 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1740 MessageBox { type = ok, parent = this, text = filePath, contents = "File doesn't exist." }.Modal();
1743 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
1744 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
1745 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
1746 !strcmp(extension, "css") || !strcmp(extension, "php") ||
1747 !strcmp(extension, "js"))
1749 CodeEditor editor { parent = this, state = state, visible = false };
1750 editor.updatingCode = true;
1751 if(editor.LoadFile(filePath))
1754 editor.visible = true;
1758 needFileModified = false;
1762 CodeEditor editor { parent = this, state = state, visible = false };
1763 if(editor.LoadFile(filePath))
1766 editor.visible = true;
1770 needFileModified = false;
1773 if(document && (document._class == class(PictureEdit) ||
1774 document._class == class(ModelView)))
1779 document.fileName = filePath;
1780 if(workspace && !workspace.holdTracking)
1781 workspace.UpdateOpenedFileInfo(filePath, opened);
1785 if(!document && createIfFails != no)
1787 if(createIfFails != yes && !needFileModified &&
1788 MessageBox { type = yesNo, parent = this, text = filePath, contents = "File doesn't exist. Create?" }.Modal() == yes)
1789 createIfFails = yes;
1790 if(createIfFails == yes || createIfFails == whatever)
1792 document = (Window)NewCodeEditor(this, state, true);
1794 document.fileName = filePath;
1800 if(projectView && document._class == class(CodeEditor) && workspace)
1802 int lineNumber, position;
1804 CodeEditor editor = (CodeEditor)document;
1805 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
1806 editor.openedFileInfo.holdTracking = true;
1807 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
1808 position = Max(editor.openedFileInfo.position - 1, 0);
1809 editor.editBox.GoToLineNum(lineNumber);
1810 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
1811 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
1812 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
1813 editor.editBox.scroll = scroll;
1814 editor.openedFileInfo.holdTracking = false;
1817 if(needFileModified)
1818 document.OnFileModified = OnFileModified;
1819 document.NotifySaved = DocumentSaved;
1822 ideSettings.AddRecentProject(document.fileName);
1824 ideSettings.AddRecentFile(document.fileName);
1825 ide.UpdateRecentMenus();
1826 settingsContainer.Save();
1834 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
1835 /*bool Window::GenericDocumentOnClose(bool parentClosing)
1837 if(!parentClosing && ide.workspace)
1838 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1841 bool ModelView::ModelViewOnClose(bool parentClosing)
1843 if(!parentClosing && ide.workspace)
1844 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1847 bool PictureEdit::PictureEditOnClose(bool parentClosing)
1849 if(!parentClosing && ide.workspace)
1850 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1855 void OnUnloadGraphics(Window window)
1857 display.ClearMaterials();
1858 display.ClearTextures();
1859 display.ClearMeshes();
1863 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
1865 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
1866 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
1870 bool OnKeyDown(Key key, unichar ch)
1875 projectView.Update(null);
1878 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
1881 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
1887 void GoToError(const char * line)
1890 projectView.GoToError(line);
1893 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
1896 char *colon = strchr(text, ':');
1897 char filePath[MAX_LOCATION];
1898 char completePath[MAX_LOCATION];
1899 int line = 0, col = 0;
1904 char * close = strchr(text, ')');
1908 strncpy(name, &text[4], close - text - 4);
1909 name[close - text - 4] = '\0';
1910 for(p : ide.workspace.projects)
1912 if(!strcmp(p.name, name))
1922 prj = project ? project : (dir ? null : ide.project);
1923 if(colon && (colon[1] == '/' || colon[1] == '\\'))
1925 path = (colon - 1 > path) ? colon - 1 : path;
1926 colon = strstr(colon + 1, ":");
1928 while(isspace(*path)) path++;
1931 strncpy(filePath, path, colon - path);
1932 filePath[colon - path] = '\0';
1933 line = atoi(colon + 1);
1934 colon = strstr(colon + 1, ":");
1936 col = atoi(colon + 1);
1938 else if(path - 1 >= path && *(path - 1) == '\"')
1940 colon = strchr(path, '\"');
1943 strncpy(filePath, path, colon - path);
1944 filePath[colon - path] = '\0';
1949 strcpy(completePath, prj.topNode.path);
1950 else if(dir && dir[0])
1951 strcpy(completePath, dir);
1953 completePath[0] = '\0';
1954 PathCat(completePath, filePath);
1956 if(FileExists(completePath).isFile)
1958 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
1959 if(codeEditor && line)
1961 EditBox editBox = codeEditor.editBox;
1962 editBox.GoToLineNum(line - 1);
1963 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
1968 void OnRedraw(Surface surface)
1970 Bitmap bitmap = back.bitmap;
1972 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
1975 void SheetSelected(SheetType sheetSelected)
1977 if(activeChild == sheet)
1979 if(sheetSelected == methods)
1981 viewPropertiesItem.accelerator = f4;
1982 viewPropertiesItem.parent = viewMenu;
1983 viewMethodsItem.parent = null;
1987 viewMethodsItem.accelerator = f4;
1988 viewMethodsItem.parent = viewMenu;
1989 viewPropertiesItem.parent = null;
1994 viewMethodsItem.parent = viewMenu;
1995 viewPropertiesItem.parent = viewMenu;
1996 if(sheetSelected == methods)
1998 viewMethodsItem.accelerator = f4;
1999 viewPropertiesItem.accelerator = 0;
2003 viewMethodsItem.accelerator = 0;
2004 viewPropertiesItem.accelerator = f4;
2009 void OnActivateClient(Window client, Window previous)
2011 //if(!client || client != previous)
2014 if(!client || client != previous)
2017 dataType = previous._class;
2018 if(previous && !strcmp(dataType.name, "CodeEditor"))
2020 ((CodeEditor)previous).UpdateFormCode();
2022 else if(previous && !strcmp(dataType.name, "Designer"))
2024 ((Designer)previous).codeEditor.UpdateFormCode();
2029 dataType = client._class;
2030 if(client && !strcmp(dataType.name, "CodeEditor"))
2032 CodeEditor codeEditor = (CodeEditor)client;
2033 SetPrivateModule(codeEditor.privateModule);
2034 SetCurrentContext(codeEditor.globalContext);
2035 SetTopContext(codeEditor.globalContext);
2036 SetGlobalContext(codeEditor.globalContext);
2038 SetDefines(&codeEditor.defines);
2039 SetImports(&codeEditor.imports);
2041 SetActiveDesigner(codeEditor.designer);
2043 sheet.codeEditor = codeEditor;
2044 toolBox.codeEditor = codeEditor;
2046 viewDesignerItem.parent = viewMenu;
2047 if(activeChild != codeEditor)
2049 viewCodeItem.parent = viewMenu;
2050 viewDesignerItem.accelerator = 0;
2051 viewCodeItem.accelerator = f8;
2055 viewCodeItem.parent = null;
2056 viewDesignerItem.accelerator = f8;
2059 else if(client && !strcmp(dataType.name, "Designer"))
2061 CodeEditor codeEditor = ((Designer)client).codeEditor;
2064 SetPrivateModule(codeEditor.privateModule);
2065 SetCurrentContext(codeEditor.globalContext);
2066 SetTopContext(codeEditor.globalContext);
2067 SetGlobalContext(codeEditor.globalContext);
2068 SetDefines(&codeEditor.defines);
2069 SetImports(&codeEditor.imports);
2073 SetPrivateModule(null);
2074 SetCurrentContext(null);
2075 SetTopContext(null);
2076 SetGlobalContext(null);
2081 SetActiveDesigner((Designer)client);
2083 sheet.codeEditor = codeEditor;
2084 toolBox.codeEditor = codeEditor;
2086 viewCodeItem.parent = viewMenu;
2087 if(activeChild != client)
2089 viewDesignerItem.parent = viewMenu;
2090 viewDesignerItem.accelerator = f8;
2091 viewCodeItem.accelerator = 0;
2095 viewDesignerItem.parent = null;
2096 viewCodeItem.accelerator = f8;
2102 sheet.codeEditor = null;
2103 toolBox.codeEditor = null;
2104 SetActiveDesigner(null);
2106 viewDesignerItem.parent = null;
2107 viewCodeItem.parent = null;
2110 SheetSelected(sheet.sheetSelected);
2113 projectCompileItem = null;
2118 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2120 CodeEditor codeEditor = (CodeEditor)client;
2121 EditBox editBox = codeEditor.editBox;
2123 statusBar.AddField(pos);
2125 caps = { width = 40, text = "CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2126 statusBar.AddField(caps);
2128 ovr = { width = 30, text = "OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2129 statusBar.AddField(ovr);
2131 num = { width = 30, text = "NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2132 statusBar.AddField(num);
2134 //statusBar.text = "Ready";
2136 if(projectView && projectView.project)
2138 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2142 sprintf(name, "Compile %s", node.name);
2143 projectCompileItem =
2145 copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress;
2147 bool NotifySelect(MenuItem selection, Modifiers mods)
2151 ProjectNode node = projectView.GetNodeFromWindow(activeClient, null);
2153 projectView.Compile(node);
2158 projectMenu.AddDynamic(projectCompileItem, null, false);
2164 caps = ovr = num = null;
2169 bool OnClose(bool parentClosing)
2171 //return !projectView.buildInProgress;
2172 if(projectView && projectView.buildInProgress)
2174 if(DontTerminateDebugSession("Close IDE"))
2176 if(findInFilesDialog)
2177 findInFilesDialog.SearchStop();
2180 workspace.timer.Stop();
2189 for(c = 1; c<app.argc; c++)
2191 char fullPath[MAX_LOCATION];
2192 GetWorkingDir(fullPath, MAX_LOCATION);
2193 PathCat(fullPath, app.argv[c]);
2194 if(FileExists(fullPath))
2195 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2202 // IS THIS NEEDED? WASN'T HERE BEFORE...
2205 projectView.visible = false;
2206 projectView.Destroy(0);
2209 #ifdef GDB_DEBUG_GUI
2210 gdbDialog.Destroy(0);
2215 void SetPath(bool projectsDirs)
2219 char * oldPaths[128];
2220 char oldList[MAX_LOCATION * 128];
2221 Array<String> newExePaths { };
2222 //Map<String, bool> exePathExists { };
2224 #if defined(__unix__) || defined(__APPLE__)
2225 Array<String> newLibPaths { };
2226 Map<String, bool> libPathExists { };
2228 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
2232 for(prj : workspace.projects)
2234 DirExpression targetDirExp;
2236 // SKIP FIRST PROJECT...
2237 if(prj == workspace.projects.firstIterator.data) continue;
2239 targetDirExp = prj.targetDir;
2241 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2245 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2246 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2250 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2251 if(cfg.targetType == sharedLibrary && cfg.debug)
2255 if(targetDirExp.dir)
2257 char buffer[MAX_LOCATION];
2258 #if defined(__WIN32__)
2259 Array<String> paths = newExePaths;
2261 Array<String> paths = newLibPaths;
2263 GetSystemPathBuffer(buffer, prj.topNode.path);
2264 PathCat(buffer, targetDirExp.dir);
2267 if(!fstrcmp(p, buffer))
2274 paths.Add(CopyString(buffer));
2276 delete targetDirExp;
2280 for(item : compiler.executableDirs)
2283 for(p : newExePaths)
2285 if(!fstrcmp(p, item))
2292 newExePaths.Add(CopySystemPath(item));
2295 GetEnvironment("PATH", oldList, sizeof(oldList));
2297 printf("Old value of PATH: %s\n", oldList);
2299 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2300 for(c = 0; c < count; c++)
2303 for(p : newExePaths)
2305 if(!fstrcmp(p, oldPaths[c]))
2312 newExePaths.Add(CopySystemPath(oldPaths[c]));
2316 for(path : newExePaths)
2317 len += strlen(path) + 1;
2318 newList = new char[len + 1];
2320 for(path : newExePaths)
2322 strcat(newList, path);
2323 strcat(newList, pathListSep);
2325 newList[len - 1] = '\0';
2326 SetEnvironment("PATH", newList);
2328 printf("New value of PATH: %s\n", newList);
2335 #if defined(__unix__) || defined(__APPLE__)
2337 for(item : compiler.libraryDirs)
2339 if(!libPathExists[item]) // fstrcmp should be used
2341 newLibPaths.Add(item);
2342 libPathExists[item] = true;
2346 #if defined(__APPLE__)
2347 GetEnvironment("DYLD_LIBRARY_PATH", oldList, sizeof(oldList));
2349 GetEnvironment("LD_LIBRARY_PATH", oldList, sizeof(oldList));
2352 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2354 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2355 for(c = 0; c < count; c++)
2357 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2359 newLibPaths.Add(oldPaths[c]);
2360 libPathExists[oldPaths[c]] = true;
2365 for(path : newLibPaths)
2366 len += strlen(path) + 1;
2367 newList = new char[len + 1];
2369 for(path : newLibPaths)
2371 strcat(newList, path);
2372 strcat(newList, pathListSep);
2374 newList[len - 1] = '\0';
2375 #if defined(__APPLE__)
2376 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2378 SetEnvironment("LD_LIBRARY_PATH", newList);
2381 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2386 delete libPathExists;
2391 void DestroyTemporaryProjectDir()
2393 if(tmpPrjDir && tmpPrjDir[0])
2395 if(FileExists(tmpPrjDir).isDirectory)
2396 DestroyDir(tmpPrjDir);
2397 property::tmpPrjDir = null;
2403 // Graphics Driver Menu
2407 app.currentSkin.selectionColor = selectionColor;
2408 app.currentSkin.selectionText = selectionText;
2412 driverItems = new MenuItem[app.numDrivers];
2413 for(c = 0; c < app.numDrivers; c++)
2415 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2416 driverItems[c].id = c;
2417 driverItems[c].isRadio = true;
2420 driverItems = new MenuItem[2];
2421 #if defined(__unix__)
2422 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2423 driverItems[0].id = 0;
2424 driverItems[0].isRadio = true;
2426 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2427 driverItems[0].id = 0;
2428 driverItems[0].isRadio = true;
2430 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2431 driverItems[1].id = 1;
2432 driverItems[1].isRadio = true;
2434 /* skinItems = new MenuItem[app.numSkins];
2435 for(c = 0; c < app.numSkins; c++)
2437 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2438 skinItems[c].id = c;
2439 skinItems[c].isRadio = true;
2442 ideFileDialog.master = this;
2443 ideProjectFileDialog.master = this;
2445 //SetDriverAndSkin();
2449 void UpdateRecentMenus()
2452 Menu fileMenu = menu.FindMenu("File");
2453 Menu recentFiles = fileMenu.FindMenu("Recent Files");
2454 Menu recentProjects = fileMenu.FindMenu("Recent Projects");
2455 char itemName[MAX_LOCATION + 4];
2458 recentFiles.Clear();
2461 for(recent : ideSettings.recentFiles)
2463 sprintf(itemName, "%d %s", 1 + c, recent);
2464 MakeSystemPath(itemName);
2465 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, null, true);
2469 recentProjects.Clear();
2471 for(recent : ideSettings.recentProjects)
2473 sprintf(itemName, "%d %s", 1 + c, recent);
2474 MakeSystemPath(itemName);
2475 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, null, true);
2487 void DestroyDir(char * path)
2489 RecursiveDeleteFolderFSI fsi { };
2494 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2496 bool preserveRootFolder;
2498 void OutFolder(char * folderPath, bool isRoot)
2500 if(!(preserveRootFolder && isRoot))
2501 RemoveDir(folderPath);
2504 bool OnFile(char * filePath)
2506 DeleteFile(filePath);
2511 class IDEApp : GuiApplication
2513 //driver = "Win32Console";
2514 // driver = "OpenGL";
2519 SetLoggingMode(stdOut, null);
2520 //SetLoggingMode(debug, null);
2522 settingsContainer.Load();
2523 #if defined(__unix__) || defined(__APPLE__)
2524 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2526 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2528 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2532 desktop.text = titleECEREIDE;
2535 for(c = 1; c<app.argc; c++)
2537 char fullPath[MAX_LOCATION];
2538 GetWorkingDir(fullPath, MAX_LOCATION);
2539 PathCat(fullPath, app.argv[c]);
2540 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2549 define app = ((IDEApp)__thisModule);
2551 define titleECEREIDE = "ECERE IDE (Debug)";
2553 define titleECEREIDE = "ECERE IDE";