File: w_main.srw
Size: 29725
Date: Thu, 18 Aug 2022 16:40:50 +0200
$PBExportHeader$w_main.srw
$PBExportComments$Main window
forward
global type w_main from window
end type
type mdi_1 from mdiclient within w_main
end type
type uo_editor from u_scintilla within w_main
end type
end forward

global type w_main from window
boolean visible = false
integer x = 101
integer y = 112
integer width = 3771
integer height = 2572
boolean titlebar = true
string title = "Untitled - PBEditor"
string menuname = "m_main"
boolean controlmenu = true
boolean minbox = true
boolean maxbox = true
boolean resizable = true
windowtype windowtype = mdihelp!
long backcolor = 67108864
string icon = "AppIcon!"
event m_findnext ( )
event m_open ( )
event type long m_save ( )
event type long m_saveas ( )
event m_print ( )
event m_new ( )
event wm_command pbm_command
event m_font ( )
event wm_notify pbm_notify
event wm_syscommand pbm_syscommand
event wm_wininichange pbm_wininichange
mdi_1 mdi_1
uo_editor uo_editor
end type
global w_main w_main

type variables
Constant String WINTITLE = "PBEditor"
Encoding iEncoding = EncodingAnsi!
Boolean ib_AutoComplete = False
String is_pathname
String is_filename
String is_theme

end variables

forward prototypes
public subroutine wf_restorewindowstate ()
public subroutine wf_savewindowstate ()
public subroutine wf_menu (string as_menuaction)
public subroutine wf_recentfiles ()
public subroutine wf_dynamicmenus (integer ai_index)
public subroutine wf_registerxpmimage ()
public subroutine wf_registerrgbaimage ()
public subroutine wf_openfile (string as_filename)
end prototypes

event m_findnext();String ls_msg

// find the next occurrence of the search string
If gn_app.is_findstr <> "" Then
   uo_editor.of_SetFindOptions(gn_app.ib_MatchCase, gn_app.ib_WholeWord, &
                     gn_app.ib_WordStart, gn_app.ib_RegEx, &
                     gn_app.ib_Backwards, gn_app.ib_IgnoreComment)
   If Not uo_editor.of_Find(gn_app.is_findstr) Then
      ls_msg = "Cannot find text ~"" + gn_app.is_findstr + "~""
      this.SetMicroHelp(ls_msg)
      MessageBox("Find Next", ls_msg)
      uo_editor.SetFocus()
   End If
End If

end event

event m_open();// open a file

Integer li_rc
String ls_title, ls_filter, ls_initdir, ls_pathname, ls_filename

SetPointer(HourGlass!)

// check for unsaved changes
li_rc = this.Event CloseQuery()
If li_rc = 1 Then Return

ls_initdir = gn_app.of_GetFolderPath("PERSONAL")

ls_title = "Open"

ls_filter  = "All Files (*.*),*.*"
ls_filter += ",JSON Files (*.json),*.json"
ls_filter += ",PowerBuilder Files (*.sr*),*.sr*"
ls_filter += ",PS1 Files (*.ps1),*.ps1"
ls_filter += ",SQL Files (*.sql),*.sql"
ls_filter += ",Text Documents (*.txt),*.txt"
ls_filter += ",XML Files (*.xml),*.xml"

li_rc = GetFileOpenName(ls_title, ls_pathname, &
               ls_filename, "txt", ls_filter, ls_initdir)
If li_rc = 1 Then
   wf_openfile(ls_pathname)
End If

end event

event type long m_save();// save the file

Blob lblb_contents
Integer li_fnum
Long ll_bytes

If is_pathname = "" Then
   Return this.Event m_saveas()
End If

lblb_contents = uo_editor.of_GetContents()

li_fnum = FileOpen(is_pathname, TextMode!, Write!, &
               LockReadWrite!, Replace!, uo_editor.#Encoding)
If li_fnum > 0 Then
   ll_bytes = FileWriteEx(li_fnum, lblb_contents)
   FileClose(li_fnum)

   // add file to list
   gn_mru.of_AddToList(is_pathname)
   // add items to menu
   gw_frame.wf_RecentFiles()

Else
   Return this.Event m_saveas()
End If

uo_editor.of_SetNotModified()
uo_editor.SetFocus()

Return 0

end event

event type long m_saveas();// save as

Integer li_rc
String ls_title, ls_filter, ls_initdir

ls_initdir = gn_app.of_GetFolderPath("PERSONAL")

ls_title  = "Save As"
ls_filter = "All Files (*.*),*.*"

li_rc = GetFileSaveName(ls_title, is_pathname, &
               is_filename, "txt", ls_filter, ls_initdir)
If li_rc = 1 Then
   this.title = is_filename + " - " + WINTITLE
   Return this.Event m_save()
End If

Return 1

end event

event m_print();// print

uo_editor.of_Print(False)

end event

event m_new();m_main lm_menu
Integer li_rc

lm_menu = this.MenuID

// check for unsaved changes
li_rc = this.Event CloseQuery()
If li_rc = 0 Then
   is_filename = ""
   is_pathname = ""
   iEncoding = EncodingAnsi!
   lm_menu.mf_Encoding(iEncoding)
   uo_editor.of_SetEncoding(iEncoding)
   this.title = "Untitled - " + WINTITLE
   uo_editor.of_Set_NoLanguage()
   uo_editor.of_Clear()
   uo_editor.of_SetNotModified()
   uo_editor.SetFocus()
   uo_editor.Event scn_updateui()
End If

end event

event wm_command;// process control messages

Constant UInt SCEN_CHANGE    = 768
Constant UInt SCEN_KILLFOCUS = 256
Constant UInt SCEN_SETFOCUS  = 512

If hwndchild = Handle(uo_editor) Then
   choose case notificationcode
      case SCEN_CHANGE
         uo_editor.Event EditChanged()
      case SCEN_KILLFOCUS
         uo_editor.Event LoseFocus()
      case SCEN_SETFOCUS
         uo_editor.Event GetFocus()
   end choose
End If

end event

event m_font();// choose font

n_choosefont ln_cf
Long ll_TextSize
Boolean lb_Italic, lb_Bold
String ls_FontName

ls_FontName = uo_editor.#FontName

If ln_cf.of_ChooseFont(this, ls_FontName) Then
   // get settings
   ls_FontName = ln_cf.iFaceName
   lb_Bold     = ln_cf.iBold
   lb_Italic   = ln_cf.iItalic
   ll_TextSize = ln_cf.iTextSize
   // save settings in registry
   gn_app.of_SetReg("FontName", ls_FontName)
   gn_app.of_SetReg("Bold", String(lb_Bold))
   gn_app.of_SetReg("Italic", String(lb_Italic))
   gn_app.of_SetReg("TextSize", String(ll_TextSize))
   // apply settings
   uo_editor.of_SetFont(ls_FontName)
   uo_editor.of_SetFontBold(lb_Bold)
   uo_editor.of_SetFontItalic(lb_Italic)
   uo_editor.of_SetFontSize(ll_TextSize)
End If

end event

event wm_notify;// trigger this event on the edit control
uo_editor.Event wm_notify(wparam, lparam)

end event

event wm_syscommand;Constant ulong SC_RESTORE = 61728 // 0xF120
Integer li_xpos, li_ypos, li_hght, li_wdth

li_xpos = Integer(gn_app.of_GetReg("Window", "XPos", String(this.X)))
li_ypos = Integer(gn_app.of_GetReg("Window", "YPos", String(this.Y)))
li_hght = Integer(gn_app.of_GetReg("Window", "Width", String(this.Width)))
li_wdth = Integer(gn_app.of_GetReg("Window", "Height", String(this.Height)))

// restore window to previous size after Restore (maximized button was clicked)
If commandtype = SC_RESTORE Then
   this.Post Move(li_xpos, li_ypos)
   this.Post Resize(li_hght, li_wdth)
End If

end event

event wm_wininichange;// move if positioned outside the boundaries of any monitor
If Not gn_app.of_IsOnMonitor(this) Then
   this.Post Move(0, 0)
End If

end event

public subroutine wf_restorewindowstate ();String ls_value

// restore window size and position
this.x = Integer(gn_app.of_GetReg("Window", "XPos", String(this.X)))
this.y = Integer(gn_app.of_GetReg("Window", "YPos", String(this.Y)))
this.width  = Integer(gn_app.of_GetReg("Window", "Width", String(this.Width)))
this.height = Integer(gn_app.of_GetReg("Window", "Height", String(this.Height)))

// restore windowstate
ls_value = gn_app.of_GetReg("Window", "WindowState", "Normal")
If Lower(ls_value) = "maximized" Then
   // maximize window
   gn_app.of_ShowWindow(this, Maximized!)
Else
   // normalize window
   gn_app.of_ShowWindow(this, Normal!)
End If

this.Visible = True

// check to see if located off screen
this.Event wm_wininichange("")

end subroutine

public subroutine wf_savewindowstate ();// save window position/size
If this.WindowState = Normal! Then
   gn_app.of_SetReg("Window", "XPos", String(this.X))
   gn_app.of_SetReg("Window", "YPos", String(this.Y))
   gn_app.of_SetReg("Window", "Width", String(this.Width))
   gn_app.of_SetReg("Window", "Height", String(this.Height))
   gn_app.of_SetReg("Window", "WindowState", "Normal")
Else
   gn_app.of_SetReg("Window", "WindowState", "Maximized")
End If

end subroutine

public subroutine wf_menu (string as_menuaction);// process menu actions

Application la_app
String ls_value, ls_SearchURL, ls_language, ls_extn
Long ll_line, ll_tabwidth, ll_columns

choose case as_menuaction
   // process the Popup menu
   case "m_websearch"
      ls_value = uo_editor.of_GetSelectedText()
      If ls_value <> "" Then
         gn_app.of_WebBrowse("? " + ls_value)
      End If
   case "m_gotowebsite"
      ls_value = uo_editor.of_GetSelectedText()
      If ls_value <> "" Then
         gn_app.of_WebBrowse(ls_value)
      End If
   // process the File menu
   case "m_new"
      this.Event m_new()
   case "m_open"
      this.Event m_open()
   case "m_save"
      this.Event m_save()
   case "m_saveas"
      this.Event m_saveas()
   case "m_print"
      this.Event m_print()
   case "m_exit"
      Close(this)
   // process the Edit menu
   case "m_undo"
      uo_editor.of_Undo()
   case "m_redo"
      uo_editor.of_Redo()
   case "m_cut"
      uo_editor.of_Cut()
   case "m_copy"
      uo_editor.of_Copy()
   case "m_paste"
      uo_editor.of_Paste()
   case "m_delete"
      uo_editor.of_Delete()
   case "m_find"
      ls_value = uo_editor.of_GetSelectedText()
      If ls_value <> "" Then
         gn_app.is_findstr = Left(ls_value, Pos(ls_value + " ", " ") - 1)
      End If
      Open(w_find)
      uo_editor.SetFocus()
   case "m_findnext"
      ls_value = uo_editor.of_GetSelectedText()
      If ls_value <> "" Then
         gn_app.is_findstr = Left(ls_value, Pos(ls_value + " ", " ") - 1)
      End If
      this.Event m_findnext()
   case "m_replace"
      Open(w_replace)
      If gn_app.ii_replaced >= 0 Then
         MessageBox("Replace All", &
               "Number of items replaced: " + String(gn_app.ii_replaced))
      End if
      uo_editor.SetFocus()
   case "m_gotoline"
      ll_line = uo_editor.of_GetCurrentLine()
      OpenWithParm(w_goto, ll_line)
      uo_editor.SetFocus()
      If Message.StringParm = "cancel" Then Return
      ll_line = Long(Message.StringParm)
      If ll_line > 0 Then
         uo_editor.of_GotoLine(ll_line)
      End If
   case "m_selectall"
      uo_editor.of_SelectAll()
   // process the View menu
   case "m_bigtoolbarbuttons"
      la_app = GetApplication()
      ls_value = gn_app.of_GetReg("ToolbarText", "false")
      If ls_value = "true" Then
         la_app.ToolbarText = True
      Else
         la_app.ToolbarText = False
      End If
      wf_RecentFiles()
   case "m_darktheme"
      ls_language = uo_editor.of_GetLanguage()
      ls_extn = Lower(Mid(is_filename, LastPos(is_filename, ".") + 1))
      choose case ls_extn
         case "json"
            uo_editor.of_Set_JSON()
         case "ps1"
            uo_editor.of_Set_PowerShell()
         case "sql"
            uo_editor.of_Set_SQL()
         case "xml", "xslt", "xaml"
            uo_editor.of_Set_XML()
         case else
            If Left(ls_extn, 2) = "sr" Then
               uo_editor.of_Set_PowerBuilder()
            Else
               uo_editor.of_Set_NoLanguage()
            End If
      end choose
   case "m_showlinenumbers"
      ls_value = gn_app.of_GetReg("LineNumbers", "false")
      If ls_value = "true" Then
         uo_editor.of_ShowLineNumbers(True)
      Else
         uo_editor.of_ShowLineNumbers(False)
      End If
   case "m_showindentguides"
      ls_value = gn_app.of_GetReg("IndentGuides", "false")
      If ls_value = "true" Then
         uo_editor.of_ShowIndentGuides(True)
      Else
         uo_editor.of_ShowIndentGuides(False)
      End If
   case "m_showwhitespace"
      ls_value = gn_app.of_GetReg("WhiteSpace", "false")
      If ls_value = "true" Then
         uo_editor.of_ShowWhiteSpace(True)
      Else
         uo_editor.of_ShowWhiteSpace(False)
      End If
   case "m_showeolmarks"
      ls_value = gn_app.of_GetReg("EOLMarks", "false")
      If ls_value = "true" Then
         uo_editor.of_ShowEOL(True)
      Else
         uo_editor.of_ShowEOL(False)
      End If
   case "m_caretlineback"
      ls_value = gn_app.of_GetReg("CaretLineBack", "false")
      If ls_value = "true" Then
         uo_editor.of_SetCaretLineBack(True)
      Else
         uo_editor.of_SetCaretLineBack(False)
      End If
   case "m_wordwrap"
      ls_value = gn_app.of_GetReg("WordWrap", "false")
      If ls_value = "true" Then
         uo_editor.of_SetWordWrap(True)
      Else
         uo_editor.of_SetWordWrap(False)
      End If
   case "m_font"
      this.Event m_font()
   case "m_tabwidth"
      Open(w_tabwidth)
      uo_editor.SetFocus()
      If Message.StringParm = "cancel" Then
      Else
         ll_tabwidth = Long(Message.StringParm)
         If ll_tabwidth > 0 Then
            gn_app.of_SetReg("TabWidth", String(ll_tabwidth))
            uo_editor.of_SetTabWidth(ll_tabwidth)
         End If
      End If
   case "m_longlines"
      Open(w_longlines)
      uo_editor.SetFocus()
      If Message.StringParm = "cancel" Then
      Else
         If gn_app.of_GetReg("EdgeMode", "false") = "false" Then
            uo_editor.of_SetEdgeMode(uo_editor.EDGE_NONE)
         Else
            ll_columns = Long(gn_app.of_GetReg("EdgeColumns", "72"))
            uo_editor.of_SetEdgeColumn(ll_columns)
            uo_editor.of_SetEdgeMode(uo_editor.EDGE_BACKGROUND)
         End If
      End If
   // process the Tools menu
   case "m_commentselection"
      uo_editor.of_CommentSelected()
   case "m_uncommentselection"
      uo_editor.of_UnCommentSelected()
   case "m_lefttrimselection"
      uo_editor.of_LeftTrimSelected()
   case "m_righttrimselection"
      uo_editor.of_RightTrimSelected()
   case "m_sortselectionascending"
      uo_editor.of_SortSelected("A")
   case "m_sortselectiondescending"
      uo_editor.of_SortSelected("D")
   case "m_clearread-only"
      If gn_app.of_IsFileReadOnly(is_pathname) Then
         gn_app.of_SetReadOnly(is_pathname, False)
         wf_openfile(is_pathname)
      End If
   // process the Tools\Change Case menu
   case "m_lower"
      uo_editor.of_ChangeCase(Lower!)
   case "m_upper"
      uo_editor.of_ChangeCase(Upper!)
   case "m_wordcap"
      uo_editor.of_Wordcap()
   // process the Tools\Encoding menu
   case "m_ansi"
      uo_editor.of_SetEncoding(EncodingAnsi!)
   case "m_utf8"
      uo_editor.of_SetEncoding(EncodingUTF8!)
   case "m_utf16be"
      uo_editor.of_SetEncoding(EncodingUTF16BE!)
   case "m_utf16le"
      uo_editor.of_SetEncoding(EncodingUTF16LE!)
   // process the Tools\EOL Conversion menu
   case "m_windowscrlf"
      uo_editor.of_ConvertEOLS(uo_editor.SC_EOL_CRLF)
      uo_editor.of_SetEOLMode(uo_editor.SC_EOL_CRLF)
   case "m_unixlf"
      uo_editor.of_ConvertEOLS(uo_editor.SC_EOL_LF)
      uo_editor.of_SetEOLMode(uo_editor.SC_EOL_LF)
   case "m_macintoshcr"
      uo_editor.of_ConvertEOLS(uo_editor.SC_EOL_CR)
      uo_editor.of_SetEOLMode(uo_editor.SC_EOL_CR)
   // process the Tools\Markers menu
   case "m_togglemarker"
      ll_line = uo_editor.of_GetCurrentLine()
      If uo_editor.of_MarkerActive(ll_line) Then
         uo_editor.of_MarkerDelete(ll_line)
      Else
         uo_editor.of_MarkerAdd(uo_editor.SC_MARK_CIRCLE, &
                        ll_line, uo_editor.of_Color("Red"))
      End If
   case "m_removeallmarkers"
      uo_editor.of_MarkerDeleteAll()
   case "m_gotonextmarker"
      ll_line = uo_editor.of_GetCurrentLine()
      ll_line = uo_editor.of_MarkerNext(ll_line)
      If ll_line > 0 Then
         uo_editor.of_GotoLine(ll_line)
         uo_editor.SetFocus()
      End If
   case "m_gotoprevmarker"
      ll_line = uo_editor.of_GetCurrentLine()
      ll_line = uo_editor.of_MarkerPrev(ll_line)
      If ll_line > 0 Then
         uo_editor.of_GotoLine(ll_line)
         uo_editor.SetFocus()
      End If
   case "m_deletemarkedlines"
      ll_line = uo_editor.of_MarkerNext(0)
      do while ll_line > 0
         uo_editor.of_MarkerDelete(ll_line)
         uo_editor.of_DeleteLine(ll_line)
         ll_line = uo_editor.of_MarkerNext(ll_line)
      loop
   case else
      MessageBox("wf_menu Error", &
            "Invalid Action: " + as_menuaction, StopSign!)
end choose

// update the status bar
If IsValid(w_statusbar) Then
   w_statusbar.wf_updateui(uo_editor)
End If

end subroutine

public subroutine wf_recentfiles ();// populate the recent files menu
// set all the editor options that have checkmarks on the menu

Application la_app
m_main lm_menu
Menu lm_item
String ls_value

// reset the menu
this.ChangeMenu(m_main)

// get reference to the menu
lm_menu = this.MenuID

// get reference to the menu item
lm_item = lm_menu.m_file.m_recentfiles

// set the parent window
gn_dyn.of_SetParent(this)

// update recent files menu item
gn_mru.of_RecentFiles(lm_item)

// set Encoding
lm_menu.mf_Encoding(iEncoding)

// disable the Save option
lm_menu.mf_EnableSave(False)

// determine toolbar size
la_app = GetApplication()
ls_value = gn_app.of_GetReg("Window", "ToolbarText", "false")
If ls_value = "true" Then
   la_app.ToolbarText = True
   lm_menu.mf_BigToolbarButtons(True)
Else
   la_app.ToolbarText = False
   lm_menu.mf_BigToolbarButtons(False)
End If

// set the theme checkmark
If is_theme = "dark" Then
   lm_menu.mf_DarkTheme(True)
Else
   lm_menu.mf_DarkTheme(False)
End If

// determine line numbers
ls_value = gn_app.of_GetReg("LineNumbers", "false")
If ls_value = "true" Then
   uo_editor.of_ShowLineNumbers(True)
   lm_menu.mf_LineNumbers(True)
Else
   uo_editor.of_ShowLineNumbers(False)
   lm_menu.mf_LineNumbers(False)
End If

// determine indent guides
ls_value = gn_app.of_GetReg("IndentGuides", "false")
If ls_value = "true" Then
   uo_editor.of_ShowIndentGuides(True)
   lm_menu.mf_IndentGuides(True)
Else
   uo_editor.of_ShowIndentGuides(False)
   lm_menu.mf_IndentGuides(False)
End If

// determine whitespace
ls_value = gn_app.of_GetReg("WhiteSpace", "false")
If ls_value = "true" Then
   uo_editor.of_ShowWhiteSpace(True)
   lm_menu.mf_WhiteSpace(True)
Else
   uo_editor.of_ShowWhiteSpace(False)
   lm_menu.mf_WhiteSpace(False)
End If

// determine eol marks
ls_value = gn_app.of_GetReg("EOLMarks", "false")
If ls_value = "true" Then
   uo_editor.of_ShowEOL(True)
   lm_menu.mf_EOLMarks(True)
Else
   uo_editor.of_ShowEOL(False)
   lm_menu.mf_EOLMarks(False)
End If

// determine caret background
ls_value = gn_app.of_GetReg("CaretLineBack", "false")
If ls_value = "true" Then
   uo_editor.of_SetCaretLineBack(True)
   lm_menu.mf_CaretLineBack(True)
Else
   uo_editor.of_SetCaretLineBack(False)
   lm_menu.mf_CaretLineBack(False)
End If

// determine word wrap
ls_value = gn_app.of_GetReg("WordWrap", "false")
If ls_value = "true" Then
   uo_editor.of_SetWordWrap(True)
   lm_menu.mf_WordWrap(True)
Else
   uo_editor.of_SetWordWrap(False)
   lm_menu.mf_WordWrap(False)
End If

end subroutine

public subroutine wf_dynamicmenus (integer ai_index);// Dynamic Menu Item Clicked

String ls_filename

// get filename from tag
ls_filename = gn_dyn.of_GetItemString(ai_index, "tag")

If Not FileExists(ls_filename) Then
   // update the MRU List
   gn_mru.of_RemoveFromList(ls_filename)
   // update the menu items
   wf_RecentFiles()
   MessageBox("Recent Files", &
         "The file you chose does not exist!", StopSign!)
   Return
End If

// update the MRU List
gn_mru.of_AddToList(ls_filename)

// update the menu items
wf_RecentFiles()

// check for unsaved changes
If this.Event CloseQuery() = 1 Then Return

// open the file
wf_openfile(ls_filename)

end subroutine

public subroutine wf_registerxpmimage ();// This function registers an XPM image for use by
// the Auto-Complete process.

String ls_picture

ls_picture = '&
/* XPM */&
static char *pbw[] = {&
/* columns rows colors chars-per-pixel */&
"16 16 13 1",&
"  c #604040",&
". c #406040",&
"X c #404060",&
"o c #806040",&
"O c #FF4040",&
"+ c #408040",&
"@ c #BF8040",&
"# c #818181",&
"$ c #BEAE9D",&
"% c #DFBF80",&
"& c #FFFF9F",&
"* c #D9D0C6",&
"= c #FFFFFF",&
/* pixels */&
"================",&
"===========O====",&
"===========O====",&
"==========X ====",&
"==@@@@@@@@X @@==",&
"=*@%%%%%+%oo%@*=",&
"=@%%##@%++%%%%@=",&
"*@%#==#%.%+%%%@$",&
"@%%####%....%%%o",&
"o&&&&&&&&&&&&&&o",&
"oooooooooooooooo",&
"== XXXXXXXXXX ==",&
"==o@@@@@@@@@@o==",&
"==o@@@@@@@@@@o==",&
"==o@ oooooo @o==",&
"==ooo******ooo=="&
};&
'
uo_editor.of_RegisterImage(1, ls_picture)

end subroutine

public subroutine wf_registerrgbaimage ();// This function registers an RGBA image for use by
// the Auto-Complete process.
// It is creating a 16x16 block of one color.

Blob lblb_pixels
Long ll_Width, ll_Height, ll_pixel, ll_row, ll_col

ll_Width    = 16
ll_Height   = 16
lblb_pixels = Blob(Space((ll_Width * ll_Height) * 4), EncodingAnsi!)

For ll_row = 1 To ll_Height
   For ll_col = 1 To ll_Width
      ll_pixel ++
      BlobEdit(lblb_pixels, ll_pixel, Char(255), EncodingAnsi!)   // Red
      ll_pixel ++
      BlobEdit(lblb_pixels, ll_pixel, Char(192), EncodingAnsi!)   // Green
      ll_pixel ++
      BlobEdit(lblb_pixels, ll_pixel, Char(192), EncodingAnsi!)      // Blue
      ll_pixel ++
      BlobEdit(lblb_pixels, ll_pixel, Char(255), EncodingAnsi!)   // Alpha
   Next
Next

uo_editor.of_RegisterRGBAImage(1, lblb_pixels, ll_Width, ll_Height)

end subroutine

public subroutine wf_openfile (string as_filename);Blob lblb_source
Integer li_fnum
Long ll_bytes
String ls_source, ls_extn

SetPointer(HourGlass!)

is_pathname = as_filename
is_filename = Mid(as_filename, LastPos(as_filename, "\") + 1)

// set the window title
this.title = is_filename + " - " + WINTITLE

// read the file
li_fnum = FileOpen(is_pathname, StreamMode!, Read!, Shared!)
ll_bytes = FileReadEx(li_fnum, lblb_source)
FileClose(li_fnum)

// determine the file encoding
iEncoding = uo_editor.of_GetEncoding(lblb_source)
uo_editor.of_SetEncoding(iEncoding)
ls_source = String(lblb_source, iEncoding)

// put the text into the control
uo_editor.of_SetText(ls_source)
uo_editor.of_SetNotModified()
uo_editor.of_GotoPos(1)

// set the text language
ls_extn = Lower(Mid(is_filename, LastPos(is_filename, ".") + 1))
choose case ls_extn
   case "json"
      uo_editor.of_Set_JSON()
   case "ps1"
      uo_editor.of_Set_PowerShell()
   case "sql"
      uo_editor.of_Set_SQL()
   case "xml", "xslt", "xaml"
      uo_editor.of_Set_XML()
   case else
      If Left(ls_extn, 2) = "sr" Then
         uo_editor.of_Set_PowerBuilder()
      Else
         uo_editor.of_Set_NoLanguage()
      End If
end choose

// check for read-only
If gn_app.of_IsFileReadOnly(is_pathname) Then
   this.title = is_filename + " [ReadOnly] - " + WINTITLE
   uo_editor.of_SetReadOnly(True)
Else
   uo_editor.of_SetReadOnly(False)
End If

// add file to list
gn_mru.of_AddToList(is_pathname)

// add items to menu
gw_frame.wf_RecentFiles()

uo_editor.SetFocus()
uo_editor.Event scn_updateui()

end subroutine

on w_main.create
if this.MenuName = "m_main" then this.MenuID = create m_main
this.mdi_1=create mdi_1
this.uo_editor=create uo_editor
this.Control[]={this.mdi_1,&
this.uo_editor}
end on

on w_main.destroy
if IsValid(MenuID) then destroy(MenuID)
destroy(this.mdi_1)
destroy(this.uo_editor)
end on

event resize;Integer li_height

// move control
uo_editor.Move(4, WorkspaceY() + 2)

// resize control
li_height = (WorkspaceHeight() - mdi_1.MicroHelpHeight) - 6
uo_editor.Resize(WorkspaceWidth() - 8, li_height)

// reposition statusbar
If IsValid(w_statusbar) Then
   w_statusbar.wf_reposition()
End If

end event

event close;// save list to registry
gn_mru.of_SaveList()

// save window state
wf_SaveWindowState()

end event

event closequery;// check for unsaved changes

Integer li_rc
String ls_msg

If uo_editor.of_IsModified() Then
   ls_msg  = "The text in the file has changed.~r~n"
   ls_msg += "~r~nDo you want to save the changes?"
   li_rc = MessageBox(WINTITLE, &
               ls_msg, Exclamation!, YesNoCancel!)
   Choose Case li_rc
      Case 1
         // Save the file
         Return this.Event m_save()
      Case 2
         // Don't save the file
         Return 0
      Case 3
         // Cancel the window close
         Return 1
   End Choose
End If

Return 0

end event

event open;Boolean lb_FontBold, lb_FontItalic
Integer li_FontSize, li_TabStops, li_Columns
String ls_value, ls_FontName, ls_cmdline, ls_filename

gw_frame = this

// load list from registry
gn_mru.of_LoadList()

// add items to menu
wf_RecentFiles()

// restore window state
wf_RestoreWindowState()

// open statusbar
Open(w_statusbar)
w_statusbar.wf_updateui(uo_editor)

// retrieve font properties
ls_FontName = gn_app.of_GetReg("FontName", "Fixedsys")
lb_FontBold = (gn_app.of_GetReg("Bold", "false") = "true")
lb_FontItalic = (gn_app.of_GetReg("Italic", "false") = "true")
li_FontSize = Long(gn_app.of_GetReg("TextSize", "9"))
li_TabStops = Long(gn_app.of_GetReg("TabWidth", "3"))

// set EdgeMode (Long Lines)
If gn_app.of_GetReg("EdgeMode", "false") = "false" Then
   uo_editor.of_SetEdgeMode(uo_editor.EDGE_NONE)
Else
   li_Columns = Long(gn_app.of_GetReg("EdgeColumns", "72"))
   uo_editor.of_SetEdgeColumn(li_Columns)
   uo_editor.of_SetEdgeMode(uo_editor.EDGE_BACKGROUND)
End If

// apply font properties
uo_editor.of_SetFont(ls_FontName)
uo_editor.of_SetFontBold(lb_FontBold)
uo_editor.of_SetFontItalic(lb_FontItalic)
uo_editor.of_SetFontSize(li_FontSize)
uo_editor.of_SetTabWidth(li_TabStops)

// disable standard popup menu
uo_editor.of_SetUsePopup(False)

// check for passed filename
ls_cmdline = CommandParm()
If ls_cmdline <> "" Then
   ls_filename = Trim(ls_cmdline)
   If Left(ls_filename, 1) = "~"" And &
      Right(ls_filename, 1) = "~"" Then
      ls_filename = Mid(ls_filename, 2, Len(ls_filename) - 2)
   End If
   this.Post wf_openfile(ls_filename)
End If

// give control focus
uo_editor.SetFocus()

end event

type mdi_1 from mdiclient within w_main
long BackColor=268435456
end type

type uo_editor from u_scintilla within w_main
integer x = 37
integer y = 32
integer width = 3589
integer height = 2116
integer taborder = 10
end type

event constructor;call super::constructor;// register Auto-Complete image
If ib_AutoComplete Then
   //wf_RegisterXPMImage()
   wf_RegisterRGBAImage()
End If

end event

event rbuttondown;call super::rbuttondown;// show custom popup

m_popup_menu lm_popup
Boolean lb_cancopy, lb_canpaste, lb_canredo, lb_canundo
Long ll_textlen
String ls_Selected

lm_popup = CREATE m_popup_menu

lb_cancopy  = this.of_CanCopy()
lb_canpaste = this.of_CanPaste()
lb_canredo  = this.of_CanRedo()
lb_canundo  = this.of_CanUndo()

ll_textlen  = this.of_GetTextLength()
ls_Selected = this.of_GetSelectedText()

lm_popup.mf_EditStatus(lb_cancopy, lb_canpaste, &
            lb_canredo, lb_canundo, ll_textlen, ls_Selected)

lm_popup.m_popup.PopMenu(Parent.PointerX(), Parent.PointerY())

DESTROY lm_popup

end event

event scn_charadded;call super::scn_charadded;// This is an example of how to use autocomplete. The ?1 in the word list
// refers to the image defined by of_RegisterImage/of_RegisterRGBAImage.

String ls_wordlist

If ib_AutoComplete Then
   choose case ch
      case "."
         If this.of_AutoCActive() Then
            // complete the AutoComplete window
            of_AutoCComplete()
         Else
            // activate the AutoComplete window
            ls_wordlist = "apple?1,beta?1,cat?1,dog?1,elephant?1,frog?1"
            this.of_AutoCSetSeparator(",")
            this.of_AutoCSetFillups("~t")
            this.of_AutoCShow(0, ls_wordlist)
         End If
   end choose
End If

end event

event scn_savepoint;call super::scn_savepoint;// set the window title

m_main lm_menu
String ls_filename

// get reference to the menu
lm_menu = Parent.MenuID

If is_filename = "" Then
   ls_filename = "Untitled"
Else
   ls_filename = is_filename
End If

If reached Then
   lm_menu.mf_EnableSave(False)
   Parent.title = ls_filename + " - " + WINTITLE
Else
   lm_menu.mf_EnableSave(True)
   Parent.title = ls_filename + " * - " + WINTITLE
End If

end event

event scn_updateui;call super::scn_updateui;m_main lm_menu
Boolean lb_cancopy, lb_canpaste, lb_canredo, lb_canundo, lb_readonly
Long ll_textlen

// update the status bar
If IsValid(w_statusbar) Then
   w_statusbar.wf_updateui(this)
End If

// update the status of menu items
lm_menu = Parent.MenuID

lb_cancopy  = this.of_CanCopy()
lb_canpaste = this.of_CanPaste()
lb_canredo  = this.of_CanRedo()
lb_canundo  = this.of_CanUndo()
lb_readonly = this.of_GetReadOnly()

ll_textlen = this.of_GetTextLength()

lm_menu.mf_EditStatus(lb_cancopy, lb_canpaste, &
            lb_canredo, lb_canundo, lb_readonly, ll_textlen)

end event

event ue_setlanguagecolors;call super::ue_setlanguagecolors;String ls_language

is_theme = gn_app.of_GetReg("Theme", "")
ls_language = of_GetLanguage()

// set language neutral colors
choose case Lower(is_theme)
   case "dark"
      of_SetMarginBackColor(RGB(36,36,36))
      of_SetMarginTextColor(of_Color("DeepSkyBlue"))
      of_SetFoldBackColor(of_Color("DeepSkyBlue"))
      of_SetFoldForeColor(RGB(36,36,36))
      of_SetBackColor(RGB(30,30,30))
      of_SetTextColor(of_Color("Gainsboro"))
      of_SetSelectColor(of_Color("SlateGray"))
      of_SetCaretColor(of_Color("Gainsboro"))
      of_SetCaretLineColor(RGB(36,36,36))
end choose

// set language specific colors
choose case ls_language
   case "cppnocase"  // PowerBuilder
      choose case Lower(is_theme)
         case "dark"
            of_SetTextColor(of_Color("Gainsboro"))
            of_SetStyleFore(SCE_C_COMMENT,      of_Color("RoyalBlue"))
            of_SetStyleFore(SCE_C_COMMENTLINE,  of_Color("RoyalBlue"))
            of_SetStyleFore(SCE_C_COMMENTDOC,   of_Color("RoyalBlue"))
            of_SetStyleFore(SCE_C_NUMBER,       of_Color("DeepSkyBlue"))
            of_SetStyleFore(SCE_C_WORD,         of_Color("MediumSeaGreen"))
            of_SetStyleFore(SCE_C_STRING,       of_Color("Salmon"))
            of_SetStyleFore(SCE_C_CHARACTER,    of_Color("Salmon"))
            of_SetStyleFore(SCE_C_WORD2,        of_Color("FireBrick"))
      end choose
   case "sql"
      choose case Lower(is_theme)
         case "dark"
            of_SetTextColor(of_Color("Gainsboro"))
            of_SetStyleFore(SCE_SQL_COMMENT,       of_Color("MediumSeaGreen"))
            of_SetStyleFore(SCE_SQL_COMMENTLINE,   of_Color("MediumSeaGreen"))
            of_SetStyleFore(SCE_SQL_COMMENTDOC,    of_Color("MediumSeaGreen"))
            of_SetStyleFore(SCE_SQL_NUMBER,        of_Color("DeepSkyBlue"))
            of_SetStyleFore(SCE_SQL_WORD,          of_Color("DeepSkyBlue"))
            of_SetStyleFore(SCE_SQL_STRING,        of_Color("Salmon"))
            of_SetStyleFore(SCE_SQL_CHARACTER,     of_Color("Salmon"))
            of_SetStyleFore(SCE_SQL_WORD2,         of_Color("FireBrick"))
      end choose
end choose

end event