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;
219 anchor = Anchor { left = 0, top = 0, right = 0, bottom = 0 };
222 MenuItem * driverItems, * skinItems;
223 StatusField pos { width = 150 };
224 StatusField ovr, caps, num;
226 BitmapResource back { ":ecereBack.jpg", window = this };
227 BitmapResource bmpBp { ":codeMarks/breakpoint.png", window = this };
228 BitmapResource bmpBpDisabled { ":codeMarks/breakpointDisabled.png", window = this };
229 BitmapResource bmpBpHalf { ":codeMarks/breakpointHalf.png", window = this };
230 BitmapResource bmpBpHalfDisabled { ":codeMarks/breakpointHalfDisabled.png", window = this };
231 BitmapResource bmpCursor { ":codeMarks/cursor.png", window = this };
232 BitmapResource bmpCursorError { ":codeMarks/cursorError.png", window = this };
233 BitmapResource bmpTopFrame { ":codeMarks/topFrame.png", window = this };
234 BitmapResource bmpTopFrameError { ":codeMarks/topFrameError.png", window = this };
235 BitmapResource bmpTopFrameHalf { ":codeMarks/topFrameHalf.png", window = this };
236 BitmapResource bmpTopFrameHalfError { ":codeMarks/topFrameHalfError.png", window = this };
238 FontResource font { "Courier New", 10 };
240 Debugger debugger { };
242 ProjectView projectView;
244 OutputView outputView
248 void OnGotoError(char * line)
253 void OnCodeLocationParseAndGoTo(char * line)
255 ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir);
258 bool OnKeyDown(Key key, unichar ch)
263 if(!ide.findInFilesDialog || !ide.findInFilesDialog.SearchAbort())
264 ide.ShowCodeEditor();
271 OutputView::OnKeyDown(key, ch);
278 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
281 ide.RepositionWindows(false);
285 bool OnClose(bool parentClosing)
289 ide.RepositionWindows(false);
290 return parentClosing;
294 CallStackView callStackView
296 parent = this, font = font;
298 void OnGotoLine(char * line)
301 stackLvl = atoi(line);
302 ide.debugger.GoToStackFrameLine(stackLvl, true);
305 void OnSelectFrame(int lineNumber)
307 ide.debugger.SelectFrame(lineNumber);
310 void OnToggleBreakpoint()
312 Debugger debugger = ide.debugger;
313 if(debugger.activeFrame && debugger.activeFrame.absoluteFile)
315 int line = debugger.activeFrame.line;
316 char name[MAX_LOCATION];
318 // TOFIX: Improve on this, don't use only filename, make a function
319 GetLastDirectory(debugger.activeFrame.absoluteFile, name);
320 if(ide && ide.workspace)
322 for(p : ide.workspace.projects)
324 if(p.topNode.Find(name, false))
332 for(p : ide.workspace.projects)
334 if(eString_PathInsideOf(debugger.activeFrame.absoluteFile, p.topNode.path))
342 debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line, prj);
345 CodeEditor codeEditor = (CodeEditor)ide.FindWindow(debugger.activeFrame.absoluteFile);
346 if(codeEditor) { codeEditor.Update(null); Activate(); }
351 bool OnKeyDown(Key key, unichar ch)
355 case escape: ide.ShowCodeEditor(); break;
360 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
363 ide.RepositionWindows(false);
367 bool OnClose(bool parentClosing)
371 ide.RepositionWindows(false);
372 return parentClosing;
375 void OnRedraw(Surface surface)
378 int lineCursor, lineTopFrame, activeThread, hitThread;
379 int lineH, scrollY, boxH;
381 Breakpoint bp = null;
382 Debugger debugger = ide.debugger;
383 Frame activeFrame = debugger.activeFrame;
386 scrollY = editBox.scroll.y;
387 displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
389 activeThread = debugger.activeThread;
390 hitThread = debugger.hitThread;
391 debugger.GetCallStackCursorLine(&error, &lineCursor, &lineTopFrame);
393 if(activeFrame && activeFrame.absoluteFile)
395 for(i : ide.workspace.breakpoints; i.type == user)
397 if(i.absoluteFilePath && i.absoluteFilePath[0] &&
398 !fstrcmp(i.absoluteFilePath, activeFrame.absoluteFile) &&
399 activeFrame.line == i.line)
408 DrawLineMarginIcon(surface,
409 /*(lineCursor == 1 || lineTopFrame == 1) ? */ide.bmpBpHalf/* : ide.bmpBp*/,
410 lineCursor /*1*/, lineH, scrollY, boxH);
413 if(activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
414 DrawLineMarginIcon(surface,
415 (lineCursor == 1 || lineTopFrame == 1) ? ide.bmpBpHalf : ide.bmpBp,
416 1, lineH, scrollY, boxH);
418 DrawLineMarginIcon(surface, error ? ide.bmpCursorError : ide.bmpCursor, lineCursor, lineH, scrollY, boxH);
419 if(bp && lineCursor == 1) //activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
420 bmp = error ? ide.bmpTopFrameHalfError : ide.bmpTopFrameHalf;
422 bmp = error ? ide.bmpTopFrameError : ide.bmpTopFrame;
423 DrawLineMarginIcon(surface, bmp, lineTopFrame, lineH, scrollY, boxH);
424 if(editBox.horzScroll && editBox.horzScroll.visible)
426 surface.SetBackground(control);
427 surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
432 WatchesView watchesView { parent = this };
433 ThreadsView threadsView
435 parent = this, font = font;
437 bool OnKeyDown(Key key, unichar ch)
441 case escape: ide.ShowCodeEditor(); break;
446 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
449 ide.RepositionWindows(false);
453 bool OnClose(bool parentClosing)
457 ide.RepositionWindows(false);
458 return parentClosing;
461 void OnSelectThread(int threadId)
464 ide.debugger.SelectThread(threadId);
467 bool OnGetThreadsInfo(int * activeThread, int * hitThread, int * signalThread)
470 Debugger debugger = ide.debugger;
471 *activeThread = debugger.activeThread;
472 *hitThread = debugger.hitThread;
473 *signalThread = debugger.signalThread;
478 BreakpointsView breakpointsView { parent = this };
480 ToolBox toolBox { parent = this };
481 Sheet sheet { parent = this };
483 bool buildInProgress;
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.Show();
551 MenuDivider { fileMenu };
552 MenuItem globalSettingsItem
554 fileMenu, "Global Settings...", g;
555 bool NotifySelect(MenuItem selection, Modifiers mods)
557 globalSettingsDialog.master = this;
558 if(ide.workspace && ide.workspace.compiler)
559 globalSettingsDialog.workspaceActiveCompiler = ide.workspace.compiler;
560 else if(ideSettings.defaultCompiler)
561 globalSettingsDialog.workspaceActiveCompiler = ideSettings.defaultCompiler;
562 globalSettingsDialog.Modal();
566 MenuDivider { fileMenu };
567 Menu recentFiles { fileMenu, "Recent Files", r };
568 Menu recentProjects { fileMenu, "Recent Projects", p };
569 MenuDivider { fileMenu };
570 MenuItem exitItem { fileMenu, "Exit", x, altF4, NotifySelect = MenuFileExit };
572 bool FileRecentFile(MenuItem selection, Modifiers mods)
575 for(file : ideSettings.recentFiles)
577 if(id == selection.id)
579 OpenFile(file, normal, true, null, no, normal);
587 bool FileRecentProject(MenuItem selection, Modifiers mods)
590 for(file : ideSettings.recentProjects)
592 if(id == selection.id)
594 OpenFile(file, normal, true, null, no, normal);
602 MenuPlacement editMenu { menu, "Edit", e };
604 Menu projectMenu { menu, "Project", p };
605 MenuItem projectNewItem
607 projectMenu, "New...", n, Key { n, true, true };
608 bool NotifySelect(MenuItem selection, Modifiers mods)
610 if(!DontTerminateDebugSession("New Project"))
611 if(MenuWindowCloseAll(null, 0))
613 NewProjectDialog newProjectDialog;
617 projectView.visible = false;
618 if(!projectView.Destroy(0))
622 newProjectDialog = { master = this };
623 newProjectDialog.Modal();
626 ideSettings.AddRecentProject(projectView.fileName);
627 ide.UpdateRecentMenus();
628 settingsContainer.Save();
634 MenuItem projectOpenItem
636 projectMenu, "Open...", o, Key { o, true, true };
637 bool NotifySelect(MenuItem selection, Modifiers mods)
639 if(ideSettings.ideProjectFileDialogLocation)
640 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
642 if(ideProjectFileDialog.Modal() == ok)
644 OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal);
645 //ChangeProjectFileDialogDirectory(ideProjectFileDialog.currentDirectory);
650 MenuItem projectQuickItem
652 projectMenu, "Quick...", q, f7;
653 bool NotifySelect(MenuItem selection, Modifiers mods)
656 QuickProjectDialog{ this }.Modal();
660 MenuItem projectAddItem
662 projectMenu, "Add project to workspace...", a, Key { a, true, true };
664 bool NotifySelect(MenuItem selection, Modifiers mods)
666 if(ideSettings.ideProjectFileDialogLocation)
667 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
671 if(ideProjectFileDialog.Modal() == ok)
673 if(OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add))
675 if(MessageBox { type = yesNo, master = this, text = "Error opening project file",
676 contents = "Add a different project?" }.Modal() == no)
687 MenuItem projectCloseItem
689 projectMenu, "Close", c, disabled = true;
690 bool NotifySelect(MenuItem selection, Modifiers mods)
694 if(findInFilesDialog)
695 findInFilesDialog.SearchStop();
696 projectView.visible = false;
697 if(projectView.Destroy(0))
698 MenuWindowCloseAll(null, 0);
700 char workingDir[MAX_LOCATION];
701 GetWorkingDir(workingDir, MAX_LOCATION);
702 findInFilesDialog.currentDirectory = workingDir;
708 MenuDivider { projectMenu };
709 MenuItem activeCompilerItem
711 projectMenu, "Active Compiler...", g, /*altF5, */disabled = true;
712 bool NotifySelect(MenuItem selection, Modifiers mods)
714 projectView.MenuCompiler(null, mods);
718 MenuItem projectActiveConfigItem
720 projectMenu, "Active Configuration...", g, altF5, disabled = true;
721 bool NotifySelect(MenuItem selection, Modifiers mods)
723 projectView.MenuConfig(projectView.active ? selection : null, mods);
727 MenuItem projectSettingsItem
729 projectMenu, "Settings...", s, altF7, disabled = true;
730 bool NotifySelect(MenuItem selection, Modifiers mods)
732 projectView.MenuSettings(projectView.active ? selection : null, mods);
736 MenuDivider { projectMenu };
737 MenuItem projectBrowseFolderItem
739 projectMenu, "Browse Project Folder", p, disabled = true;
740 bool NotifySelect(MenuItem selection, Modifiers mods)
743 projectView.MenuBrowseFolder(null, mods);
747 MenuDivider { projectMenu };
748 MenuItem projectRunItem
750 projectMenu, "Run", r, ctrlF5, disabled = true;
751 bool NotifySelect(MenuItem selection, Modifiers mods)
754 projectView.Run(null, mods);
758 MenuItem projectBuildItem
760 projectMenu, "Build", b, f7, disabled = true;
761 bool NotifySelect(MenuItem selection, Modifiers mods)
764 projectView.ProjectBuild(projectView.active ? selection : null, mods);
768 MenuItem projectLinkItem
770 projectMenu, "Relink", l, disabled = true;
771 bool NotifySelect(MenuItem selection, Modifiers mods)
774 projectView.ProjectLink(projectView.active ? selection : null, mods);
778 MenuItem projectRebuildItem
780 projectMenu, "Rebuild", d, shiftF7, disabled = true;
781 bool NotifySelect(MenuItem selection, Modifiers mods)
784 projectView.ProjectRebuild(projectView.active ? selection : null, mods);
788 MenuItem projectCleanItem
790 projectMenu, "Clean", e, disabled = true;
791 bool NotifySelect(MenuItem selection, Modifiers mods)
796 projectView.ProjectClean(projectView.active ? selection : null, mods);
801 MenuItem projectRegenerateItem
803 projectMenu, "Regenerate Makefile", m, disabled = true;
804 bool NotifySelect(MenuItem selection, Modifiers mods)
807 projectView.ProjectRegenerate(projectView.active ? selection : null, mods);
811 MenuItem projectCompileItem;
812 Menu debugMenu { menu, "Debug", d };
813 MenuItem debugStartResumeItem
815 debugMenu, "Start", s, f5, disabled = true;
816 NotifySelect = MenuDebugStart;
818 bool MenuDebugStart(MenuItem selection, Modifiers mods)
822 debugStartResumeItem.disabled = true;
823 if(!projectView.DebugStart())
824 debugStartResumeItem.disabled = false;
828 bool MenuDebugResume(MenuItem selection, Modifiers mods)
832 /*if(projectView.IsProjectModified())
834 debugStartResumeItem.disabled = true;
835 if(!projectView.DebugStart(null, null))
836 debugStartResumeItem.disabled = false;
839 projectView.DebugResume();
843 MenuItem debugRestartItem
845 debugMenu, "Restart", r, Key { f5, ctrl = true, shift = true }, disabled = true;
846 bool NotifySelect(MenuItem selection, Modifiers mods)
849 projectView.DebugRestart();
853 MenuItem debugBreakItem
855 debugMenu, "Break", b, Key { pauseBreak, ctrl = true }, disabled = true;
856 bool NotifySelect(MenuItem selection, Modifiers mods)
859 projectView.DebugBreak();
863 MenuItem debugStopItem
865 debugMenu, "Stop", p, shiftF5, disabled = true;
866 bool NotifySelect(MenuItem selection, Modifiers mods)
869 projectView.DebugStop();
873 MenuDivider { debugMenu };
874 MenuItem debugStepIntoItem
876 debugMenu, "Step Into", i, f11, disabled = true;
877 bool NotifySelect(MenuItem selection, Modifiers mods)
880 projectView.DebugStepInto();
884 MenuItem debugStepOverItem
886 debugMenu, "Step Over", v, f10, disabled = true;
887 bool NotifySelect(MenuItem selection, Modifiers mods)
890 projectView.DebugStepOver(false);
894 MenuItem debugStepOutItem
896 debugMenu, "Step Out", o, shiftF11, disabled = true;
897 bool NotifySelect(MenuItem selection, Modifiers mods)
900 projectView.DebugStepOut(false);
904 MenuPlacement debugRunToCursorItem { debugMenu, "Run To Cursor", c };
905 MenuItem debugSkipStepOverItem
907 debugMenu, "Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
908 bool NotifySelect(MenuItem selection, Modifiers mods)
911 projectView.DebugStepOver(true);
915 MenuItem debugSkipStepOutItem
917 debugMenu, "Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
918 bool NotifySelect(MenuItem selection, Modifiers mods)
921 projectView.DebugStepOut(true);
925 MenuPlacement debugSkipRunToCursorItem { debugMenu, "Run To Cursor Skipping Breakpoints", u };
926 //MenuDivider { debugMenu };
927 //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
928 MenuPlacement imageMenu { menu, "Image", i };
929 Menu viewMenu { menu, "View", v };
930 MenuItem viewProjectItem
932 viewMenu, "Project", j, alt0, disabled = true;
933 bool NotifySelect(MenuItem selection, Modifiers mods)
937 projectView.visible = true;
938 projectView.Activate();
943 MenuPlacement { viewMenu, "View Designer" };
944 MenuPlacement { viewMenu, "View Code" };
945 MenuPlacement { viewMenu, "View Properties" };
946 MenuPlacement { viewMenu, "View Methods" };
947 MenuItem viewDesignerItem
949 viewMenu, "View Designer", d, f8;
950 bool NotifySelect(MenuItem selection, Modifiers mods)
952 Window client = activeClient;
953 Class dataType = client._class;
954 if(!strcmp(dataType.name, "Designer"))
956 client.visible = true;
960 ((CodeEditor)client).ViewDesigner();
964 MenuItem viewCodeItem
966 viewMenu, "View Code", c, f8;
967 bool NotifySelect(MenuItem selection, Modifiers mods)
969 Window client = activeClient;
970 Class dataType = client._class;
971 if(!strcmp(dataType.name, "Designer"))
972 client = ((Designer)client).codeEditor;
975 // Do this after so the caret isn't moved yet...
976 client.visible = true;
980 MenuItem viewPropertiesItem
982 viewMenu, "View Properties", p, f4;
983 bool NotifySelect(MenuItem selection, Modifiers mods)
985 sheet.visible = true;
986 sheet.sheetSelected = properties;
991 MenuItem viewMethodsItem
993 viewMenu, "View Methods", m, f4;
994 bool NotifySelect(MenuItem selection, Modifiers mods)
996 sheet.visible = true;
997 sheet.sheetSelected = methods;
1002 MenuItem viewToolBoxItem
1004 viewMenu, "View Toolbox", x, f12;
1005 bool NotifySelect(MenuItem selection, Modifiers mods)
1007 toolBox.visible = true;
1012 MenuItem viewOutputItem
1014 viewMenu, "Output", o, alt2;
1015 bool NotifySelect(MenuItem selection, Modifiers mods)
1021 MenuItem viewWatchesItem
1023 viewMenu, "Watches", w, alt3;
1024 bool NotifySelect(MenuItem selection, Modifiers mods)
1030 MenuItem viewThreadsItem
1032 viewMenu, "Threads", t, alt4;
1033 bool NotifySelect(MenuItem selection, Modifiers mods)
1039 MenuItem viewBreakpointsItem
1041 viewMenu, "Breakpoints", b, alt5;
1042 bool NotifySelect(MenuItem selection, Modifiers mods)
1044 breakpointsView.Show();
1048 MenuItem viewCallStackItem
1050 viewMenu, "Call Stack", s, alt7;
1051 bool NotifySelect(MenuItem selection, Modifiers mods)
1053 callStackView.Show();
1057 MenuItem viewAllDebugViews
1059 viewMenu, "All Debug Views", a, alt9;
1060 bool NotifySelect(MenuItem selection, Modifiers mods)
1065 callStackView.Show();
1066 breakpointsView.Show();
1070 #ifdef GDB_DEBUG_GUI
1071 MenuDivider { viewMenu };
1072 MenuItem viewGDBItem
1074 viewMenu, "GDB Dialog", g, Key { f9, shift = true, ctrl = true };
1075 bool NotifySelect(MenuItem selection, Modifiers mods)
1082 MenuDivider { viewMenu };
1083 MenuItem viewColorPicker
1085 viewMenu, "Color Picker...", c, Key { c, ctrl = true , shift = true };
1086 bool NotifySelect(MenuItem selection, Modifiers mods)
1088 ColorPicker colorPicker { master = this, parent = this, stayOnTop = true };
1089 colorPicker.Create();
1093 MenuDivider { viewMenu };
1097 viewMenu, "Full Screen", f, checkable = true;
1099 bool NotifySelect(MenuItem selection, Modifiers mods)
1101 app.fullScreen ^= true;
1103 anchor = { 0, 0, 0, 0 };
1108 Menu driversMenu { viewMenu, "Graphics Driver", v };
1109 //Menu skinsMenu { viewMenu, "GUI Skins", k };
1110 Menu windowMenu { menu, "Window", w };
1111 MenuItem { windowMenu, "Close All", l, NotifySelect = MenuWindowCloseAll };
1112 MenuDivider { windowMenu };
1113 MenuItem { windowMenu, "Next", n, f6, NotifySelect = MenuWindowNext };
1114 MenuItem { windowMenu, "Previous", p, shiftF6, NotifySelect = MenuWindowPrevious };
1115 MenuDivider { windowMenu };
1116 MenuItem { windowMenu, "Cascade", c, NotifySelect = MenuWindowCascade };
1117 MenuItem { windowMenu, "Tile Horizontally", h, NotifySelect = MenuWindowTileHorz };
1118 MenuItem { windowMenu, "Tile Vertically", v, NotifySelect = MenuWindowTileVert };
1119 MenuItem { windowMenu, "Arrange Icons", a, NotifySelect = MenuWindowArrangeIcons };
1120 MenuDivider { windowMenu };
1121 MenuItem { windowMenu, "Windows...", w, NotifySelect = MenuWindowWindows };
1122 Menu helpMenu { menu, "Help", h };
1125 helpMenu, "API Reference", r, f1;
1126 bool NotifySelect(MenuItem selection, Modifiers mods)
1128 Execute("documentor");
1132 MenuDivider { helpMenu };
1135 helpMenu, "About...", a;
1136 bool NotifySelect(MenuItem selection, Modifiers mods)
1138 AboutIDE { master = this }.Modal();
1143 property ToolBox toolBox
1145 get { return toolBox; }
1148 property Sheet sheet
1150 get { return sheet; }
1153 property Project project
1155 get { return projectView ? projectView.project : null; }
1158 property Workspace workspace
1160 get { return projectView ? projectView.workspace : null; }
1163 FindInFilesDialog findInFilesDialog
1165 master = this, parent = this;
1166 filters = findInFilesFileFilters, sizeFilters = sizeof(findInFilesFileFilters);
1170 #ifdef GDB_DEBUG_GUI
1173 master = this, parent = this;
1174 anchor = { left = 100, top = 100, right = 100, bottom = 100 };
1176 void OnCommand(char * string)
1179 ide.debugger.SendGDBCommand(string);
1184 bool NotifySelectDisplayDriver(MenuItem selection, Modifiers mods)
1186 //app.driver = app.drivers[selection.id];
1188 app.driver = selection.id ? "OpenGL" : "X";
1190 app.driver = selection.id ? "OpenGL" : "GDI";
1192 delete ideSettings.displayDriver;
1193 ideSettings.displayDriver = CopyString(selection.id ? "OpenGL" : "Default");
1195 settingsContainer.Save();
1196 //SetDriverAndSkin();
1200 bool NotifySelectDisplaySkin(MenuItem selection, Modifiers mods)
1202 app.skin = app.skins[selection.id];
1207 void SetDriverAndSkin()
1210 for(c = 0; c < app.numSkins; c++)
1211 if(!strcmp(app.skins[c], app.skin))
1213 skinItems[c].checked = true;
1216 for(c = 0; c < app.numDrivers; c++)
1217 if(!strcmp(app.drivers[c], app.driver))
1219 driverItems[c].checked = true;
1224 ProjectView CreateProjectView(Workspace workspace, char * fileName)
1226 Project project = workspace.projects.firstIterator.data;
1227 projectView = ProjectView
1230 fileName = fileName;
1232 void NotifyDestroyed(Window window, DialogResult result)
1235 text = titleECEREIDE;
1237 UpdateDisabledMenus();
1239 viewProjectItem.disabled = true;
1242 projectView.Create();
1243 RepositionWindows(false);
1245 // Leave it after Create to avoid flicker due to seeing IDE without a project view
1246 projectView.workspace = workspace;
1247 projectView.project = project;
1248 SetText("%s - %s", project.topNode.name, titleECEREIDE);
1250 UpdateDisabledMenus();
1251 if(project.targetType == executable)
1252 DebugUpdateMenus(loaded, false);
1254 projectCloseItem.disabled = false;
1255 projectBuildItem.disabled = false;
1256 projectRebuildItem.disabled = false;
1257 projectRegenerateItem.disabled = false;
1258 projectCompileItem.disabled = false;
1259 projectLinkItem.disabled = false;
1260 projectCleanItem.disabled = false;
1261 viewProjectItem.disabled = false;
1263 if(project.config.targetType == executable)
1265 projectRunItem.disabled = false;
1266 debugStartResumeItem.disabled = false;
1267 DebugUpdateMenus(loaded, false);
1269 projectActiveConfigItem.disabled = false;
1270 projectSettingsItem.disabled = false;
1273 ide.breakpointsView.LoadFromWorkspace();
1274 ide.watchesView.LoadFromWorkspace();
1277 char fileName[MAX_LOCATION];
1278 strcpy(fileName, project.topNode.path);
1279 PathCat(fileName, project.topNode.name);
1284 bool GetDebugMenusDisabled()
1288 Project project = projectView.project;
1290 if(project.targetType == executable)
1297 void RepositionWindows(bool expand)
1302 bool inDebugMode = debugger.isInDebugMode;
1303 bool callStackVisible = expand ? false : callStackView.visible;
1304 bool threadsVisible = expand ? false : threadsView.visible;
1305 bool watchesVisible = expand ? false : watchesView.visible;
1306 bool breakpointsVisible = expand ? false : breakpointsView.visible;
1307 bool toolBoxVisible = toolBox.visible;
1308 bool outputVisible = expand ? false : outputView.visible;
1309 int topDistance = (callStackVisible || threadsVisible) ? 200 : 0;
1310 int bottomDistance = (outputVisible || watchesVisible || breakpointsVisible) ? 240 : 0;
1312 for(child = firstChild; child; child = child.next)
1314 if(child._class == class(CodeEditor) || child._class == class(Designer) ||
1315 child._class == class(Sheet) || child._class == class(ProjectView))
1317 Anchor anchor = child.anchor;
1318 anchor.top = topDistance;
1319 anchor.bottom = bottomDistance;
1320 if(child._class == class(CodeEditor) || child._class == class(Designer))
1322 anchor.right = toolBoxVisible ? 150 : 0;
1324 child.anchor = anchor;
1328 if(child._class == class(OutputView) || child._class == class(CallStackView) || child._class == class(ThreadsView) || child._class == class(WatchesView) ||
1329 child._class == class(BreakpointsView))
1330 child.visible = false;
1333 // If this is not here, the IDE is not updated when doing Debug/Break then Alt-4 to show call stack (IDE not updated)
1338 bool ShowCodeEditor()
1341 activeClient.Activate();
1342 else if(projectView)
1344 projectView.visible = true;
1345 projectView.Activate();
1349 sheet.visible = true;
1355 void DisableBuildItems(bool disabled, bool debugStart)
1359 projectNewItem.disabled = disabled;
1360 projectOpenItem.disabled = disabled;
1361 projectCompileItem.disabled = disabled;
1362 projectRebuildItem.disabled = disabled;
1363 projectRegenerateItem.disabled = disabled;
1364 projectLinkItem.disabled = disabled;
1365 projectBuildItem.disabled = disabled;
1366 projectCleanItem.disabled = disabled;
1367 projectCloseItem.disabled = disabled;
1368 projectRunItem.disabled = disabled;
1370 debugStartResumeItem.disabled = debugStart;
1373 debugRestartItem.disabled = true;
1374 debugBreakItem.disabled = true;
1375 debugStopItem.disabled = true;
1377 /*else if(!debugStart)
1379 debugRestartItem.disabled = false;
1380 debugBreakItem.disabled = false;
1381 debugStopItem.disabled = false;
1384 buildInProgress = disabled;
1385 if(!disabled) stopBuild = false;
1389 void StopBuild(bool state)
1394 bool ShouldStopBuild()
1399 void DocumentSaved(Window document, char * fileName)
1401 ideSettings.AddRecentFile(fileName);
1402 ide.UpdateRecentMenus();
1403 settingsContainer.Save();
1406 bool Window::OnFileModified(FileChange fileChange, char * param)
1409 sprintf(temp, "The document %s was modified by another application.\n"
1410 "Would you like to reload it and lose your changes?", this.fileName);
1411 if(MessageBox { type = yesNo, master = this/*.parent*/,
1412 text = "Document has been modified", contents = temp }.Modal() == yes)
1414 char * fileName = CopyString(this.fileName);
1415 WindowState state = this.state;
1416 Anchor anchor = this.anchor;
1417 Size size = this.size;
1419 this.modifiedDocument = false;
1421 this = ide.OpenFile(fileName, normal, true, null, no, normal);
1424 this.anchor = anchor;
1426 this.SetState(state, true, 0);
1434 void UpdateMakefiles()
1438 for(prj : workspace.projects)
1440 bool first = prj == workspace.projects.firstIterator.data;
1441 projectView.ProjectUpdateMakefileForAllConfigs(prj, first, first);
1446 void UpdateDisabledMenus()
1448 projectQuickItem.disabled = (bool)projectView;
1449 projectAddItem.disabled = !projectView;
1450 projectCloseItem.disabled = !projectView;
1452 activeCompilerItem.disabled = !projectView;
1453 projectActiveConfigItem.disabled = !projectView;
1454 projectSettingsItem.disabled = !projectView;
1456 projectBrowseFolderItem.disabled = !projectView;
1457 projectRunItem.disabled = projectView && project.targetType != executable;
1458 projectBuildItem.disabled = !projectView;
1459 projectLinkItem.disabled = !projectView;
1460 projectRebuildItem.disabled = !projectView;
1461 projectCleanItem.disabled = !projectView;
1462 projectRegenerateItem.disabled = !projectView;
1463 projectCompileItem.disabled = !projectView;
1465 debugStartResumeItem.disabled = !projectView; // && project.targetType == executable);
1466 debugRestartItem.disabled = true;
1467 debugBreakItem.disabled = true;
1468 debugStopItem.disabled = true;
1470 debugStepIntoItem.disabled = true;
1471 debugStepOverItem.disabled = true;
1472 debugStepOutItem.disabled = true;
1473 debugRunToCursorItem.disabled = true;
1474 debugSkipStepOverItem.disabled = true;
1475 debugSkipStepOutItem.disabled = true;
1476 debugSkipRunToCursorItem.disabled = true;
1478 viewProjectItem.disabled = !projectView;
1481 void DebugUpdateMenus(DebuggerState state, bool breaking)
1483 debugStartResumeItem.text = (state == loaded) ? "Start" : "Resume";
1484 debugStartResumeItem.NotifySelect = (state == loaded) ? MenuDebugStart : MenuDebugResume;
1485 debugStartResumeItem.disabled = (state == running);
1486 debugBreakItem.disabled = (state != running || breaking);
1487 debugStopItem.disabled = (state == loaded);
1488 debugRestartItem.disabled = (state == loaded);
1490 debugStepIntoItem.disabled = (state == running);
1491 debugStepOverItem.disabled = (state == running);
1492 debugStepOutItem.disabled = (state == running) || (state == loaded);
1493 debugSkipStepOverItem.disabled = (state == running);
1494 debugSkipStepOutItem.disabled = (state == running) || (state == loaded);
1496 if((Designer)GetActiveDesigner())
1498 CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor;
1501 codeEditor.debugRunToCursor.disabled = (state == running);
1502 codeEditor.debugSkipRunToCursor.disabled = (state == running);
1507 void ChangeFileDialogsDirectory(char * directory, bool saveSettings)
1509 char tempString[MAX_LOCATION];
1510 strcpy(tempString, directory);
1511 if(saveSettings && !projectView)
1513 ideSettings.ideFileDialogLocation = directory;
1514 settingsContainer.Save();
1517 ideFileDialog.currentDirectory = tempString;
1518 codeEditorFileDialog.currentDirectory = tempString;
1519 codeEditorFormFileDialog.currentDirectory = tempString;
1522 void ChangeProjectFileDialogDirectory(char * directory)
1524 ideSettings.ideProjectFileDialogLocation = directory;
1525 settingsContainer.Save();
1528 Window FindWindow(char * filePath)
1530 Window document = null;
1532 // TOCHECK: Do we need to change slashes here?
1533 for(document = firstChild; document; document = document.next)
1535 char * fileName = document.fileName;
1536 if(document.isDocument && fileName && !fstrcmp(fileName, filePath))
1538 document.visible = true;
1539 document.Activate();
1546 bool DontTerminateDebugSession(char * title)
1548 if(debugger.isActive)
1550 if(MessageBox { type = yesNo, master = ide,
1551 contents = "Do you want to terminate the debugging session in progress?",
1552 text = title }.Modal() == no)
1555 MessageBox msg { type = yesNo, master = ide,
1556 contents = "Do you want to terminate the debugging session in progress?",
1558 if(msg.Modal() == no)
1570 Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod)
1572 char extension[MAX_EXTENSION] = "";
1573 Window document = null;
1574 bool isProject = false;
1575 bool needFileModified = true;
1576 char winFilePath[MAX_LOCATION];
1577 char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath);
1581 GetExtension(filePath, extension);
1585 strcpy(extension, type);
1587 if(strcmp(extension, ProjectExtension))
1589 for(document = firstChild; document; document = document.next)
1591 char * fileName = document.fileName;
1592 if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created)
1594 document.visible = true;
1595 document.Activate();
1601 if(createIfFails == whatever)
1603 else if(!strcmp(extension, ProjectExtension) || !strcmp(extension, WorkspaceExtension))
1605 if(openMethod == normal)
1607 if(DontTerminateDebugSession("Open Project"))
1610 if(MenuWindowCloseAll(null, 0))
1614 projectView.visible = false;
1615 projectView.Destroy(0);
1616 // Where did this come from? projectView = null;
1623 Workspace workspace = null;
1625 if(FileExists(filePath))
1627 if(!strcmp(extension, ProjectExtension))
1629 char workspaceFile[MAX_LOCATION];
1630 strcpy(workspaceFile, filePath);
1631 ChangeExtension(workspaceFile, WorkspaceExtension, workspaceFile);
1632 workspace = LoadWorkspace(workspaceFile, filePath);
1634 else if(!strcmp(extension, WorkspaceExtension))
1635 workspace = LoadWorkspace(filePath, null);
1638 //project = LoadProject(filePath);
1643 char absolutePath[MAX_LOCATION];
1644 CreateProjectView(workspace, filePath);
1645 document = projectView;
1647 workspace.DropInvalidBreakpoints();
1650 ide.projectView.ShowOutputBuildLog(true);
1651 ide.projectView.DisplayCompiler(false);
1654 char newWorkingDir[MAX_LOCATION];
1655 StripLastDirectory(filePath, newWorkingDir);
1656 ChangeFileDialogsDirectory(newWorkingDir, false);
1659 document.fileName = filePath;
1661 SetText("%s - %s", filePath, titleECEREIDE);
1663 // this crashes on starting ide with epj file, solution please?
1664 // app.UpdateDisplay();
1666 workspace.holdTracking = true;
1667 for(ofi : workspace.openedFiles)
1669 if(ofi.state != closed)
1671 Window file = OpenFile(ofi.path, normal, true, null, no, normal);
1674 char fileName[MAX_LOCATION];
1676 GetLastDirectory(ofi.path, fileName);
1677 node = projectView.project.topNode.Find(fileName, true);
1679 node.EnsureVisible();
1683 workspace.holdTracking = false;
1685 workspace.timer.Start();
1687 findInFilesDialog.mode = FindInFilesMode::project;
1688 findInFilesDialog.currentDirectory = ide.project.topNode.path;
1691 char location[MAX_LOCATION];
1692 StripLastDirectory(ide.project.topNode.path, location);
1693 ChangeProjectFileDialogDirectory(location);
1697 if(projectView.debugger)
1698 projectView.debugger.EvaluateWatches();
1705 if(MessageBox { type = yesNo, parent = this, text = "Error opening project", contents = "Open a different project?" }.Modal() == yes)
1707 if(ideProjectFileDialog.Modal() == cancel)
1709 filePath = ideProjectFileDialog.filePath;
1710 GetExtension(filePath, extension);
1721 else if(openMethod == add)
1726 char slashFilePath[MAX_LOCATION];
1727 GetSlashPathBuffer(slashFilePath, filePath);
1728 for(p : workspace.projects)
1730 if(!fstrcmp(p.filePath, slashFilePath))
1738 MessageBox { type = ok, parent = parent, master = this, text = "Same Project",
1739 contents = "This project is already present in workspace." }.Modal();
1743 prj = LoadProject(filePath);
1746 workspace.projects.Add(prj);
1748 projectView.AddNode(prj.topNode, null);
1749 workspace.modified = true;
1751 findInFilesDialog.AddProjectItem(prj);
1752 projectView.ProjectUpdateMakefileForAllConfigs(prj, true, true);
1753 // projectView is associated with the main project and not with the one just added but
1754 return projectView; // just to let the caller know something was opened
1762 else if(!strcmp(extension, "bmp") || !strcmp(extension, "pcx") ||
1763 !strcmp(extension, "jpg") || !strcmp(extension, "gif") ||
1764 !strcmp(extension, "jpeg") || !strcmp(extension, "png"))
1766 if(FileExists(filePath))
1767 document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1768 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1769 visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/;
1772 MessageBox { type = ok, parent = this, text = filePath, contents = "File doesn't exist." }.Modal();
1775 else if(!strcmp(extension, "3ds"))
1777 if(FileExists(filePath))
1778 document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable,
1779 hasVertScroll = true, hasHorzScroll = true, parent = this, state = state,
1780 visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/
1784 MessageBox { type = ok, parent = this, text = filePath, contents = "File doesn't exist." }.Modal();
1787 else if(!strcmp(extension, "txt") || !strcmp(extension, "text") ||
1788 !strcmp(extension, "nfo") || !strcmp(extension, "info") ||
1789 !strcmp(extension, "htm") || !strcmp(extension, "html") ||
1790 !strcmp(extension, "css") || !strcmp(extension, "php") ||
1791 !strcmp(extension, "js"))
1793 CodeEditor editor { parent = this, state = state, visible = false };
1794 editor.updatingCode = true;
1795 if(editor.LoadFile(filePath))
1798 editor.visible = true;
1802 needFileModified = false;
1806 CodeEditor editor { parent = this, state = state, visible = false };
1807 if(editor.LoadFile(filePath))
1810 editor.visible = true;
1814 needFileModified = false;
1817 if(document && (document._class == class(PictureEdit) ||
1818 document._class == class(ModelView)))
1823 document.fileName = filePath;
1824 if(workspace && !workspace.holdTracking)
1825 workspace.UpdateOpenedFileInfo(filePath, opened);
1829 if(!document && createIfFails != no)
1831 if(createIfFails != yes && !needFileModified &&
1832 MessageBox { type = yesNo, parent = this, text = filePath, contents = "File doesn't exist. Create?" }.Modal() == yes)
1833 createIfFails = yes;
1834 if(createIfFails == yes || createIfFails == whatever)
1836 document = (Window)NewCodeEditor(this, state, true);
1838 document.fileName = filePath;
1844 if(projectView && document._class == class(CodeEditor) && workspace)
1846 int lineNumber, position;
1848 CodeEditor editor = (CodeEditor)document;
1849 editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened);
1850 editor.openedFileInfo.holdTracking = true;
1851 lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0);
1852 position = Max(editor.openedFileInfo.position - 1, 0);
1853 editor.editBox.GoToLineNum(lineNumber);
1854 editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position);
1855 scroll.x = Max(editor.openedFileInfo.scroll.x, 0);
1856 scroll.y = Max(editor.openedFileInfo.scroll.y, 0);
1857 editor.editBox.scroll = scroll;
1858 editor.openedFileInfo.holdTracking = false;
1861 if(needFileModified)
1862 document.OnFileModified = OnFileModified;
1863 document.NotifySaved = DocumentSaved;
1866 ideSettings.AddRecentProject(document.fileName);
1868 ideSettings.AddRecentFile(document.fileName);
1869 ide.UpdateRecentMenus();
1870 settingsContainer.Save();
1878 // TOCHECK: I can't use a generic one for both ModelView and PictureEdit both derived from Window
1879 /*bool Window::GenericDocumentOnClose(bool parentClosing)
1881 if(!parentClosing && ide.workspace)
1882 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1885 bool ModelView::ModelViewOnClose(bool parentClosing)
1887 if(!parentClosing && ide.workspace)
1888 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1891 bool PictureEdit::PictureEditOnClose(bool parentClosing)
1893 if(!parentClosing && ide.workspace)
1894 ide.workspace.UpdateOpenedFileInfo(fileName, unknown);
1899 void OnUnloadGraphics(Window window)
1901 display.ClearMaterials();
1902 display.ClearTextures();
1903 display.ClearMeshes();
1907 bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct)
1909 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
1910 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
1914 bool OnKeyDown(Key key, unichar ch)
1919 projectView.Update(null);
1922 caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 };
1925 num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 };
1931 void GoToError(const char * line)
1934 projectView.GoToError(line);
1937 void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir)
1940 char *colon = strchr(text, ':');
1941 char filePath[MAX_LOCATION];
1942 char completePath[MAX_LOCATION];
1943 int line = 0, col = 0;
1948 char * close = strchr(text, ')');
1952 strncpy(name, &text[4], close - text - 4);
1953 name[close - text - 4] = '\0';
1954 for(p : ide.workspace.projects)
1956 if(!strcmp(p.name, name))
1966 prj = project ? project : (dir ? null : ide.project);
1967 if(colon && (colon[1] == '/' || colon[1] == '\\'))
1969 path = (colon - 1 > path) ? colon - 1 : path;
1970 colon = strstr(colon + 1, ":");
1972 while(isspace(*path)) path++;
1975 strncpy(filePath, path, colon - path);
1976 filePath[colon - path] = '\0';
1977 line = atoi(colon + 1);
1978 colon = strstr(colon + 1, ":");
1980 col = atoi(colon + 1);
1982 else if(path - 1 >= path && *(path - 1) == '\"')
1984 colon = strchr(path, '\"');
1987 strncpy(filePath, path, colon - path);
1988 filePath[colon - path] = '\0';
1993 strcpy(completePath, prj.topNode.path);
1994 else if(dir && dir[0])
1995 strcpy(completePath, dir);
1997 completePath[0] = '\0';
1998 PathCat(completePath, filePath);
2000 if(FileExists(completePath).isFile)
2002 CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal);
2003 if(codeEditor && line)
2005 EditBox editBox = codeEditor.editBox;
2006 editBox.GoToLineNum(line - 1);
2007 editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0);
2012 void OnRedraw(Surface surface)
2014 Bitmap bitmap = back.bitmap;
2016 surface.Blit(bitmap, (clientSize.w - bitmap.width) / 2, (clientSize.h - bitmap.height) / 2, 0, 0, bitmap.width, bitmap.height);
2019 void SheetSelected(SheetType sheetSelected)
2021 if(activeChild == sheet)
2023 if(sheetSelected == methods)
2025 viewPropertiesItem.accelerator = f4;
2026 viewPropertiesItem.parent = viewMenu;
2027 viewMethodsItem.parent = null;
2031 viewMethodsItem.accelerator = f4;
2032 viewMethodsItem.parent = viewMenu;
2033 viewPropertiesItem.parent = null;
2038 viewMethodsItem.parent = viewMenu;
2039 viewPropertiesItem.parent = viewMenu;
2040 if(sheetSelected == methods)
2042 viewMethodsItem.accelerator = f4;
2043 viewPropertiesItem.accelerator = 0;
2047 viewMethodsItem.accelerator = 0;
2048 viewPropertiesItem.accelerator = f4;
2053 void OnActivateClient(Window client, Window previous)
2055 //if(!client || client != previous)
2058 if(!client || client != previous)
2061 dataType = previous._class;
2062 if(previous && !strcmp(dataType.name, "CodeEditor"))
2064 ((CodeEditor)previous).UpdateFormCode();
2066 else if(previous && !strcmp(dataType.name, "Designer"))
2068 ((Designer)previous).codeEditor.UpdateFormCode();
2073 dataType = client._class;
2074 if(client && !strcmp(dataType.name, "CodeEditor"))
2076 CodeEditor codeEditor = (CodeEditor)client;
2077 SetPrivateModule(codeEditor.privateModule);
2078 SetCurrentContext(codeEditor.globalContext);
2079 SetTopContext(codeEditor.globalContext);
2080 SetGlobalContext(codeEditor.globalContext);
2082 SetDefines(&codeEditor.defines);
2083 SetImports(&codeEditor.imports);
2085 SetActiveDesigner(codeEditor.designer);
2087 sheet.codeEditor = codeEditor;
2088 toolBox.codeEditor = codeEditor;
2090 viewDesignerItem.parent = viewMenu;
2091 if(activeChild != codeEditor)
2093 viewCodeItem.parent = viewMenu;
2094 viewDesignerItem.accelerator = 0;
2095 viewCodeItem.accelerator = f8;
2099 viewCodeItem.parent = null;
2100 viewDesignerItem.accelerator = f8;
2103 else if(client && !strcmp(dataType.name, "Designer"))
2105 CodeEditor codeEditor = ((Designer)client).codeEditor;
2108 SetPrivateModule(codeEditor.privateModule);
2109 SetCurrentContext(codeEditor.globalContext);
2110 SetTopContext(codeEditor.globalContext);
2111 SetGlobalContext(codeEditor.globalContext);
2112 SetDefines(&codeEditor.defines);
2113 SetImports(&codeEditor.imports);
2117 SetPrivateModule(null);
2118 SetCurrentContext(null);
2119 SetTopContext(null);
2120 SetGlobalContext(null);
2125 SetActiveDesigner((Designer)client);
2127 sheet.codeEditor = codeEditor;
2128 toolBox.codeEditor = codeEditor;
2130 viewCodeItem.parent = viewMenu;
2131 if(activeChild != client)
2133 viewDesignerItem.parent = viewMenu;
2134 viewDesignerItem.accelerator = f8;
2135 viewCodeItem.accelerator = 0;
2139 viewDesignerItem.parent = null;
2140 viewCodeItem.accelerator = f8;
2146 sheet.codeEditor = null;
2147 toolBox.codeEditor = null;
2148 SetActiveDesigner(null);
2150 viewDesignerItem.parent = null;
2151 viewCodeItem.parent = null;
2154 SheetSelected(sheet.sheetSelected);
2157 projectCompileItem = null;
2162 if(client && client._class == eSystem_FindClass(__thisModule, "CodeEditor")) // !strcmp(client._class.name, "CodeEditor")
2164 CodeEditor codeEditor = (CodeEditor)client;
2165 EditBox editBox = codeEditor.editBox;
2167 statusBar.AddField(pos);
2169 caps = { width = 40, text = "CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } };
2170 statusBar.AddField(caps);
2172 ovr = { width = 30, text = "OVR", color = editBox.overwrite ? black : Color { 128, 128, 128 } };
2173 statusBar.AddField(ovr);
2175 num = { width = 30, text = "NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } };
2176 statusBar.AddField(num);
2178 //statusBar.text = "Ready";
2180 if(projectView && projectView.project)
2182 ProjectNode node = projectView.GetNodeFromWindow(client, null);
2186 sprintf(name, "Compile %s", node.name);
2187 projectCompileItem =
2189 copyText = true, text = name, c, ctrlF7, disabled = buildInProgress;
2191 bool NotifySelect(MenuItem selection, Modifiers mods)
2195 ProjectNode node = projectView.GetNodeFromWindow(activeClient, null);
2197 projectView.Compile(node);
2202 projectMenu.AddDynamic(projectCompileItem, null, false);
2208 caps = ovr = num = null;
2213 bool OnClose(bool parentClosing)
2215 //return !buildInProgress;
2218 if(DontTerminateDebugSession("Close IDE"))
2220 if(findInFilesDialog)
2221 findInFilesDialog.SearchStop();
2224 workspace.timer.Stop();
2233 for(c = 1; c<app.argc; c++)
2235 char fullPath[MAX_LOCATION];
2236 GetWorkingDir(fullPath, MAX_LOCATION);
2237 PathCat(fullPath, app.argv[c]);
2238 if(FileExists(fullPath))
2239 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2246 // IS THIS NEEDED? WASN'T HERE BEFORE...
2249 projectView.visible = false;
2250 projectView.Destroy(0);
2253 #ifdef GDB_DEBUG_GUI
2254 gdbDialog.Destroy(0);
2259 void SetPath(bool projectsDirs)
2263 char * oldPaths[128];
2264 char oldList[MAX_LOCATION * 128];
2265 Array<String> newExePaths { };
2266 //Map<String, bool> exePathExists { };
2268 #if defined(__unix__) || defined(__APPLE__)
2269 Array<String> newLibPaths { };
2270 Map<String, bool> libPathExists { };
2272 CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
2276 for(prj : workspace.projects)
2278 DirExpression targetDirExp;
2280 // SKIP FIRST PROJECT...
2281 if(prj == workspace.projects.firstIterator.data) continue;
2283 targetDirExp = prj.targetDir;
2285 /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
2289 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2290 if(cfg.targetType == sharedLibrary && cfg.debug && !strcmpi(cfg.name, "Debug"))
2294 for(cfg = prj.configurations.first; cfg; cfg = cfg.next)
2295 if(cfg.targetType == sharedLibrary && cfg.debug)
2299 if(targetDirExp.dir)
2301 char buffer[MAX_LOCATION];
2302 #if defined(__WIN32__)
2303 Array<String> paths = newExePaths;
2305 Array<String> paths = newLibPaths;
2307 GetSystemPathBuffer(buffer, prj.topNode.path);
2308 PathCat(buffer, targetDirExp.dir);
2311 if(!fstrcmp(p, buffer))
2318 paths.Add(CopyString(buffer));
2320 delete targetDirExp;
2324 for(item : compiler.executableDirs)
2327 for(p : newExePaths)
2329 if(!fstrcmp(p, item))
2336 newExePaths.Add(CopySystemPath(item));
2339 GetEnvironment("PATH", oldList, sizeof(oldList));
2341 printf("Old value of PATH: %s\n", oldList);
2343 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2344 for(c = 0; c < count; c++)
2347 for(p : newExePaths)
2349 if(!fstrcmp(p, oldPaths[c]))
2356 newExePaths.Add(CopySystemPath(oldPaths[c]));
2360 for(path : newExePaths)
2361 len += strlen(path) + 1;
2362 newList = new char[len + 1];
2364 for(path : newExePaths)
2366 strcat(newList, path);
2367 strcat(newList, pathListSep);
2369 newList[len - 1] = '\0';
2370 SetEnvironment("PATH", newList);
2372 printf("New value of PATH: %s\n", newList);
2379 #if defined(__unix__) || defined(__APPLE__)
2381 for(item : compiler.libraryDirs)
2383 if(!libPathExists[item]) // fstrcmp should be used
2385 newLibPaths.Add(item);
2386 libPathExists[item] = true;
2390 #if defined(__APPLE__)
2391 GetEnvironment("DYLD_LIBRARY_PATH", oldList, sizeof(oldList));
2393 GetEnvironment("LD_LIBRARY_PATH", oldList, sizeof(oldList));
2396 printf("Old value of [DY]LD_LIBRARY_PATH: %s\n", oldList);
2398 count = TokenizeWith(oldList, sizeof(oldPaths) / sizeof(char *), oldPaths, pathListSep, false);
2399 for(c = 0; c < count; c++)
2401 if(!libPathExists[oldPaths[c]]) // fstrcmp should be used
2403 newLibPaths.Add(oldPaths[c]);
2404 libPathExists[oldPaths[c]] = true;
2409 for(path : newLibPaths)
2410 len += strlen(path) + 1;
2411 newList = new char[len + 1];
2413 for(path : newLibPaths)
2415 strcat(newList, path);
2416 strcat(newList, pathListSep);
2418 newList[len - 1] = '\0';
2419 #if defined(__APPLE__)
2420 SetEnvironment("DYLD_LIBRARY_PATH", newList);
2422 SetEnvironment("LD_LIBRARY_PATH", newList);
2425 printf("New value of [DY]LD_LIBRARY_PATH: %s\n", newList);
2430 delete libPathExists;
2435 void DestroyTemporaryProjectDir()
2437 if(tmpPrjDir && tmpPrjDir[0])
2439 if(FileExists(tmpPrjDir).isDirectory)
2440 DestroyDir(tmpPrjDir);
2441 property::tmpPrjDir = null;
2447 // Graphics Driver Menu
2450 driverItems = new MenuItem[app.numDrivers];
2451 for(c = 0; c < app.numDrivers; c++)
2453 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2454 driverItems[c].id = c;
2455 driverItems[c].isRadio = true;
2458 driverItems = new MenuItem[2];
2459 #if defined(__unix__)
2460 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2461 driverItems[0].id = 0;
2462 driverItems[0].isRadio = true;
2464 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2465 driverItems[0].id = 0;
2466 driverItems[0].isRadio = true;
2468 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2469 driverItems[1].id = 1;
2470 driverItems[1].isRadio = true;
2472 /* skinItems = new MenuItem[app.numSkins];
2473 for(c = 0; c < app.numSkins; c++)
2475 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2476 skinItems[c].id = c;
2477 skinItems[c].isRadio = true;
2480 ideFileDialog.master = this;
2481 ideProjectFileDialog.master = this;
2483 //SetDriverAndSkin();
2487 void UpdateRecentMenus()
2490 Menu fileMenu = menu.FindMenu("File");
2491 Menu recentFiles = fileMenu.FindMenu("Recent Files");
2492 Menu recentProjects = fileMenu.FindMenu("Recent Projects");
2493 char itemName[MAX_LOCATION + 4];
2496 recentFiles.Clear();
2499 for(recent : ideSettings.recentFiles)
2501 sprintf(itemName, "%d %s", 1 + c, recent);
2502 MakeSystemPath(itemName);
2503 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, null, true);
2507 recentProjects.Clear();
2509 for(recent : ideSettings.recentProjects)
2511 sprintf(itemName, "%d %s", 1 + c, recent);
2512 MakeSystemPath(itemName);
2513 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, null, true);
2525 void DestroyDir(char * path)
2527 RecursiveDeleteFolderFSI fsi { };
2532 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2534 bool preserveRootFolder;
2536 void OutFolder(char * folderPath, bool isRoot)
2538 if(!(preserveRootFolder && isRoot))
2539 RemoveDir(folderPath);
2542 bool OnFile(char * filePath)
2544 DeleteFile(filePath);
2549 class IDEApp : GuiApplication
2551 //driver = "Win32Console";
2552 // driver = "OpenGL";
2557 SetLoggingMode(stdOut, null);
2558 //SetLoggingMode(debug, null);
2560 settingsContainer.Load();
2561 #if defined(__unix__) || defined(__APPLE__)
2562 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2564 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2566 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2570 desktop.text = titleECEREIDE;
2573 for(c = 1; c<app.argc; c++)
2575 char fullPath[MAX_LOCATION];
2576 GetWorkingDir(fullPath, MAX_LOCATION);
2577 PathCat(fullPath, app.argv[c]);
2578 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2587 define app = ((IDEApp)__thisModule);
2589 define titleECEREIDE = "ECERE IDE (Debug)";
2591 define titleECEREIDE = "ECERE IDE";