'BEGIN LICENCE "Lynnecence V1" '1. pls no bully '2. don't pass this software off as your own (covered by clause 1) ' a. also, don't sell this software (also covered by clause 1) '3. if you decide to modify this for others to use, note the following: ' a. you must change the name and the icon (idk why you'd even want to keep the icon) ' b. you must express that the initial version is called notepad ultra and is made by lynnear software, and provide a link to the original ' c. feel free to include the original credits, you don't have to though ' d. use whatever licence you want for your version ' e. i'd appreciate being notified of the modified version's existence, but it's not necessary to do so. if you do want to, email me at thecoolone3@hotmail.com '4. if you modify it for personal use, then go ahead and do whatever you want, but you still can't sell it '5. feel free to rehost this, but provide a link to the original location '6. if something is technically allowed by the licence, but it is against the spirit of the licence, don't do it (also covered by clause 1) '7. you can't hold me liable if there's damages or whatever (unless you are pet) 'if you feel that this licence is too stupid/vague/memeish, use MPL 2.0 instead since that's pretty much what i was going for (sans the whole "YOU MUST INHERIT THIS LICENCE" rubbish) 'END LICENCE Imports System.IO Imports System.Text.RegularExpressions Imports System.Text 'saves precious, precious bytes. also it makes my code look cleaner! ~u0 Public Class NPUWindow 'NPU is short for Notepad Ultra 'i know that "it's self commenting" is a copout, but... well, it kinda is. UpdateFilePicker() obviously updates the file picker. still, i've left comments here and there. 'DELICIOUS, DELICIOUS GLOBAL VARIABLES! AAAAHAHAHAHAHAHA! I AM THE BEST PROGRAMMER TO EVER LIIIIIVE! Dim npuLocation As String = Application.StartupPath() 'i'm lazy, sue me Dim currentFile As String = "" Dim rightClickedFile As String = "" Dim Bullet As String Dim showSidebar, unsaved, ShowRightClick, AutoBullets, FirstTabPress As Boolean Dim checkPrint, IndentLevel As Integer 'Dim trueDpiX As Single = CreateGraphics.DpiX 'dpi shit 'Dim trueDpiY As Single = CreateGraphics.DpiY 'Dim dpiX = trueDpiX / 100 'for multiplication 'Dim dpiY = trueDpiY / 100 Dim MenuBarWidth = 10 'temp Dim encType As System.Text.Encoding Dim unableToDetermineEncType As Boolean = False Dim notifyStack As Queue(Of Notification) = New Queue(Of Notification) 'don't remove this, it'll make mustard gas. seriously though it causes notifystack to equal nothing, which gives us a nullreferenceexception at runtime Dim UndoList As LinkedList(Of String) = New LinkedList(Of String) 'oh boy, here we go Dim UndoPos As Integer = 0 Private basedirectory As String Private newfilebg As Boolean = False Public Property basedir() As String Get Return basedirectory End Get Private Set(ByVal value As String) basedirectory = value BaseDirWatch.Path = value StatDirectory.ToolTipText = value My.Settings.WorkingDirectory = value End Set End Property Public Property NewFile() As Boolean Get Return newfilebg End Get Set(value As Boolean) newfilebg = value FileInfoToolStripMenuItem.Enabled = Not value DuplicateToolStripMenuItem.Enabled = Not value DeleteToolStripMenuItem2.Enabled = Not value End Set End Property Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Icon = ProgramIcon() NewFile = True UndoList.AddLast(TextFileHolder.Text) SetDefaultThemes() Try basedir = My.Settings.WorkingDirectory FilePicker.Width = ViewToolStripMenuItem.Width + ViewToolStripMenuItem.Bounds.X + 15 Find.npu = Me FindReplace.npu = Me FindCommon.npu = Me 'visual studio will try to tell you that the name can be shortened, but it's a nest of lies Settings.npu = Me chocolatePuddingOvenTimer.Start() SaveDialogue.InitialDirectory = basedir FontPicker.Font = TextFileHolder.Font Redraw() UpdateFilePicker() updateStatusBar() RedrawStatusBar() Notify("Welcome!", 3) Catch ex As Exception If Not My.Computer.FileSystem.DirectoryExists(basedir) Then MsgBox("Your working directory is unavailable! Press OK to select a new working directory. For reference, your working directory is currently set as" & vbNewLine & basedir & ".") FolderPicker.ShowDialog() basedir = FolderPicker.SelectedPath My.Settings.WorkingDirectory = basedir If basedir = "" Then MsgBox("Don't play me like this") 'GoTo fug 'shhhh... it's our little secret! c; End End If My.Settings.WorkingDirectory = basedir UpdateFilePicker() Else MsgBox("Whoops!" & vbNewLine & "We've run into a bit of a fuckup." & vbNewLine & ex.Message & vbNewLine & "Press F to pay respects, then click OK.", MsgBoxStyle.OkOnly, "You've gone and busted, my good man") End If Finally BaseDirWatch.Path = basedir TextFileHolder.Font = My.Settings.Font TextFileHolder.WordWrap = My.Settings.WordWrap WordWrapToolStripMenuItem.Checked = My.Settings.WordWrap showSidebar = Not My.Settings.ShowSidebar SidebarToolStripMenuItem_Click(sender, e) reloadCurrentTheme() CleanOutTextFileHolder() Splash_Screen.Hide() Splash_Screen.ShowInTaskbar = False Splash_Screen.TopMost = False Activate() SplashKillTimer.Start() If FileToOpen <> "" And FileToOpen IsNot Nothing Then 'for opening files directly (open with ==> npu) Dim SelectMe As String = GetFile(FileToOpen) For fileIndex = 0 To FilePicker.Items.Count - 1 If FilePicker.Items(fileIndex).ToString = SelectMe Then If My.Computer.FileSystem.FileExists(basedir & SelectMe) Then FilePicker.SelectedIndex = fileIndex Exit For End If Next Open_Passed_File.Hide() Open_Passed_File.ShowInTaskbar = False OPFKillTimer.Start() End If End Try End Sub Private Sub UpdateFilePicker() FilePicker.Items.Clear() Dim filenames = My.Computer.FileSystem.GetFiles(basedir, FileIO.SearchOption.SearchTopLevelOnly, "*.anusberries") 'don't edit this. it's temporary, and avoids the NullReferenceException meme If Not basedir.EndsWith("\") Then basedir &= "\" 'basedir *needs* to end with a backslash. if it somehow doesn't, it does now Dim files As Boolean = False For i = 0 To My.Settings.SupportedExtensions.Count - 1 Dim ext As String = My.Settings.SupportedExtensions(i) filenames = My.Computer.FileSystem.GetFiles(basedir, FileIO.SearchOption.SearchTopLevelOnly, "*." & ext) For Each fileName As String In filenames If fileName.ToLower.EndsWith(ext) Then FilePicker.Items.Add(fileName.Remove(0, Len(basedir))) 'if the user only wants to open txt files, files with extensions like "txt1" and such will also open. this fixes that. files = True 'TODO: not this Next Next FilePicker.Items.Add(" ..\") If Not files Then 'Notify("Directory contains no compatible files", 2) StatStatus.Text = "No compatible files" End If Dim directoryNames = My.Computer.FileSystem.GetDirectories(basedir, FileIO.SearchOption.SearchTopLevelOnly) For Each dirName As String In directoryNames FilePicker.Items.Add(" " & dirName.Remove(0, Len(basedir)) & "\") 'add every subdirectory in basedir, and put a space in front of them so they show up first Next End Sub Private Sub Redraw() Handles Me.Resize, Me.ResizeEnd 'FIX THIS FOR WEIRD DPI SETTINGS! ensures that everything's the right size to fit in the window. Dim TitleBarHeight As Integer = RectangleToScreen(ClientRectangle).Top - Top If showSidebar Then FilePicker.Height = ClientRectangle.Height - MenuBar.Height - Notification.Bounds.Height - 3 'thanks to http://stackoverflow.com/a/41018091/4480824 for this one weird ClientRectangle trick FilePicker.Top = MenuBar.Height TextFileHolder.Height = FilePicker.Height + MenuBar.Height + 3 TextFileHolder.Width = Width - FilePicker.Width - 15 '*shrugs knowingly* TextFileHolder.Left = FilePicker.Width - 1 TextFileHolder.Top = -1 TextFileHolder.BorderStyle = BorderStyle.FixedSingle Else TextFileHolder.Height = ClientRectangle.Height - MenuBar.Height - Notification.Bounds.Height - 3 TextFileHolder.Width = Width - 15 TextFileHolder.Left = 0 TextFileHolder.Top = MenuBar.Height TextFileHolder.BorderStyle = BorderStyle.None End If End Sub Private Async Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles FilePicker.SelectedIndexChanged 'when the user clicks on a file/directory in the filepicker If unsaved Then BaseDirWatch.EnableRaisingEvents = False ' turn basedirwatch off because it'll try to reselect the file we just saved while it's still saving, which will cause bad things to take place Dim response As MsgBoxResult = MsgBox("Save changes made to " & If(NewFile, "new file", """" & currentFile & """") & "?", MsgBoxStyle.YesNoCancel) If response = MsgBoxResult.Yes Then SaveToolStripMenuItem.PerformClick() 'the save function ends up reenabling basedirwatch, don't worry ElseIf response = MsgBoxResult.No Then BaseDirWatchReenabler.Start() 'if they don't wanna save, then reenable basedirwatch Else BaseDirWatch.EnableRaisingEvents = True Exit Sub 'handle cancel End If End If If IsNothing(FilePicker.SelectedItem) Or FilePicker.SelectedItem = "" Or FilePicker.SelectedItem Is Nothing Then Notify("Please select a file or directory.", 2) 'if the user clicks on the blank space at the bottom of the filepicker (which is possible for some reason), shoo them reselectCurrentFile() 'already checks to make sure it's not empty Else Cursor = Cursors.WaitCursor Enabled = False StatStatus.Text = "Loading..." 'MsgBox(basedir & FilePicker.SelectedItem.ToString.Substring(1)) If FilePicker.SelectedItem.ToString = " ..\" Then 'if you clicked the ..\ item (which means go up)... Enabled = True Cursor = Cursors.Default StatStatus.Text = "No file loaded" GoUpToolStripMenuItem.PerformClick() '...click the go up button! ;p Else If FilePicker.SelectedItem.ToString.EndsWith("\") Then 'if you clicked on a directory Try If Not My.Computer.FileSystem.DirectoryExists(basedir & FilePicker.SelectedItem.ToString.Substring(1)) Then Throw New DirectoryNotFoundException BaseDirWatch.Path = basedir + FilePicker.SelectedItem.ToString.Substring(1) 'cd into it! basedir = BaseDirWatch.Path CleanOutTextFileHolder() Notify("Directory changed", 3) ResetUndoList() Catch ex As Exception Notify("Failed to load directory!", 1) CleanOutTextFileHolder() ResetUndoList() End Try Enabled = True Cursor = Cursors.Default ElseIf My.Computer.FileSystem.FileExists(basedir & FilePicker.SelectedItem.ToString) Then 'or, if you clicked a file... Dim chosenFile As StreamReader currentFile = FilePicker.SelectedItem Dim fileToLoad As String = basedir & currentFile Dim p As New Process p.StartInfo.UseShellExecute = False p.StartInfo.RedirectStandardOutput = True p.StartInfo.FileName = "dependencies\file\bin\file.exe" p.StartInfo.CreateNoWindow = True p.StartInfo.Arguments = "-b --mime-encoding """ & basedir & currentFile & """" p.Start() Dim output As String = p.StandardOutput.ReadToEnd() p.WaitForExit() 'firstly, get the encoding. unableToDetermineEncType = False output = output.ToLower() 'just to be 1000% sure 'MsgBox(output) 'and now we load that encoding! Select Case True 'call the cops, i don't give a fuck Case output.Contains("utf-8") 'TODO: find better way of doing this, it's disgusting encType = Encoding.UTF8 Case output.Contains("utf-32") encType = Encoding.UTF32 Case output.Contains("utf-7") encType = Encoding.UTF7 Case output.Contains("unicode") Or output.Contains("utf-16") 'microsoft, the absolute madmen encType = Encoding.Unicode Case output.Contains("ansi") Or output.Contains("iso-8859") 'fucking apple i swear to god encType = Encoding.Default 'idk why but there's no System.Text.Encoding.ANSI. Case output.Contains("ascii") encType = Encoding.ASCII Case output.Contains("no read permission") Or output.Contains("no such file") 'basedirwatch tries to reload the file immediately after it's saved, which causes errors. it also causes the "couldn't determine encoding" notification to pop erroneously. this "fixes" that. encType = Encoding.UTF8 Case Else Notify("Unsupported encoding: " & output.Replace(vbCrLf, "").Replace(vbNewLine, "") & ". Saving will convert to UTF-8.", 2) 'TODO: replace utf-8 with the user's default encType = Encoding.Default unableToDetermineEncType = True End Select Try 'you never know what'll happen with IO chosenFile = New StreamReader(fileToLoad, encoding:=encType) 'schnik the file into a streamreader LoadTimeWarningTimer.Start() 'start waiting for it to load. if it takes more than 10 seconds, bad things are taking place. TextFileHolder.Text = Await chosenFile.ReadToEndAsync 'When building for Windows XP, remove the "async" bit, as .Net 4.0 (the last version XP supports, rip ;u;7) doesn't support it LoadTimeWarningTimer.Stop() 'it's over, isn't it? isn't it? isn't it over? Text = currentFile & " - Notepad Ultra" 'just in case the user forgets that they're using THE BEST PROGRAM EVER WRITTEN BY MORTAL HANDS TextFileHolder.Select(0, 0) TextFileHolder.ScrollToCaret() 'jump to the top of the file chosenFile.Close() 'close the streamreader ResetUndoList() 'clear the undo list, because it'd be stupid if you could undo file2.txt so it becomes file1.txt NewFile = False 'we're not using a new file 'reset the font because certain characters (like AESTHETIC) fuck things up TextFileHolder.Font = New Font("FUCK", 10) 'unless the user actually has a font called FUCK, and is using it for notepad ultra, it'll be fine TextFileHolder.Font = My.Settings.Font updateStatusBar() StatStatus.Text = "Loaded" Cursor = Cursors.Default Enabled = True 'FilePicker.Visible = True Catch ex As Exception 'FilePicker.Visible = False 'I don't know why, but that fucks things up BADLY Notify("Failed to load file!", 1) Enabled = True Cursor = Cursors.Default CleanOutTextFileHolder() End Try 'reselectCurrentFile() unsaved = False Else Enabled = True Cursor = Cursors.Default Notify("Failed to load selected object!", 1) 'just in case things go terribly wrong CleanOutTextFileHolder() End If End If End If 'you know it's good code when the subroutine ends with 3 "end if" statements End Sub Private Sub WordWrapToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles WordWrapToolStripMenuItem.Click 'TODO: fucking hell Select Case WordWrapToolStripMenuItem.Checked Case False WordWrapToolStripMenuItem.Checked = True TextFileHolder.WordWrap = True Case True WordWrapToolStripMenuItem.Checked = False TextFileHolder.WordWrap = False End Select End Sub Private Sub DeleteToolStripMenuItem2_Click(sender As Object, e As EventArgs) Handles DeleteToolStripMenuItem2.Click If currentFile = "" Or NewFile Then MsgBox("You can't delete the current file when there isn't a current file, you dunce!" & vbNewLine & "(This message box should never appear! If it does, invest everything you have in gold and move out of the country)") Else If MsgBox("Are you sure you want to delete " & currentFile & "?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then Dim DeleteOption As FileIO.RecycleOption = 3 If My.Settings.UseRecycleBin Then DeleteOption = 2 'if the user wants to use the recycle bin because they're afraid of commitment, then so be it End If Enabled = False My.Computer.FileSystem.DeleteFile(basedir & currentFile, FileIO.UIOption.OnlyErrorDialogs, DeleteOption) CleanOutTextFileHolder() Enabled = True End If End If End Sub Private Sub NewToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewToolStripMenuItem.Click currentFile = "New file" NewFile = True 'TODO: a LOT of stuff (probably) breaks with new files. fix it all! Text = "Notepad Ultra: New file" TextFileHolder.Clear() Redraw() UpdateFilePicker() 'it's really quick, and deselects any files ResetUndoList() End Sub Private Sub SaveToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SaveToolStripMenuItem.Click If NewFile Then SaveAsToolStripMenuItem_Click(sender, e) 'if you try to save a new file, bring up the Save As dialogue instead Else StatStatus.Text = "Saving..." Enabled = False BaseDirWatch.EnableRaisingEvents = False If unableToDetermineEncType Then encType = Encoding.UTF8 My.Computer.FileSystem.WriteAllText(basedir & currentFile, TextFileHolder.Text.Replace(vbLf, vbCrLf), False, encType) 'TODO: make this an async streamwriter? 'While Not My.Computer.FileSystem.FileExists(basedir & currentFile) 'wait for the file to exist before continuing ' Threading.Thread.Sleep(25) 'pause briefly to make sure we aren't thrashing the disk 'End While Enabled = True Notify("Saved!", 3) StatStatus.Text = "Loaded" unsaved = False If Text.EndsWith(" (Unsaved)") Then Text = Text.RemoveLast(10) 'get rid of the (Unsaved) bit BaseDirWatchReenabler.Start() 'TODO: does this really need to be a timer? End If End Sub Private Sub SaveAsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SaveAsToolStripMenuItem.Click 'all new files save as utf-8 at the moment, and that's probably for the best SaveDialogue.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*" SaveDialogue.FilterIndex = 1 SaveDialogue.RestoreDirectory = True SaveDialogue.InitialDirectory = basedir If NewFile Then encType = Encoding.UTF8 'TODO: load this from My.Settings.DefaultEncoding If IsNothing(encType) Then encType = Encoding.UTF8 If SaveDialogue.ShowDialog() = DialogResult.OK Then My.Computer.FileSystem.WriteAllText(SaveDialogue.FileName, TextFileHolder.Text.Replace(vbLf, vbCrLf), False, encType) StatStatus.Text = "Saving..." End If currentFile = SaveDialogue.FileName.Split("\")(SaveDialogue.FileName.Split("\").Length - 1) If Text.EndsWith(" (Unsaved)") Then Text = Text.RemoveLast(10) If NewFile Then NewFile = False reselectCurrentFile() End If 'BaseDirWatch will take over from here End Sub Private Sub OneDriveTextFilesToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OneDriveTextFilesToolStripMenuItem.Click basedir = "F:\OneDrive\Documents\Other\Text files" UpdateFilePicker() End Sub Private Sub ChangeTheme(sender As Object, e As EventArgs, Optional ByVal silent As Boolean = False) Handles NightTheme.Click, StandardTheme.Click, TertiaryTheme.Click StandardTheme.Checked = False NightTheme.Checked = False TertiaryTheme.Checked = False sender.checked = True Dim themeName As String = sender.Name.ToString.Replace("Theme", "").Replace("Night", "Nite") TextFileHolder.BackColor = CallByName(My.Settings, themeName & "TextBG", CallType.Get) TextFileHolder.ForeColor = CallByName(My.Settings, themeName & "TextFG", CallType.Get) FilePicker.BackColor = CallByName(My.Settings, themeName & "SidebarBG", CallType.Get) FilePicker.ForeColor = CallByName(My.Settings, themeName & "SidebarFG", CallType.Get) StatusBar.BackColor = CallByName(My.Settings, themeName & "StatBG", CallType.Get) StatusBar.ForeColor = CallByName(My.Settings, themeName & "StatFG", CallType.Get) If Not silent Then Notify("Applied " & sender.Name.ToString.Replace("Theme", " Theme") & "!", 3) 'have some sort of cooldown? Dim themeToSet As Integer = 0 Select Case sender.name Case "StandardTheme" themeToSet = 0 Case "NightTheme" themeToSet = 1 Case "TertiaryTheme" themeToSet = 2 Case Else 'you never know when shit will hit the fan themeToSet = 0 End Select My.Settings.CurrentTheme = themeToSet End Sub Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click saveSettings() End End Sub Private Sub SidebarToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SidebarToolStripMenuItem.Click 'TODO: i'm pretty sure this doesn't really do anything except waste cycles Select Case SidebarToolStripMenuItem.Checked Case False SidebarToolStripMenuItem.Checked = True showSidebar = True FilePicker.Visible = True TextFileHolder.Left = MenuBarWidth + 25 '*shrugs knowingly* Case True SidebarToolStripMenuItem.Checked = False showSidebar = False FilePicker.Visible = False TextFileHolder.Left = 0 End Select Redraw() End Sub Private Sub updateStatusBar() Handles TextFileHolder.TextChanged 'TODO: wait for user to stop typing before updating? this could murder slow computers, or any computer working with a fucking MASSIVE text file UndoTimer.Stop() StatChars.Text = "Characters: " & TextFileHolder.Text.Length 'MsgBox(unsaved) If Not IsNothing(encType) Then StatBytes.Text = encType.GetByteCount(TextFileHolder.Text) & " Bytes" If My.Settings.UndoSteps <> 0 Then UndoTimer.Start() End Sub Public Sub unsavedCheck(sender As Object, e As EventArgs) Handles TextFileHolder.KeyPress If Not My.Computer.Keyboard.CtrlKeyDown Then 'don't mark as unsaved if you only press ctrl-a, ctrl-c, etc. TODO: handle ctrl v, ctrl, x... If Not unsaved Then Text = Text + " (Unsaved)" unsaved = True End If If Text.EndsWith("(Unsaved) (Unsaved)") Then Text = Text.RemoveLastInstanceOf(" (Unsaved)") 'just to be sure. this will break if the user is editing a file with the extension ".(Unsaved) (Unsaved)", but, i mean... come on. End If End Sub Private Sub opacify() Handles Me.Move If My.Settings.MoveTransparency Then Opacity = 0.5 'fade on move! If Not IsNothing(chocolatePuddingOvenTimer) Then chocolatePuddingOvenTimer.Stop() chocolatePuddingOvenTimer.Start() Else Opacity = 1 End If End Sub Private Sub chocolatePuddingOvenTimer_Tick(sender As Object, e As EventArgs) Handles chocolatePuddingOvenTimer.Tick Opacity = 1 'stop being faded on stopped being moved! chocolatePuddingOvenTimer.Stop() End Sub Private Sub ToolStripSplitButton1_ButtonClick(sender As Object, e As EventArgs) Handles StatDirectory.ButtonClick Process.Start(basedir) End Sub Private Sub toggleSidebar(sender As Object, e As EventArgs) SidebarToolStripMenuItem.PerformClick() End Sub Private Sub RestartToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles RestartToolStripMenuItem.Click saveSettings() 'better safe than sorry! Application.Restart() End Sub Private Sub saveSettings() My.Settings.Font = TextFileHolder.Font My.Settings.WordWrap = TextFileHolder.WordWrap My.Settings.ShowSidebar = showSidebar My.Settings.WorkingDirectory = basedir My.Settings.Save() End Sub Private Sub emergencySave(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing Try My.Computer.Clipboard.SetText(My.Computer.Clipboard.GetText) saveSettings() If unsaved Then Dim response As MsgBoxResult = MsgBox("Save changes made to " & If(NewFile, "new file", """" & currentFile & """") & "?", MsgBoxStyle.YesNoCancel) If response = MsgBoxResult.Yes Then SaveToolStripMenuItem_Click(SaveToolStripMenuItem, EventArgs.Empty) ElseIf response = MsgBoxResult.Cancel Then e.Cancel = True Exit Sub End If End If End Catch ex As Exception MsgBox(ex.Message) End Try End Sub Private Sub SHOWRECENTSHEREToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SHOWRECENTSHEREToolStripMenuItem.Click '??? currentFile = "" FolderPicker.ShowDialog() basedir = FolderPicker.SelectedPath UpdateFilePicker() End Sub Private Sub ChangeToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ChangeToolStripMenuItem.Click '????? SHOWRECENTSHEREToolStripMenuItem_Click(sender, e) End Sub Private Sub UndoToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles UndoToolStripMenuItem.Click If My.Settings.UndoSteps <> 0 Then Try If UndoPos <> 0 Then UndoPos -= 1 TextFileHolder.Text = UndoList(UndoPos).ToString UndoTimer.Stop() Else Notify("Nothing to undo", 2) End If Catch ex As Exception 'better safe than sorry Notify("Undo error: " & ex.Message, 1) End Try Else Notify("Undo disabled by user.", 2) 'just in case the user's being a silly billy and forgets that they've turned off undo End If End Sub Private Sub RedoToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles RedoToolStripMenuItem.Click 'TODO: consider merge with undo If My.Settings.UndoSteps <> 0 Then Try If UndoPos <> UndoList.Count - 1 Then UndoPos += 1 TextFileHolder.Text = UndoList(UndoPos).ToString UndoTimer.Stop() Else Notify("Nothing to redo", 2) End If Catch ex As Exception Notify("Undo error: " & ex.Message, 1) End Try Else Notify("Undo disabled by user.", 2) End If End Sub Private Sub FindToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles FindToolStripMenuItem.Click Find.npu = Me 'ensure that the find menu can access npu's main window Find.Show(Me) End Sub Private Sub CustomToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CustomToolStripMenuItem.Click FontPicker.ShowDialog() TextFileHolder.Font = FontPicker.Font My.Settings.Font = TextFileHolder.Font End Sub Private Sub AboutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AboutToolStripMenuItem.Click 'MsgBox("NotePad Ultra (Version 0.10 Alpha)" & vbNewLine & vbNewLine & "An advanced Notepad for advanced minds." & vbNewLine & vbNewLine & "© 2016 Lynnear Software" & vbNewLine & "QA: Petra Morse") About.Show() End Sub Private Sub ArialToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ArialToolStripMenuItem.Click My.Settings.Font = New Font("Arial", My.Settings.Font.SizeInPoints, My.Settings.Font.Style) TextFileHolder.Font = My.Settings.Font End Sub Private Sub GoUpToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GoUpToolStripMenuItem.Click If basedir.Length <> 3 And Not Regex.IsMatch(basedir, "^\\\\[^?:+\\<>]+\\[^?:\\<>*""|/]+\\$", RegexOptions.None) Then basedir = StrReverse(Replace(Replace(StrReverse(basedir), StrReverse(basedir.Split("\")(basedir.Split("\").Length - 2)), "",, 1), "\\", "\",, 1)) Else Notify("Already at root!", 2) 'wew lady 'HOW THIS WORKS: '>check to make sure that we're not at the root path (either C:\, D:\ etc OR \\server\folder) '>start with basedir (C:\Path\Folder\) '>split it into an array using backslash as a separator ("C:", "Path", "Folder", "") '>select the second last string in this array ("Folder") '>reverse it ("redloF") '>reverse the whole basedir string (\redloF\htaP\:C) '>replace the first instance of the reversed second-last item in the array inside the reversed basedir with nothing (replace the first instance of "redloF" with "", giving "\\htaP\:C") '>replace the first instance of "\\" with "\" (\htaP\:C) '>reverse the whole thing ("C:\Path\") 'a few weeks after writing this, i found out about My.Computer.FileSystem.ParentPath. but i'm not fucking changing it. Text = "Notepad Ultra" If My.Computer.FileSystem.DirectoryExists(basedir) Then 'Notify("Directory changed", 3) 'Notification stack is FIFO, we gotta get in there first UpdateFilePicker() CleanOutTextFileHolder() Else Notify("Failed to change directory!", 1) End If End Sub Private Sub GoUpToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles GoUpToolStripMenuItem1.Click 'TODO: why are there two separate subs for this, what the fuck? GoUpToolStripMenuItem_Click(sender, e) End Sub Private Sub FileInfoToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles FileInfoToolStripMenuItem.Click Dim p As New Process p.StartInfo.UseShellExecute = False p.StartInfo.RedirectStandardOutput = True p.StartInfo.FileName = "dependencies\file\bin\file.exe" p.StartInfo.CreateNoWindow = True p.StartInfo.Arguments = "-b """ & basedir & currentFile & """" p.Start() Dim output As String = p.StandardOutput.ReadToEnd() p.WaitForExit() Dim q As New Process q.StartInfo.UseShellExecute = False q.StartInfo.RedirectStandardOutput = True q.StartInfo.FileName = "dependencies\file\bin\file.exe" q.StartInfo.CreateNoWindow = True q.StartInfo.Arguments = "-b --mime-encoding """ & basedir & currentFile & """" q.Start() Dim output2 As String = q.StandardOutput.ReadToEnd() q.WaitForExit() Try MsgBox("Detected type: " & output & "Detected encoding: " & output2 & "Approximate file size (on save): " & encType.GetByteCount(TextFileHolder.Text) & " Bytes" & vbNewLine & "Creation date: " & My.Computer.FileSystem.GetFileInfo(basedir & currentFile).CreationTime) Catch ex As Exception If ex.Message = "Object reference not set to an instance of an object." Then MsgBox("Failed to get file info: " & ex.Message & vbNewLine & "This almost certainly means that the file does not exist.") Else MsgBox("Failed to get file info: " & ex.Message) End Try End Sub Private Sub SoftwareUsedToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SoftwareUsedToolStripMenuItem.Click MsgBox("Notepad Ultra makes use of the following open-source software:" & vbNewLine & vbNewLine & "GNU file" & vbNewLine & "http://www.darwinsys.com/file/" & vbNewLine & "http://gnuwin32.sourceforge.net/packages/file.htm" & "(Used for detecting file encoding)") 'i looked for a windows tool that could do the job of "file" for so fucking long! anyone who cares enough to open the software used box should know about it! End Sub Private Sub EDocumentsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles EDocumentsToolStripMenuItem.Click 'tempura basedir = "E:\Documents" UpdateFilePicker() End Sub Private Sub autoFPUpdate() Handles BaseDirWatch.Deleted, BaseDirWatch.Created, BaseDirWatch.Renamed ', Me.Activated, Me.Deactivate, Me.GotFocus, Me.LostFocus UpdateFilePicker() reselectCurrentFile() End Sub Private Sub MakeFontLarger_Click(sender As Object, e As EventArgs) Handles MakeFontLarger.Click 'TODO: merge with vvv If My.Settings.Font.SizeInPoints < 500 Then My.Settings.Font = New Font(My.Settings.Font.FontFamily, My.Settings.Font.SizeInPoints + 1, My.Settings.Font.Style) TextFileHolder.Font = My.Settings.Font Else Notify("Maximum font size!", 2) End If End Sub Private Sub MakeFontSmaller_Click(sender As Object, e As EventArgs) Handles MakeFontSmaller.Click 'TODO: merge with ^^^ If My.Settings.Font.SizeInPoints > 4 Then My.Settings.Font = New Font(My.Settings.Font.FontFamily, My.Settings.Font.SizeInPoints - 1, My.Settings.Font.Style) TextFileHolder.Font = My.Settings.Font Else Notify("Minimum font size!", 2) End If End Sub Private Sub RefreshFileList_Click(sender As Object, e As EventArgs) Handles RefreshFileList.Click UpdateFilePicker() reselectCurrentFile() End Sub Private Sub SegoeUIToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SegoeUIToolStripMenuItem.Click 'TODO: merge this with the following 3 My.Settings.Font = New Font("Segoe UI", My.Settings.Font.SizeInPoints, My.Settings.Font.Style) TextFileHolder.Font = My.Settings.Font End Sub Private Sub ConsolasToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ConsolasToolStripMenuItem.Click My.Settings.Font = New Font("Consolas", My.Settings.Font.SizeInPoints, My.Settings.Font.Style) TextFileHolder.Font = My.Settings.Font End Sub Private Sub LucidaConsoleToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles LucidaConsoleToolStripMenuItem.Click My.Settings.Font = New Font("Lucida Console", My.Settings.Font.SizeInPoints, My.Settings.Font.Style) TextFileHolder.Font = My.Settings.Font End Sub Private Sub SettingsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SettingsToolStripMenuItem.Click Settings.npu = Me Settings.Show(Me) End Sub Private Sub CleanOutTextFileHolder() UpdateFilePicker() ResetUndoList() NewFile = True unsaved = False Text = "Notepad Ultra" StatStatus.Text = "No file loaded" TextFileHolder.Text = "Welcome to Notepad Ultra! Select a file from the left." 'get everything nice and phresh End Sub Private Sub TimeDateToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles TimeDateToolStripMenuItem1.Click 'Dim timeAndDate As String = My.Computer.Clock.LocalTime.ToShortTimeString & " " & My.Computer.Clock.LocalTime.ToShortDateString TextFileHolder.SelectionLength = 0 TextFileHolder.SelectedText = My.Computer.Clock.LocalTime.ToShortTimeString & " " & My.Computer.Clock.LocalTime.ToShortDateString 'schnick the current time in End Sub Private Sub Notification_Click(sender As Object, e As EventArgs) Handles Notification.MouseDown Notification.Visible = False ShowNotificationTimer.Interval = 1 End Sub Private Sub Notify(notifyText As String, category As Integer) notifyStack.Enqueue(New Notification() With {.Text = notifyText, .Category = category}) ShowNotificationTimer.Start() End Sub Private Sub ShowNotificationTimer_Tick(sender As Object, e As EventArgs) Handles ShowNotificationTimer.Tick If notifyStack.Count = 0 Then ShowNotificationTimer.Stop() Notification.Visible = False ShowNotificationTimer.Interval = 1 'The next time the timer is called after showing all pending notifications, it should appear immediately. Else Dim PoppedNotify As Notification = notifyStack.Dequeue() Notification.Text = PoppedNotify.Text ShowNotificationTimer.Interval = 3000 Select Case PoppedNotify.Category Case 1 'Critical: Something critical has gone wrong Notification.BackColor = ReturnThemeSettingsAsThemeObject(My.Settings.CurrentTheme).NotificationCriticalBG Notification.ForeColor = ReturnThemeSettingsAsThemeObject(My.Settings.CurrentTheme).NotificationCriticalFG Case 2 'Warning: Something minor has gone wrong, or an action is unavailable imSorryCLU: Notification.BackColor = ReturnThemeSettingsAsThemeObject(My.Settings.CurrentTheme).NotificationWarningBG Notification.ForeColor = ReturnThemeSettingsAsThemeObject(My.Settings.CurrentTheme).NotificationWarningFG Case 3 'Just letting you know... Notification.BackColor = ReturnThemeSettingsAsThemeObject(My.Settings.CurrentTheme).NotificationInfoBG Notification.ForeColor = ReturnThemeSettingsAsThemeObject(My.Settings.CurrentTheme).NotificationInfoFG ShowNotificationTimer.Interval = 1500 Case Else GoTo imSorryCLU 'apparently, you can't say "Case 2, Else" :c End Select Notification.Visible = True End If End Sub Private Sub BaseDirWatchPathToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BaseDirWatchPathToolStripMenuItem.Click MsgBox(BaseDirWatch.Path) End Sub Private Sub reselectCurrentFile() Dim RestoreOnReload As Boolean = False Dim TempFileHolder As String = "An error occurred while switching files. Any unsaved changes made to this document have been lost. We apologise for the inconvenience." 'let's hope this shit never happens If currentFile IsNot "" And currentFile IsNot Nothing Then RestoreOnReload = unsaved If RestoreOnReload Then TempFileHolder = TextFileHolder.Text 'try to set tempfileholder to the textbox's text unsaved = False End If For fileIndex = 0 To FilePicker.Items.Count - 1 If FilePicker.Items(fileIndex).ToString = currentFile Then If My.Computer.FileSystem.FileExists(basedir & currentFile) Then FilePicker.SelectedIndex = fileIndex Exit For End If Next If RestoreOnReload Then TextFileHolder.Text = TempFileHolder unsaved = True Text = Text + " (Unsaved)" End If End If End Sub Private Sub BaseDirWatchReenabler_Tick(sender As Object, e As EventArgs) Handles BaseDirWatchReenabler.Tick BaseDirWatch.EnableRaisingEvents = True 'updateFilePicker() 'reselectCurrentFile() BaseDirWatchReenabler.Stop() End Sub Private Sub DuplicateToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DuplicateToolStripMenuItem.Click Dim response As String = InputBox("Duplicate """ & currentFile & """ with name:", "Duplicate", "Copy of " & currentFile) If response IsNot "" And Not NewFile Then If My.Computer.FileSystem.FileExists(basedir & response) Then If MsgBox("A file with the name """ & response & """ already exists. Please choose a different name.", MsgBoxStyle.OkCancel) = MsgBoxResult.Ok Then DuplicateToolStripMenuItem.PerformClick() 'reprompt the user for a new name if it's already taken here End If Else Dim ValidExt As Boolean = False For i = 0 To My.Settings.SupportedExtensions.Count - 1 If response.EndsWith("." & My.Settings.SupportedExtensions(i)) Then ValidExt = True 'if the user only wants npu to work with txt files, and they save it as a cfg, schnick a .txt on the end If ValidExt Then Exit For Next If Not ValidExt Then response &= ".txt" 'default to the txt ending Dim OldCurrentFile As String = currentFile currentFile = response My.Computer.FileSystem.CopyFile(basedir & OldCurrentFile, basedir & response) Notify("Duplicated!", 3) End If End If End Sub Public Sub reloadCurrentTheme() Select Case My.Settings.CurrentTheme Case 0 ChangeTheme(StandardTheme, EventArgs.Empty, True) Case 1 ChangeTheme(NightTheme, EventArgs.Empty, True) Case 2 ChangeTheme(TertiaryTheme, EventArgs.Empty, True) End Select End Sub Public Sub RedrawStatusBar() Dim StatBarSettings As String() = {"Chars", "Date", "Dir", "FontSize", "Size", "Status", "Mode"} For i = 0 To 6 GetStatBarObject(i).visible = CallByName(My.Settings, "StatBar" & StatBarSettings(i), CallType.Get) 'only show the ones that the user wants Next End Sub Private Sub ReplaceToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ReplaceToolStripMenuItem.Click FindReplace.npu = Me FindReplace.Show(Me) End Sub Private Sub GoToToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GoToToolStripMenuItem.Click MsgBox("Not yet supported") 'TODO: make it supported End Sub Private Sub GoUpValidatorToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GoUpValidatorToolStripMenuItem.Click Dim benis As String = InputBox("String to check:") If benis IsNot Nothing And benis <> "" Then If benis.Length <> 3 And Not Regex.IsMatch(benis, "^\\\\[^?:+\\<>]+\\[^?:\\<>*""|/]+\\$", RegexOptions.None) Then MsgBox("Valid!") Else MsgBox("Invalid!") ' ensure it's a valid filename (ignoring stuff like AUX and COM, which windows should catch anyway... right?) End If End Sub Private Sub ShowInExplorer_Click(sender As Object, e As EventArgs) Handles ShowInExplorer.Click Process.Start("explorer.exe", "/select, " & basedir & rightClickedFile) End Sub Public Sub GetFileToShowMenuFor(sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles FilePicker.MouseDown If e.Button = MouseButtons.Right Then Try rightClickedFile = FilePicker.Items(FilePicker.IndexFromPoint(e.X, e.Y)).ToString 'try to show the right-click menu with the right-clicked file as the target Catch fug As System.ArgumentOutOfRangeException 'if the user right-clicks that blank bit at the bottom of the filepicker... Notify("Invalid selection!", 2) '...tell them to fuck off. rightClickedFile = "" End Try End If End Sub Private Sub DeleteToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DeleteToolStripMenuItem.Click Dim DeleteOption As FileIO.RecycleOption = 3 If My.Settings.UseRecycleBin Then DeleteOption = 2 If MsgBox("Delete """ & rightClickedFile & """?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then My.Computer.FileSystem.DeleteFile(basedir & rightClickedFile, FileIO.UIOption.OnlyErrorDialogs, DeleteOption) UpdateFilePicker() If rightClickedFile = currentFile Then CleanOutTextFileHolder() currentFile = "" End If End If End Sub 'Printing stuff (courtesy of https://support.microsoft.com/en-us/kb/811401) Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocumentThingy.BeginPrint checkPrint = 0 End Sub Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocumentThingy.PrintPage ' Print the content of the RichTextBox. Store the last character printed. checkPrint = TextFileHolder.Print(checkPrint, TextFileHolder.TextLength, e) ' Look for more pages If checkPrint < TextFileHolder.TextLength Then e.HasMorePages = True Else e.HasMorePages = False End If End Sub Private Sub PrintToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PrintToolStripMenuItem.Click Try PrintDocumentThingy.DocumentName = currentFile If PrintPreviewDialog1.ShowDialog() > -1 Then 'wait for the user to close the preview before continuing If PrintDialogue.ShowDialog() = DialogResult.OK Then PrintDocumentThingy.Print() End If End If Catch ex As Exception MsgBox("Failed to print file!" & vbNewLine & ex.Message) End Try End Sub Public Function GetStatBarObject(index) Select Case index Case 0 Return StatChars Case 1 Return StatDate Case 2 Return StatDirectory Case 3 Return StatFontSize Case 4 Return StatBytes Case 5 Return StatStatus Case 6 Return StatMode Case Else Throw New Exception("GetStatBarObject: Invalid index!") End Select End Function Private Sub LoadTimeWarning_Tick(sender As Object, e As EventArgs) Handles LoadTimeWarningTimer.Tick LoadTimeWarning.Show() 'if it takes more than 10s to load the file, something's gone wrong LoadTimeWarningTimer.Stop() End Sub Private Sub SplashKillTimer_Tick(sender As Object, e As EventArgs) Handles SplashKillTimer.Tick Splash_Screen.Close() 'the program crashes unless you give it some time to do its thing SplashKillTimer.Stop() End Sub Private Sub OPFKillTimer_Tick(sender As Object, e As EventArgs) Handles OPFKillTimer.Tick Open_Passed_File.Close() OPFKillTimer.Stop() End Sub Private Sub FilePickerMenu_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles FilePickerMenu.Opening FilePickerMenu.Enabled = False If rightClickedFile = "" Then FilenametxtToolStripMenuItem.Text = "Invalid selection" Else FilePickerMenu.Enabled = True FilenametxtToolStripMenuItem.Text = rightClickedFile End If End Sub Private Sub UndoTimer_Tick(sender As Object, e As EventArgs) Handles UndoTimer.Tick Dim UndoListTooBig As Boolean = False If My.Settings.UndoMemoryLimit Then Dim UndoListSize As Long Dim ms As New IO.MemoryStream Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter() bf.Serialize(ms, UndoList) UndoListSize = ms.Position If UndoListSize / (1024 * 1024) >= My.Settings.UndoMaxMemory Then UndoListTooBig = True 'divide by 1024 to make bytes into kb, then again to make into mb End If If Not (UndoList.Count < My.Settings.UndoSteps OrElse My.Settings.UndoUnlimitedSteps) OrElse UndoListTooBig Then UndoList.RemoveFirst() 'Notify("Undo limit reached, removing oldest entries", 3) End If If UndoList.Count > 0 And UndoPos > 0 And UndoList.Count > UndoPos Then While UndoPos <> UndoList.Count - 1 UndoList.RemoveLast() End While End If UndoList.AddLast(TextFileHolder.Text) UndoPos = UndoList.Count - 1 UndoTimer.Stop() End Sub Private Sub PageSetup_Click(sender As Object, e As EventArgs) Handles PageSetup.Click PageSetupDialog1.ShowDialog() End Sub Public Sub ThrobberToggler() Handles Me.EnabledChanged 'this subroutine ensures that whenever the form is disabled, the throbber is visible. the throbber's throbbing animation is designed to let the user know that things are happening in the background and that the program is not frozen. after all, who /doesn't/ love throbbers? i know i do! 'for more about throbbers, visit https://en.wikipedia.org/wiki/Throbber. if you are still interested, and your desire for throbbers is not quenched by this page, the internet contains an astronomical amount of images, posts, videos, games, and more, all revolving around the concept of throbbers. Try Throbber.Visible = Not Enabled Catch ex As Exception 'could not toggle throbber! throbber must be untoggleable. Notify("Throbber toggling failed: " & ex.Message, 1) 'notify the user of their untoggleable throbber. they'll want to know why their throbber isn't throbbing away down there! End Try 'keep things short, we don't want the program sitting around toggling its throbber all day! End Sub Private Sub RenameToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles RenameToolStripMenuItem.Click 'nearly identical to the duplicate sub Dim response As String = InputBox("Enter new name for """ & currentFile & """:", "Rename", currentFile) If response IsNot "" And Not NewFile Then If My.Computer.FileSystem.FileExists(basedir & response) Then If MsgBox("A file with the name """ & response & """ already exists. Please choose a different name.", MsgBoxStyle.OkCancel) = MsgBoxResult.Ok Then RenameToolStripMenuItem.PerformClick() End If Else Dim ValidExt As Boolean = False For i = 0 To My.Settings.SupportedExtensions.Count - 1 If response.EndsWith("." & My.Settings.SupportedExtensions(i)) Then ValidExt = True If ValidExt Then Exit For Next If Not ValidExt Then response &= ".txt" Dim OldCurrentFile As String = currentFile currentFile = response My.Computer.FileSystem.RenameFile(basedir & OldCurrentFile, response) currentFile = response Notify("Renamed!", 3) For fileIndex = 0 To FilePicker.Items.Count - 1 If FilePicker.Items(fileIndex).ToString = currentFile Then If My.Computer.FileSystem.FileExists(basedir & currentFile) Then FilePicker.SelectedIndex = fileIndex NewFile = False End If Exit For End If Next End If End If End Sub Private Sub MoveToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles MoveToolStripMenuItem.Click 'also nearly identical to the duplicate sub MoveFileDialogue.InitialDirectory = basedir If MoveFileDialogue.ShowDialog() = DialogResult.OK Then Dim response As String = MoveFileDialogue.FileName If response IsNot "" And Not NewFile Then Dim ValidExt As Boolean = False For i = 0 To My.Settings.SupportedExtensions.Count - 1 If response.EndsWith("." & My.Settings.SupportedExtensions(i)) Then ValidExt = True If ValidExt Then Exit For Next If Not ValidExt Then response &= ".txt" Dim OldCurrentFile As String = currentFile currentFile = response My.Computer.FileSystem.MoveFile(basedir & OldCurrentFile, response) basedir = GetPath(response) currentFile = GetFile(response) Notify("Moved!", 3) For fileIndex = 0 To FilePicker.Items.Count - 1 If FilePicker.Items(fileIndex).ToString = currentFile Then If My.Computer.FileSystem.FileExists(basedir & currentFile) Then FilePicker.SelectedIndex = fileIndex NewFile = False End If Exit For End If Next End If End If End Sub Private Sub RenameToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles RenameToolStripMenuItem1.Click Dim response As String = InputBox("Enter new name for """ & rightClickedFile & """:", "Rename", currentFile) If response IsNot "" Then If My.Computer.FileSystem.FileExists(basedir & response) Then If MsgBox("A file with the name """ & response & """ already exists. Please choose a different name.", MsgBoxStyle.OkCancel) = MsgBoxResult.Ok Then RenameToolStripMenuItem1_Click(sender, e) End If Else Dim ValidExt As Boolean = False For i = 0 To My.Settings.SupportedExtensions.Count - 1 If response.EndsWith("." & My.Settings.SupportedExtensions(i)) Then ValidExt = True If ValidExt Then Exit For Next If Not ValidExt Then response &= ".txt" My.Computer.FileSystem.RenameFile(basedir & rightClickedFile, response) Notify("Renamed!", 3) UpdateFilePicker() If currentFile = rightClickedFile Then currentFile = response reselectCurrentFile() End If End If End If End Sub Private Sub EncryptToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles EncryptToolStripMenuItem.Click 'If MsgBox("Create an encrypted copy of this file?") = MsgBoxResult.Yes Then 'End If End Sub Private Sub OvertypeToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OvertypeToolStripMenuItem.Click My.Computer.Keyboard.SendKeys(Keys.Insert) 'just schnick the insert key End Sub Private Sub DashesToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DashesToolStripMenuItem.Click Bullet = "-" BulletPointsToolStripMenuItem.Checked = False AutoBullets = sender.Checked TextFileHolder.Focus() My.Computer.Keyboard.SendKeys("{END}") My.Computer.Keyboard.SendKeys("~") 'TODO: fix weird DING noise End Sub Private Sub BulletPointsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BulletPointsToolStripMenuItem.Click Bullet = "•" DashesToolStripMenuItem.Checked = False AutoBullets = sender.Checked TextFileHolder.Focus() My.Computer.Keyboard.SendKeys("{END}") My.Computer.Keyboard.SendKeys("~") End Sub Public Sub ResetUndoList() UndoList.Clear() UndoPos = 0 UndoList.AddLast(TextFileHolder.Text) End Sub Private Sub rtb_KeyDown(sender As Object, e As KeyEventArgs) Handles TextFileHolder.KeyDown Dim Spaces As String = String.Concat(Enumerable.Repeat(" ", IndentLevel)) & " " 'put two spaces in for every level the user is indented up to, as well as an initial space TextFileHolder.Focus() 'sometimes the tab key changes menu settings instead of inserting a tab, this should fix it If e.Control AndAlso e.KeyCode = Keys.V Then 'stops people pasting in rich text DirectCast(sender, RichTextBox).Paste(DataFormats.GetFormat("Text")) e.Handled = True End If If AutoBullets Then 'handle automatic bullet points If e.KeyCode = Keys.Enter Then TextFileHolder.SelectedText = vbNewLine & Spaces & Bullet & " " My.Computer.Keyboard.SendKeys(vbBack) ':/ ElseIf e.KeyCode = Keys.Tab Then 'if they pressed tab, they want to increase the indent level e.Handled = True 'this should stop a tab being inserted but it doesn't Dim WordWrap As Boolean = TextFileHolder.WordWrap TextFileHolder.WordWrap = False 'TODO: try to find a better way of doing this Dim Lines As String() = TextFileHolder.Lines() Dim OldPos As Integer = TextFileHolder.SelectionStart If e.Shift Then 'if they pressed shift tab IndentLevel -= 1 'unindent If Lines(TextFileHolder.GetLineFromCharIndex(TextFileHolder.SelectionStart - 1)).StartsWith(" ") Then Lines(TextFileHolder.GetLineFromCharIndex(TextFileHolder.SelectionStart - 1)) = Lines(TextFileHolder.GetLineFromCharIndex(TextFileHolder.SelectionStart - 1)).RemoveFirst(2) 'if the line starts with 2 spaces, get rid of them End If If IndentLevel < 0 Then Notify("AutoBullets disabled", 3) 'turn off autobullets if they unindent when on the lowest level AutoBullets = False IndentLevel = 0 DashesToolStripMenuItem.Checked = False BulletPointsToolStripMenuItem.Checked = False End If Else IndentLevel += 1 Lines(TextFileHolder.GetLineFromCharIndex(TextFileHolder.SelectionStart)) = " " & Lines(TextFileHolder.GetLineFromCharIndex(TextFileHolder.SelectionStart)) 'add the spaces End If TextFileHolder.Lines = Lines If e.Shift Then If OldPos > 2 Then TextFileHolder.SelectionStart = OldPos - 2 'move the cursor back 2 spaces because we just deleted 2 characters Else TextFileHolder.SelectionStart = OldPos + 2 End If My.Computer.Keyboard.SendKeys(vbBack) ':\ If WordWrap Then TextFileHolder.WordWrap = True My.Computer.Keyboard.SendKeys(" ") End If End If End If End Sub End Class