X-Git-Url: https://ecere.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ide%2Fsrc%2Fide.ec;h=815c3b0e7a711d34549eab07d512dfbf3f3acc5f;hb=84e623c3cb902d941ac9967bcf91767bae8f128b;hp=562de3e2e81a3a27364092c26ee3e6575a13eeda;hpb=15e8c4687c299c61fb5d21cf0e4715db88a3d554;p=sdk diff --git a/ide/src/ide.ec b/ide/src/ide.ec index 562de3e..815c3b0 100644 --- a/ide/src/ide.ec +++ b/ide/src/ide.ec @@ -44,12 +44,39 @@ import "about" import "FileSystemIterator" +AVLTree binaryDocExt +{ [ + "wav", "mp3", "flac", "ogg", + "mid", + "avi", "mkv", "mpg", "mpeg", + "7z", "zip", "gz", "bz2", "xz", "rar", "z", "tar", "ear", + "pdf", "odp", "ods", "odt", "ppt", "doc", "xls", "pptx", "docx", "xlsx" +] }; + #if defined(__WIN32__) define pathListSep = ";"; #else define pathListSep = ":"; #endif +IDEConfigHolder ideConfig { }; + +FontResource panelFont { $"Courier New", 10 }; +FontResource codeFont { $"Courier New", 10 }; + +IDESettings ideSettings; + +IDESettingsContainer settingsContainer +{ + dataOwner = &ideSettings; + dataClass = class(IDESettings); + + void onLoadCompilerConfigs() { ide.UpdateCompilerConfigs(true); } + void onLoadRecentFiles() { ide.updateRecentFilesMenu(); } + void onLoadRecentProjects() { ide.updateRecentProjectsMenu(); } + void onLoad() { ide.ApplyColorScheme(colorScheme); ide.ApplyFont(ideSettings.codeEditorFont, ideSettings.codeEditorFontSize); } +}; + define maxPathLen = 65 * MAX_LOCATION; class PathBackup : struct @@ -142,9 +169,6 @@ FileDialog ideProjectFileDialog GlobalSettingsDialog globalSettingsDialog { - ideSettings = ideSettings; - settingsContainer = settingsContainer; - void OnGlobalSettingChange(GlobalSettingsChange globalSettingsChange) { switch(globalSettingsChange) @@ -195,7 +219,7 @@ void DrawLineMarginIcon(Surface surface, BitmapResource resource, int line, int class IDEToolbar : ToolBar { - /* File options */ + // File options // New ToolButton buttonNewFile { this, toolTip = $"New file", menuItemPtr = IDEItem(fileNewItem) }; // Open @@ -209,16 +233,16 @@ class IDEToolbar : ToolBar ToolSeparator separator1 { this }; - /* Edit options */ + // Edit options // Cut - // Copy + // Copy // Paste // Undo // Redo // ToolSeparator separator2 { this }; - /* Project options */ + // Project options // New project ToolButton buttonNewProject { this, toolTip = $"New project", menuItemPtr = IDEItem(projectNewItem) }; // Open project @@ -230,7 +254,7 @@ class IDEToolbar : ToolBar ToolSeparator separator3 { this }; - /* Build/Execution options */ + // Build/Execution options // Build ToolButton buttonBuild { this, toolTip = $"Build project", menuItemPtr = IDEItem(projectBuildItem), disabled = true; }; // Re-link @@ -246,10 +270,13 @@ class IDEToolbar : ToolBar // Compile actual file // Execute ToolButton buttonRun { this, toolTip = $"Run", menuItemPtr = IDEItem(projectRunItem), disabled = true; }; +#ifdef IDE_SHOW_INSTALL_MENU_BUTTON + ToolButton buttonInstall { this, toolTip = $"Install", menuItemPtr = IDEItem(projectInstallItem), disabled = true; }; +#endif ToolSeparator separator4 { this }; - /* Debug options */ + // Debug options // Start/Resume ToolButton buttonDebugStartResume { this, toolTip = $"Start", menuItemPtr = IDEItem(debugStartResumeItem), disabled = true; }; // Restart @@ -279,21 +306,7 @@ class IDEToolbar : ToolBar bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods) { if(row) - { - for(prj : ide.workspace.projects) - { - for(cfg : prj.configurations) - { - if(cfg.name && !strcmp(cfg.name, row.string)) - { - prj.config = cfg; - break; - } - } - } - ide.UpdateToolBarActiveConfigs(true); - ide.projectView.Update(null); - } + ide.workspace.SelectActiveConfig(row.string); return true; } }; @@ -305,11 +318,11 @@ class IDEToolbar : ToolBar this, toolTip = $"Active Compiler", size = { 160 }, disabled = true; bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods) { - if(ide.workspace && ide.projectView && row && strcmp(row.string, ide.workspace.compiler)) + if(ide.workspace && ide.projectView && row && strcmp(row.string, ide.workspace.activeCompiler)) { bool silent = ide.projectView.buildInProgress == none ? false : true; - CompilerConfig compiler = ideSettings.GetCompilerConfig(row.string); - ide.workspace.compiler = row.string; + CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(row.string); + ide.workspace.activeCompiler = row.string; ide.projectView.ShowOutputBuildLog(!silent); if(!silent) ide.projectView.DisplayCompiler(compiler, false); @@ -324,13 +337,13 @@ class IDEToolbar : ToolBar DropBox activeBitDepth { - this, toolTip = $"Active Bit Depth", size = { 60 }, disabled = true; + this, toolTip = $"Active Bit Length", size = { 60 }, disabled = true; bool NotifySelect(DropBox dropBox, DataRow row, Modifiers mods) { if(ide.workspace && ide.projectView && row) { bool silent = ide.projectView.buildInProgress == none ? false : true; - CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler); + CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler); ide.workspace.bitDepth = (int)row.tag; ide.projectView.ShowOutputBuildLog(!silent); if(!silent) @@ -355,7 +368,6 @@ class IDEToolbar : ToolBar activeBitDepth.AddString("64 bit").tag = 64; activeBitDepth.currentRow = row; } - } class IDEMainFrame : Window @@ -415,9 +427,10 @@ class IDEWorkSpace : Window menu = Menu { }; IDEToolbar toolBar; - MenuItem * driverItems, * skinItems; + MenuItem * driverItems, * skinItems, * languageItems; StatusField pos { width = 150 }; StatusField ovr, caps, num; + DualPipe documentor; BitmapResource back { ":ecereBack.jpg", window = this }; BitmapResource bmpBp { ":codeMarks/breakpoint.png", window = this }; @@ -430,32 +443,145 @@ class IDEWorkSpace : Window BitmapResource bmpTopFrameError { ":codeMarks/topFrameError.png", window = this }; BitmapResource bmpTopFrameHalf { ":codeMarks/topFrameHalf.png", window = this }; BitmapResource bmpTopFrameHalfError { ":codeMarks/topFrameHalfError.png", window = this }; - + + BuildOutputMode rightClickMenuBuildOutputMode; + Debugger debugger { }; + void ApplyFont(const String faceName, float size) + { + panelFont.faceName = faceName; + panelFont.size = size; + + codeFont.faceName = faceName; + codeFont.size = size; + + { + CodeEditor ce; + for(ce = (CodeEditor)firstChild; ce; ce = (CodeEditor)ce.next) + if(ce._class == class(CodeEditor)) + { + ce.font = { codeFont.faceName, codeFont.size, codeFont.bold, codeFont.italic }; + ce.editBox.font = ce.font; + ce.OnPostCreate(); + } + } + + threadsView.font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; + callStackView.font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; + outputView.buildBox.font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; + outputView.debugBox.font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; + outputView.findBox.font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; + #ifdef GDB_DEBUG_OUTPUT + outputView.gdbBox.font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; + #endif +#ifdef GDB_DEBUG_GUI + if(gdbDialog) + { + gdbDialog.tree.font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; + gdbDialog.output.font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; + } +#endif + } + + void ApplyColorScheme(IDEColorScheme cs) + { + CodeEditor ce; + + colorScheme = cs; + + for(ce = (CodeEditor)firstChild; ce; ce = (CodeEditor)ce.next) + if(ce._class == class(CodeEditor)) + { + EditBox eb = ce.editBox; + ce.background = cs.marginColor; + eb.selectionColor = cs.selectionColor; + eb.selectionText = cs.selectionText; + eb.background = cs.codeEditorBG; + eb.foreground = cs.codeEditorFG; + eb.syntaxColorScheme = cs.syntaxColors; + } + + if(projectView) + { + projectView.fileList.background = cs.projectViewBackground; + projectView.fileList.foreground = cs.projectViewText; + projectView.fileList.selectionColor = cs.selectionColor; + projectView.fileList.selectionText = cs.selectionText; + } + + sheet.properties.background = cs.viewsBackground; + sheet.properties.foreground = cs.viewsText; + sheet.properties.selectionText = cs.sheetSelectionText; + sheet.properties.selectionColor = cs.sheetSelectionColor; + sheet.methods.background = cs.viewsBackground; + sheet.methods.foreground = cs.viewsText; + + threadsView.editBox.background = cs.viewsBackground; + threadsView.editBox.foreground = cs.viewsText; + threadsView.editBox.selectionColor = cs.selectionColor; + threadsView.editBox.selectionText = cs.selectionText; + + callStackView.editBox.background = cs.viewsBackground; + callStackView.editBox.foreground = cs.viewsText; + callStackView.editBox.selectionColor = cs.selectionColor; + callStackView.editBox.selectionText = cs.selectionText; + + watchesView.listBox.background = cs.viewsBackground; + watchesView.listBox.foreground = cs.viewsText; + watchesView.listBox.selectionColor = cs.selectionColor; + watchesView.listBox.selectionText = cs.selectionText; + + breakpointsView.listBox.background = cs.viewsBackground; + breakpointsView.listBox.foreground = cs.viewsText; + breakpointsView.listBox.selectionColor = cs.selectionColor; + breakpointsView.listBox.selectionText = cs.selectionText; + + outputView.buildBox.background = cs.outputBackground; + outputView.buildBox.foreground = cs.outputText; + outputView.buildBox.selectionColor = cs.selectionColor; + outputView.buildBox.selectionText = cs.selectionText; + + outputView.debugBox.background = cs.outputBackground; + outputView.debugBox.foreground = cs.outputText; + outputView.debugBox.selectionColor = cs.selectionColor; + outputView.debugBox.selectionText = cs.selectionText; + + outputView.findBox.background = cs.outputBackground; + outputView.findBox.foreground = cs.outputText; + outputView.findBox.selectionColor = cs.selectionColor; + outputView.findBox.selectionText = cs.selectionText; + } + ProjectView projectView; OutputView outputView { parent = this; - void OnGotoError(char * line, bool noParsing) + void OnGotoError(const char * line, bool noParsing) { - ide.GoToError(line, noParsing); + CompilerConfig compiler = ide.workspace ? ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler) : null; + const char * objectFileExt = compiler ? compiler.objectFileExt : objectDefaultFileExt; + ide.GoToError(line, noParsing, objectFileExt); + delete compiler; } - void OnCodeLocationParseAndGoTo(char * line) + void OnCodeLocationParseAndGoTo(const char * line) { - ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir); + CompilerConfig compiler = ide.workspace ? ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler) : null; + const char * objectFileExt = compiler ? compiler.objectFileExt : objectDefaultFileExt; + ide.CodeLocationParseAndGoTo(line, ide.findInFilesDialog.findProject, ide.findInFilesDialog.findDir, objectFileExt); + delete compiler; } bool OnKeyDown(Key key, unichar ch) { switch(key) { - case escape: + case escape: if(activeBox != findBox || !ide.findInFilesDialog || !ide.findInFilesDialog.SearchAbort()) - ide.ShowCodeEditor(); + ide.ShowCodeEditor(); break; default: { @@ -466,13 +592,6 @@ class IDEWorkSpace : Window return true; } - bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct) - { - if(active) - ide.RepositionWindows(false); - return true; - } - bool OnClose(bool parentClosing) { visible = false; @@ -484,18 +603,13 @@ class IDEWorkSpace : Window CallStackView callStackView { - parent = this, font = { panelFont.faceName, panelFont.size }; - - void OnGotoLine(char * line) - { - int stackLvl; - stackLvl = atoi(line); - ide.debugger.GoToStackFrameLine(stackLvl, true); - } + parent = this, font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; - void OnSelectFrame(int lineNumber) + void OnSelectFrame(int frameIndex) { - ide.debugger.SelectFrame(lineNumber); + ide.debugger.GoToStackFrameLine(frameIndex, true, true); + if(frameIndex >= 0) + ide.debugger.SelectFrame(frameIndex); } void OnToggleBreakpoint() @@ -504,33 +618,7 @@ class IDEWorkSpace : Window if(debugger.activeFrame && debugger.activeFrame.absoluteFile) { int line = debugger.activeFrame.line; - char name[MAX_LOCATION]; - Project prj = null; - // TOFIX: Improve on this, don't use only filename, make a function - GetLastDirectory(debugger.activeFrame.absoluteFile, name); - if(ide && ide.workspace) - { - for(p : ide.workspace.projects) - { - if(p.topNode.Find(name, false)) - { - prj = p; - break; - } - } - if(!prj) - { - for(p : ide.workspace.projects) - { - if(IsPathInsideOf(debugger.activeFrame.absoluteFile, p.topNode.path)) - { - prj = p; - break; - } - } - } - } - debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line, prj); + debugger.ToggleBreakpoint(debugger.activeFrame.absoluteFile, line); Update(null); { CodeEditor codeEditor = (CodeEditor)ide.FindWindow(debugger.activeFrame.absoluteFile); @@ -548,13 +636,6 @@ class IDEWorkSpace : Window return true; } - bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct) - { - if(active) - ide.RepositionWindows(false); - return true; - } - bool OnClose(bool parentClosing) { visible = false; @@ -570,7 +651,7 @@ class IDEWorkSpace : Window if(activeFrame) { bool error; - int lineCursor, lineTopFrame, activeThread, hitThread; + int lineCursor, lineTopFrame; int lineH, scrollY, boxH; BitmapResource bmp; Breakpoint bp = null; @@ -578,8 +659,8 @@ class IDEWorkSpace : Window boxH = clientSize.h; scrollY = editBox.scroll.y; displaySystem.FontExtent(editBox.font.font, " ", 1, null, &lineH); - activeThread = debugger.activeThread; - hitThread = debugger.hitThread; + //activeThread = debugger.activeThread; + //hitThread = debugger.hitThread; debugger.GetCallStackCursorLine(&error, &lineCursor, &lineTopFrame); // TODO: improve bp drawing... it should be visible even if it's not on the activeFrame @@ -620,11 +701,11 @@ class IDEWorkSpace : Window } } }; - + WatchesView watchesView { parent = this }; ThreadsView threadsView { - parent = this, font = { panelFont.faceName, panelFont.size }; + parent = this, font = { panelFont.faceName, panelFont.size, panelFont.bold, panelFont.italic }; bool OnKeyDown(Key key, unichar ch) { @@ -635,13 +716,6 @@ class IDEWorkSpace : Window return true; } - bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct) - { - if(active) - ide.RepositionWindows(false); - return true; - } - bool OnClose(bool parentClosing) { visible = false; @@ -669,8 +743,8 @@ class IDEWorkSpace : Window }; BreakpointsView breakpointsView { parent = this }; - ToolBox toolBox { parent = this }; - Sheet sheet { parent = this }; + ToolBox toolBox { parent = this, visible = false }; + Sheet sheet { parent = this, visible = false }; char * tmpPrjDir; property char * tmpPrjDir { set { delete tmpPrjDir; if(value) tmpPrjDir = CopyString(value); } get { return tmpPrjDir; } }; @@ -682,11 +756,14 @@ class IDEWorkSpace : Window bitmap = { ":actions/docNew.png" }; bool NotifySelect(MenuItem selection, Modifiers mods) { - Window document = (Window)NewCodeEditor(this, normal, false); + Window currentDoc = activeClient; + bool maximizeDoc = ((currentDoc && currentDoc.state == maximized) || (!currentDoc && !projectView)); + Window document = (Window)NewCodeEditor(this, maximizeDoc ? maximized : normal, false); + RepositionWindows(false); document.NotifySaved = DocumentSaved; return true; } - } + }; MenuItem fileOpenItem { fileMenu, $"Open...", o, ctrlO; @@ -702,19 +779,20 @@ class IDEWorkSpace : Window bool gotWhatWeWant = false; int c; int numSelections = ideFileDialog.numSelections; - char ** multiFilePaths = ideFileDialog.multiFilePaths; + const char * const * multiFilePaths = ideFileDialog.multiFilePaths; for(c = 0; c < numSelections; c++) { - if(OpenFile(multiFilePaths[c], normal, true, fileTypes[ideFileDialog.fileType].typeExtension, no, normal, mods.ctrl && mods.shift)) + if(OpenFile(multiFilePaths[c], false, true, fileTypes[ideFileDialog.fileType].typeExtension, no, normal, mods.ctrl && mods.shift)) gotWhatWeWant = true; } if(gotWhatWeWant || - MessageBox { type = yesNo, master = this, text = $"Error opening file", + MessageBox { type = yesNo, master = this, text = $"Error opening file", contents = $"Open a different file?" }.Modal() == no) { if(!projectView && gotWhatWeWant) ChangeFileDialogsDirectory(ideFileDialog.currentDirectory, true); + ide.RepositionWindows(false); break; } } @@ -723,7 +801,7 @@ class IDEWorkSpace : Window } return true; } - } + }; MenuItem fileCloseItem { fileMenu, $"Close", c, ctrlF4, NotifySelect = MenuFileClose }; MenuDivider { fileMenu }; MenuItem fileSaveItem @@ -751,7 +829,7 @@ class IDEWorkSpace : Window findInFilesDialog.Show(); return true; } - } + }; MenuItem replaceInFiles { fileMenu, $"Replace In Files...", e, Key { r, ctrl = true , shift = true }; @@ -761,29 +839,32 @@ class IDEWorkSpace : Window findInFilesDialog.Show(); return true; } - } + }; MenuDivider { fileMenu }; MenuItem globalSettingsItem { fileMenu, $"Global Settings...", g; bool NotifySelect(MenuItem selection, Modifiers mods) { + // Reload configs here until we setup a configs directory monitor + ideConfig.compilers.read(settingsContainer); + globalSettingsDialog.master = this; - if(ide.workspace && ide.workspace.compiler) - globalSettingsDialog.workspaceActiveCompiler = ide.workspace.compiler; + if(ide.workspace && ide.workspace.activeCompiler) + globalSettingsDialog.workspaceActiveCompiler = ide.workspace.activeCompiler; else if(ideSettings.defaultCompiler) globalSettingsDialog.workspaceActiveCompiler = ideSettings.defaultCompiler; globalSettingsDialog.Modal(); return true; } - } + }; MenuDivider { fileMenu }; - Menu recentFiles { fileMenu, $"Recent Files", r }; - Menu recentProjects { fileMenu, $"Recent Projects", p }; + Menu recentFilesMenu { fileMenu, $"Recent Files", r }; + Menu recentProjectsMenu { fileMenu, $"Recent Projects", p }; MenuDivider { fileMenu }; MenuItem exitItem { - fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit; + fileMenu, $"Exit", x, altF4; bool NotifySelect(MenuItem selection, Modifiers mods) { @@ -795,7 +876,8 @@ class IDEWorkSpace : Window bool FileRecentFile(MenuItem selection, Modifiers mods) { int id = 0; - for(file : ideSettings.recentFiles) + RecentPaths recentFiles = workspace ? workspace.recentFiles : ideConfig.recentFiles; + for(file : recentFiles) { if(id == selection.id) { @@ -803,14 +885,17 @@ class IDEWorkSpace : Window char extension[MAX_EXTENSION] = ""; GetExtension(file, extension); isProjectFile = (!strcmpi(extension, "epj") || !strcmpi(extension, "ews")); - if(mods.ctrl) + if(mods.ctrl && !mods.shift) { - char * command = PrintString("ide ", isProjectFile ? "-t " : "", file); + char * command = PrintString("ecere-ide ", isProjectFile ? "-t " : "", file); Execute(command); delete command; } else - OpenFile(file, normal, true, isProjectFile ? "txt" : null, no, normal, mods.ctrl && mods.shift); + { + OpenFile(file, false, true, isProjectFile ? "txt" : null, no, normal, mods.ctrl && mods.shift); + ide.RepositionWindows(false); + } break; } id++; @@ -821,18 +906,18 @@ class IDEWorkSpace : Window bool FileRecentProject(MenuItem selection, Modifiers mods) { int id = 0; - for(file : ideSettings.recentProjects) + for(file : ideConfig.recentWorkspaces) { if(id == selection.id) { - if(mods.ctrl) + if(mods.ctrl && !mods.shift) { - char * command = PrintString("ide ", file); + char * command = PrintString("ecere-ide ", file); Execute(command); delete command; } else - OpenFile(file, normal, true, null, no, normal, mods.ctrl && mods.shift); + OpenFile(file, false, true, (mods.ctrl && mods.shift) ? "txt" : null, no, normal, mods.ctrl && mods.shift); break; } id++; @@ -841,7 +926,7 @@ class IDEWorkSpace : Window } MenuPlacement editMenu { menu, $"Edit", e }; - + Menu projectMenu { menu, $"Menu"."Project", p, hasMargin = true }; MenuItem projectNewItem { @@ -853,6 +938,7 @@ class IDEWorkSpace : Window { DialogResult result; NewProjectDialog newProjectDialog { master = this }; + incref newProjectDialog; result = newProjectDialog.Modal(); if(result == ok) { @@ -861,16 +947,17 @@ class IDEWorkSpace : Window newProjectDialog.CreateNewProject(); if(projectView) { - ideSettings.AddRecentProject(projectView.fileName); - ide.UpdateRecentMenus(); - settingsContainer.Save(); + ideConfig.recentWorkspaces.addRecent(projectView.fileName); + ideConfig.recentWorkspaces.write(settingsContainer); + ide.updateRecentProjectsMenu(); } } } + delete newProjectDialog; } return true; } - } + }; MenuItem projectOpenItem { projectMenu, $"Open...", o, Key { o, true, true }; @@ -883,12 +970,12 @@ class IDEWorkSpace : Window ideProjectFileDialog.text = openProjectFileDialogTitle; if(ideProjectFileDialog.Modal() == ok) { - OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal, mods.ctrl && mods.shift); + OpenFile(ideProjectFileDialog.filePath, false, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, normal, mods.ctrl && mods.shift); //ChangeProjectFileDialogDirectory(ideProjectFileDialog.currentDirectory); } return true; } - } + }; MenuItem projectQuickItem { projectMenu, $"Quick...", q, f7, disabled = true; @@ -898,7 +985,7 @@ class IDEWorkSpace : Window QuickProjectDialog { this }.Modal(); return true; } - } + }; MenuItem projectAddItem { projectMenu, $"Add project to workspace...", a, Key { a, true, true }; @@ -914,9 +1001,9 @@ class IDEWorkSpace : Window { if(ideProjectFileDialog.Modal() == ok) { - if(OpenFile(ideProjectFileDialog.filePath, normal, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add, mods.ctrl && mods.shift)) + if(OpenFile(ideProjectFileDialog.filePath, false, true, projectTypes[ideProjectFileDialog.fileType].typeExtension, no, add, mods.ctrl && mods.shift)) break; - if(MessageBox { type = yesNo, master = this, text = $"Error opening project file", + if(MessageBox { type = yesNo, master = this, text = $"Error opening project file", contents = $"Add a different project?" }.Modal() == no) { break; @@ -927,7 +1014,7 @@ class IDEWorkSpace : Window } return true; } - } + }; MenuItem projectCloseItem { projectMenu, $"Close", c, disabled = true; @@ -940,7 +1027,7 @@ class IDEWorkSpace : Window } return true; } - } + }; MenuDivider { projectMenu }; MenuItem projectSettingsItem { @@ -950,7 +1037,7 @@ class IDEWorkSpace : Window projectView.MenuSettings(projectView.active ? selection : null, mods); return true; } - } + }; MenuDivider { projectMenu }; MenuItem projectBrowseFolderItem { @@ -961,7 +1048,7 @@ class IDEWorkSpace : Window projectView.MenuBrowseFolder(null, mods); return true; } - } + }; MenuDivider { projectMenu }; MenuItem projectRunItem { @@ -973,7 +1060,7 @@ class IDEWorkSpace : Window projectView.Run(null, mods); return true; } - } + }; MenuItem projectBuildItem { projectMenu, $"Build", b, f7, disabled = true; @@ -989,7 +1076,7 @@ class IDEWorkSpace : Window } return true; } - } + }; MenuItem projectLinkItem { projectMenu, $"Relink", l, disabled = true; @@ -1000,7 +1087,7 @@ class IDEWorkSpace : Window projectView.ProjectLink(projectView.active ? selection : null, mods); return true; } - } + }; MenuItem projectRebuildItem { projectMenu, $"Rebuild", d, shiftF7, disabled = true; @@ -1011,7 +1098,7 @@ class IDEWorkSpace : Window projectView.ProjectRebuild(projectView.active ? selection : null, mods); return true; } - } + }; MenuItem projectCleanTargetItem { projectMenu, $"Clean Target", g, disabled = true; @@ -1025,7 +1112,7 @@ class IDEWorkSpace : Window } return true; } - } + }; MenuItem projectCleanItem { projectMenu, $"Clean", e, disabled = true; @@ -1039,7 +1126,7 @@ class IDEWorkSpace : Window } return true; } - } + }; MenuItem projectRealCleanItem { projectMenu, $"Real Clean", disabled = true; @@ -1053,7 +1140,7 @@ class IDEWorkSpace : Window } return true; } - } + }; MenuItem projectRegenerateItem { projectMenu, $"Regenerate Makefile", m, disabled = true; @@ -1064,7 +1151,20 @@ class IDEWorkSpace : Window projectView.ProjectRegenerate(projectView.active ? selection : null, mods); return true; } - } + }; + MenuItem projectInstallItem + { +#ifdef IDE_SHOW_INSTALL_MENU_BUTTON + projectMenu, $"Install", t, disabled = true; +#endif + bitmap = { ":status/software-update-available.png" }; + bool NotifySelect(MenuItem selection, Modifiers mods) + { + if(projectView) + projectView.ProjectInstall(projectView.active ? selection : null, mods); + return true; + } + }; MenuItem projectCompileItem; Menu debugMenu { menu, $"Debug", d, hasMargin = true }; MenuItem debugStartResumeItem @@ -1072,7 +1172,7 @@ class IDEWorkSpace : Window debugMenu, $"Start", s, f5, disabled = true; bitmap = { ":actions/debug.png" }; NotifySelect = MenuDebugStart; - } + }; bool MenuDebugStart(MenuItem selection, Modifiers mods) { if(projectView) @@ -1099,7 +1199,7 @@ class IDEWorkSpace : Window projectView.DebugRestart(); return true; } - } + }; MenuItem debugBreakItem { debugMenu, $"Break", b, Key { pauseBreak, ctrl = true }, disabled = true; @@ -1112,7 +1212,7 @@ class IDEWorkSpace : Window projectView.DebugBreak(); return true; } - } + }; MenuItem debugStopItem { debugMenu, $"Stop", p, shiftF5, disabled = true; @@ -1123,7 +1223,151 @@ class IDEWorkSpace : Window projectView.DebugStop(); return true; } - } + }; + MenuDivider { debugMenu }; + ModelView duck + { + this, + // nonClient = true, + autoCreate = false, + alphaBlend = true, + opacity = 0, + isRemote = true, + borderStyle = 0, + moveable = true, + anchor = { right = 0, bottom = 0 }, + inactive = true, + isActiveClient = false, + stayOnTop = true, + clickThrough = true, + size = { 500, 500 }; + + bool OnLoadGraphics() + { + ModelView::OnLoadGraphics(); + camera.position.z /= 1.3; + camera.orientation = Euler { yaw = 280, pitch = 20 }; + camera.Update(); + Update(null); + return true; + } + + bool OnRightButtonDown(int x, int y, Modifiers mods) + { + if(!displaySystem.flags.flipping) return true; + MenuWindowMove(null, 0); + return false; + } + + bool OnRightButtonUp(int x, int y, Modifiers mods) + { + position = position; + state = normal; + return true; + } + }; + MenuItem debugRubberDuck + { + debugMenu, $"Rubber Duck", checkable = true, disabled = true; + bool NotifySelect(MenuItem selection, Modifiers mods) + { + if(selection.checked) + duck.Create(); + else + duck.Destroy(0); + return true; + } + }; +#ifndef __WIN32__ + MenuDivider { debugMenu }; + MenuItem debugUseValgrindItem + { + debugMenu, $"Use Valgrind", d, disabled = true, checkable = true; + bool NotifySelect(MenuItem selection, Modifiers mods) + { + if(ide.workspace) + { + ide.workspace.useValgrind = selection.checked; + ide.workspace.Save(); + } + ide.AdjustValgrindMenus(); + return true; + } + }; + Menu debugValgrindLeakCheckItem { debugMenu, $"Valgrind Leak Check", h }; + MenuItem debugValgrindNoLeakCheckItem { debugValgrindLeakCheckItem, $"No" , f, id = ValgrindLeakCheck::no , checkable = true, disabled = true; NotifySelect = ValgrindLCSelect; }; + MenuItem debugValgrindSummaryLeakCheckItem { debugValgrindLeakCheckItem, $"Summary", f, id = ValgrindLeakCheck::summary, checkable = true, disabled = true; NotifySelect = ValgrindLCSelect, checked = true; }; + MenuItem debugValgrindYesLeakCheckItem { debugValgrindLeakCheckItem, $"Yes" , f, id = ValgrindLeakCheck::yes , checkable = true, disabled = true; NotifySelect = ValgrindLCSelect; }; + MenuItem debugValgrindFullLeakCheckItem { debugValgrindLeakCheckItem, $"Full" , f, id = ValgrindLeakCheck::full , checkable = true, disabled = true; NotifySelect = ValgrindLCSelect; }; + bool ValgrindLCSelect(MenuItem selection, Modifiers mods) + { + if(ide.workspace) + { + if(selection.checked) + { + ValgrindLeakCheck vgLeakCheck = (ValgrindLeakCheck)selection.id; + + debugValgrindNoLeakCheckItem.checked = debugValgrindNoLeakCheckItem.id == vgLeakCheck; + debugValgrindSummaryLeakCheckItem.checked = debugValgrindSummaryLeakCheckItem.id == vgLeakCheck; + debugValgrindYesLeakCheckItem.checked = debugValgrindYesLeakCheckItem.id == vgLeakCheck; + debugValgrindFullLeakCheckItem.checked = debugValgrindFullLeakCheckItem.id == vgLeakCheck; + + ide.workspace.vgLeakCheck = vgLeakCheck; + ide.workspace.Save(); + } + else + selection.checked = true; + } + return true; + } + Menu debugValgrindRedzoneSizeItem { debugMenu, $"Valgrind Redzone Size", z }; + MenuItem debugValgrindRSDefaultItem { debugValgrindRedzoneSizeItem, $"Default", f, id = -1, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect, checked = true; }; + MenuItem debugValgrindRS0Item { debugValgrindRedzoneSizeItem, "0" , f, id = 0, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }; + MenuItem debugValgrindRS16Item { debugValgrindRedzoneSizeItem, "16" , f, id = 16, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }; + MenuItem debugValgrindRS32Item { debugValgrindRedzoneSizeItem, "32" , f, id = 32, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }; + MenuItem debugValgrindRS64Item { debugValgrindRedzoneSizeItem, "64" , f, id = 64, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }; + MenuItem debugValgrindRS128Item { debugValgrindRedzoneSizeItem, "128" , f, id = 128, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }; + MenuItem debugValgrindRS256Item { debugValgrindRedzoneSizeItem, "256" , f, id = 256, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }; + MenuItem debugValgrindRS512Item { debugValgrindRedzoneSizeItem, "512" , f, id = 512, checkable = true, disabled = true; NotifySelect = ValgrindRSSelect; }; + bool ValgrindRSSelect(MenuItem selection, Modifiers mods) + { + if(ide.workspace) + { + if(selection.checked) + { + int vgRedzoneSize = (int)selection.id; + + debugValgrindRSDefaultItem.checked = debugValgrindRSDefaultItem.id == vgRedzoneSize; + debugValgrindRS0Item.checked = debugValgrindRS0Item.id == vgRedzoneSize; + debugValgrindRS16Item.checked = debugValgrindRS16Item.id == vgRedzoneSize; + debugValgrindRS32Item.checked = debugValgrindRS32Item.id == vgRedzoneSize; + debugValgrindRS64Item.checked = debugValgrindRS64Item.id == vgRedzoneSize; + debugValgrindRS128Item.checked = debugValgrindRS128Item.id == vgRedzoneSize; + debugValgrindRS256Item.checked = debugValgrindRS256Item.id == vgRedzoneSize; + debugValgrindRS512Item.checked = debugValgrindRS512Item.id == vgRedzoneSize; + + ide.workspace.vgRedzoneSize = vgRedzoneSize; + ide.workspace.Save(); + } + else + selection.checked = true; + } + return true; + } + MenuItem debugValgrindTrackOriginsItem + { + debugMenu, $"Valgrind Track Origins", k, checkable = true, disabled = true; + bool NotifySelect(MenuItem selection, Modifiers mods) + { + if(ide.workspace) + { + ide.workspace.vgTrackOrigins = selection.checked; + ide.workspace.Save(); + } + return true; + } + }; +#endif MenuDivider { debugMenu }; MenuItem debugStepIntoItem { @@ -1131,57 +1375,80 @@ class IDEWorkSpace : Window bitmap = { ":actions/stepInto.png" }; bool NotifySelect(MenuItem selection, Modifiers mods) { - if(projectView) - projectView.DebugStepInto(); + if(projectView) projectView.DebugStepInto(); return true; } - } + }; MenuItem debugStepOverItem { debugMenu, $"Step Over", v, f10, disabled = true; bitmap = { ":actions/stepOver.png" }; bool NotifySelect(MenuItem selection, Modifiers mods) { - if(projectView) - projectView.DebugStepOver(false); + if(projectView) projectView.DebugStepOver(false); return true; } - } + }; + MenuItem debugSkipStepOverItem + { + debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true; + bitmap = { ":actions/stepOverSkipBreak.png" }; + bool NotifySelect(MenuItem selection, Modifiers mods) + { + if(projectView) projectView.DebugStepOver(true); + return true; + } + }; MenuItem debugStepOutItem { debugMenu, $"Step Out", o, shiftF11, disabled = true; bitmap = { ":actions/stepOut.png" }; bool NotifySelect(MenuItem selection, Modifiers mods) { - if(projectView) - projectView.DebugStepOut(false); + if(projectView) projectView.DebugStepOut(false); return true; } - } - MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c }; - MenuItem debugSkipStepOverItem + }; + MenuItem debugSkipStepOutItem { - debugMenu, $"Step Over Skipping Breakpoints", e, shiftF10, disabled = true; + debugMenu, $"Step Out Skipping Breakpoints", n, Key { f11, ctrl = true, shift = true }, disabled = true; + bitmap = { ":actions/skipBreaks.png" }; bool NotifySelect(MenuItem selection, Modifiers mods) { - if(projectView) - projectView.DebugStepOver(true); + if(projectView) projectView.DebugStepOut(true); return true; } - } - MenuItem debugSkipStepOutItem + }; +#if 0 + MenuItem debugStepUntilItem { - debugMenu, $"Step Out Skipping Breakpoints", t, Key { f11, ctrl = true, shift = true }, disabled = true; - bitmap = { ":actions/skipBreaks.png" }; + debugMenu, $"Step Over Until Next Line", x, disabled = true; bool NotifySelect(MenuItem selection, Modifiers mods) { - if(projectView) - projectView.DebugStepOut(true); + if(projectView) projectView.DebugStepUntil(false); return true; } - } + }; + MenuItem debugSkipStepUntilItem + { + debugMenu, $"Step Over Until Next Line Skipping Breakpoints", e, Key { f10, shift = true, alt = true }, disabled = true; + bool NotifySelect(MenuItem selection, Modifiers mods) + { + if(projectView) projectView.DebugStepUntil(true); + return true; + } + }; +#endif + MenuPlacement debugRunToCursorItem { debugMenu, $"Run To Cursor", c }; MenuPlacement debugSkipRunToCursorItem { debugMenu, $"Run To Cursor Skipping Breakpoints", u }; - MenuPlacement debugSkipRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", s }; + MenuPlacement debugRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level", l }; + MenuPlacement debugSkipRunToCursorAtSameLevelItem { debugMenu, $"Run To Cursor At Same Level Skipping Breakpoints", g }; +#if 0 + MenuPlacement debugBpRunToCursorItem { debugMenu, $"BP Run To Cursor" }; + MenuPlacement debugBpSkipRunToCursorItem { debugMenu, $"BP Run To Cursor Skipping Breakpoints" }; + MenuPlacement debugBpRunToCursorAtSameLevelItem { debugMenu, $"BP Run To Cursor At Same Level" }; + MenuPlacement debugBpSkipRunToCursorAtSameLevelItem { debugMenu, $"BP Run To Cursor At Same Level Skipping Breakpoints" }; +#endif //MenuDivider { debugMenu }; //MenuPlacement debugToggleBreakpoint { debugMenu, "Toggle Breakpoint", t }; MenuPlacement imageMenu { menu, $"Image", i }; @@ -1198,7 +1465,7 @@ class IDEWorkSpace : Window } return true; } - } + }; MenuPlacement { viewMenu, $"View Designer" }; MenuPlacement { viewMenu, $"View Code" }; MenuPlacement { viewMenu, $"View Properties" }; @@ -1219,7 +1486,7 @@ class IDEWorkSpace : Window ((CodeEditor)client).ViewDesigner(); return true; } - } + }; MenuItem viewCodeItem { viewMenu, $"View Code", c, f8; @@ -1235,7 +1502,7 @@ class IDEWorkSpace : Window client.visible = true; return true; } - } + }; MenuItem viewPropertiesItem { viewMenu, $"View Properties", p, f4; @@ -1246,7 +1513,7 @@ class IDEWorkSpace : Window sheet.Activate(); return true; } - } + }; MenuItem viewMethodsItem { viewMenu, $"View Methods", m, f4; @@ -1257,7 +1524,7 @@ class IDEWorkSpace : Window sheet.Activate(); return true; } - } + }; MenuItem viewToolBoxItem { viewMenu, $"View Toolbox", x, f12; @@ -1267,7 +1534,7 @@ class IDEWorkSpace : Window toolBox.Activate(); return true; } - } + }; MenuItem viewOutputItem { viewMenu, $"Output", o, alt2; @@ -1276,7 +1543,7 @@ class IDEWorkSpace : Window outputView.Show(); return true; } - } + }; MenuItem viewWatchesItem { viewMenu, $"Watches", w, alt3; @@ -1285,7 +1552,7 @@ class IDEWorkSpace : Window watchesView.Show(); return true; } - } + }; MenuItem viewThreadsItem { viewMenu, $"Threads", t, alt4; @@ -1294,7 +1561,7 @@ class IDEWorkSpace : Window threadsView.Show(); return true; } - } + }; MenuItem viewBreakpointsItem { viewMenu, $"Breakpoints", b, alt5; @@ -1303,7 +1570,7 @@ class IDEWorkSpace : Window breakpointsView.Show(); return true; } - } + }; MenuItem viewCallStackItem { viewMenu, $"Call Stack", s, alt7; @@ -1312,7 +1579,7 @@ class IDEWorkSpace : Window callStackView.Show(); return true; } - } + }; MenuItem viewAllDebugViews { viewMenu, $"All Debug Views", a, alt9; @@ -1325,7 +1592,7 @@ class IDEWorkSpace : Window breakpointsView.Show(); return true; } - } + }; #ifdef GDB_DEBUG_GUI MenuDivider { viewMenu }; MenuItem viewGDBItem @@ -1336,7 +1603,7 @@ class IDEWorkSpace : Window gdbDialog.Show(); return true; } - } + }; #endif MenuDivider { viewMenu }; MenuItem viewColorPicker @@ -1348,7 +1615,7 @@ class IDEWorkSpace : Window colorPicker.Modal(); return true; } - } + }; MenuDivider { viewMenu }; /* MenuItem @@ -1365,6 +1632,11 @@ class IDEWorkSpace : Window }; */ Menu driversMenu { viewMenu, $"Graphics Driver", v }; + + MenuDivider { viewMenu }; + + Menu languageMenu { viewMenu, "Language", l }; + //Menu skinsMenu { viewMenu, "GUI Skins", k }; Menu windowMenu { menu, $"Window", w }; MenuItem { windowMenu, $"Close All", l, NotifySelect = MenuWindowCloseAll }; @@ -1384,21 +1656,29 @@ class IDEWorkSpace : Window helpMenu, $"API Reference", r, f1; bool NotifySelect(MenuItem selection, Modifiers mods) { - char * p = new char[MAX_LOCATION]; - p[0] = '\0'; - strncpy(p, settingsContainer.moduleLocation, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, "documentor"); -#if defined(__WIN32__) - ChangeExtension(p, "exe", p); -#endif - if(FileExists(p).isFile) - Execute(p); + if(!documentor) + { + char * p = new char[MAX_LOCATION]; + p[0] = '\0'; + strncpy(p, settingsContainer.moduleLocation, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; + PathCat(p, "documentor"); + #if defined(__WIN32__) + ChangeExtension(p, "exe", p); + #endif + if(!FileExists(p).isFile) + strcpy(p, "documentor"); + + documentor = DualPipeOpen({ input = true, output = true, showWindow = true }, p); + delete p; + } else - Execute("documentor"); - delete p; + { + Process_ShowWindows(documentor.GetProcessID()); + // documentor.Puts("Activate\n"); + } return true; } - } + }; MenuDivider { helpMenu }; MenuItem { @@ -1408,7 +1688,7 @@ class IDEWorkSpace : Window FindAndShellOpenInstalledFile("doc", "Ecere Tao of Programming [work in progress].pdf"); return true; } - } + }; MenuDivider { helpMenu }; MenuItem { @@ -1418,7 +1698,7 @@ class IDEWorkSpace : Window FindAndShellOpenInstalledFolder("doc"); return true; } - } + }; MenuItem { helpMenu, $"Samples Folder", s; @@ -1427,7 +1707,7 @@ class IDEWorkSpace : Window FindAndShellOpenInstalledFolder("samples"); return true; } - } + }; MenuItem { helpMenu, $"Extras Folder", x; @@ -1436,7 +1716,7 @@ class IDEWorkSpace : Window FindAndShellOpenInstalledFolder("extras"); return true; } - } + }; MenuDivider { helpMenu }; MenuItem { @@ -1446,7 +1726,7 @@ class IDEWorkSpace : Window ShellOpen("http://ecere.com/forums"); return true; } - } + }; MenuDivider { helpMenu }; MenuItem { @@ -1456,7 +1736,7 @@ class IDEWorkSpace : Window AboutIDE { master = this }.Modal(); return true; } - } + }; property ToolBox toolBox { @@ -1486,21 +1766,22 @@ class IDEWorkSpace : Window }; bool noParsing; + bool debugStart; #ifdef GDB_DEBUG_GUI GDBDialog gdbDialog { master = this, parent = this; - anchor = { left = 100, top = 100, right = 100, bottom = 100 }; + //anchor = { left = 100, top = 100, right = 100, bottom = 100 }; - void OnCommand(char * string) + void OnCommand(const char * string) { if(ide) ide.debugger.SendGDBCommand(string); } }; #endif - + bool NotifySelectDisplayDriver(MenuItem selection, Modifiers mods) { //app.driver = app.drivers[selection.id]; @@ -1512,6 +1793,8 @@ class IDEWorkSpace : Window delete ideSettings.displayDriver; ideSettings.displayDriver = CopyString(selection.id ? "OpenGL" : "Default"); + ide.debugRubberDuck.disabled = !ide.duck.modelFile || strcmpi(app.driver, "OpenGL"); + settingsContainer.Save(); //SetDriverAndSkin(); return true; @@ -1541,19 +1824,19 @@ class IDEWorkSpace : Window } } - ProjectView CreateProjectView(Workspace workspace, char * fileName) + ProjectView CreateProjectView(Workspace workspace, const char * fileName) { Project project = workspace.projects.firstIterator.data; projectView = ProjectView { this; fileName = fileName; - + void NotifyDestroyed(Window window, DialogResult result) { projectView = null; text = titleECEREIDE; - + AdjustMenus(); } }; @@ -1566,6 +1849,7 @@ class IDEWorkSpace : Window ideMainFrame.SetText("%s - %s", project.topNode.name, titleECEREIDE); AdjustMenus(); + updateRecentMenus(); ide.breakpointsView.LoadFromWorkspace(); ide.watchesView.LoadFromWorkspace(); @@ -1592,8 +1876,12 @@ class IDEWorkSpace : Window findInFilesDialog.SearchStop(); findInFilesDialog.currentDirectory = workingDir; } + sheet.visible = false; + toolBox.visible = false; + outputView.visible = false; ideMainFrame.text = titleECEREIDE; ide.AdjustMenus(); + ide.updateRecentMenus(); return true; } return false; @@ -1604,7 +1892,6 @@ class IDEWorkSpace : Window if(this) { Window child; - bool inDebugMode = debugger.isActive; bool callStackVisible = expand ? false : callStackView.visible; bool threadsVisible = expand ? false : threadsView.visible; bool watchesVisible = expand ? false : watchesView.visible; @@ -1613,10 +1900,10 @@ class IDEWorkSpace : Window bool outputVisible = expand ? false : outputView.visible; int topDistance = (callStackVisible || threadsVisible) ? 200 : 0; int bottomDistance = (outputVisible || watchesVisible || breakpointsVisible) ? 240 : 0; - + for(child = firstChild; child; child = child.next) { - if(child._class == class(CodeEditor) || child._class == class(Designer) || + if(child._class == class(CodeEditor) || child._class == class(Designer) || child._class == class(Sheet) || child._class == class(ProjectView)) { Anchor anchor = child.anchor; @@ -1624,19 +1911,22 @@ class IDEWorkSpace : Window anchor.bottom = bottomDistance; if(child._class == class(CodeEditor) || child._class == class(Designer)) { + anchor.left = (sheet.visible || (projectView && projectView.visible)) ? 300 : 0; anchor.right = toolBoxVisible ? 150 : 0; } - child.anchor = anchor; + if(ide.projectView) + child.anchor = anchor; } else if(expand) { - if(child._class == class(OutputView) || child._class == class(CallStackView) || child._class == class(ThreadsView) || child._class == class(WatchesView) || + if(child._class == class(OutputView) || child._class == class(CallStackView) || child._class == class(ThreadsView) || child._class == class(WatchesView) || child._class == class(BreakpointsView)) child.visible = false; } } // If this is not here, the IDE is not updated when doing Debug/Break then Alt-4 to show call stack (IDE not updated) Update(null); + if(duck.visible) duck.Update(null); // TOFIX: If this is not here, the duck disappears -- Why? } } @@ -1645,32 +1935,31 @@ class IDEWorkSpace : Window if(activeClient) activeClient.Activate(); else if(projectView) - { + { projectView.visible = true; projectView.Activate(); } - else - { - sheet.visible = true; + else if(sheet.visible) sheet.Activate(); - } + else + outputView.visible = false; return false; } - void DocumentSaved(Window document, char * fileName) + void DocumentSaved(Window document, const char * fileName) { - ideSettings.AddRecentFile(fileName); - ide.UpdateRecentMenus(); + ideConfig.recentFiles.addRecent(fileName); + ideConfig.recentFiles.write(settingsContainer); + ide.updateRecentFilesMenu(); ide.AdjustFileMenus(); - settingsContainer.Save(); } - bool Window::OnFileModified(FileChange fileChange, char * param) + bool Window::OnFileModified(FileChange fileChange, const char * param) { char temp[4096]; sprintf(temp, $"The document %s was modified by another application.\n" "Would you like to reload it and lose your changes?", this.fileName); - if(MessageBox { type = yesNo, master = this/*.parent*/, + if(MessageBox { creationActivation = flash, type = yesNo, master = this/*.parent*/, text = $"Document has been modified", contents = temp }.Modal() == yes) { bool noParsing = (this._class == class(CodeEditor) && ((CodeEditor)this).noParsing) ? true : false; @@ -1681,7 +1970,7 @@ class IDEWorkSpace : Window this.modifiedDocument = false; this.Destroy(0); - this = ide.OpenFile(fileName, normal, true, null, no, normal, noParsing); + this = ide.OpenFile(fileName, false, true, null, no, normal, noParsing); if(this) { this.anchor = anchor; @@ -1698,7 +1987,7 @@ class IDEWorkSpace : Window { if(workspace) { - CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler); + CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(workspace.activeCompiler); for(prj : workspace.projects) projectView.ProjectUpdateMakefileForAllConfigs(prj); delete compiler; @@ -1711,7 +2000,7 @@ class IDEWorkSpace : Window if(workspace) { bool silent = mute || (ide.projectView.buildInProgress == none ? false : true); - CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler); + CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(workspace.activeCompiler); if(!silent) { projectView.ShowOutputBuildLog(true); @@ -1726,14 +2015,15 @@ class IDEWorkSpace : Window void UpdateToolBarActiveCompilers() { toolBar.activeCompiler.Clear(); - for(compiler : ideSettings.compilerConfigs) + for(compiler : ideConfig.compilers) { DataRow row = toolBar.activeCompiler.AddString(compiler.name); - if(workspace && workspace.compiler && !strcmp(compiler.name, workspace.compiler)) + if(workspace && workspace.activeCompiler && !strcmp(compiler.name, workspace.activeCompiler)) toolBar.activeCompiler.currentRow = row; } if(!toolBar.activeCompiler.currentRow && toolBar.activeCompiler.firstRow) toolBar.activeCompiler.SelectRow(toolBar.activeCompiler.firstRow); + toolBar.activeBitDepth.SelectRow(toolBar.activeBitDepth.FindRow(workspace ? workspace.bitDepth : 0)); } void UpdateToolBarActiveConfigs(bool selectionOnly) @@ -1828,11 +2118,38 @@ class IDEWorkSpace : Window toolBar.activeCompiler.disabled = unavailable; toolBar.activeBitDepth.disabled = unavailable; +#ifndef __WIN32__ + debugUseValgrindItem.disabled = unavailable; + AdjustValgrindMenus(); +#endif + AdjustFileMenus(); AdjustBuildMenus(); AdjustDebugMenus(); } +#ifndef __WIN32__ + void AdjustValgrindMenus() + { + bool unavailable = !project || !debugUseValgrindItem.checked; + debugValgrindNoLeakCheckItem.disabled = unavailable; + debugValgrindSummaryLeakCheckItem.disabled = unavailable; + debugValgrindYesLeakCheckItem.disabled = unavailable; + debugValgrindFullLeakCheckItem.disabled = unavailable; + + debugValgrindTrackOriginsItem.disabled = unavailable; + + debugValgrindRSDefaultItem.disabled = unavailable; + debugValgrindRS0Item.disabled = unavailable; + debugValgrindRS16Item.disabled = unavailable; + debugValgrindRS32Item.disabled = unavailable; + debugValgrindRS64Item.disabled = unavailable; + debugValgrindRS128Item.disabled = unavailable; + debugValgrindRS256Item.disabled = unavailable; + debugValgrindRS512Item.disabled = unavailable; + } +#endif + property bool hasOpenedCodeEditors { get @@ -1857,6 +2174,8 @@ class IDEWorkSpace : Window void AdjustBuildMenus() { bool unavailable = project && projectView.buildInProgress; + bool naForRun = unavailable || !project || project.GetTargetType(project.config) != executable; + BuildOutputMode mode = ide.rightClickMenuBuildOutputMode; projectNewItem.disabled = unavailable; toolBar.buttonNewProject.disabled = unavailable; @@ -1868,11 +2187,11 @@ class IDEWorkSpace : Window projectCloseItem.disabled = unavailable; // toolBar.buttonCloseProject.disabled = unavailable; - projectRunItem.disabled = unavailable || project.GetTargetType(project.config) != executable; - toolBar.buttonRun.disabled = unavailable || project.GetTargetType(project.config) != executable; + projectRunItem.disabled = naForRun; + toolBar.buttonRun.disabled = naForRun; projectBuildItem.disabled = false; - projectBuildItem.text = unavailable ? $"Stop Build" : $"Build"; + projectBuildItem.text = unavailable ? $"Stop Build" : bldMnuStrBuild[mode]; projectBuildItem.accelerator = unavailable ? Key { pauseBreak, ctrl = true } : f7; projectLinkItem.disabled = unavailable; @@ -1886,6 +2205,10 @@ class IDEWorkSpace : Window // toolBar.buttonRealClean.disabled = unavailable; projectRegenerateItem.disabled = unavailable; toolBar.buttonRegenerateMakefile.disabled = unavailable; +#ifdef IDE_SHOW_INSTALL_MENU_BUTTON + projectInstallItem.disabled = unavailable; + toolBar.buttonInstall.disabled = unavailable; +#endif projectCompileItem.disabled = unavailable; AdjustPopupBuildMenus(); @@ -1898,26 +2221,28 @@ class IDEWorkSpace : Window if(projectView && projectView.popupMenu && projectView.popupMenu.menu && projectView.popupMenu.created) { MenuItem menu; - menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectBuild, 0); + BuildOutputMode mode = ide.rightClickMenuBuildOutputMode; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectBuild, mode); if(menu) { menu.disabled = false; - menu.text = unavailable ? $"Stop Build" : $"Build"; + menu.text = unavailable ? $"Stop Build" : bldMnuStrBuild[mode]; menu.accelerator = unavailable ? Key { pauseBreak, ctrl = true } : f7; } - menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectLink, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRebuild, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectCleanTarget, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectClean, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRealClean, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRegenerate, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRemove, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::FileClean, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::FileCompile, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::FileDebugPrecompile, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::FileDebugCompile, 0); if(menu) menu.disabled = unavailable; - menu = projectView.popupMenu.menu.FindItem(ProjectView::FileDebugGenerateSymbols, 0); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectLink, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRebuild, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectCleanTarget, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectClean, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRealClean, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRegenerate, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectInstall, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::ProjectRemove, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::FileClean, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::FileCompile, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::FileDebugPrecompile, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::FileDebugCompile, mode); if(menu) menu.disabled = unavailable; + menu = projectView.popupMenu.menu.FindItem(ProjectView::FileDebugGenerateSymbols, mode); if(menu) menu.disabled = unavailable; projectView.popupMenu.Update(null); } } @@ -1928,66 +2253,67 @@ class IDEWorkSpace : Window projectView.buildInProgress == buildingMainProject; } } - property bool isBreakpointTogglingUnavailable { get { - return !project; - } } - - property bool isDebuggerExecuting { get { - if(!ide.debugger) - return false; - else - return ide.debugger.state == running; - } } + property bool isBreakpointTogglingUnavailable { get { return !project; } } + property bool isDebuggerRunning { get { if(ide.debugger) return ide.debugger.state == running; return false; } } + property bool isDebuggerStopped { get { if(ide.debugger) return ide.debugger.state == stopped; return false; } } void AdjustDebugMenus() { bool unavailable = areDebugMenusUnavailable; + bool running = isDebuggerRunning; + bool stopped = isDebuggerStopped; bool active = debugger.isActive; - bool bpNoToggle = isBreakpointTogglingUnavailable; - bool executing = isDebuggerExecuting; - //bool holding = debugger.state == stopped; - debugStartResumeItem.disabled = unavailable || executing; + bool isNotRunning = unavailable || !running; + bool isNotNotRunning = unavailable || running; + bool isNotStopped = unavailable || !stopped; + bool isNotActive = unavailable || !active; + + debugStartResumeItem.disabled = isNotNotRunning; debugStartResumeItem.text = active ? $"Resume" : $"Start"; debugStartResumeItem.NotifySelect = active ? MenuDebugResume : MenuDebugStart; if(toolBar) { - toolBar.buttonDebugStartResume.disabled = unavailable || executing; + toolBar.buttonDebugStartResume.disabled = isNotNotRunning; toolBar.buttonDebugStartResume.toolTip = active ? $"Resume" : $"Start"; } - debugBreakItem.disabled = unavailable || !executing; - debugStopItem.disabled = unavailable || !active; - debugRestartItem.disabled = unavailable || !active; + debugBreakItem.disabled = isNotRunning; + debugStopItem.disabled = isNotActive; + debugRestartItem.disabled = isNotActive; if(toolBar) { - toolBar.buttonDebugPause.disabled = unavailable || !executing; - toolBar.buttonDebugStop.disabled = unavailable || !active; - toolBar.buttonDebugRestart.disabled = unavailable || !active; + toolBar.buttonDebugPause.disabled = isNotRunning; + toolBar.buttonDebugStop.disabled = isNotActive; + toolBar.buttonDebugRestart.disabled = isNotActive; } - debugStepIntoItem.disabled = unavailable || executing; - debugStepOverItem.disabled = unavailable || executing; - debugStepOutItem.disabled = unavailable || executing || !active; - debugSkipStepOverItem.disabled = unavailable || executing; - debugSkipStepOutItem.disabled = unavailable || executing || !active; + debugStepIntoItem.disabled = isNotNotRunning; + debugStepOverItem.disabled = isNotNotRunning; + debugSkipStepOverItem.disabled = isNotNotRunning; + debugStepOutItem.disabled = isNotStopped; + debugSkipStepOutItem.disabled = isNotStopped; +#if 0 + debugStepUntilItem.disabled = isNotStopped; + debugSkipStepUntilItem.disabled = isNotStopped; +#endif if(toolBar) { - toolBar.buttonDebugStepInto.disabled = unavailable || executing; - toolBar.buttonDebugStepOver.disabled = unavailable || executing; - toolBar.buttonDebugStepOut.disabled = unavailable || executing || !active; - toolBar.buttonDebugSkipStepOver.disabled = unavailable || executing; - // toolBar.buttonDebugSkipStepOutItem.disabled = unavailable || executing; + toolBar.buttonDebugStepInto.disabled = isNotNotRunning; + toolBar.buttonDebugStepOver.disabled = isNotNotRunning; + toolBar.buttonDebugSkipStepOver.disabled = isNotNotRunning; + toolBar.buttonDebugStepOut.disabled = isNotStopped; + //toolBar.buttonDebugSkipStepOutItem.disabled = isNotNotRunning; } if((Designer)GetActiveDesigner()) { CodeEditor codeEditor = ((Designer)GetActiveDesigner()).codeEditor; if(codeEditor) - codeEditor.AdjustDebugMenus(unavailable, bpNoToggle, executing); + codeEditor.AdjustDebugMenus(); } } - void ChangeFileDialogsDirectory(char * directory, bool saveSettings) + void ChangeFileDialogsDirectory(const char * directory, bool saveSettings) { char tempString[MAX_LOCATION]; strcpy(tempString, directory); @@ -2008,14 +2334,14 @@ class IDEWorkSpace : Window settingsContainer.Save(); } - Window FindWindow(char * filePath) + Window FindWindow(const char * filePath) { Window document = null; // TOCHECK: Do we need to change slashes here? for(document = firstChild; document; document = document.next) { - char * fileName = document.fileName; + const char * fileName = document.fileName; if(document.isDocument && fileName && !fstrcmp(fileName, filePath)) { document.visible = true; @@ -2026,17 +2352,17 @@ class IDEWorkSpace : Window return null; } - bool DontTerminateDebugSession(char * title) + bool DontTerminateDebugSession(const char * title) { if(debugger.isActive) { - if(MessageBox { type = yesNo, master = ide, - contents = $"Do you want to terminate the debugging session in progress?", + if(MessageBox { type = yesNo, master = ide, + contents = $"Do you want to terminate the debugging session in progress?", text = title }.Modal() == no) return true; /* - MessageBox msg { type = yesNo, master = ide, - contents = "Do you want to terminate the debugging session in progress?", + MessageBox msg { type = yesNo, master = ide, + contents = "Do you want to terminate the debugging session in progress?", text = title }; if(msg.Modal() == no) { @@ -2050,15 +2376,16 @@ class IDEWorkSpace : Window return false; } - Window OpenFile(char * origFilePath, WindowState state, bool visible, char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod, bool noParsing) + Window OpenFile(const char * origFilePath, bool dontMaximize, bool visible, const char * type, OpenCreateIfFails createIfFails, OpenMethod openMethod, bool noParsing) { char extension[MAX_EXTENSION] = ""; Window document = null; bool isProject = false; bool needFileModified = true; char winFilePath[MAX_LOCATION]; - char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath); - + const char * filePath = strstr(origFilePath, "http://") == origFilePath ? strcpy(winFilePath, origFilePath) : GetSystemPathBuffer(winFilePath, origFilePath); + Window currentDoc = activeClient; + bool maximizeDoc = !dontMaximize && ((currentDoc && currentDoc.state == maximized) || (!currentDoc && !projectView)); if(!type) { GetExtension(filePath, extension); @@ -2071,7 +2398,7 @@ class IDEWorkSpace : Window { for(document = firstChild; document; document = document.next) { - char * fileName = document.fileName; + const char * fileName = document.fileName; if(document.isDocument && fileName && !fstrcmp(fileName, filePath) && document.created) { document.visible = true; @@ -2098,9 +2425,8 @@ class IDEWorkSpace : Window { for(;;) { - Project project; Workspace workspace = null; - + if(FileExists(filePath)) { if(!strcmp(extension, ProjectExtension)) @@ -2114,21 +2440,24 @@ class IDEWorkSpace : Window workspace = LoadWorkspace(filePath, null); else return null; - //project = LoadProject(filePath, null); } - + if(workspace) { - char absolutePath[MAX_LOCATION]; CreateProjectView(workspace, filePath); document = projectView; - workspace.DropInvalidBreakpoints(); + toolBox.visible = true; + sheet.visible = true; + projectView.MakeActive(); + + workspace.ParseLoadedBreakpoints(); + workspace.DropInvalidBreakpoints(null); workspace.Save(); ide.projectView.ShowOutputBuildLog(true); { - CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler); + CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(ide.workspace.activeCompiler); ide.projectView.DisplayCompiler(compiler, false); delete compiler; } @@ -2147,44 +2476,46 @@ class IDEWorkSpace : Window // this crashes on starting ide with epj file, solution please? // app.UpdateDisplay(); + workspace.OpenPreviouslyOpenedFiles(noParsing); workspace.holdTracking = true; - for(ofi : workspace.openedFiles) - { - if(ofi.state != closed) - { - Window file = OpenFile(ofi.path, normal, true, null, no, normal, noParsing); - if(file) - { - char fileName[MAX_LOCATION]; - ProjectNode node; - GetLastDirectory(ofi.path, fileName); - node = projectView.project.topNode.Find(fileName, true); - if(node) - node.EnsureVisible(); - } - } - } + ide.RepositionWindows(false); workspace.holdTracking = false; workspace.timer.Start(); +#if !defined(__WIN32__) + // Valgrind Debug menu updates + debugUseValgrindItem.checked = workspace.useValgrind; + + debugValgrindNoLeakCheckItem.checked = workspace.vgLeakCheck == no; + debugValgrindSummaryLeakCheckItem.checked = workspace.vgLeakCheck == summary; + debugValgrindYesLeakCheckItem.checked = workspace.vgLeakCheck == yes; + debugValgrindFullLeakCheckItem.checked = workspace.vgLeakCheck == full; + + debugValgrindRSDefaultItem.checked = workspace.vgRedzoneSize == -1; + debugValgrindRS0Item.checked = workspace.vgRedzoneSize == 0; + debugValgrindRS16Item.checked = workspace.vgRedzoneSize == 16; + debugValgrindRS32Item.checked = workspace.vgRedzoneSize == 32; + debugValgrindRS64Item.checked = workspace.vgRedzoneSize == 64; + debugValgrindRS128Item.checked = workspace.vgRedzoneSize == 128; + debugValgrindRS256Item.checked = workspace.vgRedzoneSize == 256; + debugValgrindRS512Item.checked = workspace.vgRedzoneSize == 512; + + debugValgrindTrackOriginsItem.checked = workspace.vgTrackOrigins; +#endif + findInFilesDialog.mode = FindInFilesMode::project; findInFilesDialog.currentDirectory = ide.project.topNode.path; - + { char location[MAX_LOCATION]; StripLastDirectory(ide.project.topNode.path, location); ChangeProjectFileDialogDirectory(location); } - - /* - if(projectView.debugger) - projectView.debugger.EvaluateWatches(); - */ - + break; } - else + else { if(MessageBox { type = yesNo, master = this, text = $"Error opening project", contents = $"Open a different project?" }.Modal() == yes) { @@ -2220,7 +2551,7 @@ class IDEWorkSpace : Window } if(prj) { - MessageBox { type = ok, parent = parent, master = this, text = $"Same Project", + MessageBox { type = ok, parent = parent, master = this, text = $"Same Project", contents = $"This project is already present in workspace." }.Modal(); } else @@ -2228,10 +2559,10 @@ class IDEWorkSpace : Window prj = LoadProject(filePath, null); if(prj) { - char * activeConfigName = null; - CompilerConfig compiler = ideSettings.GetCompilerConfig(workspace.compiler); + const char * activeConfigName = null; + CompilerConfig compiler = ideConfig.compilers.GetCompilerConfig(workspace.activeCompiler); prj.StartMonitoring(); - workspace.projects.Add(prj); + workspace.AddProject(prj, null); if(toolBar.activeConfig.currentRow && toolBar.activeConfig.currentRow != toolBar.activeConfig.firstRow && toolBar.activeConfig.currentRow.string && toolBar.activeConfig.currentRow.string[0]) activeConfigName = toolBar.activeConfig.currentRow.string; @@ -2276,8 +2607,8 @@ class IDEWorkSpace : Window !strcmp(extension, "jpeg") || !strcmp(extension, "png")) { if(FileExists(filePath)) - document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable, - hasVertScroll = true, hasHorzScroll = true, parent = this, state = state, + document = PictureEdit { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable, + hasVertScroll = true, hasHorzScroll = true, parent = this, state = state, visible = visible, bitmapFile = filePath, OnClose = PictureEditOnClose/*why?--GenericDocumentOnClose*/; }; if(!document) @@ -2287,8 +2618,8 @@ class IDEWorkSpace : Window else if(!strcmp(extension, "3ds")) { if(FileExists(filePath)) - document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable, - hasVertScroll = true, hasHorzScroll = true, parent = this, state = state, + document = ModelView { hasMaximize = true, hasMinimize = true, hasClose = true, borderStyle = sizable, + hasVertScroll = true, hasHorzScroll = true, parent = this, state = state, visible = visible, modelFile = filePath, OnClose = ModelViewOnClose/*why?--GenericDocumentOnClose*/ }; @@ -2334,18 +2665,18 @@ class IDEWorkSpace : Window { document.fileName = filePath; if(workspace && !workspace.holdTracking) - workspace.UpdateOpenedFileInfo(filePath, opened); + workspace.UpdateOpenedFileInfo(filePath, opened, true); } } - + if(!document && createIfFails != no) { - if(createIfFails != yes && !needFileModified && + if(createIfFails != yes && !needFileModified && MessageBox { type = yesNo, master = this, text = filePath, contents = $"File doesn't exist. Create?" }.Modal() == yes) createIfFails = yes; if(createIfFails == yes || createIfFails == whatever) { - document = (Window)NewCodeEditor(this, state, true); + document = (Window)NewCodeEditor(this, maximizeDoc ? maximized : normal, true); if(document) document.fileName = filePath; } @@ -2354,34 +2685,29 @@ class IDEWorkSpace : Window if(document) { if(projectView && document._class == class(CodeEditor) && workspace) - { - int lineNumber, position; - Point scroll; - CodeEditor editor = (CodeEditor)document; - editor.openedFileInfo = workspace.UpdateOpenedFileInfo(filePath, opened); - editor.openedFileInfo.holdTracking = true; - lineNumber = Max(editor.openedFileInfo.lineNumber - 1, 0); - position = Max(editor.openedFileInfo.position - 1, 0); - editor.editBox.GoToLineNum(lineNumber); - editor.editBox.GoToPosition(editor.editBox.line, lineNumber, position); - scroll.x = Max(editor.openedFileInfo.scroll.x, 0); - scroll.y = Max(editor.openedFileInfo.scroll.y, 0); - editor.editBox.scroll = scroll; - editor.openedFileInfo.holdTracking = false; - } - + workspace.RestorePreviouslyOpenedFileState((CodeEditor)document); + if(needFileModified) document.OnFileModified = OnFileModified; document.NotifySaved = DocumentSaved; - + if(maximizeDoc && document.hasMaximize) + document.state = maximized; + if(isProject) - ideSettings.AddRecentProject(document.fileName); + { + ideConfig.recentWorkspaces.addRecent(document.fileName); + ideConfig.recentWorkspaces.write(settingsContainer); + ide.updateRecentProjectsMenu(); + } + else if(workspace) + workspace.recentFiles.addRecent(document.fileName); else - ideSettings.AddRecentFile(document.fileName); - ide.UpdateRecentMenus(); + { + ideConfig.recentFiles.addRecent(document.fileName); + ideConfig.recentFiles.write(settingsContainer); + } + ide.updateRecentFilesMenu(); ide.AdjustFileMenus(); - settingsContainer.Save(); - return document; } else @@ -2392,19 +2718,19 @@ class IDEWorkSpace : Window /*bool Window::GenericDocumentOnClose(bool parentClosing) { if(!parentClosing && ide.workspace) - ide.workspace.UpdateOpenedFileInfo(fileName, unknown); + ide.workspace.UpdateOpenedFileInfo(fileName, unknown, false); return true; }*/ bool ModelView::ModelViewOnClose(bool parentClosing) { if(!parentClosing && ide.workspace) - ide.workspace.UpdateOpenedFileInfo(fileName, unknown); + ide.workspace.UpdateOpenedFileInfo(fileName, unknown, false); return true; } bool PictureEdit::PictureEditOnClose(bool parentClosing) { if(!parentClosing && ide.workspace) - ide.workspace.UpdateOpenedFileInfo(fileName, unknown); + ide.workspace.UpdateOpenedFileInfo(fileName, unknown, false); return true; } @@ -2417,10 +2743,17 @@ class IDEWorkSpace : Window } */ + void UpdateStateLight(StatusField fld, bool on) + { + fld.color = on ? lime : Color { 128,128,128 }; + fld.backColor = on ? dimGray : 0; + fld.bold = on; + } + bool OnActivate(bool active, Window swap, bool * goOnWithActivation, bool direct) { - caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 }; - num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 }; + UpdateStateLight(caps, app.GetKeyState(capsState)); + UpdateStateLight(num, app.GetKeyState(numState)); return true; } @@ -2428,41 +2761,139 @@ class IDEWorkSpace : Window { switch(key) { - case b: - projectView.Update(null); - break; - case capsLock: - caps.color = app.GetKeyState(capsState) ? black : Color { 128,128,128 }; - break; - case numLock: - num.color = app.GetKeyState(numState) ? black : Color { 128,128,128 }; - break; + case b: projectView.Update(null); break; + case capsLock: UpdateStateLight(caps, app.GetKeyState(capsState)); break; + case numLock: UpdateStateLight(num, app.GetKeyState(numState)); break; } return true; } - void GoToError(const char * line, bool noParsing) + bool OnKeyUp(Key key, unichar ch) + { + switch(key) + { + case capsLock: UpdateStateLight(caps, app.GetKeyState(capsState)); break; + case numLock: UpdateStateLight(num, app.GetKeyState(numState)); break; + } + return true; + } + + void GoToError(const char * line, bool noParsing, const char * objectFileExt) { if(projectView) - projectView.GoToError(line, noParsing); + projectView.GoToError(line, noParsing, objectFileExt); + } + + FileAttribs GoToCodeSelectFile(const char * filePath, const char * dir, Project prj, ProjectNode * node, char * selectedPath, const char * objectFileExt) + { + FileAttribs result { }; + FileAttribs fileAttribs; + if(filePath[0]) + { + if(prj) + strcpy(selectedPath, prj.topNode.path); + else if(dir && dir[0]) + strcpy(selectedPath, dir); + else + selectedPath[0] = '\0'; + PathCat(selectedPath, filePath); + + if((fileAttribs = FileExists(selectedPath)).isFile) + result = fileAttribs; + else if(workspace) + { + bool done = false; + for(p : workspace.projects) + { + strcpy(selectedPath, p.topNode.path); + PathCat(selectedPath, filePath); + if((fileAttribs = FileExists(selectedPath)).isFile) + { + done = true; + result = fileAttribs; + break; + } + } + if(!done) + { + Project project; + ProjectNode n = null; + for(p : workspace.projects) + { + if((n = p.topNode.Find(filePath, false))) + { + n.GetFullFilePath(selectedPath, true); + if((fileAttribs = FileExists(selectedPath)).isFile) + { + if(node) *node = n; + result = fileAttribs; + break; + } + } + } + if(!n && (n = workspace.GetObjectFileNode(filePath, &project, selectedPath, objectFileExt)) && project && + (fileAttribs = FileExists(selectedPath)).isFile) + { + if(node) *node = n; + result = fileAttribs; + } + } + } + } + return result; } - void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir) + void CodeLocationParseAndGoTo(const char * text, Project project, const char * dir, const char * objectFileExt) { - char *path = text; + char *s = null; + const char *path = text; char *colon = strchr(text, ':'); char filePath[MAX_LOCATION] = ""; char completePath[MAX_LOCATION]; int line = 0, col = 0; + int len = strlen(text); Project prj = null; FileAttribs fileAttribs; - if(colon && (colon[1] == '/' || colon[1] == '\\')) + // support for valgrind output + if((s = strstr(text, "==")) && s == text && (s = strstr(s+2, "==")) && (s = strstr(s+2, ":")) && (s = strstr(s+1, ":"))) { - path = (colon - 1 > path) ? colon - 1 : path; - colon = strstr(colon + 1, ":"); + colon = s; + for(; s>text; s--) + { + if(*s == '(') + { + path = s+1; + break; + } + } + /*for(s=colon; *s; s++) + { + if(*s == ')') + { + *s = '\0';; + break; + } + }*/ + //*colon = '\0'; + //line = atoi(colon+1); + } + // support for "Found n match(es) in "file/path"; + else if(len > 0 && path[len-1] == '\"' && strstr(path, $"Found %d match%s in \"%s\"%s\n\n"."Found") && strstr(path, $"match") && strstr(path, $"in") && (s = strstr(path, "\"")) && s != path+len-1) + { + path = s+1; + } + else + { + if(colon && (colon[1] == '/' || colon[1] == '\\')) + { + path = (colon - 1 > path) ? colon - 1 : path; + colon = strstr(colon + 1, ":"); + } + if(*path == '*' && (s = strchr(path+1, '*'))) + path = s+1; + while(isspace(*path)) path++; } - while(isspace(*path)) path++; if(*path == '(') { char * close = strchr(path, ')'); @@ -2507,44 +2938,39 @@ class IDEWorkSpace : Window strcpy(filePath, path); } - if(filePath[0]) + if((fileAttribs = GoToCodeSelectFile(filePath, dir, prj, null, completePath, objectFileExt))) + CodeLocationGoTo(completePath, fileAttribs, line, col); + } + + void CodeLocationGoTo(const char * path, const FileAttribs fileAttribs, int line, int col) + { + if(fileAttribs.isFile) { - if(prj) - strcpy(completePath, prj.topNode.path); - else if(dir && dir[0]) - strcpy(completePath, dir); + char ext[MAX_EXTENSION]; + GetExtension(path, ext); + strlwr(ext); + if(binaryDocExt.Find(ext)) + ShellOpen(path); + else if(!strcmp(ext, "a") || !strcmp(ext, "o") || !strcmp(ext, "bc") || + !strcmp(ext, "lib") || !strcmp(ext, "dll") || !strcmp(ext, "exe")) + { + char dirPath[MAX_LOCATION]; + StripLastDirectory(path, dirPath); + ShellOpen(dirPath); + } else - completePath[0] = '\0'; - PathCat(completePath, filePath); - - - fileAttribs = FileExists(completePath); - if(fileAttribs.isFile) { - char ext[MAX_EXTENSION]; - GetExtension(completePath, ext); - if(!strcmp(ext, "mp3") || !strcmp(ext, "flac") || !strcmp(ext, "ogg") || !strcmp(ext, "avi") || !strcmp(ext, "mkv")) - ShellOpen(completePath); - else if(!strcmp(ext, "a") || !strcmp(ext, "o") || !strcmp(ext, "lib") || !strcmp(ext, "dll") || !strcmp(ext, "exe")) - { - char dirPath[MAX_LOCATION]; - StripLastDirectory(completePath, dirPath); - ShellOpen(dirPath); - } - else + CodeEditor codeEditor = (CodeEditor)OpenFile(path, false, true, !strcmpi(ext, "epj") ? "txt" : ext, no, normal, false); + if(codeEditor && codeEditor._class == class(CodeEditor) && line) { - CodeEditor codeEditor = (CodeEditor)OpenFile(completePath, normal, true, "", no, normal, false); - if(codeEditor && line) - { - EditBox editBox = codeEditor.editBox; - editBox.GoToLineNum(line - 1); - editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0); - } + EditBox editBox = codeEditor.editBox; + editBox.GoToLineNum(line - 1); + editBox.GoToPosition(editBox.line, line - 1, col ? (col - 1) : 0); } } - else if(fileAttribs.isDirectory) - ShellOpen(completePath); } + else if(fileAttribs.isDirectory) + ShellOpen(path); } void OnRedraw(Surface surface) @@ -2616,12 +3042,12 @@ class IDEWorkSpace : Window SetCurrentContext(codeEditor.globalContext); SetTopContext(codeEditor.globalContext); SetGlobalContext(codeEditor.globalContext); - + SetDefines(&codeEditor.defines); SetImports(&codeEditor.imports); SetActiveDesigner(codeEditor.designer); - + sheet.codeEditor = codeEditor; toolBox.codeEditor = codeEditor; @@ -2680,6 +3106,12 @@ class IDEWorkSpace : Window } else { + if(!client && !projectView && sheet.visible) + { + if(sheet) + sheet.visible = false; + toolBox.visible = false; + } if(sheet) sheet.codeEditor = null; toolBox.codeEditor = null; @@ -2704,22 +3136,25 @@ class IDEWorkSpace : Window statusBar.AddField(pos); - caps = { width = 40, text = $"CAPS", color = app.GetKeyState(capsState) ? black : Color { 128, 128, 128 } }; + caps = { width = 40, text = $"CAPS" }; statusBar.AddField(caps); + UpdateStateLight(caps, app.GetKeyState(capsState)); - ovr = { width = 30, text = $"OVR", color = (editBox && editBox.overwrite) ? black : Color { 128, 128, 128 } }; + ovr = { width = 36, text = $"OVR" }; statusBar.AddField(ovr); + UpdateStateLight(ovr, (editBox && editBox.overwrite)); - num = { width = 30, text = $"NUM", color = app.GetKeyState(numState) ? black : Color { 128, 128, 128 } }; + num = { width = 36, text = $"NUM" }; statusBar.AddField(num); + UpdateStateLight(num, app.GetKeyState(numState)); //statusBar.text = "Ready"; if(projectView && projectView.project) { bool isCObject = false; - ProjectNode node = projectView.GetNodeFromWindow(client, null, false); - if(!node && (node = projectView.GetNodeFromWindow(client, null, true))) + ProjectNode node = projectView.GetNodeFromWindow(client, null, true, false, null); + if(!node && (node = projectView.GetNodeFromWindow(client, null, true, true, null))) isCObject = true; if(node) { @@ -2728,7 +3163,7 @@ class IDEWorkSpace : Window if(isCObject) ChangeExtension(node.name, "c", nodeName); sprintf(name, $"Compile %s", isCObject ? nodeName : node.name); - projectCompileItem = + projectCompileItem = { copyText = true, text = name, c, ctrlF7, disabled = projectView.buildInProgress; @@ -2736,26 +3171,21 @@ class IDEWorkSpace : Window { if(projectView) { - bool result = false; bool isCObject = false; - ProjectNode node = null; - for(p : ide.workspace.projects) - { - node = projectView.GetNodeFromWindow(activeClient, p, false); - if(node) break; - } - if(!node && (node = projectView.GetNodeFromWindow(activeClient, null, true))) - isCObject = true; + bool isExcluded = false; + ProjectNode node = projectView.GetNodeForCompilationFromWindow(activeClient, true, &isExcluded, &isCObject); if(node) { - List nodes { }; - nodes.Add(node); - projectView.Compile(node.project, nodes, mods.ctrl && mods.shift, isCObject ? cObject : normal); - delete nodes; - result = true; + if(isExcluded) + ide.outputView.buildBox.Logf($"%s %s is excluded from current build configuration.\n", isCObject ? "Object file" : "File", node.name); + else + { + List nodes { }; + nodes.Add(node); + projectView.Compile(node.project, nodes, normal, isCObject ? cObject : normal); + delete nodes; + } } - if(!result && node) - ide.outputView.buildBox.Logf($"File %s is excluded from current build configuration.\n", node.name); } return true; } @@ -2793,27 +3223,23 @@ class IDEWorkSpace : Window { int c; bool passThrough = false; - bool debugStart = false; bool debugWorkDir = false; char * passDebugWorkDir = null; bool openAsText = false; DynamicString passArgs { }; + int ptArg = 0; + for(c = 1; c 0) + passArgs.concat(" "); + PassArg(buf, arg); + passArgs.concat(buf); + delete buf; } else if(debugWorkDir) { @@ -2821,6 +3247,16 @@ class IDEWorkSpace : Window StripQuotes(passDebugWorkDir, passDebugWorkDir); debugWorkDir = false; } + else if(!strcmp(app.argv[c], "-t")) + openAsText = true; + else if(!strcmp(app.argv[c], "-no-parsing")) + ide.noParsing = true; + else if(!strcmp(app.argv[c], "-debug-start")) + ide.debugStart = true; + else if(!strcmp(app.argv[c], "-debug-work-dir")) + debugWorkDir = true; + else if(!strcmp(app.argv[c], "-@")) + passThrough = true; else { char fullPath[MAX_LOCATION]; @@ -2834,7 +3270,7 @@ class IDEWorkSpace : Window GetExtension(app.argv[c], ext); isProject = !openAsText && !strcmpi(ext, "epj"); - if(isProject && c > (debugStart ? 2 : 1)) continue; + if(isProject && c > 1 + (ide.debugStart ? 1 : 0)) continue; // Create directory for projects (only) if(((dirAttribs = FileExists(parentPath)) && dirAttribs.isDirectory) || isProject) @@ -2865,71 +3301,28 @@ class IDEWorkSpace : Window newProjectDialog.Modal(); if(projectView) { - ideSettings.AddRecentProject(projectView.fileName); - ide.UpdateRecentMenus(); - settingsContainer.Save(); + ideConfig.recentWorkspaces.addRecent(projectView.fileName); + ideConfig.recentWorkspaces.write(settingsContainer); + ide.updateRecentMenus(); } delete newProjectDialog; // Open only one project break; } else - ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, openAsText ? "txt" : null, yes, normal, false); + ide.OpenFile(fullPath, app.argFilesCount > 1, true, openAsText ? "txt" : null, yes, normal, false); } else if(strstr(fullPath, "http://") == fullPath) - ide.OpenFile(fullPath, (app.argc == 2) * maximized, true, openAsText ? "txt" : null, yes, normal, false); + ide.OpenFile(fullPath, app.argFilesCount > 1, true, openAsText ? "txt" : null, yes, normal, false); } } if(passThrough && projectView && projectView.project && workspace) - { - char * fixSpacing = new char[Max(passArgs.size * 1.5, 32)]; - { - int c, d = 0; - char j = 0; - char k = ' '; - char l = 0; - bool inQuote = false; - for(c=0; c paths { }; - p[0] = v[0] = '\0'; - strncpy(p, settingsContainer.moduleLocation, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - StripLastDirectory(p, p); - PathCat(p, name); - paths.Add(CopyString(p)); -#if defined(__WIN32__) - GetEnvironment("ECERE_SDK_SRC", v, maxPathLen); - if(v[0]) - { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, name); paths.Add(CopyString(p)); - } - GetEnvironment("AppData", v, maxPathLen); - if(v[0]) - { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, sdkDirName); PathCat(p, name); paths.Add(CopyString(p)); - } - GetEnvironment("ProgramFiles", v, maxPathLen); - if(v[0]) + v[0] = '\0'; + if(!found) { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, sdkDirName); PathCat(p, name); paths.Add(CopyString(p)); + strncpy(path, settingsContainer.moduleLocation, MAX_LOCATION); path[MAX_LOCATION-1] = '\0'; + StripLastDirectory(path, path); + PathCat(path, subDir); + if(name) PathCat(path, name); + if(FileExists(path) & attribs) found = true; } - GetEnvironment("ProgramFiles(x86)", v, maxPathLen); - if(v[0]) - { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, sdkDirName); PathCat(p, name); paths.Add(CopyString(p)); - } - GetEnvironment("SystemDrive", v, maxPathLen); - if(v[0]) +#if defined(__WIN32__) + if(!found) { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, "Program Files"); PathCat(p, sdkDirName); PathCat(p, name); paths.Add(CopyString(p)); + for(s : [ "ECERE_SDK_SRC", "AppData", "ALLUSERSPROFILE", "USERPROFILE", "HOMEPATH", "ProgramData", "ProgramFiles", "ProgramFiles(x86)", "SystemDrive" ]) + { + GetEnvironment(s, v, maxPathLen); + if(v[0]) + { + strncpy(path, v, MAX_LOCATION); path[MAX_LOCATION-1] = '\0'; + if(!strcmp(s, "SystemDrive")) + PathCat(path, "Program Files"); + if(strcmp(s, "ECERE_SDK_SRC")) + PathCat(path, sdkDirName); + PathCat(path, subDir); + if(name) PathCat(path, name); + if(FileExists(path) & attribs) + { + found = true; + break; + } + } + } } #else - GetEnvironment("XDG_DATA_DIRS", v, maxPathLen); - numTokens = TokenizeWith(v, sizeof(tokens) / sizeof(byte *), tokens, ":", false); - for(c=0; c paths { }; - p[0] = v[0] = '\0'; - strncpy(p, settingsContainer.moduleLocation, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - paths.Add(CopyString(p)); - StripLastDirectory(p, p); - PathCat(p, subdir); - paths.Add(CopyString(p)); -#if defined(__WIN32__) - GetEnvironment("ECERE_SDK_SRC", v, maxPathLen); - if(v[0]) - { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, sdkDirName); PathCat(p, subdir); paths.Add(CopyString(p)); - } - GetEnvironment("AppData", v, maxPathLen); - if(v[0]) - { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, sdkDirName); PathCat(p, subdir); paths.Add(CopyString(p)); - } - GetEnvironment("ProgramFiles", v, maxPathLen); - if(v[0]) - { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, sdkDirName); PathCat(p, subdir); paths.Add(CopyString(p)); - } - GetEnvironment("ProgramFiles(x86)", v, maxPathLen); - if(v[0]) - { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, sdkDirName); PathCat(p, subdir); paths.Add(CopyString(p)); - } - GetEnvironment("SystemDrive", v, maxPathLen); - if(v[0]) - { - strncpy(p, v, MAX_LOCATION); p[MAX_LOCATION-1] = '\0'; - PathCat(p, "Program Files"); PathCat(p, sdkDirName); PathCat(p, subdir); paths.Add(CopyString(p)); - } -#else - GetEnvironment("XDG_DATA_DIRS", v, maxPathLen); - numTokens = TokenizeWith(v, sizeof(tokens) / sizeof(byte *), tokens, ":", false); - for(c=0; c 0 && !strcmpi(GetExtension(argv[1], ext), "3ds")) + { + app.driver = "OpenGL"; + ide.driverItems[1].checked = true; + } + else + { #if defined(__unix__) || defined(__APPLE__) - app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X"; + app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "X"; #else - app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI"; + app.driver = (ideSettings.displayDriver && !strcmp(ideSettings.displayDriver, "OpenGL")) ? ideSettings.displayDriver : "GDI"; #endif - ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true; + ide.driverItems[ideSettings.displayDriver && !strcmp(ideSettings.displayDriver,"OpenGL")].checked = true; + } + + { + char model[MAX_LOCATION]; + if(GetInstalledFileOrFolder("samples", "3D/ModelViewer/models/duck/duck.3DS", model, { isFile = true })) + { + ide.duck.modelFile = model; + ide.duck.parent = ideMainFrame; + } + } + if(ide.duck.modelFile && !strcmpi(app.driver, "OpenGL")) + ide.debugRubberDuck.disabled = false; SetInIDE(true); - desktop.text = titleECEREIDE; + desktop.caption = titleECEREIDE; /* int c; for(c = 1; c 1, true, null, yes, normal, false); } */ + // Default to language specified by environment if no language selected + if(!ideSettings.language) + { + ideSettings.language = GetLanguageString(); + settingsContainer.Save(); + } + + // Default to home directory if no directory yet set up + if(!ideSettings.ideProjectFileDialogLocation[0]) + { + bool found = false; + char location[MAX_LOCATION]; + char * home = getenv("HOME"); + char * homeDrive = getenv("HOMEDRIVE"); + char * homePath = getenv("HOMEPATH"); + char * userProfile = getenv("USERPROFILE"); + char * systemDrive = getenv("SystemDrive"); + if(home && FileExists(home).isDirectory) + { + strcpy(location, home); + found = true; + } + if(!found && homeDrive && homePath) + { + strcpy(location, homeDrive); + PathCat(location, homePath); + if(FileExists(location).isDirectory) + found = true; + } + if(!found && FileExists(userProfile).isDirectory) + { + strcpy(location, userProfile); + found = true; + } + if(!found && FileExists(systemDrive).isDirectory) + { + strcpy(location, systemDrive); + found = true; + } + if(found) + { + ideSettings.ideProjectFileDialogLocation = location; + if(!ideSettings.ideFileDialogLocation[0]) + ideSettings.ideFileDialogLocation = location; + } + } + if(!LoadIncludeFile()) - PrintLn("error: unable to load :crossplatform.mk file inside ide binary."); + PrintLn($"error: unable to load :crossplatform.mk file inside ide binary."); + + // Create language menu + { + String language = ideSettings.language; + int i = 0; + bool found = false; + + ide.languageItems = new MenuItem[languages.count]; + for(l : languages) + { + ide.languageItems[i] = + { + ide.languageMenu, l.name; + bitmap = { l.bitmap }; + id = i; + isRadio = true; + + bool Window::NotifySelect(MenuItem selection, Modifiers mods) + { + if(!LanguageRestart(languages[(int)selection.id].code, app, ideSettings, settingsContainer, ide, ide.projectView, false)) + { + // Re-select previous selected language if aborted + String language = ideSettings.language; + int i = 0; + for(l : languages) + { + if(((!language || !language[0]) && i == 0) || + (language && !strcmpi(l.code, language))) + { + ide.languageItems[i].checked = true; + break; + } + i++; + } + } + return true; + } + }; + i++; + } + + // Try to find country-specific language first + if(language) + { + i = 0; + for(l : languages) + { + if(!strcmpi(l.code, language) || (i == 0 && !strcmpi("en", language))) + { + ide.languageItems[i].checked = true; + found = true; + break; + } + i++; + } + } + + // Try generalizing locale + if(!found && language) + { + char * under; + char genericLocale[256]; + i = 0; + strncpy(genericLocale, language, sizeof(genericLocale)); + genericLocale[sizeof(genericLocale)-1] = 0; + + under = strchr(genericLocale, '_'); + if(under) + *under = 0; + if(!strcmpi(genericLocale, "zh")) + strcpy(genericLocale, "zh_CN"); + if(strcmp(genericLocale, language)) + { + for(l : languages) + { + if(!strcmpi(l.code, genericLocale) || (i == 0 && !strcmpi("en", genericLocale))) + { + ide.languageItems[i].checked = true; + found = true; + break; + } + i++; + } + } + } + + if(!found) + ide.languageItems[0].checked = true; + + MenuDivider { ide.languageMenu }; + MenuItem + { + ide.languageMenu, "Help Translate"; + bool Window::NotifySelect(MenuItem selection, Modifiers mods) + { + ShellOpen("http://translations.launchpad.net/ecere"); + return true; + } + }; + } + + ideMainFrame.Create(); + if(app.argFilesCount > 1) + ide.MenuWindowTileVert(null, 0); + return true; + } + + bool Cycle(bool idle) + { + if(ide.documentor) + { + if(ide.documentor.Peek()) + { + char line[1024]; + ide.documentor.GetLine(line, sizeof(line)); + if(!strcmpi(line, "Exited")) + { + ide.documentor.CloseInput(); + ide.documentor.CloseOutput(); + ide.documentor.Wait(); + delete ide.documentor; + } + } + if(ide.documentor && ide.documentor.eof) + { + ide.documentor.CloseInput(); + ide.documentor.CloseOutput(); + ide.documentor.Wait(); + delete ide.documentor; + } + } return true; } @@ -3475,7 +4078,7 @@ IDEMainFrame ideMainFrame { }; define app = ((IDEApp)__thisModule); #ifdef _DEBUG -define titleECEREIDE = $"ECERE IDE (Debug)"; +define titleECEREIDE = $"Ecere IDE (Debug)"; #else -define titleECEREIDE = $"ECERE IDE"; +define titleECEREIDE = $"Ecere IDE"; #endif