summaryrefslogtreecommitdiff
path: root/tests/examplefiles/example.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/examplefiles/example.nim')
-rw-r--r--tests/examplefiles/example.nim1010
1 files changed, 1010 insertions, 0 deletions
diff --git a/tests/examplefiles/example.nim b/tests/examplefiles/example.nim
new file mode 100644
index 00000000..319da016
--- /dev/null
+++ b/tests/examplefiles/example.nim
@@ -0,0 +1,1010 @@
+import glib2, gtk2, gdk2, gtksourceview, dialogs, os, pango, osproc, strutils
+import pegs, streams
+import settings, types, cfg, search
+
+{.push callConv:cdecl.}
+
+const
+ NimrodProjectExt = ".nimprj"
+
+var win: types.MainWin
+win.Tabs = @[]
+
+search.win = addr(win)
+
+var lastSession: seq[string] = @[]
+
+var confParseFail = False # This gets set to true
+ # When there is an error parsing the config
+
+# Load the settings
+try:
+ win.settings = cfg.load(lastSession)
+except ECFGParse:
+ # TODO: Make the dialog show the exception
+ confParseFail = True
+ win.settings = cfg.defaultSettings()
+except EIO:
+ win.settings = cfg.defaultSettings()
+
+proc getProjectTab(): int =
+ for i in 0..high(win.tabs):
+ if win.tabs[i].filename.endswith(NimrodProjectExt): return i
+
+proc saveTab(tabNr: int, startpath: string) =
+ if tabNr < 0: return
+ if win.Tabs[tabNr].saved: return
+ var path = ""
+ if win.Tabs[tabNr].filename == "":
+ path = ChooseFileToSave(win.w, startpath)
+ # dialogs.nim STOCK_OPEN instead of STOCK_SAVE
+ else:
+ path = win.Tabs[tabNr].filename
+
+ if path != "":
+ var buffer = PTextBuffer(win.Tabs[tabNr].buffer)
+ # Get the text from the TextView
+ var startIter: TTextIter
+ buffer.getStartIter(addr(startIter))
+
+ var endIter: TTextIter
+ buffer.getEndIter(addr(endIter))
+
+ var text = buffer.getText(addr(startIter), addr(endIter), False)
+ # Save it to a file
+ var f: TFile
+ if open(f, path, fmWrite):
+ f.write(text)
+ f.close()
+
+ win.tempStuff.lastSaveDir = splitFile(path).dir
+
+ # Change the tab name and .Tabs.filename etc.
+ win.Tabs[tabNr].filename = path
+ win.Tabs[tabNr].saved = True
+ var name = extractFilename(path)
+
+ var cTab = win.Tabs[tabNr]
+ cTab.label.setText(name)
+ else:
+ error(win.w, "Unable to write to file")
+
+proc saveAllTabs() =
+ for i in 0..high(win.tabs):
+ saveTab(i, os.splitFile(win.tabs[i].filename).dir)
+
+# GTK Events
+# -- w(PWindow)
+proc destroy(widget: PWidget, data: pgpointer) {.cdecl.} =
+ # gather some settings
+ win.settings.VPanedPos = PPaned(win.sourceViewTabs.getParent()).getPosition()
+ win.settings.winWidth = win.w.allocation.width
+ win.settings.winHeight = win.w.allocation.height
+
+ # save the settings
+ win.save()
+ # then quit
+ main_quit()
+
+proc delete_event(widget: PWidget, event: PEvent, user_data: pgpointer): bool =
+ var quit = True
+ for i in low(win.Tabs)..len(win.Tabs)-1:
+ if not win.Tabs[i].saved:
+ var askSave = dialogNewWithButtons("", win.w, 0,
+ STOCK_SAVE, RESPONSE_ACCEPT, STOCK_CANCEL,
+ RESPONSE_CANCEL,
+ "Close without saving", RESPONSE_REJECT, nil)
+ askSave.setTransientFor(win.w)
+ # TODO: Make this dialog look better
+ var label = labelNew(win.Tabs[i].filename &
+ " is unsaved, would you like to save it ?")
+ PBox(askSave.vbox).pack_start(label, False, False, 0)
+ label.show()
+
+ var resp = askSave.run()
+ gtk2.destroy(PWidget(askSave))
+ case resp
+ of RESPONSE_ACCEPT:
+ saveTab(i, os.splitFile(win.tabs[i].filename).dir)
+ quit = True
+ of RESPONSE_CANCEL:
+ quit = False
+ break
+ of RESPONSE_REJECT:
+ quit = True
+ else:
+ quit = False
+ break
+
+ # If False is returned the window will close
+ return not quit
+
+proc windowState_Changed(widget: PWidget, event: PEventWindowState,
+ user_data: pgpointer) =
+ win.settings.winMaximized = (event.newWindowState and
+ WINDOW_STATE_MAXIMIZED) != 0
+
+# -- SourceView(PSourceView) & SourceBuffer
+proc updateStatusBar(buffer: PTextBuffer){.cdecl.} =
+ # Incase this event gets fired before
+ # bottomBar is initialized
+ if win.bottomBar != nil and not win.tempStuff.stopSBUpdates:
+ var iter: TTextIter
+
+ win.bottomBar.pop(0)
+ buffer.getIterAtMark(addr(iter), buffer.getInsert())
+ var row = getLine(addr(iter)) + 1
+ var col = getLineOffset(addr(iter))
+ discard win.bottomBar.push(0, "Line: " & $row & " Column: " & $col)
+
+proc cursorMoved(buffer: PTextBuffer, location: PTextIter,
+ mark: PTextMark, user_data: pgpointer){.cdecl.} =
+ updateStatusBar(buffer)
+
+proc onCloseTab(btn: PButton, user_data: PWidget) =
+ if win.sourceViewTabs.getNPages() > 1:
+ var tab = win.sourceViewTabs.pageNum(user_data)
+ win.sourceViewTabs.removePage(tab)
+
+ win.Tabs.delete(tab)
+
+proc onSwitchTab(notebook: PNotebook, page: PNotebookPage, pageNum: guint,
+ user_data: pgpointer) =
+ if win.Tabs.len()-1 >= pageNum:
+ win.w.setTitle("Aporia IDE - " & win.Tabs[pageNum].filename)
+
+proc createTabLabel(name: string, t_child: PWidget): tuple[box: PWidget,
+ label: PLabel] =
+ var box = hboxNew(False, 0)
+ var label = labelNew(name)
+ var closebtn = buttonNew()
+ closeBtn.setLabel(nil)
+ var iconSize = iconSizeFromName("tabIconSize")
+ if iconSize == 0:
+ iconSize = iconSizeRegister("tabIconSize", 10, 10)
+ var image = imageNewFromStock(STOCK_CLOSE, iconSize)
+ discard gSignalConnect(closebtn, "clicked", G_Callback(onCloseTab), t_child)
+ closebtn.setImage(image)
+ gtk2.setRelief(closebtn, RELIEF_NONE)
+ box.packStart(label, True, True, 0)
+ box.packEnd(closebtn, False, False, 0)
+ box.showAll()
+ return (box, label)
+
+proc changed(buffer: PTextBuffer, user_data: pgpointer) =
+ # Update the 'Line & Column'
+ #updateStatusBar(buffer)
+
+ # Change the tabs state to 'unsaved'
+ # and add '*' to the Tab Name
+ var current = win.SourceViewTabs.getCurrentPage()
+ var name = ""
+ if win.Tabs[current].filename == "":
+ win.Tabs[current].saved = False
+ name = "Untitled *"
+ else:
+ win.Tabs[current].saved = False
+ name = extractFilename(win.Tabs[current].filename) & " *"
+
+ var cTab = win.Tabs[current]
+ cTab.label.setText(name)
+
+# Other(Helper) functions
+
+proc initSourceView(SourceView: var PWidget, scrollWindow: var PScrolledWindow,
+ buffer: var PSourceBuffer) =
+ # This gets called by addTab
+ # Each tabs creates a new SourceView
+ # SourceScrolledWindow(ScrolledWindow)
+ scrollWindow = scrolledWindowNew(nil, nil)
+ scrollWindow.setPolicy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
+ scrollWindow.show()
+
+ # SourceView(gtkSourceView)
+ SourceView = sourceViewNew(buffer)
+ PSourceView(SourceView).setInsertSpacesInsteadOfTabs(True)
+ PSourceView(SourceView).setIndentWidth(win.settings.indentWidth)
+ PSourceView(SourceView).setShowLineNumbers(win.settings.showLineNumbers)
+ PSourceView(SourceView).setHighlightCurrentLine(
+ win.settings.highlightCurrentLine)
+ PSourceView(SourceView).setShowRightMargin(win.settings.rightMargin)
+ PSourceView(SourceView).setAutoIndent(win.settings.autoIndent)
+
+ var font = font_description_from_string(win.settings.font)
+ SourceView.modifyFont(font)
+
+ scrollWindow.add(SourceView)
+ SourceView.show()
+
+ buffer.setHighlightMatchingBrackets(
+ win.settings.highlightMatchingBrackets)
+
+ # UGLY workaround for yet another compiler bug:
+ discard gsignalConnect(buffer, "mark-set",
+ GCallback(aporia.cursorMoved), nil)
+ discard gsignalConnect(buffer, "changed", GCallback(aporia.changed), nil)
+
+ # -- Set the syntax highlighter scheme
+ buffer.setScheme(win.scheme)
+
+proc addTab(name, filename: string) =
+ ## Adds a tab, if filename is not "" reads the file. And sets
+ ## the tabs SourceViews text to that files contents.
+ assert(win.nimLang != nil)
+ var buffer: PSourceBuffer = sourceBufferNew(win.nimLang)
+
+ if filename != nil and filename != "":
+ var lang = win.langMan.guessLanguage(filename, nil)
+ if lang != nil:
+ buffer.setLanguage(lang)
+ else:
+ buffer.setHighlightSyntax(False)
+
+ var nam = name
+ if nam == "": nam = "Untitled"
+ if filename == "": nam.add(" *")
+ elif filename != "" and name == "":
+ # Disable the undo/redo manager.
+ buffer.begin_not_undoable_action()
+
+ # Load the file.
+ var file: string = readFile(filename)
+ if file != nil:
+ buffer.set_text(file, len(file))
+
+ # Enable the undo/redo manager.
+ buffer.end_not_undoable_action()
+
+ # Get the name.ext of the filename, for the tabs title
+ nam = extractFilename(filename)
+
+ # Init the sourceview
+ var sourceView: PWidget
+ var scrollWindow: PScrolledWindow
+ initSourceView(sourceView, scrollWindow, buffer)
+
+ var (TabLabel, labelText) = createTabLabel(nam, scrollWindow)
+ # Add a tab
+ discard win.SourceViewTabs.appendPage(scrollWindow, TabLabel)
+
+ var nTab: Tab
+ nTab.buffer = buffer
+ nTab.sourceView = sourceView
+ nTab.label = labelText
+ nTab.saved = (filename != "")
+ nTab.filename = filename
+ win.Tabs.add(nTab)
+
+ PTextView(SourceView).setBuffer(nTab.buffer)
+
+# GTK Events Contd.
+# -- TopMenu & TopBar
+
+proc newFile(menuItem: PMenuItem, user_data: pgpointer) =
+ addTab("", "")
+ win.sourceViewTabs.setCurrentPage(win.Tabs.len()-1)
+
+proc openFile(menuItem: PMenuItem, user_data: pgpointer) =
+ var startpath = ""
+ var currPage = win.SourceViewTabs.getCurrentPage()
+ if currPage <% win.tabs.len:
+ startpath = os.splitFile(win.tabs[currPage].filename).dir
+
+ if startpath.len == 0:
+ # Use lastSavePath as the startpath
+ startpath = win.tempStuff.lastSaveDir
+ if startpath.len == 0:
+ startpath = os.getHomeDir()
+
+ var files = ChooseFilesToOpen(win.w, startpath)
+ if files.len() > 0:
+ for f in items(files):
+ try:
+ addTab("", f)
+ except EIO:
+ error(win.w, "Unable to read from file")
+ # Switch to the newly created tab
+ win.sourceViewTabs.setCurrentPage(win.Tabs.len()-1)
+
+proc saveFile_Activate(menuItem: PMenuItem, user_data: pgpointer) =
+ var current = win.SourceViewTabs.getCurrentPage()
+ saveTab(current, os.splitFile(win.tabs[current].filename).dir)
+
+proc saveFileAs_Activate(menuItem: PMenuItem, user_data: pgpointer) =
+ var current = win.SourceViewTabs.getCurrentPage()
+ var (filename, saved) = (win.Tabs[current].filename, win.Tabs[current].saved)
+
+ win.Tabs[current].saved = False
+ win.Tabs[current].filename = ""
+ saveTab(current, os.splitFile(filename).dir)
+ # If the user cancels the save file dialog. Restore the previous filename
+ # and saved state
+ if win.Tabs[current].filename == "":
+ win.Tabs[current].filename = filename
+ win.Tabs[current].saved = saved
+
+proc undo(menuItem: PMenuItem, user_data: pgpointer) =
+ var current = win.SourceViewTabs.getCurrentPage()
+ if win.Tabs[current].buffer.canUndo():
+ win.Tabs[current].buffer.undo()
+
+proc redo(menuItem: PMenuItem, user_data: pgpointer) =
+ var current = win.SourceViewTabs.getCurrentPage()
+ if win.Tabs[current].buffer.canRedo():
+ win.Tabs[current].buffer.redo()
+
+proc find_Activate(menuItem: PMenuItem, user_data: pgpointer) =
+ # Get the selected text, and set the findEntry to it.
+ var currentTab = win.SourceViewTabs.getCurrentPage()
+ var insertIter: TTextIter
+ win.Tabs[currentTab].buffer.getIterAtMark(addr(insertIter),
+ win.Tabs[currentTab].buffer.getInsert())
+ var insertOffset = addr(insertIter).getOffset()
+
+ var selectIter: TTextIter
+ win.Tabs[currentTab].buffer.getIterAtMark(addr(selectIter),
+ win.Tabs[currentTab].buffer.getSelectionBound())
+ var selectOffset = addr(selectIter).getOffset()
+
+ if insertOffset != selectOffset:
+ var text = win.Tabs[currentTab].buffer.getText(addr(insertIter),
+ addr(selectIter), false)
+ win.findEntry.setText(text)
+
+ win.findBar.show()
+ win.findEntry.grabFocus()
+ win.replaceEntry.hide()
+ win.replaceLabel.hide()
+ win.replaceBtn.hide()
+ win.replaceAllBtn.hide()
+
+proc replace_Activate(menuitem: PMenuItem, user_data: pgpointer) =
+ win.findBar.show()
+ win.findEntry.grabFocus()
+ win.replaceEntry.show()
+ win.replaceLabel.show()
+ win.replaceBtn.show()
+ win.replaceAllBtn.show()
+
+proc settings_Activate(menuitem: PMenuItem, user_data: pgpointer) =
+ settings.showSettings(win)
+
+proc viewBottomPanel_Toggled(menuitem: PCheckMenuItem, user_data: pgpointer) =
+ win.settings.bottomPanelVisible = menuitem.itemGetActive()
+ if win.settings.bottomPanelVisible:
+ win.bottomPanelTabs.show()
+ else:
+ win.bottomPanelTabs.hide()
+
+var
+ pegLineError = peg"{[^(]*} '(' {\d+} ', ' \d+ ') Error:' \s* {.*}"
+ pegLineWarning = peg"{[^(]*} '(' {\d+} ', ' \d+ ') ' ('Warning:'/'Hint:') \s* {.*}"
+ pegOtherError = peg"'Error:' \s* {.*}"
+ pegSuccess = peg"'Hint: operation successful'.*"
+
+proc addText(textView: PTextView, text: string, colorTag: PTextTag = nil) =
+ if text != nil:
+ var iter: TTextIter
+ textView.getBuffer().getEndIter(addr(iter))
+
+ if colorTag == nil:
+ textView.getBuffer().insert(addr(iter), text, len(text))
+ else:
+ textView.getBuffer().insertWithTags(addr(iter), text, len(text), colorTag,
+ nil)
+
+proc createColor(textView: PTextView, name, color: string): PTextTag =
+ var tagTable = textView.getBuffer().getTagTable()
+ result = tagTable.tableLookup(name)
+ if result == nil:
+ result = textView.getBuffer().createTag(name, "foreground", color, nil)
+
+when not defined(os.findExe):
+ proc findExe(exe: string): string =
+ ## returns "" if the exe cannot be found
+ result = addFileExt(exe, os.exeExt)
+ if ExistsFile(result): return
+ var path = os.getEnv("PATH")
+ for candidate in split(path, pathSep):
+ var x = candidate / result
+ if ExistsFile(x): return x
+ result = ""
+
+proc GetCmd(cmd, filename: string): string =
+ var f = quoteIfContainsWhite(filename)
+ if cmd =~ peg"\s* '$' y'findExe' '(' {[^)]+} ')' {.*}":
+ var exe = quoteIfContainsWhite(findExe(matches[0]))
+ if exe.len == 0: exe = matches[0]
+ result = exe & " " & matches[1] % f
+ else:
+ result = cmd % f
+
+proc showBottomPanel() =
+ if not win.settings.bottomPanelVisible:
+ win.bottomPanelTabs.show()
+ win.settings.bottomPanelVisible = true
+ PCheckMenuItem(win.viewBottomPanelMenuItem).itemSetActive(true)
+ # Scroll to the end of the TextView
+ # This is stupid, it works sometimes... it's random
+ var endIter: TTextIter
+ win.outputTextView.getBuffer().getEndIter(addr(endIter))
+ discard win.outputTextView.scrollToIter(
+ addr(endIter), 0.25, False, 0.0, 0.0)
+
+proc compileRun(currentTab: int, shouldRun: bool) =
+ if win.Tabs[currentTab].filename.len == 0: return
+ # Clear the outputTextView
+ win.outputTextView.getBuffer().setText("", 0)
+
+ var outp = osProc.execProcess(GetCmd(win.settings.nimrodCmd,
+ win.Tabs[currentTab].filename))
+ # Colors
+ var normalTag = createColor(win.outputTextView, "normalTag", "#3d3d3d")
+ var errorTag = createColor(win.outputTextView, "errorTag", "red")
+ var warningTag = createColor(win.outputTextView, "warningTag", "darkorange")
+ var successTag = createColor(win.outputTextView, "successTag", "darkgreen")
+ for x in outp.splitLines():
+ if x =~ pegLineError / pegOtherError:
+ win.outputTextView.addText("\n" & x, errorTag)
+ elif x=~ pegSuccess:
+ win.outputTextView.addText("\n" & x, successTag)
+
+ # Launch the process
+ if shouldRun:
+ var filename = changeFileExt(win.Tabs[currentTab].filename, os.ExeExt)
+ var output = "\n" & osProc.execProcess(filename)
+ win.outputTextView.addText(output)
+ elif x =~ pegLineWarning:
+ win.outputTextView.addText("\n" & x, warningTag)
+ else:
+ win.outputTextView.addText("\n" & x, normalTag)
+ showBottomPanel()
+
+proc CompileCurrent_Activate(menuitem: PMenuItem, user_data: pgpointer) =
+ saveFile_Activate(nil, nil)
+ compileRun(win.SourceViewTabs.getCurrentPage(), false)
+
+proc CompileRunCurrent_Activate(menuitem: PMenuItem, user_data: pgpointer) =
+ saveFile_Activate(nil, nil)
+ compileRun(win.SourceViewTabs.getCurrentPage(), true)
+
+proc CompileProject_Activate(menuitem: PMenuItem, user_data: pgpointer) =
+ saveAllTabs()
+ compileRun(getProjectTab(), false)
+
+proc CompileRunProject_Activate(menuitem: PMenuItem, user_data: pgpointer) =
+ saveAllTabs()
+ compileRun(getProjectTab(), true)
+
+proc RunCustomCommand(cmd: string) =
+ saveFile_Activate(nil, nil)
+ var currentTab = win.SourceViewTabs.getCurrentPage()
+ if win.Tabs[currentTab].filename.len == 0 or cmd.len == 0: return
+ # Clear the outputTextView
+ win.outputTextView.getBuffer().setText("", 0)
+ var outp = osProc.execProcess(GetCmd(cmd, win.Tabs[currentTab].filename))
+ var normalTag = createColor(win.outputTextView, "normalTag", "#3d3d3d")
+ for x in outp.splitLines():
+ win.outputTextView.addText("\n" & x, normalTag)
+ showBottomPanel()
+
+proc RunCustomCommand1(menuitem: PMenuItem, user_data: pgpointer) =
+ RunCustomCommand(win.settings.customCmd1)
+
+proc RunCustomCommand2(menuitem: PMenuItem, user_data: pgpointer) =
+ RunCustomCommand(win.settings.customCmd2)
+
+proc RunCustomCommand3(menuitem: PMenuItem, user_data: pgpointer) =
+ RunCustomCommand(win.settings.customCmd3)
+
+# -- FindBar
+
+proc nextBtn_Clicked(button: PButton, user_data: pgpointer) = findText(True)
+proc prevBtn_Clicked(button: PButton, user_data: pgpointer) = findText(False)
+
+proc replaceBtn_Clicked(button: PButton, user_data: pgpointer) =
+ var currentTab = win.SourceViewTabs.getCurrentPage()
+ var start, theEnd: TTextIter
+ if not win.Tabs[currentTab].buffer.getSelectionBounds(
+ addr(start), addr(theEnd)):
+ # If no text is selected, try finding a match.
+ findText(True)
+ if not win.Tabs[currentTab].buffer.getSelectionBounds(
+ addr(start), addr(theEnd)):
+ # No match
+ return
+
+ # Remove the text
+ win.Tabs[currentTab].buffer.delete(addr(start), addr(theEnd))
+ # Insert the replacement
+ var text = getText(win.replaceEntry)
+ win.Tabs[currentTab].buffer.insert(addr(start), text, len(text))
+
+proc replaceAllBtn_Clicked(button: PButton, user_data: pgpointer) =
+ var find = getText(win.findEntry)
+ var replace = getText(win.replaceEntry)
+ discard replaceAll(find, replace)
+
+proc closeBtn_Clicked(button: PButton, user_data: pgpointer) =
+ win.findBar.hide()
+
+proc caseSens_Changed(radiomenuitem: PRadioMenuitem, user_data: pgpointer) =
+ win.settings.search = "casesens"
+proc caseInSens_Changed(radiomenuitem: PRadioMenuitem, user_data: pgpointer) =
+ win.settings.search = "caseinsens"
+proc style_Changed(radiomenuitem: PRadioMenuitem, user_data: pgpointer) =
+ win.settings.search = "style"
+proc regex_Changed(radiomenuitem: PRadioMenuitem, user_data: pgpointer) =
+ win.settings.search = "regex"
+proc peg_Changed(radiomenuitem: PRadioMenuitem, user_data: pgpointer) =
+ win.settings.search = "peg"
+
+proc extraBtn_Clicked(button: PButton, user_data: pgpointer) =
+ var extraMenu = menuNew()
+ var group: PGSList
+
+ var caseSensMenuItem = radio_menu_item_new(group, "Case sensitive")
+ extraMenu.append(caseSensMenuItem)
+ discard signal_connect(caseSensMenuItem, "toggled",
+ SIGNAL_FUNC(caseSens_Changed), nil)
+ caseSensMenuItem.show()
+ group = caseSensMenuItem.ItemGetGroup()
+
+ var caseInSensMenuItem = radio_menu_item_new(group, "Case insensitive")
+ extraMenu.append(caseInSensMenuItem)
+ discard signal_connect(caseInSensMenuItem, "toggled",
+ SIGNAL_FUNC(caseInSens_Changed), nil)
+ caseInSensMenuItem.show()
+ group = caseInSensMenuItem.ItemGetGroup()
+
+ var styleMenuItem = radio_menu_item_new(group, "Style insensitive")
+ extraMenu.append(styleMenuItem)
+ discard signal_connect(styleMenuItem, "toggled",
+ SIGNAL_FUNC(style_Changed), nil)
+ styleMenuItem.show()
+ group = styleMenuItem.ItemGetGroup()
+
+ var regexMenuItem = radio_menu_item_new(group, "Regex")
+ extraMenu.append(regexMenuItem)
+ discard signal_connect(regexMenuItem, "toggled",
+ SIGNAL_FUNC(regex_Changed), nil)
+ regexMenuItem.show()
+ group = regexMenuItem.ItemGetGroup()
+
+ var pegMenuItem = radio_menu_item_new(group, "Pegs")
+ extraMenu.append(pegMenuItem)
+ discard signal_connect(pegMenuItem, "toggled",
+ SIGNAL_FUNC(peg_Changed), nil)
+ pegMenuItem.show()
+
+ # Make the correct radio button active
+ case win.settings.search
+ of "casesens":
+ PCheckMenuItem(caseSensMenuItem).ItemSetActive(True)
+ of "caseinsens":
+ PCheckMenuItem(caseInSensMenuItem).ItemSetActive(True)
+ of "style":
+ PCheckMenuItem(styleMenuItem).ItemSetActive(True)
+ of "regex":
+ PCheckMenuItem(regexMenuItem).ItemSetActive(True)
+ of "peg":
+ PCheckMenuItem(pegMenuItem).ItemSetActive(True)
+
+ extraMenu.popup(nil, nil, nil, nil, 0, get_current_event_time())
+
+# GUI Initialization
+
+proc createAccelMenuItem(toolsMenu: PMenu, accGroup: PAccelGroup,
+ label: string, acc: gint,
+ action: proc (i: PMenuItem, p: pgpointer)) =
+ var result = menu_item_new(label)
+ result.addAccelerator("activate", accGroup, acc, 0, ACCEL_VISIBLE)
+ ToolsMenu.append(result)
+ show(result)
+ discard signal_connect(result, "activate", SIGNAL_FUNC(action), nil)
+
+proc createSeparator(menu: PMenu) =
+ var sep = separator_menu_item_new()
+ menu.append(sep)
+ sep.show()
+
+proc initTopMenu(MainBox: PBox) =
+ # Create a accelerator group, used for shortcuts
+ # like CTRL + S in SaveMenuItem
+ var accGroup = accel_group_new()
+ add_accel_group(win.w, accGroup)
+
+ # TopMenu(MenuBar)
+ var TopMenu = menuBarNew()
+
+ # FileMenu
+ var FileMenu = menuNew()
+
+ var NewMenuItem = menu_item_new("New") # New
+ FileMenu.append(NewMenuItem)
+ show(NewMenuItem)
+ discard signal_connect(NewMenuItem, "activate",
+ SIGNAL_FUNC(newFile), nil)
+
+ createSeparator(FileMenu)
+
+ var OpenMenuItem = menu_item_new("Open...") # Open...
+ # CTRL + O
+ OpenMenuItem.add_accelerator("activate", accGroup,
+ KEY_o, CONTROL_MASK, ACCEL_VISIBLE)
+ FileMenu.append(OpenMenuItem)
+ show(OpenMenuItem)
+ discard signal_connect(OpenMenuItem, "activate",
+ SIGNAL_FUNC(aporia.openFile), nil)
+
+ var SaveMenuItem = menu_item_new("Save") # Save
+ # CTRL + S
+ SaveMenuItem.add_accelerator("activate", accGroup,
+ KEY_s, CONTROL_MASK, ACCEL_VISIBLE)
+ FileMenu.append(SaveMenuItem)
+ show(SaveMenuItem)
+ discard signal_connect(SaveMenuItem, "activate",
+ SIGNAL_FUNC(saveFile_activate), nil)
+
+ var SaveAsMenuItem = menu_item_new("Save As...") # Save as...
+
+ SaveAsMenuItem.add_accelerator("activate", accGroup,
+ KEY_s, CONTROL_MASK or gdk2.SHIFT_MASK, ACCEL_VISIBLE)
+ FileMenu.append(SaveAsMenuItem)
+ show(SaveAsMenuItem)
+ discard signal_connect(SaveAsMenuItem, "activate",
+ SIGNAL_FUNC(saveFileAs_Activate), nil)
+
+ var FileMenuItem = menuItemNewWithMnemonic("_File")
+
+ FileMenuItem.setSubMenu(FileMenu)
+ FileMenuItem.show()
+ TopMenu.append(FileMenuItem)
+
+ # Edit menu
+ var EditMenu = menuNew()
+
+ var UndoMenuItem = menu_item_new("Undo") # Undo
+ EditMenu.append(UndoMenuItem)
+ show(UndoMenuItem)
+ discard signal_connect(UndoMenuItem, "activate",
+ SIGNAL_FUNC(aporia.undo), nil)
+
+ var RedoMenuItem = menu_item_new("Redo") # Undo
+ EditMenu.append(RedoMenuItem)
+ show(RedoMenuItem)
+ discard signal_connect(RedoMenuItem, "activate",
+ SIGNAL_FUNC(aporia.redo), nil)
+
+ createSeparator(EditMenu)
+
+ var FindMenuItem = menu_item_new("Find") # Find
+ FindMenuItem.add_accelerator("activate", accGroup,
+ KEY_f, CONTROL_MASK, ACCEL_VISIBLE)
+ EditMenu.append(FindMenuItem)
+ show(FindMenuItem)
+ discard signal_connect(FindMenuItem, "activate",
+ SIGNAL_FUNC(aporia.find_Activate), nil)
+
+ var ReplaceMenuItem = menu_item_new("Replace") # Replace
+ ReplaceMenuItem.add_accelerator("activate", accGroup,
+ KEY_h, CONTROL_MASK, ACCEL_VISIBLE)
+ EditMenu.append(ReplaceMenuItem)
+ show(ReplaceMenuItem)
+ discard signal_connect(ReplaceMenuItem, "activate",
+ SIGNAL_FUNC(aporia.replace_Activate), nil)
+
+ createSeparator(EditMenu)
+
+ var SettingsMenuItem = menu_item_new("Settings...") # Settings
+ EditMenu.append(SettingsMenuItem)
+ show(SettingsMenuItem)
+ discard signal_connect(SettingsMenuItem, "activate",
+ SIGNAL_FUNC(aporia.Settings_Activate), nil)
+
+ var EditMenuItem = menuItemNewWithMnemonic("_Edit")
+
+ EditMenuItem.setSubMenu(EditMenu)
+ EditMenuItem.show()
+ TopMenu.append(EditMenuItem)
+
+ # View menu
+ var ViewMenu = menuNew()
+
+ win.viewBottomPanelMenuItem = check_menu_item_new("Bottom Panel")
+ PCheckMenuItem(win.viewBottomPanelMenuItem).itemSetActive(
+ win.settings.bottomPanelVisible)
+ win.viewBottomPanelMenuItem.add_accelerator("activate", accGroup,
+ KEY_f9, CONTROL_MASK, ACCEL_VISIBLE)
+ ViewMenu.append(win.viewBottomPanelMenuItem)
+ show(win.viewBottomPanelMenuItem)
+ discard signal_connect(win.viewBottomPanelMenuItem, "toggled",
+ SIGNAL_FUNC(aporia.viewBottomPanel_Toggled), nil)
+
+ var ViewMenuItem = menuItemNewWithMnemonic("_View")
+
+ ViewMenuItem.setSubMenu(ViewMenu)
+ ViewMenuItem.show()
+ TopMenu.append(ViewMenuItem)
+
+
+ # Tools menu
+ var ToolsMenu = menuNew()
+
+ createAccelMenuItem(ToolsMenu, accGroup, "Compile current file",
+ KEY_F4, aporia.CompileCurrent_Activate)
+ createAccelMenuItem(ToolsMenu, accGroup, "Compile & run current file",
+ KEY_F5, aporia.CompileRunCurrent_Activate)
+ createSeparator(ToolsMenu)
+ createAccelMenuItem(ToolsMenu, accGroup, "Compile project",
+ KEY_F8, aporia.CompileProject_Activate)
+ createAccelMenuItem(ToolsMenu, accGroup, "Compile & run project",
+ KEY_F9, aporia.CompileRunProject_Activate)
+ createSeparator(ToolsMenu)
+ createAccelMenuItem(ToolsMenu, accGroup, "Run custom command 1",
+ KEY_F1, aporia.RunCustomCommand1)
+ createAccelMenuItem(ToolsMenu, accGroup, "Run custom command 2",
+ KEY_F2, aporia.RunCustomCommand2)
+ createAccelMenuItem(ToolsMenu, accGroup, "Run custom command 3",
+ KEY_F3, aporia.RunCustomCommand3)
+
+ var ToolsMenuItem = menuItemNewWithMnemonic("_Tools")
+
+ ToolsMenuItem.setSubMenu(ToolsMenu)
+ ToolsMenuItem.show()
+ TopMenu.append(ToolsMenuItem)
+
+ # Help menu
+ MainBox.packStart(TopMenu, False, False, 0)
+ TopMenu.show()
+
+proc initToolBar(MainBox: PBox) =
+ # TopBar(ToolBar)
+ var TopBar = toolbarNew()
+ TopBar.setStyle(TOOLBAR_ICONS)
+
+ var NewFileItem = TopBar.insertStock(STOCK_NEW, "New File",
+ "New File", SIGNAL_FUNC(aporia.newFile), nil, 0)
+ TopBar.appendSpace()
+ var OpenItem = TopBar.insertStock(STOCK_OPEN, "Open",
+ "Open", SIGNAL_FUNC(aporia.openFile), nil, -1)
+ var SaveItem = TopBar.insertStock(STOCK_SAVE, "Save",
+ "Save", SIGNAL_FUNC(saveFile_Activate), nil, -1)
+ TopBar.appendSpace()
+ var UndoItem = TopBar.insertStock(STOCK_UNDO, "Undo",
+ "Undo", SIGNAL_FUNC(aporia.undo), nil, -1)
+ var RedoItem = TopBar.insertStock(STOCK_REDO, "Redo",
+ "Redo", SIGNAL_FUNC(aporia.redo), nil, -1)
+
+ MainBox.packStart(TopBar, False, False, 0)
+ TopBar.show()
+
+proc initSourceViewTabs() =
+ win.SourceViewTabs = notebookNew()
+ #win.sourceViewTabs.dragDestSet(DEST_DEFAULT_DROP, nil, 0, ACTION_MOVE)
+ discard win.SourceViewTabs.signalConnect(
+ "switch-page", SIGNAL_FUNC(onSwitchTab), nil)
+ #discard win.SourceViewTabs.signalConnect(
+ # "drag-drop", SIGNAL_FUNC(svTabs_DragDrop), nil)
+ #discard win.SourceViewTabs.signalConnect(
+ # "drag-data-received", SIGNAL_FUNC(svTabs_DragDataRecv), nil)
+ #discard win.SourceViewTabs.signalConnect(
+ # "drag-motion", SIGNAL_FUNC(svTabs_DragMotion), nil)
+ win.SourceViewTabs.set_scrollable(True)
+
+ win.SourceViewTabs.show()
+ if lastSession.len != 0:
+ for i in 0 .. len(lastSession)-1:
+ var splitUp = lastSession[i].split('|')
+ var (filename, offset) = (splitUp[0], splitUp[1])
+ addTab("", filename)
+
+ var iter: TTextIter
+ win.Tabs[i].buffer.getIterAtOffset(addr(iter), offset.parseInt())
+ win.Tabs[i].buffer.moveMarkByName("insert", addr(iter))
+ win.Tabs[i].buffer.moveMarkByName("selection_bound", addr(iter))
+
+ # TODO: Fix this..... :(
+ discard PTextView(win.Tabs[i].sourceView).
+ scrollToIter(addr(iter), 0.25, true, 0.0, 0.0)
+ else:
+ addTab("", "")
+
+ # This doesn't work :\
+ win.Tabs[0].sourceView.grabFocus()
+
+
+proc initBottomTabs() =
+ win.bottomPanelTabs = notebookNew()
+ if win.settings.bottomPanelVisible:
+ win.bottomPanelTabs.show()
+
+ # output tab
+ var tabLabel = labelNew("Output")
+ var outputTab = vboxNew(False, 0)
+ discard win.bottomPanelTabs.appendPage(outputTab, tabLabel)
+ # Compiler tabs, gtktextview
+ var outputScrolledWindow = scrolledwindowNew(nil, nil)
+ outputScrolledWindow.setPolicy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
+ outputTab.packStart(outputScrolledWindow, true, true, 0)
+ outputScrolledWindow.show()
+
+ win.outputTextView = textviewNew()
+ outputScrolledWindow.add(win.outputTextView)
+ win.outputTextView.show()
+
+ outputTab.show()
+
+proc initTAndBP(MainBox: PBox) =
+ # This init's the HPaned, which splits the sourceViewTabs
+ # and the BottomPanelTabs
+ initSourceViewTabs()
+ initBottomTabs()
+
+ var TAndBPVPaned = vpanedNew()
+ tandbpVPaned.pack1(win.sourceViewTabs, resize=True, shrink=False)
+ tandbpVPaned.pack2(win.bottomPanelTabs, resize=False, shrink=False)
+ MainBox.packStart(TAndBPVPaned, True, True, 0)
+ tandbpVPaned.setPosition(win.settings.VPanedPos)
+ TAndBPVPaned.show()
+
+proc initFindBar(MainBox: PBox) =
+ # Create a fixed container
+ win.findBar = HBoxNew(False, 0)
+ win.findBar.setSpacing(4)
+
+ # Add a Label 'Find'
+ var findLabel = labelNew("Find:")
+ win.findBar.packStart(findLabel, False, False, 0)
+ findLabel.show()
+
+ # Add a (find) text entry
+ win.findEntry = entryNew()
+ win.findBar.packStart(win.findEntry, False, False, 0)
+ discard win.findEntry.signalConnect("activate", SIGNAL_FUNC(
+ aporia.nextBtn_Clicked), nil)
+ win.findEntry.show()
+ var rq: TRequisition
+ win.findEntry.sizeRequest(addr(rq))
+
+ # Make the (find) text entry longer
+ win.findEntry.set_size_request(190, rq.height)
+
+ # Add a Label 'Replace'
+ # - This Is only shown, when the 'Search & Replace'(CTRL + H) is shown
+ win.replaceLabel = labelNew("Replace:")
+ win.findBar.packStart(win.replaceLabel, False, False, 0)
+ #replaceLabel.show()
+
+ # Add a (replace) text entry
+ # - This Is only shown, when the 'Search & Replace'(CTRL + H) is shown
+ win.replaceEntry = entryNew()
+ win.findBar.packStart(win.replaceEntry, False, False, 0)
+ #win.replaceEntry.show()
+ var rq1: TRequisition
+ win.replaceEntry.sizeRequest(addr(rq1))
+
+ # Make the (replace) text entry longer
+ win.replaceEntry.set_size_request(100, rq1.height)
+
+ # Find next button
+ var nextBtn = buttonNew("Next")
+ win.findBar.packStart(nextBtn, false, false, 0)
+ discard nextBtn.signalConnect("clicked",
+ SIGNAL_FUNC(aporia.nextBtn_Clicked), nil)
+ nextBtn.show()
+ var nxtBtnRq: TRequisition
+ nextBtn.sizeRequest(addr(nxtBtnRq))
+
+ # Find previous button
+ var prevBtn = buttonNew("Previous")
+ win.findBar.packStart(prevBtn, false, false, 0)
+ discard prevBtn.signalConnect("clicked",
+ SIGNAL_FUNC(aporia.prevBtn_Clicked), nil)
+ prevBtn.show()
+
+ # Replace button
+ # - This Is only shown, when the 'Search & Replace'(CTRL + H) is shown
+ win.replaceBtn = buttonNew("Replace")
+ win.findBar.packStart(win.replaceBtn, false, false, 0)
+ discard win.replaceBtn.signalConnect("clicked",
+ SIGNAL_FUNC(aporia.replaceBtn_Clicked), nil)
+ #replaceBtn.show()
+
+ # Replace all button
+ # - this Is only shown, when the 'Search & Replace'(CTRL + H) is shown
+ win.replaceAllBtn = buttonNew("Replace All")
+ win.findBar.packStart(win.replaceAllBtn, false, false, 0)
+ discard win.replaceAllBtn.signalConnect("clicked",
+ SIGNAL_FUNC(aporia.replaceAllBtn_Clicked), nil)
+ #replaceAllBtn.show()
+
+ # Right side ...
+
+ # Close button - With a close stock image
+ var closeBtn = buttonNew()
+ var closeImage = imageNewFromStock(STOCK_CLOSE, ICON_SIZE_SMALL_TOOLBAR)
+ var closeBox = hboxNew(False, 0)
+ closeBtn.add(closeBox)
+ closeBox.show()
+ closeBox.add(closeImage)
+ closeImage.show()
+ discard closeBtn.signalConnect("clicked",
+ SIGNAL_FUNC(aporia.closeBtn_Clicked), nil)
+ win.findBar.packEnd(closeBtn, False, False, 2)
+ closeBtn.show()
+
+ # Extra button - When clicked shows a menu with options like 'Use regex'
+ var extraBtn = buttonNew()
+ var extraImage = imageNewFromStock(STOCK_PROPERTIES, ICON_SIZE_SMALL_TOOLBAR)
+
+ var extraBox = hboxNew(False, 0)
+ extraBtn.add(extraBox)
+ extraBox.show()
+ extraBox.add(extraImage)
+ extraImage.show()
+ discard extraBtn.signalConnect("clicked",
+ SIGNAL_FUNC(aporia.extraBtn_Clicked), nil)
+ win.findBar.packEnd(extraBtn, False, False, 0)
+ extraBtn.show()
+
+ MainBox.packStart(win.findBar, False, False, 0)
+ win.findBar.show()
+
+proc initStatusBar(MainBox: PBox) =
+ win.bottomBar = statusbarNew()
+ MainBox.packStart(win.bottomBar, False, False, 0)
+ win.bottomBar.show()
+
+ discard win.bottomBar.push(0, "Line: 0 Column: 0")
+
+proc initControls() =
+ # Load up the language style
+ win.langMan = languageManagerGetDefault()
+ var langpaths: array[0..1, cstring] =
+ [cstring(os.getApplicationDir() / langSpecs), nil]
+ win.langMan.setSearchPath(addr(langpaths))
+ var nimLang = win.langMan.getLanguage("nimrod")
+ win.nimLang = nimLang
+
+ # Load the scheme
+ var schemeMan = schemeManagerGetDefault()
+ var schemepaths: array[0..1, cstring] =
+ [cstring(os.getApplicationDir() / styles), nil]
+ schemeMan.setSearchPath(addr(schemepaths))
+ win.scheme = schemeMan.getScheme(win.settings.colorSchemeID)
+
+ # Window
+ win.w = windowNew(gtk2.WINDOW_TOPLEVEL)
+ win.w.setDefaultSize(win.settings.winWidth, win.settings.winHeight)
+ win.w.setTitle("Aporia IDE")
+ if win.settings.winMaximized: win.w.maximize()
+
+ win.w.show() # The window has to be shown before
+ # setting the position of the VPaned so that
+ # it gets set correctly, when the window is maximized.
+
+ discard win.w.signalConnect("destroy", SIGNAL_FUNC(aporia.destroy), nil)
+ discard win.w.signalConnect("delete_event",
+ SIGNAL_FUNC(aporia.delete_event), nil)
+ discard win.w.signalConnect("window-state-event",
+ SIGNAL_FUNC(aporia.windowState_Changed), nil)
+
+ # MainBox (vbox)
+ var MainBox = vboxNew(False, 0)
+ win.w.add(MainBox)
+
+ initTopMenu(MainBox)
+ initToolBar(MainBox)
+ initTAndBP(MainBox)
+ initFindBar(MainBox)
+ initStatusBar(MainBox)
+
+ MainBox.show()
+ if confParseFail:
+ dialogs.warning(win.w, "Error parsing config file, using default settings.")
+
+nimrod_init()
+initControls()
+main()
+