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 Debugger debugger { };
243 ProjectView projectView;
245 OutputView outputView
249 void OnGotoError(char * line)
254 void OnCodeLocationParseAndGoTo(char * line)
256 ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir);
259 bool OnKeyDown(Key key, unichar ch)
264 if(!ide.findInFilesDialog || !ide.findInFilesDialog.SearchAbort())
265 ide.ShowCodeEditor();
268 ide.projectView.stopBuild = true;
272 OutputView::OnKeyDown(key, ch);
279 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
282 ide.RepositionWindows(false);
286 bool OnClose(bool parentClosing)
290 ide.RepositionWindows(false);
291 return parentClosing;
295 CallStackView callStackView
297 parent = this, font = { panelFont.faceName, panelFont.size };
299 void OnGotoLine(char * line)
302 stackLvl = atoi(line);
303 ide.debugger.GoToStackFrameLine(stackLvl, true);
306 void OnSelectFrame(int lineNumber)
308 ide.debugger.SelectFrame(lineNumber);
311 void OnToggleBreakpoint()
313 Debugger debugger = ide.debugger;
314 if(debugger.activeFrame && debugger.activeFrame.absoluteFile)
316 int line = debugger.activeFrame.line;
317 char name[MAX_LOCATION];
319 // TOFIX: Improve on this, don't use only filename, make a function
320 GetLastDirectory(debugger.activeFrame.absoluteFile, name);
321 if(ide && ide.workspace)
323 for(p : ide.workspace.projects)
325 if(p.topNode.Find(name, false))
333 for(p : ide.workspace.projects)
335 if(eString_PathInsideOf(debugger.activeFrame.absoluteFile, p.topNode.path))
343 debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line, prj);
346 CodeEditor codeEditor = (CodeEditor)ide.FindWindow(debugger.activeFrame.absoluteFile);
347 if(codeEditor) { codeEditor.Update(null); Activate(); }
352 bool OnKeyDown(Key key, unichar ch)
356 case escape: ide.ShowCodeEditor(); break;
361 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
364 ide.RepositionWindows(false);
368 bool OnClose(bool parentClosing)
372 ide.RepositionWindows(false);
373 return parentClosing;
376 void OnRedraw(Surface surface)
379 int lineCursor, lineTopFrame, activeThread, hitThread;
380 int lineH, scrollY, boxH;
382 Breakpoint bp = null;
383 Debugger debugger = ide.debugger;
384 Frame activeFrame = debugger.activeFrame;
387 scrollY = editBox.scroll.y;
388 displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH);
390 activeThread = debugger.activeThread;
391 hitThread = debugger.hitThread;
392 debugger.GetCallStackCursorLine(&error, &lineCursor, &lineTopFrame);
394 if(activeFrame && activeFrame.absoluteFile)
396 for(i : ide.workspace.breakpoints; i.type == user)
398 if(i.absoluteFilePath && i.absoluteFilePath[0] &&
399 !fstrcmp(i.absoluteFilePath, activeFrame.absoluteFile) &&
400 activeFrame.line == i.line)
409 DrawLineMarginIcon(surface,
410 /*(lineCursor == 1 || lineTopFrame == 1) ? */ide.bmpBpHalf/* : ide.bmpBp*/,
411 lineCursor /*1*/, lineH, scrollY, boxH);
414 if(activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
415 DrawLineMarginIcon(surface,
416 (lineCursor == 1 || lineTopFrame == 1) ? ide.bmpBpHalf : ide.bmpBp,
417 1, lineH, scrollY, boxH);
419 DrawLineMarginIcon(surface, error ? ide.bmpCursorError : ide.bmpCursor, lineCursor, lineH, scrollY, boxH);
420 if(bp && lineCursor == 1) //activeThread && activeThread == hitThread && debugger.bpHit && debugger.bpHit.type == user)
421 bmp = error ? ide.bmpTopFrameHalfError : ide.bmpTopFrameHalf;
423 bmp = error ? ide.bmpTopFrameError : ide.bmpTopFrame;
424 DrawLineMarginIcon(surface, bmp, lineTopFrame, lineH, scrollY, boxH);
425 if(editBox.horzScroll && editBox.horzScroll.visible)
427 surface.SetBackground(control);
428 surface.Area(0, editBox.clientSize.h, 20 - 1, clientSize.h - 1);
433 WatchesView watchesView { parent = this };
434 ThreadsView threadsView
436 parent = this, font = { panelFont.faceName, panelFont.size };
438 bool OnKeyDown(Key key, unichar ch)
442 case escape: ide.ShowCodeEditor(); break;
447 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
450 ide.RepositionWindows(false);
454 bool OnClose(bool parentClosing)
458 ide.RepositionWindows(false);
459 return parentClosing;
462 void OnSelectThread(int threadId)
465 ide.debugger.SelectThread(threadId);
468 bool OnGetThreadsInfo(int * activeThread, int * hitThread, int * signalThread)
471 Debugger debugger = ide.debugger;
472 *activeThread = debugger.activeThread;
473 *hitThread = debugger.hitThread;
474 *signalThread = debugger.signalThread;
479 BreakpointsView breakpointsView { parent = this };
481 ToolBox toolBox { parent = this };
482 Sheet sheet { parent = this };
485 property char * tmpPrjDir { set { delete tmpPrjDir; if(value) tmpPrjDir = CopyString(value); } get { return tmpPrjDir; } };
487 Menu fileMenu { menu, "File", f };
490 fileMenu, "New", n, ctrlN;
491 bool NotifySelect(MenuItem selection, Modifiers mods)
493 Window document = (Window)NewCodeEditor(this, normal, false);
494 document.NotifySaved = DocumentSaved;
498 MenuItem fileOpenItem
500 fileMenu, "Open...", o, ctrlO;
501 bool NotifySelect(MenuItem selection, Modifiers mods)
503 if(!projectView && ideSettings.ideFileDialogLocation)
504 ideFileDialog.currentDirectory = ideSettings.ideFileDialogLocation;
507 if(ideFileDialog.Modal() == ok)
509 bool gotWhatWeWant = false;
511 int numSelections = ideFileDialog.numSelections;
512 char ** multiFilePaths = ideFileDialog.multiFilePaths;
514 for(c = 0; c < numSelections; c++)
516 if(OpenFile(multiFilePaths[c], normal, true, fileTypes[ideFileDialog.fileType].typeExtension, no, normal))
517 gotWhatWeWant = true;
520 MessageBox { type = yesNo, master = this, text = "Error opening file",
521 contents = "Open a different file?" }.Modal() == no)
523 if(!projectView && gotWhatWeWant)
524 ChangeFileDialogsDirectory(ideFileDialog.currentDirectory, true);
534 MenuItem fileCloseItem { fileMenu, "Close", c, ctrlF4, NotifySelect = MenuFileClose };
535 MenuDivider { fileMenu };
536 MenuItem fileSaveItem { fileMenu, "Save", s, ctrlS };
537 MenuItem fileSaveAsItem { fileMenu, "Save As...", a };
538 MenuItem fileSaveAllItem { fileMenu, "Save All", l, NotifySelect = MenuFileSaveAll };
539 MenuDivider { fileMenu };
542 fileMenu, "Find In Files...", f, Key { f, ctrl = true , shift = true };
543 bool NotifySelect(MenuItem selection, Modifiers mods)
545 findInFilesDialog.replaceMode = false;
546 findInFilesDialog.Show();
550 MenuItem replaceInFiles
552 fileMenu, "Replace In Files...", e, Key { r, ctrl = true , shift = true };
553 bool NotifySelect(MenuItem selection, Modifiers mods)
555 findInFilesDialog.replaceMode = true;
556 findInFilesDialog.Show();
560 MenuDivider { fileMenu };
561 MenuItem globalSettingsItem
563 fileMenu, "Global Settings...", g;
564 bool NotifySelect(MenuItem selection, Modifiers mods)
566 globalSettingsDialog.master = this;
567 if(ide.workspace && ide.workspace.compiler)
568 globalSettingsDialog.workspaceActiveCompiler = ide.workspace.compiler;
569 else if(ideSettings.defaultCompiler)
570 globalSettingsDialog.workspaceActiveCompiler = ideSettings.defaultCompiler;
571 globalSettingsDialog.Modal();
575 MenuDivider { fileMenu };
576 Menu recentFiles { fileMenu, "Recent Files", r };
577 Menu recentProjects { fileMenu, "Recent Projects", p };
578 MenuDivider { fileMenu };
579 MenuItem exitItem { fileMenu, "Exit", x, altF4, NotifySelect = MenuFileExit };
581 bool FileRecentFile(MenuItem selection, Modifiers mods)
584 for(file : ideSettings.recentFiles)
586 if(id == selection.id)
588 OpenFile(file, normal, true, null, no, normal);
596 bool FileRecentProject(MenuItem selection, Modifiers mods)
599 for(file : ideSettings.recentProjects)
601 if(id == selection.id)
603 OpenFile(file, normal, true, null, no, normal);
611 MenuPlacement editMenu { menu, "Edit", e };
613 Menu projectMenu { menu, "Project", p };
614 MenuItem projectNewItem
616 projectMenu, "New...", n, Key { n, true, true };
617 bool NotifySelect(MenuItem selection, Modifiers mods)
619 if(!DontTerminateDebugSession("New Project"))
620 if(MenuWindowCloseAll(null, 0))
622 NewProjectDialog newProjectDialog;
626 projectView.visible = false;
627 if(!projectView.Destroy(0))
631 newProjectDialog = { master = this };
632 newProjectDialog.Modal();
635 ideSettings.AddRecentProject(projectView.fileName);
636 ide.UpdateRecentMenus();
637 settingsContainer.Save();
643 MenuItem projectOpenItem
645 projectMenu, "Open...", o, Key { o, true, true };
646 bool NotifySelect(MenuItem selection, Modifiers mods)
648 if(ideSettings.ideProjectFileDialogLocation)
649 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
651 if(ideProjectFileDialog.Modal() == ok)
653 OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal);
654 //ChangeProjectFileDialogDirectory(ideProjectFileDialog.currentDirectory);
659 MenuItem projectQuickItem
661 projectMenu, "Quick...", q, f7;
662 bool NotifySelect(MenuItem selection, Modifiers mods)
665 QuickProjectDialog{ this }.Modal();
669 MenuItem projectAddItem
671 projectMenu, "Add project to workspace...", a, Key { a, true, true };
673 bool NotifySelect(MenuItem selection, Modifiers mods)
675 if(ideSettings.ideProjectFileDialogLocation)
676 ideProjectFileDialog.currentDirectory = ideSettings.ideProjectFileDialogLocation;
680 if(ideProjectFileDialog.Modal() == ok)
682 if(OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add))
684 if(MessageBox { type = yesNo, master = this, text = "Error opening project file",
685 contents = "Add a different project?" }.Modal() == no)
696 MenuItem projectCloseItem
698 projectMenu, "Close", c, disabled = true;
699 bool NotifySelect(MenuItem selection, Modifiers mods)
703 if(!ide.DontTerminateDebugSession("Project Close"))
705 if(findInFilesDialog)
706 findInFilesDialog.SearchStop();
707 projectView.visible = false;
708 if(projectView.Destroy(0))
709 MenuWindowCloseAll(null, 0);
711 char workingDir[MAX_LOCATION];
712 GetWorkingDir(workingDir, MAX_LOCATION);
713 findInFilesDialog.currentDirectory = workingDir;
720 MenuDivider { projectMenu };
721 MenuItem activeCompilerItem
723 projectMenu, "Active Compiler...", g, /*altF5, */disabled = true;
724 bool NotifySelect(MenuItem selection, Modifiers mods)
726 projectView.MenuCompiler(null, mods);
730 MenuItem projectActiveConfigItem
732 projectMenu, "Active Configuration...", g, altF5, disabled = true;
733 bool NotifySelect(MenuItem selection, Modifiers mods)
735 projectView.MenuConfig(projectView.active ? selection : null, mods);
739 MenuItem projectSettingsItem
741 projectMenu, "Settings...", s, altF7, disabled = true;
742 bool NotifySelect(MenuItem selection, Modifiers mods)
744 projectView.MenuSettings(projectView.active ? selection : null, mods);
748 MenuDivider { projectMenu };
749 MenuItem projectBrowseFolderItem
751 projectMenu, "Browse Project Folder", p, disabled = true;
752 bool NotifySelect(MenuItem selection, Modifiers mods)
755 projectView.MenuBrowseFolder(null, mods);
759 MenuDivider { projectMenu };
760 MenuItem projectRunItem
762 projectMenu, "Run", r, ctrlF5, disabled = true;
763 bool NotifySelect(MenuItem selection, Modifiers mods)
766 projectView.Run(null, mods);
770 MenuItem projectBuildItem
772 projectMenu, "Build", b, f7, disabled = true;
773 bool NotifySelect(MenuItem selection, Modifiers mods)
776 projectView.ProjectBuild(projectView.active ? selection : null, mods);
780 MenuItem projectLinkItem
782 projectMenu, "Relink", l, disabled = true;
783 bool NotifySelect(MenuItem selection, Modifiers mods)
786 projectView.ProjectLink(projectView.active ? selection : null, mods);
790 MenuItem projectRebuildItem
792 projectMenu, "Rebuild", d, shiftF7, disabled = true;
793 bool NotifySelect(MenuItem selection, Modifiers mods)
796 projectView.ProjectRebuild(projectView.active ? selection : null, mods);
800 MenuItem projectCleanItem
802 projectMenu, "Clean", e, disabled = true;
803 bool NotifySelect(MenuItem selection, Modifiers mods)
808 projectView.ProjectClean(projectView.active ? selection : null, mods);
813 MenuItem projectRegenerateItem
815 projectMenu, "Regenerate Makefile", m, disabled = true;
816 bool NotifySelect(MenuItem selection, Modifiers mods)
819 projectView.ProjectRegenerate(projectView.active ? selection : null, mods);
823 MenuItem projectCompileItem;
824 Menu debugMenu { menu, "Debug", d };
825 MenuItem debugStartResumeItem
827 debugMenu, "Start", s, f5, disabled = true;
828 NotifySelect = MenuDebugStart;
830 bool MenuDebugStart(MenuItem selection, Modifiers mods)
834 debugStartResumeItem.disabled = true; // a very rare exception to calling AdjustDebugMenus
835 if(!projectView.DebugStart())
836 debugStartResumeItem.disabled = false; // same exception
840 bool MenuDebugResume(MenuItem selection, Modifiers mods)
843 projectView.DebugResume();
846 MenuItem debugRestartItem
848 debugMenu, "Restart", r, Key { f5, ctrl = true, shift = true }, disabled = true;
849 bool NotifySelect(MenuItem selection, Modifiers mods)
852 projectView.DebugRestart();
856 MenuItem debugBreakItem
858 debugMenu, "Break", b, Key { pauseBreak, ctrl = true }, disabled = true;
859 bool NotifySelect(MenuItem selection, Modifiers mods)
862 projectView.DebugBreak();
866 MenuItem debugStopItem
868 debugMenu, "Stop", p, shiftF5, disabled = true;
869 bool NotifySelect(MenuItem selection, Modifiers mods)
872 projectView.DebugStop();
876 MenuDivider { debugMenu };
877 MenuItem debugStepIntoItem
879 debugMenu, "Step Into", i, f11, disabled = true;
880 bool NotifySelect(MenuItem selection, Modifiers mods)
883 projectView.DebugStepInto();
887 MenuItem debugStepOverItem
889 debugMenu, "Step Over", v, f10, disabled = true;
890 bool NotifySelect(MenuItem selection, Modifiers mods)
893 projectView.DebugStepOver(false);
897 MenuItem debugStepOutItem
899 debugMenu, "Step Out", o, shiftF11, disabled = true;
900 bool NotifySelect(MenuItem selection, Modifiers mods)
903 projectView.DebugStepOut(false);
907 MenuPlacement debugRunToCursorItem { debugMenu, "Run To Cursor", c };
908 MenuItem debugSkipStepOverItem
910 debugMenu, "Step Over Skipping Breakpoints", e, shiftF10, disabled = true;
911 bool NotifySelect(MenuItem selection, Modifiers mods)
914 projectView.DebugStepOver(true);
918 MenuItem debugSkipStepOutItem
920 debugMenu, "Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true;
921 bool NotifySelect(MenuItem selection, Modifiers mods)
924 projectView.DebugStepOut(true);
928 MenuPlacement debugSkipRunToCursorItem { debugMenu, "Run To Cursor Skipping Breakpoints", u };
929 //MenuDivider { debugMenu };
930 //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t };
931 MenuPlacement imageMenu { menu, "Image", i };
932 Menu viewMenu { menu, "View", v };
933 MenuItem viewProjectItem
935 viewMenu, "Project", j, alt0, disabled = true;
936 bool NotifySelect(MenuItem selection, Modifiers mods)
940 projectView.visible = true;
941 projectView.Activate();
946 MenuPlacement { viewMenu, "View Designer" };
947 MenuPlacement { viewMenu, "View Code" };
948 MenuPlacement { viewMenu, "View Properties" };
949 MenuPlacement { viewMenu, "View Methods" };
950 MenuItem viewDesignerItem
952 viewMenu, "View Designer", d, f8;
953 bool NotifySelect(MenuItem selection, Modifiers mods)
955 Window client = activeClient;
956 Class dataType = client._class;
957 if(!strcmp(dataType.name, "Designer"))
959 client.visible = true;
963 ((CodeEditor)client).ViewDesigner();
967 MenuItem viewCodeItem
969 viewMenu, "View Code", c, f8;
970 bool NotifySelect(MenuItem selection, Modifiers mods)
972 Window client = activeClient;
973 Class dataType = client._class;
974 if(!strcmp(dataType.name, "Designer"))
975 client = ((Designer)client).codeEditor;
978 // Do this after so the caret isn't moved yet...
979 client.visible = true;
983 MenuItem viewPropertiesItem
985 viewMenu, "View Properties", p, f4;
986 bool NotifySelect(MenuItem selection, Modifiers mods)
988 sheet.visible = true;
989 sheet.sheetSelected = properties;
994 MenuItem viewMethodsItem
996 viewMenu, "View Methods", m, f4;
997 bool NotifySelect(MenuItem selection, Modifiers mods)
999 sheet.visible = true;
1000 sheet.sheetSelected = methods;
1005 MenuItem viewToolBoxItem
1007 viewMenu, "View Toolbox", x, f12;
1008 bool NotifySelect(MenuItem selection, Modifiers mods)
1010 toolBox.visible = true;
1015 MenuItem viewOutputItem
1017 viewMenu, "Output", o, alt2;
1018 bool NotifySelect(MenuItem selection, Modifiers mods)
1024 MenuItem viewWatchesItem
1026 viewMenu, "Watches", w, alt3;
1027 bool NotifySelect(MenuItem selection, Modifiers mods)
1033 MenuItem viewThreadsItem
1035 viewMenu, "Threads", t, alt4;
1036 bool NotifySelect(MenuItem selection, Modifiers mods)
1042 MenuItem viewBreakpointsItem
1044 viewMenu, "Breakpoints", b, alt5;
1045 bool NotifySelect(MenuItem selection, Modifiers mods)
1047 breakpointsView.Show();
1051 MenuItem viewCallStackItem
1053 viewMenu, "Call Stack", s, alt7;
1054 bool NotifySelect(MenuItem selection, Modifiers mods)
1056 callStackView.Show();
1060 MenuItem viewAllDebugViews
1062 viewMenu, "All Debug Views", a, alt9;
1063 bool NotifySelect(MenuItem selection, Modifiers mods)
1068 callStackView.Show();
1069 breakpointsView.Show();
1073 #ifdef GDB_DEBUG_GUI
1074 MenuDivider { viewMenu };
1075 MenuItem viewGDBItem
1077 viewMenu, "GDB Dialog", g, Key { f9, shift = true, ctrl = true };
1078 bool NotifySelect(MenuItem selection, Modifiers mods)
1085 MenuDivider { viewMenu };
1086 MenuItem viewColorPicker
1088 viewMenu, "Color Picker...", c, Key { c, ctrl = true , shift = true };
1089 bool NotifySelect(MenuItem selection, Modifiers mods)
1091 ColorPicker colorPicker { master = this, parent = this, stayOnTop = true };
1092 colorPicker.Create();
1096 MenuDivider { viewMenu };
1100 viewMenu, "Full Screen", f, checkable = true;
1102 bool NotifySelect(MenuItem selection, Modifiers mods)
1104 app.fullScreen ^= true;
1106 anchor = { 0, 0, 0, 0 };
1111 Menu driversMenu { viewMenu, "Graphics Driver", v };
1112 //Menu skinsMenu { viewMenu, "GUI Skins", k };
1113 Menu windowMenu { menu, "Window", w };
1114 MenuItem { windowMenu, "Close All", l, NotifySelect = MenuWindowCloseAll };
1115 MenuDivider { windowMenu };
1116 MenuItem { windowMenu, "Next", n, f6, NotifySelect = MenuWindowNext };
1117 MenuItem { windowMenu, "Previous", p, shiftF6, NotifySelect = MenuWindowPrevious };
1118 MenuDivider { windowMenu };
1119 MenuItem { windowMenu, "Cascade", c, NotifySelect = MenuWindowCascade };
1120 MenuItem { windowMenu, "Tile Horizontally", h, NotifySelect = MenuWindowTileHorz };
1121 MenuItem { windowMenu, "Tile Vertically", v, NotifySelect = MenuWindowTileVert };
1122 MenuItem { windowMenu, "Arrange Icons", a, NotifySelect = MenuWindowArrangeIcons };
1123 MenuDivider { windowMenu };
1124 MenuItem { windowMenu, "Windows...", w, NotifySelect = MenuWindowWindows };
1125 Menu helpMenu { menu, "Help", h };
1128 helpMenu, "API Reference", r, f1;
1129 bool NotifySelect(MenuItem selection, Modifiers mods)
1131 Execute("documentor");
1135 MenuDivider { helpMenu };
1138 helpMenu, "About...", a;
1139 bool NotifySelect(MenuItem selection, Modifiers mods)
1141 AboutIDE { master = this }.Modal();
1146 property ToolBox toolBox
1148 get { return toolBox; }
1151 property Sheet sheet
1153 get { return sheet; }
1156 property Project project
1158 get { return projectView ? projectView.project : null; }
1161 property Workspace workspace
1163 get { return projectView ? projectView.workspace : null; }
1166 FindInFilesDialog findInFilesDialog
1168 master = this, parent = this;
1169 filters = findInFilesFileFilters, sizeFilters = sizeof(findInFilesFileFilters);
1173 #ifdef GDB_DEBUG_GUI
1176 master = this, parent = this;
1177 anchor = { left = 100, top = 100, right = 100, bottom = 100 };
1179 void OnCommand(char * string)
1182 ide.debugger.SendGDBCommand(string);
1187 bool NotifySelectDisplayDriver(MenuItem selection, Modifiers mods)
1189 //app.driver = app.drivers[selection.id];
1191 app.driver = selection.id ? "OpenGL" : "X";
1193 app.driver = selection.id ? "OpenGL" : "GDI";
1195 delete ideSettings.displayDriver;
1196 ideSettings.displayDriver = CopyString(selection.id ? "OpenGL" : "Default");
1198 settingsContainer.Save();
1199 //SetDriverAndSkin();
1203 bool NotifySelectDisplaySkin(MenuItem selection, Modifiers mods)
1205 app.skin = app.skins[selection.id];
1210 void SetDriverAndSkin()
1213 for(c = 0; c < app.numSkins; c++)
1214 if(!strcmp(app.skins[c], app.skin))
1216 skinItems[c].checked = true;
1219 for(c = 0; c < app.numDrivers; c++)
1220 if(!strcmp(app.drivers[c], app.driver))
1222 driverItems[c].checked = true;
1227 ProjectView CreateProjectView(Workspace workspace, char * fileName)
1229 Project project = workspace.projects.firstIterator.data;
1230 projectView = ProjectView
1233 fileName = fileName;
1235 void NotifyDestroyed(Window window, DialogResult result)
1238 text = titleECEREIDE;
1243 projectView.Create();
1244 RepositionWindows(false);
1246 // Leave it after Create to avoid flicker due to seeing IDE without a project view
1247 projectView.workspace = workspace;
1248 projectView.project = project;
1249 SetText("%s - %s", project.topNode.name, titleECEREIDE);
1253 ide.breakpointsView.LoadFromWorkspace();
1254 ide.watchesView.LoadFromWorkspace();
1256 findInFilesDialog.projectNodeField.userData = projectView;
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;
2389 if(compiler.distccEnabled && compiler.distccHosts)
2390 SetEnvironment("DISTCC_HOSTS", compiler.distccHosts);
2395 void DestroyTemporaryProjectDir()
2397 if(tmpPrjDir && tmpPrjDir[0])
2399 if(FileExists(tmpPrjDir).isDirectory)
2400 DestroyDir(tmpPrjDir);
2401 property::tmpPrjDir = null;
2407 // Graphics Driver Menu
2411 app.currentSkin.selectionColor = selectionColor;
2412 app.currentSkin.selectionText = selectionText;
2416 driverItems = new MenuItem[app.numDrivers];
2417 for(c = 0; c < app.numDrivers; c++)
2419 driverItems[c] = MenuItem { driversMenu, app.drivers[c], NotifySelect = NotifySelectDisplayDriver };
2420 driverItems[c].id = c;
2421 driverItems[c].isRadio = true;
2424 driverItems = new MenuItem[2];
2425 #if defined(__unix__)
2426 driverItems[0] = MenuItem { driversMenu, "X", NotifySelect = NotifySelectDisplayDriver };
2427 driverItems[0].id = 0;
2428 driverItems[0].isRadio = true;
2430 driverItems[0] = MenuItem { driversMenu, "GDI", NotifySelect = NotifySelectDisplayDriver };
2431 driverItems[0].id = 0;
2432 driverItems[0].isRadio = true;
2434 driverItems[1] = MenuItem { driversMenu, "OpenGL", NotifySelect = NotifySelectDisplayDriver };
2435 driverItems[1].id = 1;
2436 driverItems[1].isRadio = true;
2438 /* skinItems = new MenuItem[app.numSkins];
2439 for(c = 0; c < app.numSkins; c++)
2441 skinItems[c] = MenuItem {skinsMenu, app.skins[c], NotifySelect = NotifySelectDisplaySkin };
2442 skinItems[c].id = c;
2443 skinItems[c].isRadio = true;
2446 ideFileDialog.master = this;
2447 ideProjectFileDialog.master = this;
2449 //SetDriverAndSkin();
2453 void UpdateRecentMenus()
2456 Menu fileMenu = menu.FindMenu("File");
2457 Menu recentFiles = fileMenu.FindMenu("Recent Files");
2458 Menu recentProjects = fileMenu.FindMenu("Recent Projects");
2459 char itemName[MAX_LOCATION + 4];
2462 recentFiles.Clear();
2465 for(recent : ideSettings.recentFiles)
2467 sprintf(itemName, "%d %s", 1 + c, recent);
2468 MakeSystemPath(itemName);
2469 recentFiles.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentFile }, null, true);
2473 recentProjects.Clear();
2475 for(recent : ideSettings.recentProjects)
2477 sprintf(itemName, "%d %s", 1 + c, recent);
2478 MakeSystemPath(itemName);
2479 recentProjects.AddDynamic(MenuItem { copyText = true, text = itemName, (Key)k1 + c, id = c, NotifySelect = ide.FileRecentProject }, null, true);
2491 void DestroyDir(char * path)
2493 RecursiveDeleteFolderFSI fsi { };
2498 class RecursiveDeleteFolderFSI : NormalFileSystemIterator
2500 bool preserveRootFolder;
2502 void OutFolder(char * folderPath, bool isRoot)
2504 if(!(preserveRootFolder && isRoot))
2505 RemoveDir(folderPath);
2508 bool OnFile(char * filePath)
2510 DeleteFile(filePath);
2515 class IDEApp : GuiApplication
2517 //driver = "Win32Console";
2518 // driver = "OpenGL";
2523 SetLoggingMode(stdOut, null);
2524 //SetLoggingMode(debug, null);
2526 settingsContainer.Load();
2527 #if defined(__unix__) || defined(__APPLE__)
2528 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X";
2530 app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI";
2532 ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true;
2536 desktop.text = titleECEREIDE;
2539 for(c = 1; c<app.argc; c++)
2541 char fullPath[MAX_LOCATION];
2542 GetWorkingDir(fullPath, MAX_LOCATION);
2543 PathCat(fullPath, app.argv[c]);
2544 ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, null, yes, normal);
2553 define app = ((IDEApp)__thisModule);
2555 define titleECEREIDE = "ECERE IDE (Debug)";
2557 define titleECEREIDE = "ECERE IDE";