|
@@ -0,0 +1,6560 @@
|
|
|
|
+
|
|
|
|
+' maxide.bmx - blitzmax native integrated development environment
|
|
|
|
+
|
|
|
|
+' by [email protected]
|
|
|
|
+
|
|
|
|
+' released under the Blitz Shared Source Code License 2005
|
|
|
|
+' released into the public domain 2006
|
|
|
|
+
|
|
|
|
+' requires MaxGui modules to run
|
|
|
|
+
|
|
|
|
+Strict
|
|
|
|
+
|
|
|
|
+Framework MaxGUI.Drivers
|
|
|
|
+Import MaxGUI.ProxyGadgets
|
|
|
|
+
|
|
|
|
+?Win32
|
|
|
|
+Import "maxicons.o"
|
|
|
|
+?
|
|
|
|
+
|
|
|
|
+'Import bah.gtkmaxgui
|
|
|
|
+'Import bah.gtkwebgtkhtml
|
|
|
|
+'Import bah.gtkwebmozilla
|
|
|
|
+
|
|
|
|
+Import brl.eventqueue
|
|
|
|
+Import brl.standardio
|
|
|
|
+Import brl.filesystem
|
|
|
|
+Import brl.system
|
|
|
|
+Import brl.ramstream
|
|
|
|
+Import pub.freeprocess
|
|
|
|
+Import brl.pngloader
|
|
|
|
+Import brl.timer
|
|
|
|
+Import brl.maxutil
|
|
|
|
+
|
|
|
|
+Incbin "bmxlogo.png"
|
|
|
|
+Incbin "toolbar.png"
|
|
|
|
+Incbin "splash.png"
|
|
|
|
+Incbin "default.language.ini"
|
|
|
|
+
|
|
|
|
+Const DEFAULT_LANGUAGEPATH$ = "incbin::default.language.ini"
|
|
|
|
+
|
|
|
|
+?Linux
|
|
|
|
+Incbin "window_icon.png"
|
|
|
|
+?
|
|
|
|
+
|
|
|
|
+AppTitle = "MaxIDE"
|
|
|
|
+
|
|
|
|
+Const IDE_VERSION$="1.43"
|
|
|
|
+Const TIMER_FREQUENCY=15
|
|
|
|
+
|
|
|
|
+?Win32
|
|
|
|
+Extern
|
|
|
|
+ Global _bbusew 'secret 'NT' flag
|
|
|
|
+End Extern
|
|
|
|
+
|
|
|
|
+If Not _bbusew
|
|
|
|
+ Notify..
|
|
|
|
+ "This program is not compatible with Windows 95/98/ME.~n~n"+..
|
|
|
|
+ "Please visit www.blitzbasic.com to download a compatible version.",True
|
|
|
|
+ End
|
|
|
|
+EndIf
|
|
|
|
+?
|
|
|
|
+
|
|
|
|
+Global BCC_VERSION$="{unknown}" 'not valid until codeplay opened
|
|
|
|
+
|
|
|
|
+Const EOL$="~n"
|
|
|
|
+
|
|
|
|
+Const ABOUT$=..
|
|
|
|
+"{bcc_version} - Copyright Blitz Research Ltd.~n~n"+..
|
|
|
|
+"Please visit www.blitzbasic.com for all your Blitz related needs!"
|
|
|
|
+
|
|
|
|
+Const ABOUTDEMO$=..
|
|
|
|
+"This demo features both the core BlitzMax package and optional MaxGUI module.~n~n"+..
|
|
|
|
+"Please note that the MaxGUI module must be purchased separately."
|
|
|
|
+
|
|
|
|
+Const FileTypes$="bmx,bbdoc,txt,ini,doc,plist,bb,cpp,c,cc,m,cxx,s,glsl,hlsl,lua,py,h,hpp,html,htm,css,js,bat,mm,as,java,bbx,cx"
|
|
|
|
+Const FileTypeFilters$="Code Files:"+FileTypes$+";All Files:*"
|
|
|
|
+
|
|
|
|
+Const HOMEPAGE$="/docs/html/index.html"
|
|
|
|
+
|
|
|
|
+?MacOS
|
|
|
|
+Global SVNCMD$="/usr/local/bin/svn"
|
|
|
|
+Const LABELOFFSET=2
|
|
|
|
+?Win32
|
|
|
|
+Global SVNCMD$="svn"
|
|
|
|
+Const LABELOFFSET=4
|
|
|
|
+?Linux
|
|
|
|
+Global SVNCMD$="/usr/bin/svn"
|
|
|
|
+Const LABELOFFSET=0
|
|
|
|
+?
|
|
|
|
+
|
|
|
|
+Const MENUNEW=1
|
|
|
|
+Const MENUOPEN=2
|
|
|
|
+Const MENUCLOSE=3
|
|
|
|
+Const MENUSAVE=4
|
|
|
|
+Const MENUSAVEAS=5
|
|
|
|
+Const MENUSAVEALL=6
|
|
|
|
+Const MENUPRINT=7
|
|
|
|
+Const MENUQUIT=8
|
|
|
|
+
|
|
|
|
+Const MENUUNDO=9
|
|
|
|
+Const MENUREDO=10
|
|
|
|
+Const MENUCUT=11
|
|
|
|
+Const MENUCOPY=12
|
|
|
|
+Const MENUPASTE=13
|
|
|
|
+Const MENUSELECTALL=14
|
|
|
|
+Const MENUGOTO=15
|
|
|
|
+Const MENUINDENT=16
|
|
|
|
+Const MENUOUTDENT=17
|
|
|
|
+Const MENUFIND=18
|
|
|
|
+Const MENUFINDNEXT=19
|
|
|
|
+Const MENUREPLACE=20
|
|
|
|
+Const MENUNEXT=21
|
|
|
|
+Const MENUPREV=22
|
|
|
|
+Const MENUBUILD=23
|
|
|
|
+Const MENURUN=24
|
|
|
|
+
|
|
|
|
+Const MENUSTEP=25
|
|
|
|
+Const MENUSTEPIN=26
|
|
|
|
+Const MENUSTEPOUT=27
|
|
|
|
+Const MENUSTOP=28
|
|
|
|
+
|
|
|
|
+Const MENULOCKBUILD=29
|
|
|
|
+Const MENUUNLOCKBUILD=30
|
|
|
|
+Const MENUBUILDMODULES=31
|
|
|
|
+Const MENUBUILDALLMODULES=32
|
|
|
|
+
|
|
|
|
+Const MENUQUICKENABLED=33
|
|
|
|
+Const MENUDEBUGENABLED=34
|
|
|
|
+Const MENUGUIENABLED=35
|
|
|
|
+
|
|
|
|
+Const MENUCOMMANDLINE=36
|
|
|
|
+'Const MENUSYNCMODS=37
|
|
|
|
+Const MENUIMPORTBB=38
|
|
|
|
+Const MENUFINDINFILES=39
|
|
|
|
+Const MENUPROJECTMANAGER=40
|
|
|
|
+Const MENUSHOWCONSOLE=41
|
|
|
|
+Const MENUOPTIONS=42
|
|
|
|
+
|
|
|
|
+Const MENUHOME=43
|
|
|
|
+Const MENUBACK=44
|
|
|
|
+Const MENUFORWARD=45
|
|
|
|
+Const MENUQUICKHELP=46
|
|
|
|
+Const MENUABOUT=47
|
|
|
|
+
|
|
|
|
+Const MENUNEWVIEW=48
|
|
|
|
+Const MENUDOCMODS=49
|
|
|
|
+
|
|
|
|
+Const MENUTRIGGERDOCMODS=50
|
|
|
|
+Const MENUTRIGGERSYNCDOCS=51
|
|
|
|
+
|
|
|
|
+Const MENUCLOSEALL=53
|
|
|
|
+
|
|
|
|
+Const MENUREFRESH=54
|
|
|
|
+Const MENUBROWSE=55
|
|
|
|
+Const MENUSHELL=56
|
|
|
|
+Const MENUPROPS=57
|
|
|
|
+
|
|
|
|
+Const MENUUPDATE=58
|
|
|
|
+Const MENUCOMMIT=59
|
|
|
|
+
|
|
|
|
+Const MENUCLOSEOTHERS=60
|
|
|
|
+
|
|
|
|
+Const MENUTHREADEDENABLED=61
|
|
|
|
+
|
|
|
|
+Const MENURECENT=256
|
|
|
|
+
|
|
|
|
+Const TB_NEW=0
|
|
|
|
+Const TB_OPEN=1
|
|
|
|
+Const TB_CLOSE=2
|
|
|
|
+Const TB_SAVE=3
|
|
|
|
+Const TB_CUT=5
|
|
|
|
+Const TB_COPY=6
|
|
|
|
+Const TB_PASTE=7
|
|
|
|
+Const TB_FIND=8
|
|
|
|
+Const TB_BUILD=10
|
|
|
|
+Const TB_BUILDRUN=11
|
|
|
|
+Const TB_STEP=12
|
|
|
|
+Const TB_STEPIN=13
|
|
|
|
+Const TB_STEPOUT=14
|
|
|
|
+Const TB_STOP=15
|
|
|
|
+Const TB_HOME=17
|
|
|
|
+Const TB_BACK=18
|
|
|
|
+Const TB_FORWARDS=19
|
|
|
|
+Const TB_CONTINUE=20
|
|
|
|
+
|
|
|
|
+Const TAB$=Chr(9)
|
|
|
|
+Const QUOTES$=Chr(34)
|
|
|
|
+
|
|
|
|
+Global TEMPCOUNT
|
|
|
|
+Global is_demo
|
|
|
|
+Global codeplay:TCodePlay
|
|
|
|
+
|
|
|
|
+Function CheckDemo()
|
|
|
|
+ If Not is_demo Return 1
|
|
|
|
+ Notify LocalizeString("{{notify_demo_featureunavailable}}")
|
|
|
|
+ Return 0
|
|
|
|
+End Function
|
|
|
|
+
|
|
|
|
+Global defaultLanguage:TMaxGUILanguage = LoadLanguage( DEFAULT_LANGUAGEPATH )
|
|
|
|
+
|
|
|
|
+SetLocalizationLanguage( defaultLanguage )
|
|
|
|
+SetLocalizationMode( LOCALIZATION_ON|LOCALIZATION_OVERRIDE )
|
|
|
|
+
|
|
|
|
+codeplay=New TCodePlay
|
|
|
|
+codeplay.Initialize
|
|
|
|
+
|
|
|
|
+While codeplay.running
|
|
|
|
+ codeplay.poll
|
|
|
|
+Wend
|
|
|
|
+
|
|
|
|
+End
|
|
|
|
+
|
|
|
|
+Function Quote$(a$) 'add quotes to arg if spaces found
|
|
|
|
+ Local p
|
|
|
|
+ If Not a.length Return
|
|
|
|
+ If a[0]=34 Return a 'already quoted
|
|
|
|
+ p=a.find(" ")
|
|
|
|
+ If p=-1 Return a 'no spaces
|
|
|
|
+ Return Chr(34)+a+Chr(34)
|
|
|
|
+End Function
|
|
|
|
+
|
|
|
|
+Type TToken
|
|
|
|
+ Field token$
|
|
|
|
+ Field help$
|
|
|
|
+ Field ref$
|
|
|
|
+ Method Create:TToken(t$,h$,r$)
|
|
|
|
+ token=t
|
|
|
|
+ help=h
|
|
|
|
+ ref=r
|
|
|
|
+ Return Self
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TQuickHelp
|
|
|
|
+ Field map:TMap=New TMap 'key=lower(token) value=token:TToken
|
|
|
|
+
|
|
|
|
+ Method AddCommand:TQuickHelp(t$,l$,a$)
|
|
|
|
+ map.Insert t.ToLower(),New TToken.Create(t$,l$,a$)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Token$(cmd$)
|
|
|
|
+ Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
|
|
|
|
+ If t Return t.token
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Help$(cmd$)
|
|
|
|
+ Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
|
|
|
|
+ If t Return t.help
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Link$(cmd$)
|
|
|
|
+ Local t:TToken = TToken(map.ValueForKey(cmd.toLower()))
|
|
|
|
+ If t Return t.ref
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function LoadCommandsTxt:TQuickHelp(bmxpath$)
|
|
|
|
+ Local text$
|
|
|
|
+ Local qh:TQuickHelp
|
|
|
|
+ Local i:Int,c,p,q
|
|
|
|
+ Local token$,help$,anchor$
|
|
|
|
+ Try
|
|
|
|
+ text=CacheAndLoadText(bmxpath+"/docs/html/Modules/commands.txt")
|
|
|
|
+ Catch exception:Object
|
|
|
|
+ Return Null
|
|
|
|
+ EndTry
|
|
|
|
+ If Not text Return Null
|
|
|
|
+ qh=New TQuickHelp
|
|
|
|
+ For Local l$ = EachIn text.Split("~n")
|
|
|
|
+ For i=0 Until l.length
|
|
|
|
+ c=l[i]
|
|
|
|
+ If c=Asc("_") Continue
|
|
|
|
+ If c>=Asc("0") And c<=Asc("9") Continue
|
|
|
|
+ If c>=Asc("a") And c<=Asc("z") Continue
|
|
|
|
+ If c>=Asc("A") And c<=Asc("Z") Continue
|
|
|
|
+ Exit
|
|
|
|
+ Next
|
|
|
|
+ token$=l[..i]
|
|
|
|
+ help$=""
|
|
|
|
+ anchor$=""
|
|
|
|
+ q=l.findlast("|")
|
|
|
|
+ If q>=0
|
|
|
|
+ help=l[..q]
|
|
|
|
+ anchor=l[q+1..]
|
|
|
|
+ EndIf
|
|
|
|
+ qh.AddCommand token,help,anchor
|
|
|
|
+ Next
|
|
|
|
+ Return qh
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Const TOOLSHOW=1
|
|
|
|
+Const TOOLREFRESH=2
|
|
|
|
+Const TOOLNEW=3
|
|
|
|
+Const TOOLOPEN=4
|
|
|
|
+Const TOOLCLOSE=5
|
|
|
|
+Const TOOLSAVE=6
|
|
|
|
+Const TOOLHELP=7
|
|
|
|
+Const TOOLUNDO=8
|
|
|
|
+Const TOOLREDO=9
|
|
|
|
+Const TOOLCUT=10
|
|
|
|
+Const TOOLCOPY=11
|
|
|
|
+Const TOOLPASTE=12
|
|
|
|
+Const TOOLQUICKSAVE=13
|
|
|
|
+Const TOOLSAVEAS=14
|
|
|
|
+Const TOOLGOTO=15
|
|
|
|
+Const TOOLFIND=16
|
|
|
|
+Const TOOLFINDNEXT=17
|
|
|
|
+Const TOOLREPLACE=18
|
|
|
|
+Const TOOLBUILD=19
|
|
|
|
+Const TOOLRUN=20
|
|
|
|
+Const TOOLLOCK=21
|
|
|
|
+Const TOOLUNLOCK=22
|
|
|
|
+Const TOOLSELECT=23
|
|
|
|
+Const TOOLSELECTALL=24
|
|
|
|
+Const TOOLINDENT=25
|
|
|
|
+Const TOOLOUTDENT=26
|
|
|
|
+Const TOOLACTIVATE=27
|
|
|
|
+Const TOOLNAVIGATE=28
|
|
|
|
+Const TOOLNEWVIEW=29
|
|
|
|
+Const TOOLMENU=30
|
|
|
|
+Const TOOLPRINT=31
|
|
|
|
+Const TOOLERROR=32
|
|
|
|
+Const TOOLOUTPUT=32
|
|
|
|
+
|
|
|
|
+Type TTool
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TRequester
|
|
|
|
+
|
|
|
|
+ Const STYLE_OK% = 1, STYLE_CANCEL% = 2
|
|
|
|
+ Const STYLE_DIVIDER% = 4, STYLE_STATUS% = 8
|
|
|
|
+ Const STYLE_RESIZABLE% = 16, STYLE_STDBORDER% = 32
|
|
|
|
+ Const STYLE_MODAL% = 64
|
|
|
|
+
|
|
|
|
+ Field host:TCodePlay
|
|
|
|
+ Field window:TGadget,ok:TGadget,cancel:TGadget,divider:TGadget
|
|
|
|
+ Field centered, modal
|
|
|
|
+
|
|
|
|
+ Method initrequester(owner:TCodeplay,label$,w=260,h=60,flags=STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER,oktext$="{{btn_ok}}")
|
|
|
|
+
|
|
|
|
+ host=owner
|
|
|
|
+ If (flags&STYLE_MODAL) Then flags:|STYLE_STDBORDER
|
|
|
|
+
|
|
|
|
+ If (flags & (STYLE_CANCEL|STYLE_OK)) Then h:+32;If (flags&STYLE_DIVIDER) Then h:+12
|
|
|
|
+
|
|
|
|
+ Local windowflags% = WINDOW_TITLEBAR|WINDOW_HIDDEN|WINDOW_CLIENTCOORDS
|
|
|
|
+ If (flags & STYLE_STATUS) Then windowflags:|WINDOW_STATUS
|
|
|
|
+ If (flags & STYLE_RESIZABLE) Then windowflags:|WINDOW_RESIZABLE
|
|
|
|
+ If Not (flags & STYLE_STDBORDER) Then windowflags:|WINDOW_TOOL
|
|
|
|
+
|
|
|
|
+ window=CreateWindow(label,0,0,w,h,host.window,windowflags)
|
|
|
|
+
|
|
|
|
+ If (flags & STYLE_RESIZABLE) Then
|
|
|
|
+ If (flags & STYLE_STDBORDER) Then SetMaxWindowSize(window,ClientWidth(Desktop()),ClientHeight(Desktop()))
|
|
|
|
+ SetMinWindowSize(window,w,h)
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If (flags & STYLE_OK) Then
|
|
|
|
+
|
|
|
|
+ ok=CreateButton(oktext,ClientWidth(window)-101,ClientHeight(window)-32,95,26,window,BUTTON_OK)
|
|
|
|
+ SetGadgetLayout(ok,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
|
|
|
|
+
|
|
|
|
+ If (flags & STYLE_CANCEL) Then
|
|
|
|
+ cancel=CreateButton("{{btn_cancel}}",6,ClientHeight(window)-32,95,26,window,BUTTON_CANCEL)
|
|
|
|
+ SetGadgetLayout(cancel,EDGE_ALIGNED,EDGE_CENTERED,EDGE_CENTERED,EDGE_ALIGNED)
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ Else
|
|
|
|
+ If (flags & STYLE_CANCEL) Then
|
|
|
|
+ cancel=CreateButton("{{btn_close}}",ClientWidth(window)-101,ClientHeight(window)-32,95,26,window,BUTTON_CANCEL)
|
|
|
|
+ SetGadgetLayout(cancel,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If (flags & STYLE_DIVIDER) And (flags & (STYLE_OK|STYLE_CANCEL)) Then
|
|
|
|
+ divider = CreateLabel( "", 6, ClientHeight(window)-42, ClientWidth(window)-12, 4, window, LABEL_SEPARATOR )
|
|
|
|
+ SetGadgetLayout(divider,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED)
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If (flags & STYLE_MODAL) Then modal = True Else modal = False
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Show()
|
|
|
|
+ Local x,y,w,h,win:TGadget
|
|
|
|
+ If Not centered
|
|
|
|
+ win=host.window
|
|
|
|
+ w=GadgetWidth(window)
|
|
|
|
+ h=GadgetHeight(window)
|
|
|
|
+ x=GadgetX(win)+(GadgetWidth(win)-w)/2
|
|
|
|
+ y=GadgetY(win)+(GadgetHeight(win)-h)/2
|
|
|
|
+ SetGadgetShape window,x,y,w,h
|
|
|
|
+ centered=True
|
|
|
|
+ EndIf
|
|
|
|
+ host.HookRequester Self
|
|
|
|
+ ShowGadget window
|
|
|
|
+ ActivateGadget window
|
|
|
|
+ PollSystem
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Hide()
|
|
|
|
+ EnableGadget host.window
|
|
|
|
+ HideGadget window
|
|
|
|
+ host.UnhookRequester Self
|
|
|
|
+ host.SelectPanel host.currentpanel
|
|
|
|
+ End Method
|
|
|
|
+ Method IsModal()
|
|
|
|
+ Return modal
|
|
|
|
+ EndMethod
|
|
|
|
+ Method Poll()
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Rem
|
|
|
|
+Type TProgressRequester Extends TRequester
|
|
|
|
+ Field message$,value
|
|
|
|
+ Field showing
|
|
|
|
+ Field label:TGadget
|
|
|
|
+ Field progbar:TGadget
|
|
|
|
+
|
|
|
|
+ Method Show() 'returns false if cancelled
|
|
|
|
+ showing=True
|
|
|
|
+ Super.Show
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Hide()
|
|
|
|
+ showing=False
|
|
|
|
+ Super.Hide()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Open(title$)
|
|
|
|
+ SetGadgetText window,title
|
|
|
|
+ Show
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Update(msg$,val)
|
|
|
|
+ If msg$<>message
|
|
|
|
+ message=msg
|
|
|
|
+ If label FreeGadget label
|
|
|
|
+ label=CreateLabel(message,8,8,260,20,window)
|
|
|
|
+ EndIf
|
|
|
|
+ If showing And (val&$fc)<>(value&$fc) 'only update every 4 percent
|
|
|
|
+ UpdateProgBar( progbar,val/100.0 )
|
|
|
|
+ PollSystem
|
|
|
|
+ EndIf
|
|
|
|
+ value=val
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TProgressRequester(host:TCodePlay)
|
|
|
|
+ Local progress:TProgressRequester
|
|
|
|
+ progress=New TProgressRequester
|
|
|
|
+ progress.initrequester(host,"{{progress_window_title}}",280,128,STYLE_CANCEL)
|
|
|
|
+ progress.progbar=CreateProgBar( 8,32,260,20,progress.window )
|
|
|
|
+ Return progress
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+EndRem
|
|
|
|
+
|
|
|
|
+Type TPanelRequester Extends TRequester
|
|
|
|
+ Field tabber:TGadget
|
|
|
|
+ Field panels:TGadget[]
|
|
|
|
+ Field index
|
|
|
|
+
|
|
|
|
+ Method InitPanelRequester(owner:TCodeplay,label$,w=280,h=128)
|
|
|
|
+ InitRequester owner,label,w,h,STYLE_OK|STYLE_CANCEL|STYLE_STDBORDER|STYLE_MODAL
|
|
|
|
+ tabber=CreateTabber(6,6,w-12,h-12,window)
|
|
|
|
+ SetGadgetLayout tabber,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetPanelIndex(i)
|
|
|
|
+ HideGadget panels[index]
|
|
|
|
+ index=i
|
|
|
|
+ ShowGadget panels[index]
|
|
|
|
+ SelectGadgetItem tabber,index
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetPanel(panel:TGadget)
|
|
|
|
+ Local i
|
|
|
|
+ For Local p:TGadget = EachIn panels
|
|
|
|
+ If p=panel SetPanelIndex i;Exit
|
|
|
|
+ i:+1
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddPanel:TGadget(name$)
|
|
|
|
+ Local panel:TGadget
|
|
|
|
+ panel=CreatePanel(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber)
|
|
|
|
+ SetGadgetLayout panel,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
|
|
|
|
+ HideGadget panel
|
|
|
|
+ AddGadgetItem tabber,name,GADGETITEM_LOCALIZED
|
|
|
|
+ panels=panels[..panels.length+1]
|
|
|
|
+ panels[panels.length-1]=panel
|
|
|
|
+ Return panel
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RemovePanel(panel)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TAboutRequester Extends TRequester
|
|
|
|
+
|
|
|
|
+ Global pixLogo:TPixmap
|
|
|
|
+
|
|
|
|
+ Field pnlLogo:TGadget, lblTitle:TGadget, lblSubtitle:TGadget
|
|
|
|
+ Field lblLeftAligned:TGadget[], lblRightAligned:TGadget[]
|
|
|
|
+ Field hypBlitz:TGadget
|
|
|
|
+
|
|
|
|
+ Method PopulateText()
|
|
|
|
+
|
|
|
|
+ Local strHeadings$[], strValues$[]
|
|
|
|
+
|
|
|
|
+ strHeadings:+["{{about_label_bccver}}:"]
|
|
|
|
+ strValues:+[BCC_VERSION]
|
|
|
|
+
|
|
|
|
+ strHeadings:+[""]
|
|
|
|
+ strValues:+[""]
|
|
|
|
+
|
|
|
|
+ strHeadings:+["{{about_label_bmxpath}}:"]
|
|
|
|
+ ?Win32
|
|
|
|
+ strValues:+[BlitzMaxPath().Replace("/","\")]
|
|
|
|
+ ?Not Win32
|
|
|
|
+ strValues:+[BlitzMaxPath()]
|
|
|
|
+ ?
|
|
|
|
+
|
|
|
|
+ ?Win32
|
|
|
|
+ strHeadings:+["{{about_label_mingwpath}}:"]
|
|
|
|
+ If getenv_("MINGW") Then
|
|
|
|
+ strValues:+[getenv_("MINGW")]
|
|
|
|
+ Else
|
|
|
|
+ strValues:+[LocalizeString("{{about_error_unavailable}}")]
|
|
|
|
+ EndIf
|
|
|
|
+ ?
|
|
|
|
+
|
|
|
|
+ strHeadings:+[""]
|
|
|
|
+ strValues:+[""]
|
|
|
|
+
|
|
|
|
+ ?Not MacOS
|
|
|
|
+ strHeadings:+["{{about_label_fasmver}}:"]
|
|
|
|
+ strValues:+[GetFASM()]
|
|
|
|
+ ?
|
|
|
|
+
|
|
|
|
+ strHeadings:+["{{about_label_gccver}}:"]
|
|
|
|
+ strValues:+[GetGCC()]
|
|
|
|
+
|
|
|
|
+ strHeadings:+["{{about_label_gplusplusver}}:"]
|
|
|
|
+ strValues:+[GetGpp()]
|
|
|
|
+
|
|
|
|
+ PopulateColumns( strHeadings, strValues )
|
|
|
|
+
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Function GetProcessOutput$(cmd$, flags$ = "")
|
|
|
|
+
|
|
|
|
+ Local version$
|
|
|
|
+
|
|
|
|
+ ?Win32
|
|
|
|
+ cmd:+".exe"
|
|
|
|
+ ?
|
|
|
|
+
|
|
|
|
+ cmd=Quote(cmd)
|
|
|
|
+ If flags Then cmd:+" "+flags
|
|
|
|
+
|
|
|
|
+ Local process:TProcess = CreateProcess(cmd,HIDECONSOLE)
|
|
|
|
+
|
|
|
|
+ If process
|
|
|
|
+ Local bytes:Byte[]
|
|
|
|
+ Local tmpTimeout:Int = MilliSecs() + 500
|
|
|
|
+ Repeat
|
|
|
|
+ Delay 10
|
|
|
|
+ bytes=process.pipe.ReadPipe()
|
|
|
|
+ If bytes
|
|
|
|
+ version:+String.FromBytes(bytes,bytes.length)
|
|
|
|
+ EndIf
|
|
|
|
+ Until (Not process.status()) Or (MilliSecs() > tmpTimeout)
|
|
|
|
+ process.Close()
|
|
|
|
+ Return version.Trim().Replace("~r","")
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ Return LocalizeString("{{about_error_unavailable}}")
|
|
|
|
+
|
|
|
|
+ EndFunction
|
|
|
|
+
|
|
|
|
+ Method GetFASM$()
|
|
|
|
+ ?Not MacOS
|
|
|
|
+ Local tmpSections$[] = GetProcessOutput(BlitzMaxPath()+"/bin/fasm").Split("~n")[0].Split(" ")
|
|
|
|
+ Return tmpSections[tmpSections.length-1]
|
|
|
|
+ ?
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method GetGCC$()
|
|
|
|
+ ?Win32
|
|
|
|
+ If Not getenv_("MinGW") Then Return LocalizeString("{{about_error_notapplicable}}")
|
|
|
|
+ ?
|
|
|
|
+ Return GetProcessOutput("gcc", "-dumpversion").Split("~n")[0]
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method GetGpp$()
|
|
|
|
+ ?Win32
|
|
|
|
+ If Not getenv_("MinGW") Then Return LocalizeString("{{about_error_notapplicable}}")
|
|
|
|
+ ?
|
|
|
|
+ Return GetProcessOutput("g++", "-dumpversion").Split("~n")[0]
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method PopulateColumns( strHeadings$[], strValues$[] )
|
|
|
|
+
|
|
|
|
+ strHeadings = strHeadings[..lblLeftAligned.length]
|
|
|
|
+ strValues = strValues[..lblRightAligned.length]
|
|
|
|
+
|
|
|
|
+ For Local i:Int = 0 Until lblLeftAligned.length
|
|
|
|
+ LocalizeGadget( lblLeftAligned[i], strHeadings[i] )
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ For Local i:Int = 0 Until lblRightAligned.length
|
|
|
|
+ SetGadgetText( lblRightAligned[i], strValues[i] )
|
|
|
|
+ SetGadgetToolTip( lblRightAligned[i], strValues[i] )
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method Show()
|
|
|
|
+ PopulateText()
|
|
|
|
+ Super.Show()
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE
|
|
|
|
+ Hide()
|
|
|
|
+ EndIf
|
|
|
|
+ Case cancel
|
|
|
|
+ If EventID()=EVENT_GADGETACTION
|
|
|
|
+ Hide()
|
|
|
|
+ EndIf
|
|
|
|
+ Default
|
|
|
|
+ Return 0
|
|
|
|
+ End Select
|
|
|
|
+ Return 1
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TAboutRequester(host:TCodePlay)
|
|
|
|
+
|
|
|
|
+ Local abt:TAboutRequester = New TAboutRequester
|
|
|
|
+ abt.initrequester(host,"{{about_window_title}}",420,255,STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
|
|
|
|
+
|
|
|
|
+ Local win:TGadget = abt.window, w = ClientWidth(abt.window)-12, h = ClientHeight(abt.window)
|
|
|
|
+
|
|
|
|
+ abt.pnlLogo = CreatePanel(w-(64-6),0,64,64,win)
|
|
|
|
+ SetGadgetLayout abt.pnlLogo, EDGE_CENTERED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
|
|
|
|
+
|
|
|
|
+ 'abt.pnlLogo = CreatePanel(0,0,64,64,win)
|
|
|
|
+ 'SetGadgetLayout abt.pnlLogo, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED, EDGE_CENTERED
|
|
|
|
+
|
|
|
|
+ If Not pixLogo Then pixLogo = LoadPixmapPNG("incbin::bmxlogo.png")
|
|
|
|
+ SetGadgetPixmap abt.pnlLogo, pixLogo, PANELPIXMAP_CENTER
|
|
|
|
+
|
|
|
|
+ Local y = 12
|
|
|
|
+
|
|
|
|
+ abt.lblTitle = CreateLabel("MaxIDE "+IDE_VERSION,6,y,w,18,win,LABEL_LEFT)
|
|
|
|
+ SetGadgetFont abt.lblTitle, LookupGuiFont( GUIFONT_SYSTEM, 12, FONT_BOLD )
|
|
|
|
+ SetGadgetLayout abt.lblTitle, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
|
|
|
|
+ y:+19
|
|
|
|
+
|
|
|
|
+ abt.lblSubtitle = CreateLabel("Copyright Blitz Research Ltd.",6,y,w,22,win,LABEL_LEFT)
|
|
|
|
+ SetGadgetFont abt.lblSubtitle, LookupGuiFont( GUIFONT_SYSTEM, 10, FONT_ITALIC )
|
|
|
|
+ SetGadgetLayout abt.lblSubtitle, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED
|
|
|
|
+
|
|
|
|
+ y = 64
|
|
|
|
+
|
|
|
|
+ SetGadgetLayout( CreateLabel("",6,y,w,4,win,LABEL_SEPARATOR), EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED )
|
|
|
|
+
|
|
|
|
+ y:+(4+6)
|
|
|
|
+
|
|
|
|
+ Local tmpGadget:TGadget
|
|
|
|
+
|
|
|
|
+ For y = y Until (255-21) Step 22
|
|
|
|
+
|
|
|
|
+ tmpGadget = CreateLabel("",6,y,135,22,win,LABEL_LEFT)
|
|
|
|
+ SetGadgetLayout( tmpGadget, EDGE_ALIGNED, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_CENTERED )
|
|
|
|
+ abt.lblLeftAligned:+[tmpGadget]
|
|
|
|
+
|
|
|
|
+ tmpGadget = CreateLabel("",135+6,y,w-135,22,win,LABEL_LEFT)
|
|
|
|
+ SetGadgetLayout( tmpGadget, EDGE_RELATIVE, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED )
|
|
|
|
+ DelocalizeGadget tmpGadget
|
|
|
|
+ abt.lblRightAligned:+[tmpGadget]
|
|
|
|
+
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ abt.hypBlitz = CreateHyperlink("http://www.blitzbasic.com/",6,(h-28),200,26,win,LABEL_LEFT)
|
|
|
|
+ SetGadgetLayout abt.hypBlitz, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_CENTERED, EDGE_ALIGNED
|
|
|
|
+
|
|
|
|
+ Return abt
|
|
|
|
+
|
|
|
|
+ EndFunction
|
|
|
|
+
|
|
|
|
+ Function Spacer( height:Int, inpout:Int Var )
|
|
|
|
+ inpout:+height+6
|
|
|
|
+ Return height
|
|
|
|
+ EndFunction
|
|
|
|
+
|
|
|
|
+EndType
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Type TCmdLineRequester Extends TRequester
|
|
|
|
+ Field label:TGadget,textfield:TGadget
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE
|
|
|
|
+ Hide
|
|
|
|
+ EndIf
|
|
|
|
+ Case ok
|
|
|
|
+ If EventID()=EVENT_GADGETACTION
|
|
|
|
+ host.SetCommandLine TextFieldText(textfield)
|
|
|
|
+ Hide
|
|
|
|
+ EndIf
|
|
|
|
+ Case cancel
|
|
|
|
+ If EventID()=EVENT_GADGETACTION
|
|
|
|
+ SetGadgetText textfield,host.GetCommandLine()
|
|
|
|
+ Hide
|
|
|
|
+ EndIf
|
|
|
|
+ Default
|
|
|
|
+ Return 0
|
|
|
|
+ End Select
|
|
|
|
+ Return 1
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Show()
|
|
|
|
+ SetGadgetText textfield,host.GetCommandLine()
|
|
|
|
+ Super.Show()
|
|
|
|
+ ActivateGadget textfield
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TCmdLineRequester(host:TCodePlay)
|
|
|
|
+ Local cmd:TCmdLineRequester = New TCmdLineRequester
|
|
|
|
+ cmd.initrequester(host,"{{cmdline_window_title}}",260,60,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
|
|
|
|
+ cmd.label=CreateLabel("{{cmdline_label_cmdline}}:",6,8,260,20,cmd.window)
|
|
|
|
+ cmd.textfield=CreateTextField(6,30,ClientWidth(cmd.window)-12,21,cmd.window)
|
|
|
|
+ Return cmd
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TGotoRequester Extends TRequester
|
|
|
|
+ Field linenumber:TGadget
|
|
|
|
+
|
|
|
|
+ Method Show()
|
|
|
|
+ Super.Show()
|
|
|
|
+ ActivateGadget linenumber
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Local line,data,text$
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case linenumber
|
|
|
|
+ If EventID() = EVENT_GADGETACTION
|
|
|
|
+ text = GadgetText(linenumber)
|
|
|
|
+ If text And (Int(text) <> text) Then SetGadgetText linenumber, Int(text)
|
|
|
|
+ EndIf
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE
|
|
|
|
+ Hide
|
|
|
|
+ EndIf
|
|
|
|
+ Case ok
|
|
|
|
+ line=Int(GadgetText(linenumber))
|
|
|
|
+ Hide
|
|
|
|
+ host.activepanel.Invoke TOOLGOTO,String(line)
|
|
|
|
+ Case cancel
|
|
|
|
+ Hide
|
|
|
|
+ Default
|
|
|
|
+ Return 0
|
|
|
|
+ End Select
|
|
|
|
+ Return 1
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TGotoRequester(host:TCodePlay)
|
|
|
|
+ Local seek:TGotoRequester = New TGotoRequester
|
|
|
|
+ seek.initrequester(host,"{{goto_window_title}}",260,66,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL,"{{goto_btn_goto}}")
|
|
|
|
+ CreateLabel("{{goto_label_linenum}}:",6,8+4,114,20,seek.window)
|
|
|
|
+ seek.linenumber=CreateTextField(150,8,ClientWidth(seek.window)-(150+6),21,seek.window)
|
|
|
|
+ SetGadgetFilter( seek.linenumber, IntegerFilter )
|
|
|
|
+ Return seek
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function IntegerFilter:Int( event:TEvent, context:Object )
|
|
|
|
+ Select event.id
|
|
|
|
+ Case EVENT_KEYCHAR
|
|
|
|
+ If event.data >= Asc("0") And event.data <= Asc("9") Return True
|
|
|
|
+ If event.data = 8 Or event.data = 127 Or event.data = 13 Return True
|
|
|
|
+ Return False
|
|
|
|
+ Case EVENT_KEYDOWN
|
|
|
|
+ Return True
|
|
|
|
+ EndSelect
|
|
|
|
+ EndFunction
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TColor
|
|
|
|
+ Field red,green,blue
|
|
|
|
+
|
|
|
|
+ Method Set(rgb)
|
|
|
|
+ red=(rgb Shr 16)&$FF
|
|
|
|
+ green=(rgb Shr 8)&$FF
|
|
|
|
+ blue=rgb&$FF
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ToString$()
|
|
|
|
+ Return ""+red+","+green+","+blue
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FromString(s$)
|
|
|
|
+ Local p=s.Find(",")+1
|
|
|
|
+ If Not p Return
|
|
|
|
+ Local q=s.Find(",",p)+1
|
|
|
|
+ If Not q Return
|
|
|
|
+ red=Int(s[..p-1])
|
|
|
|
+ green=Int(s[p..q-1])
|
|
|
|
+ blue=Int(s[q..])
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Request()
|
|
|
|
+ If RequestColor(red,green,blue)
|
|
|
|
+ red=RequestedRed()
|
|
|
|
+ green=RequestedGreen()
|
|
|
|
+ blue=RequestedBlue()
|
|
|
|
+ Return True
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TTextStyle
|
|
|
|
+
|
|
|
|
+ Field label:TGadget,panel:TGadget,combo:TGadget
|
|
|
|
+ Field underline:TGadget, color:TColor
|
|
|
|
+ Field flags
|
|
|
|
+
|
|
|
|
+ Method Set(rgb,bolditalic)
|
|
|
|
+ color.set(rgb)
|
|
|
|
+ flags=bolditalic
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Format(textarea:TGadget,pos,length,emphasise:Int = False)
|
|
|
|
+ Local tmpFlags:Int = flags
|
|
|
|
+ If emphasise Then tmpFlags:|TEXTFORMAT_BOLD
|
|
|
|
+ FormatTextAreaText textarea,color.red,color.green,color.blue,tmpFlags,pos,length
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ToString$()
|
|
|
|
+ Return ""+color.red+","+color.green+","+color.blue+","+flags
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FromString(s$)
|
|
|
|
+ Local p,q,r
|
|
|
|
+ p=s.Find(",")+1;If Not p Return
|
|
|
|
+ q=s.Find(",",p)+1;If Not q Return
|
|
|
|
+ r=s.Find(",",q)+1;If Not r Return
|
|
|
|
+ color.red=Int(s[..p-1])
|
|
|
|
+ color.green=Int(s[p..q-1])
|
|
|
|
+ color.blue=Int(s[q..r-1])
|
|
|
|
+ flags=Int(s[r..])
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case panel
|
|
|
|
+ If EventID()=EVENT_MOUSEDOWN
|
|
|
|
+ Return color.Request()
|
|
|
|
+ EndIf
|
|
|
|
+ Case combo
|
|
|
|
+ flags=(flags&~3)|SelectedGadgetItem(combo)
|
|
|
|
+ Return True
|
|
|
|
+ Case underline
|
|
|
|
+ If EventData() Then flags:|TEXTFORMAT_UNDERLINE Else flags:&~TEXTFORMAT_UNDERLINE
|
|
|
|
+ Return True
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Refresh()
|
|
|
|
+ SetPanelColor panel,color.red,color.green,color.blue
|
|
|
|
+ SelectGadgetItem combo,flags&3
|
|
|
|
+ SetButtonState(underline,(flags&TEXTFORMAT_UNDERLINE <> 0))
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TTextStyle(name$,xpos,ypos,window:TGadget)
|
|
|
|
+ Local s:TTextStyle
|
|
|
|
+ s=New TTextStyle
|
|
|
|
+ s.color=New TColor
|
|
|
|
+ s.label=CreateLabel(name,xpos,ypos+4,90,24,window)
|
|
|
|
+ s.panel=CreatePanel(xpos+94,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE)
|
|
|
|
+ SetPanelColor s.panel,255,255,0
|
|
|
|
+ s.combo=CreateComboBox(xpos+122,ypos,96,24,window)
|
|
|
|
+ s.underline=CreateButton("{{txtstyle_underline}}",xpos+226,ypos,ClientWidth(window)-(xpos+220),24,window,BUTTON_CHECKBOX)
|
|
|
|
+ AddGadgetItem s.combo,"{{txtstyle_normal}}",GADGETITEM_LOCALIZED
|
|
|
|
+ AddGadgetItem s.combo,"{{txtstyle_bold}}",GADGETITEM_LOCALIZED
|
|
|
|
+ AddGadgetItem s.combo,"{{txtstyle_italic}}",GADGETITEM_LOCALIZED
|
|
|
|
+ AddGadgetItem s.combo,"{{txtstyle_bolditalic}}",GADGETITEM_LOCALIZED
|
|
|
|
+ Return s
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TGadgetStyle
|
|
|
|
+
|
|
|
|
+ Global fntLibrary:TGUIFont[] = [TGuiFont(Null), LookupGuiFont(GUIFONT_SYSTEM), LookupGuiFont(GUIFONT_MONOSPACED), ..
|
|
|
|
+ LookupGuiFont(GUIFONT_SANSSERIF), LookupGuiFont(GUIFONT_SERIF), ..
|
|
|
|
+ LookupGuiFont(GUIFONT_SCRIPT) ]
|
|
|
|
+
|
|
|
|
+ Field label:TGadget,fpanel:TGadget,bpanel:TGadget,fcombo:TGadget,fbutton:TGadget
|
|
|
|
+ Field font_name$, font_size:Double
|
|
|
|
+ Field fg:TColor, bg:TColor
|
|
|
|
+ Field font_type = GUIFONT_SYSTEM, font:TGUIFont = fntLibrary[font_type]
|
|
|
|
+
|
|
|
|
+ Method Apply(gadget:TGadget)
|
|
|
|
+ SetGadgetFont gadget,font
|
|
|
|
+ SetGadgetColor gadget,bg.red,bg.green,bg.blue,True
|
|
|
|
+ SetGadgetColor gadget,fg.red,fg.green,fg.blue,False
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Set(fg_rgb,bg_rgb,ftype,fname$="",fsize=0)
|
|
|
|
+ fg.set(fg_rgb)
|
|
|
|
+ bg.set(bg_rgb)
|
|
|
|
+ If Not fntLibrary[ftype] Then
|
|
|
|
+ font_name=fname
|
|
|
|
+ font_size=fsize
|
|
|
|
+ Else
|
|
|
|
+ font_name=FontName(fntLibrary[ftype])
|
|
|
|
+ font_size=FontSize(fntLibrary[ftype])
|
|
|
|
+ EndIf
|
|
|
|
+ font_type=ftype
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ToString$()
|
|
|
|
+ Return font_name+","+font_size+","+fg.ToString()+","+bg.ToString()+","+font_type
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function GetArg$(a$ Var)
|
|
|
|
+ Local p = a.Find(",")
|
|
|
|
+ If p=-1 Then p=a.length
|
|
|
|
+ Local r$ = a$[..p]
|
|
|
|
+ a$=a$[p+1..]
|
|
|
|
+ Return r$
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method FromString(s$)
|
|
|
|
+ font_name=GetArg(s$)
|
|
|
|
+ font_size=Double(GetArg(s$))
|
|
|
|
+ fg.red=Int(GetArg(s$))
|
|
|
|
+ fg.green=Int(GetArg(s$))
|
|
|
|
+ fg.blue=Int(GetArg(s$))
|
|
|
|
+ bg.red=Int(GetArg(s$))
|
|
|
|
+ bg.green=Int(GetArg(s$))
|
|
|
|
+ bg.blue=Int(GetArg(s$))
|
|
|
|
+ font_type=Int(GetArg(s$))
|
|
|
|
+ If fntLibrary[font_type] Then
|
|
|
|
+ font_name=FontName(fntLibrary[font_type])
|
|
|
|
+ font_size=FontSize(fntLibrary[font_type])
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Local f:TGUIFont
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case fpanel
|
|
|
|
+ If EventID()=EVENT_MOUSEDOWN
|
|
|
|
+ Return fg.Request()
|
|
|
|
+ EndIf
|
|
|
|
+ Case bpanel
|
|
|
|
+ If EventID()=EVENT_MOUSEDOWN
|
|
|
|
+ Return bg.Request()
|
|
|
|
+ EndIf
|
|
|
|
+ Case fcombo, fbutton
|
|
|
|
+ If EventSource() = fcombo Then
|
|
|
|
+ If Not (EventData() < 0) Then
|
|
|
|
+ font_type = EventData()
|
|
|
|
+ f = fntLibrary[font_type]
|
|
|
|
+ EndIf
|
|
|
|
+ Else
|
|
|
|
+ font_type = 0
|
|
|
|
+ SelectGadgetItem fcombo, font_type
|
|
|
|
+ EndIf
|
|
|
|
+ If Not f Then f=RequestFont(font)
|
|
|
|
+ If f
|
|
|
|
+ font_name=FontName(f)
|
|
|
|
+ font_size=FontSize(f)
|
|
|
|
+ Return True
|
|
|
|
+ EndIf
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Refresh()
|
|
|
|
+ font=fntLibrary[font_type]
|
|
|
|
+ If Not font Then font=LoadGuiFont(font_name,font_size)
|
|
|
|
+ SetPanelColor fpanel,fg.red,fg.green,fg.blue
|
|
|
|
+ SetPanelColor bpanel,bg.red,bg.green,bg.blue
|
|
|
|
+ SelectGadgetItem fcombo, font_type
|
|
|
|
+ Local tmpFloatText$[] = String(font_size).Split(".")
|
|
|
|
+ If tmpFloatText.length > 1 Then tmpFloatText[1] = tmpFloatText[1][..Min(2,tmpFloatText[1].length)]
|
|
|
|
+ SetGadgetText fbutton,font_name+" : "+".".Join(tmpFloatText)+"pt"
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TGadgetStyle(name$,xpos,ypos,window:TGadget)
|
|
|
|
+ Local s:TGadgetStyle
|
|
|
|
+ s=New TGadgetStyle
|
|
|
|
+ s.fg=New TColor
|
|
|
|
+ s.bg=New TColor
|
|
|
|
+ s.label=CreateLabel(name,xpos,ypos+LABELOFFSET,66,50,window)
|
|
|
|
+ s.fpanel=CreatePanel(xpos+68,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE)
|
|
|
|
+ s.bpanel=CreatePanel(xpos+96,ypos,24,24,window,PANEL_BORDER|PANEL_ACTIVE)
|
|
|
|
+ s.fbutton=CreateButton("..",xpos+122,ypos+30,ClientWidth(window)-(xpos+128),24,window)
|
|
|
|
+ s.fcombo=CreateComboBox(xpos+122,ypos,ClientWidth(window)-(xpos+128),24,window)
|
|
|
|
+ AddGadgetItem s.fcombo, "{{options_font_desc_user}}", GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED
|
|
|
|
+ AddGadgetItem s.fcombo, "{{options_font_desc_guidefault}}", GADGETITEM_LOCALIZED
|
|
|
|
+ AddGadgetItem s.fcombo, "{{options_font_desc_monospaced}}", GADGETITEM_LOCALIZED
|
|
|
|
+ AddGadgetItem s.fcombo, "{{options_font_desc_sansserif}}", GADGETITEM_LOCALIZED
|
|
|
|
+ AddGadgetItem s.fcombo, "{{options_font_desc_serif}}", GADGETITEM_LOCALIZED
|
|
|
|
+ AddGadgetItem s.fcombo, "{{options_font_desc_script}}", GADGETITEM_LOCALIZED
|
|
|
|
+ Return s
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Const NORMAL=0
|
|
|
|
+Const COMMENT=1
|
|
|
|
+Const QUOTED=2
|
|
|
|
+Const KEYWORD=3
|
|
|
|
+Const NUMBER=4
|
|
|
|
+Const MATCHING=5
|
|
|
|
+
|
|
|
|
+Type TOptionsRequester Extends TPanelRequester
|
|
|
|
+' panels
|
|
|
|
+ Field optionspanel:TGadget,editorpanel:TGadget,toolpanel:TGadget
|
|
|
|
+' settings
|
|
|
|
+ Field showtoolbar,restoreopenfiles,autocapitalize,syntaxhighlight,autobackup,autoindent,hideoutput
|
|
|
|
+ Field bracketmatching, externalhelp,systemkeys,sortcode
|
|
|
|
+ Field tabsize,language$
|
|
|
|
+ Field editfontname$,editfontsize,editcolor:TColor
|
|
|
|
+ Field outputfontname$,outputfontsize,outputcolor:TColor
|
|
|
|
+' states
|
|
|
|
+ Field editfont:TGUIFont
|
|
|
|
+' gadgets
|
|
|
|
+ Field languages:TGadget
|
|
|
|
+ Field tabbutton:TGadget
|
|
|
|
+ Field editpanel:TGadget,editbutton:TGadget
|
|
|
|
+ Field buttons:TGadget[11]
|
|
|
|
+ Field styles:TTextStyle[]
|
|
|
|
+ Field textarea:TGadget
|
|
|
|
+ Field outputstyle:TGadgetStyle
|
|
|
|
+ Field navstyle:TGadgetStyle
|
|
|
|
+ Field dirty
|
|
|
|
+ Field undo:TBank
|
|
|
|
+
|
|
|
|
+ Method Show()
|
|
|
|
+ RefreshGadgets()
|
|
|
|
+ Super.Show()
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method Snapshot()
|
|
|
|
+ If Not undo undo=CreateBank(8192)
|
|
|
|
+ Local stream:TStream=CreateBankStream(undo)
|
|
|
|
+ write stream
|
|
|
|
+ stream.close
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Restore()
|
|
|
|
+ If Not undo Return
|
|
|
|
+ Local stream:TStream=CreateBankStream(undo)
|
|
|
|
+ Read stream
|
|
|
|
+ stream.close
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetDefaults()
|
|
|
|
+ language=DEFAULT_LANGUAGEPATH
|
|
|
|
+ bracketmatching=True
|
|
|
|
+ showtoolbar=True
|
|
|
|
+ restoreopenfiles=True
|
|
|
|
+ autocapitalize=True
|
|
|
|
+ syntaxhighlight=True
|
|
|
|
+ autobackup=True
|
|
|
|
+ autoindent=True
|
|
|
|
+ tabsize=4
|
|
|
|
+ editfontname$=FontName(TGadgetStyle.fntLibrary[GUIFONT_MONOSPACED])
|
|
|
|
+ editfontsize=FontSize(TGadgetStyle.fntLibrary[GUIFONT_MONOSPACED])
|
|
|
|
+ editcolor.set( $334455 )
|
|
|
|
+ styles[NORMAL].set( $ffffff,0 )
|
|
|
|
+ styles[COMMENT].set( $bbeeff,0 )
|
|
|
|
+ styles[QUOTED].set( $00ff66,0 )
|
|
|
|
+ styles[KEYWORD].set( $ffff00,0 )
|
|
|
|
+ styles[NUMBER].set( $40ffff,0 )
|
|
|
|
+ styles[MATCHING].set( $ff4040,TEXTFORMAT_BOLD )
|
|
|
|
+ outputstyle.set(0,-1,GUIFONT_MONOSPACED)
|
|
|
|
+ navstyle.set(0,-1,GUIFONT_SYSTEM)
|
|
|
|
+ RefreshGadgets
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Write(stream:TStream)
|
|
|
|
+ stream.WriteLine "[Options]"
|
|
|
|
+ stream.WriteLine "language="+language
|
|
|
|
+ stream.WriteLine "showtoolbar="+showtoolbar
|
|
|
|
+ stream.WriteLine "restoreopenfiles="+restoreopenfiles
|
|
|
|
+ stream.WriteLine "autocapitalize="+autocapitalize
|
|
|
|
+ stream.WriteLine "syntaxhighlight="+syntaxhighlight
|
|
|
|
+ stream.WriteLine "bracketmatching="+bracketmatching
|
|
|
|
+ stream.WriteLine "autobackup="+autobackup
|
|
|
|
+ stream.WriteLine "autoindent="+autoindent
|
|
|
|
+ stream.WriteLine "tabsize="+tabsize
|
|
|
|
+ stream.WriteLine "editfontname="+editfontname
|
|
|
|
+ stream.WriteLine "editfontsize="+editfontsize
|
|
|
|
+ stream.WriteLine "editcolor="+editcolor.ToString()
|
|
|
|
+ stream.WriteLine "normal_style="+styles[NORMAL].ToString()
|
|
|
|
+ stream.WriteLine "comment_style="+styles[COMMENT].ToString()
|
|
|
|
+ stream.WriteLine "quote_style="+styles[QUOTED].ToString()
|
|
|
|
+ stream.WriteLine "keyword_style="+styles[KEYWORD].ToString()
|
|
|
|
+ stream.WriteLine "number_style="+styles[NUMBER].ToString()
|
|
|
|
+ stream.WriteLine "matched_style="+styles[MATCHING].ToString()
|
|
|
|
+ stream.WriteLine "console_style="+outputstyle.ToString() 'Renamed from 'output_style' to bump users to default monospace font.
|
|
|
|
+ stream.WriteLine "navi_style="+navstyle.ToString() 'Renamed from 'nav_style' to bump users to default treeview font.
|
|
|
|
+ stream.WriteLine "hide_output="+hideoutput
|
|
|
|
+ stream.WriteLine "external_help="+externalhelp
|
|
|
|
+ stream.WriteLine "system_keys="+systemkeys
|
|
|
|
+ stream.WriteLine "sort_code="+sortcode
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Read(stream:TStream)
|
|
|
|
+ Local f$,p,a$,b$,t
|
|
|
|
+ While Not stream.Eof()
|
|
|
|
+ f$=stream.ReadLine()
|
|
|
|
+ If f$="" Or (f$[..1]="[" And f$<>"[Options]") Exit
|
|
|
|
+ p=f.find("=")
|
|
|
|
+ a$=f[..p]
|
|
|
|
+ b$=f[p+1..]
|
|
|
|
+ t=Int(b)
|
|
|
|
+ Select a$
|
|
|
|
+ Case "showtoolbar" showtoolbar=t
|
|
|
|
+ Case "restoreopenfiles" restoreopenfiles=t
|
|
|
|
+ Case "autocapitalize" autocapitalize=t
|
|
|
|
+ Case "syntaxhighlight" syntaxhighlight=t
|
|
|
|
+ Case "bracketmatching" bracketmatching=t
|
|
|
|
+ Case "autobackup" autobackup=t
|
|
|
|
+ Case "autoindent" autoindent=t
|
|
|
|
+ Case "tabsize" tabsize=t
|
|
|
|
+ Case "editfontname" editfontname=b
|
|
|
|
+ Case "editfontsize" editfontsize=t
|
|
|
|
+ Case "editcolor" editcolor.FromString(b)
|
|
|
|
+ Case "normal_style" styles[NORMAL].FromString(b)
|
|
|
|
+ Case "comment_style" styles[COMMENT].FromString(b)
|
|
|
|
+ Case "quote_style" styles[QUOTED].FromString(b)
|
|
|
|
+ Case "keyword_style" styles[KEYWORD].FromString(b)
|
|
|
|
+ Case "number_style" styles[NUMBER].FromString(b)
|
|
|
|
+ Case "matched_style" styles[MATCHING].FromString(b)
|
|
|
|
+ Case "console_style" outputstyle.FromString(b) 'Renamed from 'output_style' to bump users to default monospace font.
|
|
|
|
+ Case "navi_style" navstyle.FromString(b) 'Renamed from 'nav_style' to bump users to default treeview font.
|
|
|
|
+ Case "hide_output" hideoutput=t
|
|
|
|
+ Case "external_help" externalhelp=t
|
|
|
|
+ Case "system_keys" systemkeys=t
|
|
|
|
+ Case "sort_code" sortcode=t
|
|
|
|
+ Case "language"
|
|
|
|
+ Try
|
|
|
|
+ Local tmpLanguage:TMaxGUILanguage = LoadLanguage(host.FullPath(b))
|
|
|
|
+ If tmpLanguage Then
|
|
|
|
+ language = b
|
|
|
|
+ SetLocalizationLanguage tmpLanguage
|
|
|
|
+ host.RefreshMenu()
|
|
|
|
+ EndIf
|
|
|
|
+ Catch excn:Object
|
|
|
|
+ EndTry
|
|
|
|
+ End Select
|
|
|
|
+ Wend
|
|
|
|
+ RefreshGadgets
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RefreshGadgets()
|
|
|
|
+ Local rgb:TColor,flags
|
|
|
|
+ editfont=LoadGuiFont(editfontname,editfontsize)
|
|
|
|
+
|
|
|
|
+ 'Language Loading / Enumeration
|
|
|
|
+ ClearGadgetItems languages
|
|
|
|
+ AddGadgetItem languages, "English (English) [Embedded]", GADGETITEM_DEFAULT,-1,"",DEFAULT_LANGUAGEPATH
|
|
|
|
+ For Local tmpFile$ = EachIn LoadDir( host.bmxpath+"/cfg", True )
|
|
|
|
+ Local tmpPath$ = host.bmxpath+"/cfg/"+tmpFile
|
|
|
|
+ If FileType(tmpPath) = FILETYPE_FILE And tmpFile.ToLower().EndsWith(".language.ini") Then
|
|
|
|
+ If tmpPath = host.FullPath(language) Then flags = GADGETITEM_DEFAULT Else flags = 0
|
|
|
|
+ AddGadgetItem languages, tmpFile.Split(".")[0], flags, -1, "", "$BMXPATH/cfg/"+tmpFile
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ SetButtonState buttons[0],showtoolbar
|
|
|
|
+ SetButtonState buttons[1],restoreopenfiles
|
|
|
|
+ SetButtonState buttons[2],autocapitalize
|
|
|
|
+ SetButtonState buttons[3],syntaxhighlight
|
|
|
|
+ SetButtonState buttons[4],bracketmatching
|
|
|
|
+ SetButtonState buttons[5],autobackup
|
|
|
|
+ SetButtonState buttons[6],autoindent
|
|
|
|
+ SetButtonState buttons[7],hideoutput
|
|
|
|
+ SetButtonState buttons[8],externalhelp
|
|
|
|
+ SetButtonState buttons[9],systemkeys
|
|
|
|
+ SetButtonState buttons[10],sortcode
|
|
|
|
+ SelectGadgetItem tabbutton,Min(Max(tabsize/2-1,0),7)
|
|
|
|
+ SetPanelColor editpanel,editcolor.red,editcolor.green,editcolor.blue
|
|
|
|
+ SetGadgetText editbutton,editfontname+" : "+editfontsize + "pt"
|
|
|
|
+ For Local i:Int = 0 Until styles.length
|
|
|
|
+ styles[i].Refresh
|
|
|
|
+ Next
|
|
|
|
+ LockTextArea textarea
|
|
|
|
+ SetTextAreaColor textarea,editcolor.red,editcolor.green,editcolor.blue,True
|
|
|
|
+ SetGadgetFont textarea,editfont
|
|
|
|
+ styles[NORMAL].format(textarea,0,TEXTAREA_ALL)
|
|
|
|
+ styles[COMMENT].format(textarea,0,12)
|
|
|
|
+ styles[MATCHING].format(textarea,24,1)
|
|
|
|
+ styles[NUMBER].format(textarea,25,3)
|
|
|
|
+ styles[NUMBER].format(textarea,31,1)
|
|
|
|
+ styles[MATCHING].format(textarea,32,1)
|
|
|
|
+ styles[NUMBER].format(textarea,36,1)
|
|
|
|
+ styles[KEYWORD].format(textarea,39,5)
|
|
|
|
+ styles[QUOTED].format(textarea,46,10)
|
|
|
|
+ UnlockTextArea textarea
|
|
|
|
+ outputstyle.Refresh
|
|
|
|
+ navstyle.Refresh
|
|
|
|
+ dirty=True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Local font:TGUIFont,refresh,processed = 1
|
|
|
|
+ For Local i:Int = 0 Until styles.length
|
|
|
|
+ refresh:|styles[i].Poll()
|
|
|
|
+ Next
|
|
|
|
+ refresh:|outputstyle.Poll()
|
|
|
|
+ refresh:|navstyle.Poll()
|
|
|
|
+ Select EventID()
|
|
|
|
+ Case EVENT_GADGETACTION, EVENT_WINDOWCLOSE
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case buttons[0];showtoolbar=ButtonState(buttons[0]);dirty=True
|
|
|
|
+ Case buttons[1];restoreopenfiles=ButtonState(buttons[1])
|
|
|
|
+ Case buttons[2];autocapitalize=ButtonState(buttons[2]);dirty=True
|
|
|
|
+ Case buttons[3];syntaxhighlight=ButtonState(buttons[3]);dirty=True
|
|
|
|
+ Case buttons[4];bracketmatching=ButtonState(buttons[4])
|
|
|
|
+ Case buttons[5];autobackup=ButtonState(buttons[5])
|
|
|
|
+ Case buttons[6];autoindent=ButtonState(buttons[6])
|
|
|
|
+ Case buttons[7];hideoutput=ButtonState(buttons[7])
|
|
|
|
+ Case buttons[8];externalhelp=ButtonState(buttons[8])
|
|
|
|
+ Case buttons[9];systemkeys=ButtonState(buttons[9]);dirty=2
|
|
|
|
+ Case buttons[10];sortcode=ButtonState(buttons[10]);dirty=3
|
|
|
|
+ Case tabber;SetPanelIndex SelectedGadgetItem(tabber)
|
|
|
|
+ Case ok
|
|
|
|
+ Hide()
|
|
|
|
+ Select dirty
|
|
|
|
+ Case 1
|
|
|
|
+ host.RefreshAll
|
|
|
|
+ Case 2
|
|
|
|
+ host.Restart
|
|
|
|
+ End Select
|
|
|
|
+ dirty=False
|
|
|
|
+ SnapShot()
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE
|
|
|
|
+ Restore()
|
|
|
|
+ dirty=False
|
|
|
|
+ Hide()
|
|
|
|
+ EndIf
|
|
|
|
+ Case cancel
|
|
|
|
+ Restore()
|
|
|
|
+ dirty=False
|
|
|
|
+ Hide()
|
|
|
|
+ Case tabbutton
|
|
|
|
+ tabsize=(SelectedGadgetItem(tabbutton)+1)*2
|
|
|
|
+ refresh=True
|
|
|
|
+ Case editpanel
|
|
|
|
+ If EventID()=EVENT_MOUSEDOWN
|
|
|
|
+ refresh=editcolor.Request()
|
|
|
|
+ EndIf
|
|
|
|
+ Case editbutton
|
|
|
|
+ font=RequestFont(editfont)
|
|
|
|
+ If font
|
|
|
|
+ editfontname=FontName(font)
|
|
|
|
+ editfontsize=FontSize(font)
|
|
|
|
+ refresh=True
|
|
|
|
+ EndIf
|
|
|
|
+ Case languages
|
|
|
|
+ If EventData() > 0 Then
|
|
|
|
+ language = String(GadgetItemExtra(languages,EventData()))
|
|
|
|
+ SetLocalizationLanguage TMaxGUILanguage(LoadLanguage(host.FullPath(language)))
|
|
|
|
+ Else
|
|
|
|
+ language = DEFAULT_LANGUAGEPATH
|
|
|
|
+ SetLocalizationLanguage defaultLanguage
|
|
|
|
+ EndIf
|
|
|
|
+ host.RefreshMenu()
|
|
|
|
+ Default
|
|
|
|
+ processed = 0
|
|
|
|
+ EndSelect
|
|
|
|
+ Case EVENT_MOUSEDOWN
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case editpanel
|
|
|
|
+ If EventID()=EVENT_MOUSEDOWN
|
|
|
|
+ editcolor.Request()
|
|
|
|
+ refresh=True
|
|
|
|
+ EndIf
|
|
|
|
+ Default
|
|
|
|
+ processed = 0
|
|
|
|
+ EndSelect
|
|
|
|
+ EndSelect
|
|
|
|
+ If refresh Then RefreshGadgets()
|
|
|
|
+ Return processed
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method InitOptionsRequester(host:TCodePlay)
|
|
|
|
+ Local w:TGadget
|
|
|
|
+ InitPanelRequester(host,"{{options_window_title}}",380,430)
|
|
|
|
+' init values
|
|
|
|
+ editcolor=New TColor
|
|
|
|
+' init gadgets
|
|
|
|
+ optionspanel=AddPanel("{{options_optionstab}}")
|
|
|
|
+ editorpanel=AddPanel("{{options_editortab}}")
|
|
|
|
+ toolpanel=AddPanel("{{options_toolstab}}")
|
|
|
|
+
|
|
|
|
+ SetGadgetShape( tabber, GadgetX(tabber), GadgetY(tabber)+32, GadgetWidth(tabber), GadgetHeight(tabber)-32 )
|
|
|
|
+
|
|
|
|
+ w=window
|
|
|
|
+ CreateLabel("{{options_options_label_language}}:",6,6+4,80,24,w)
|
|
|
|
+ languages = CreateComboBox(90,6,ClientWidth(w)-96,26,w)
|
|
|
|
+
|
|
|
|
+ w=optionspanel
|
|
|
|
+
|
|
|
|
+ buttons[0]=CreateButton("{{options_options_btn_showtoolbar}}",6,6,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[1]=CreateButton("{{options_options_btn_autorestore}}",6,34,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[2]=CreateButton("{{options_options_btn_autocaps}}",6,60,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[3]=CreateButton("{{options_options_btn_syntaxhighlight}}",6,86,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[4]=CreateButton("{{options_options_btn_bracketmatching}}",6,112,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[5]=CreateButton("{{options_options_btn_autobackup}}",6,138,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[6]=CreateButton("{{options_options_btn_autoindent}}",6,164,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[7]=CreateButton("{{options_options_btn_autohideoutput}}",6,190,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[8]=CreateButton("{{options_options_btn_useexternalbrowser}}",6,216,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[9]=CreateButton("{{options_options_btn_osshortcuts}}",6,242,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+ buttons[10]=CreateButton("{{options_options_btn_sortcodeviewnodes}}",6,268,ClientWidth(w)-12,26,w,BUTTON_CHECKBOX)
|
|
|
|
+
|
|
|
|
+ w=editorpanel
|
|
|
|
+ CreateLabel("{{options_editor_label_background}}:",6,6+4,90,24,w)
|
|
|
|
+ editpanel=CreatePanel(100,6,24,24,w,PANEL_BORDER|PANEL_ACTIVE)
|
|
|
|
+ editbutton=CreateButton("..",128,6,ClientWidth(w)-134,24,w)
|
|
|
|
+
|
|
|
|
+ tabbutton=CreateComboBox(128,36,ClientWidth(w)-134,24,w)
|
|
|
|
+ For Local i=1 To 8
|
|
|
|
+ AddGadgetItem tabbutton,"{{options_editor_itemlabel_tabsize}} "+(i*2),GADGETITEM_LOCALIZED
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ styles=New TTextStyle[6]
|
|
|
|
+ styles[NORMAL]=TTextStyle.Create("{{options_editor_label_plaintext}}:",6,66,w)
|
|
|
|
+ styles[COMMENT]=TTextStyle.Create("{{options_editor_label_remarks}}:",6,96,w)
|
|
|
|
+ styles[QUOTED]=TTextStyle.Create("{{options_editor_label_strings}}:",6,126,w)
|
|
|
|
+ styles[KEYWORD]=TTextStyle.Create("{{options_editor_label_keywords}}:",6,156,w)
|
|
|
|
+ styles[NUMBER]=TTextStyle.Create("{{options_editor_label_numbers}}:",6,186,w)
|
|
|
|
+ styles[MATCHING]=TTextStyle.Create("{{options_editor_label_matchings}}:",6,216,w)
|
|
|
|
+
|
|
|
|
+ textarea=CreateTextArea(6,250,ClientWidth(w)-12,ClientHeight(w)-256,w,TEXTAREA_READONLY)
|
|
|
|
+ SetGadgetText textarea,"'Sample Code~n~nresult = ((2.0 * 4) + 1)~nPrint( ~qResult: ~q + result )~n"
|
|
|
|
+
|
|
|
|
+ w=toolpanel
|
|
|
|
+ outputstyle=TGadgetStyle.Create("{{options_tools_label_output}}: ",6,6,w)
|
|
|
|
+ navstyle=TGadgetStyle.Create("{{options_tools_label_navbar}}: ",6,66,w)
|
|
|
|
+
|
|
|
|
+ SetDefaults()
|
|
|
|
+ SetPanel optionspanel
|
|
|
|
+
|
|
|
|
+ SnapShot
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TOptionsRequester(host:TCodePlay)
|
|
|
|
+ Local o:TOptionsRequester
|
|
|
|
+ o=New TOptionsRequester
|
|
|
|
+ o.InitOptionsRequester host
|
|
|
|
+ Return o
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TFindRequester Extends TRequester
|
|
|
|
+ Field findterm:TGadget
|
|
|
|
+
|
|
|
|
+ Method ShowFind(term$="")
|
|
|
|
+ If term SetGadgetText(findterm,term)
|
|
|
|
+ Super.Show()
|
|
|
|
+ ActivateGadget findterm
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Local find$,data
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE
|
|
|
|
+ Hide()
|
|
|
|
+ EndIf
|
|
|
|
+ Case ok
|
|
|
|
+ If EventID() = EVENT_GADGETACTION
|
|
|
|
+ If TextFieldText(findterm)
|
|
|
|
+ find=TextFieldText(findterm)
|
|
|
|
+ Hide()
|
|
|
|
+ host.activepanel.Invoke TOOLFINDNEXT,find
|
|
|
|
+ Else
|
|
|
|
+ Notify LocalizeString("{{search_error_nosearchstring}}"), True
|
|
|
|
+ ActivateGadget findterm
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Case cancel
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then Hide()
|
|
|
|
+ Default
|
|
|
|
+ Return 0
|
|
|
|
+ End Select
|
|
|
|
+ Return 1
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TFindRequester(host:TCodePlay)
|
|
|
|
+ Local seek:TFindRequester
|
|
|
|
+ seek=New TFindRequester
|
|
|
|
+ seek.initrequester(host,"{{find_window_title}}",280,66,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL,"{{find_btn_find}}")
|
|
|
|
+ CreateLabel("{{find_label_find}}:",6,12,82,24,seek.window)
|
|
|
|
+ seek.findterm=CreateTextField(88,8,ClientWidth(seek.window)-(88+6),21,seek.window)
|
|
|
|
+ Return seek
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TReplaceRequester Extends TRequester
|
|
|
|
+ Field findterm:TGadget,replaceterm:TGadget
|
|
|
|
+ Field findnext:TGadget,replaceit:TGadget,replaceall:TGadget
|
|
|
|
+
|
|
|
|
+ Method Show()
|
|
|
|
+ Super.Show()
|
|
|
|
+ ActivateGadget findterm
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Local find$,Replace$
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE
|
|
|
|
+ Hide()
|
|
|
|
+ EndIf
|
|
|
|
+ Case cancel
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then Hide
|
|
|
|
+ Case ok
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then
|
|
|
|
+ If TextFieldText(findterm) Then
|
|
|
|
+ find=TextFieldText(findterm)
|
|
|
|
+ host.activepanel.Invoke TOOLFINDNEXT,find
|
|
|
|
+ Else
|
|
|
|
+ Notify LocalizeString("{{search_error_nosearchstring}}"), True
|
|
|
|
+ ActivateGadget findterm
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Case replaceit
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then
|
|
|
|
+ Replace=TextFieldText(replaceterm)
|
|
|
|
+ If host.activepanel.Invoke(TOOLREPLACE,Replace)
|
|
|
|
+ host.activepanel.Invoke TOOLFINDNEXT,find
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Case replaceall
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then
|
|
|
|
+ find=TextFieldText(findterm)
|
|
|
|
+ Replace=TextFieldText(replaceterm)
|
|
|
|
+ host.activepanel.Invoke TOOLREPLACE,find+Chr(0)+Replace
|
|
|
|
+ EndIf
|
|
|
|
+ Default
|
|
|
|
+ Return 0
|
|
|
|
+ End Select
|
|
|
|
+ Return 1
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TReplaceRequester(host:TCodePlay)
|
|
|
|
+ Local x,y
|
|
|
|
+ Local seek:TReplaceRequester
|
|
|
|
+ seek=New TReplaceRequester
|
|
|
|
+ seek.initrequester(host,"{{replace_window_title}}",380,80,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER,"{{replace_btn_findnext}}")
|
|
|
|
+
|
|
|
|
+ y=11
|
|
|
|
+ CreateLabel( "{{replace_label_find}}:",6,y+4,88,24,seek.window )
|
|
|
|
+ seek.findterm=CreateTextField( 96,y,168,21,seek.window )
|
|
|
|
+
|
|
|
|
+ y:+32
|
|
|
|
+ CreateLabel( "{{replace_label_replacewith}}:",6,y+4,88,24,seek.window )
|
|
|
|
+ seek.replaceterm=CreateTextField( 96,y,168,21,seek.window )
|
|
|
|
+
|
|
|
|
+ x=ClientWidth(seek.window)-102
|
|
|
|
+ y=8
|
|
|
|
+ seek.replaceit=CreateButton("{{replace_btn_replace}}",x,y,96,26,seek.window)
|
|
|
|
+ seek.replaceall=CreateButton("{{replace_btn_replaceall}}",x,y+32,96,26,seek.window)
|
|
|
|
+
|
|
|
|
+ Return seek
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TEventHandler Extends TTool
|
|
|
|
+ Method OnEvent() Abstract
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TToolPanel Extends TEventHandler
|
|
|
|
+ Field name$,path$
|
|
|
|
+ Field panel:TGadget
|
|
|
|
+ Field index
|
|
|
|
+ Field active
|
|
|
|
+
|
|
|
|
+ Method Show()
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TView
|
|
|
|
+ Field node:TGadget
|
|
|
|
+ Field state
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TNode Extends TTool
|
|
|
|
+ Const HIDESTATE=0
|
|
|
|
+ Const CLOSEDSTATE=1
|
|
|
|
+ Const OPENSTATE=2
|
|
|
|
+
|
|
|
|
+ Field name$,sortname$
|
|
|
|
+ Field parent:TNode
|
|
|
|
+ Field kids:TList=New TList
|
|
|
|
+ Field views:TView[]
|
|
|
|
+' activate program
|
|
|
|
+ Field target:TTool
|
|
|
|
+ Field action
|
|
|
|
+ Field argument:Object
|
|
|
|
+
|
|
|
|
+ Method SortKids( ascending=True )
|
|
|
|
+ Local term:TLink=kids._head
|
|
|
|
+ Repeat
|
|
|
|
+ Local link:TLink=kids._head._succ
|
|
|
|
+ Local sorted=True
|
|
|
|
+ Repeat
|
|
|
|
+ Local succ:TLink=link._succ
|
|
|
|
+ If succ=term Exit
|
|
|
|
+ Local cc=TNode(link._value).sortname.Compare( TNode(succ._value).sortname )
|
|
|
|
+ If (cc>0 And ascending) Or (cc<0 And Not ascending)
|
|
|
|
+ Local link_pred:TLink=link._pred
|
|
|
|
+ Local succ_succ:TLink=succ._succ
|
|
|
|
+ link_pred._succ=succ
|
|
|
|
+ succ._succ=link
|
|
|
|
+ succ._pred=link_pred
|
|
|
|
+ link._succ=succ_succ
|
|
|
|
+ link._pred=succ
|
|
|
|
+ succ_succ._pred=link
|
|
|
|
+ sorted=False
|
|
|
|
+ Else
|
|
|
|
+ link=succ
|
|
|
|
+ EndIf
|
|
|
|
+ Forever
|
|
|
|
+ If sorted Return
|
|
|
|
+ term=link
|
|
|
|
+ Forever
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FindArgument:TNode(arg:Object)
|
|
|
|
+ Local n:TNode,r:TNode,a$
|
|
|
|
+ If arg.Compare(argument)=0 Return Self
|
|
|
|
+ a$=(String(arg)).ToLower()
|
|
|
|
+ If a And a=(String(argument)).toLower() Return Self
|
|
|
|
+ For n=EachIn kids
|
|
|
|
+ r=n.FindArgument(arg)
|
|
|
|
+ If r Return r
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ ?Debug
|
|
|
|
+ Method Dump(indent$="")
|
|
|
|
+ Local n:TNode
|
|
|
|
+ Print indent+name
|
|
|
|
+ indent:+"~t"
|
|
|
|
+ For n=EachIn kids
|
|
|
|
+ n.Dump indent
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+ ?
|
|
|
|
+
|
|
|
|
+ Method IsHidden()
|
|
|
|
+ Local v:TView
|
|
|
|
+ If Not parent Return False
|
|
|
|
+ For v=EachIn parent.views
|
|
|
|
+ If v.state=OPENSTATE Return False
|
|
|
|
+ Next
|
|
|
|
+ Return True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetAction(tool:TTool,cmd,arg:Object=Null)
|
|
|
|
+ target=tool
|
|
|
|
+ action=cmd
|
|
|
|
+ argument=arg
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Hide(v:TView=Null) 'null means hide in all views
|
|
|
|
+ For Local n:TNode = EachIn kids
|
|
|
|
+ n.hide v
|
|
|
|
+ Next
|
|
|
|
+ If v
|
|
|
|
+ If v.node FreeTreeViewNode v.node;v.node=Null
|
|
|
|
+ Else
|
|
|
|
+ For v=EachIn views
|
|
|
|
+ If v.node FreeTreeViewNode v.node;v.node=Null
|
|
|
|
+ Next
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Detach()
|
|
|
|
+ Hide()
|
|
|
|
+ If parent parent.kids.remove Self;parent=Null
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FreeKids()
|
|
|
|
+ For Local n:TNode = EachIn kids
|
|
|
|
+ n.free
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Free()
|
|
|
|
+ FreeKids()
|
|
|
|
+ Detach()
|
|
|
|
+ target=Null;argument=Null;views=Null
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,arg:Object=Null)
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLACTIVATE
|
|
|
|
+ If target Return target.Invoke(action,argument)
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Find:TNode(treeviewnode:TGadget,view=0)
|
|
|
|
+ Local n:TNode,r:TNode
|
|
|
|
+ Local v:TView
|
|
|
|
+ v=getview(view)
|
|
|
|
+ If v And v.node=treeviewnode Return Self
|
|
|
|
+ For n=EachIn kids
|
|
|
|
+ r=n.Find(treeviewnode,view)
|
|
|
|
+ If r Return r
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetNode(treeviewnode:TGadget,view=0)
|
|
|
|
+ Local v:TView = getview(view)
|
|
|
|
+ v.node=treeviewnode
|
|
|
|
+ open view
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method HighLight(view=-1)
|
|
|
|
+ Local v:TView
|
|
|
|
+ If view=-1
|
|
|
|
+ For view=0 Until views.length
|
|
|
|
+ HighLight view
|
|
|
|
+ Next
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ v=GetView(view)
|
|
|
|
+ If v.node SelectTreeViewNode v.node
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Open(view=-1)
|
|
|
|
+ Local v:TView
|
|
|
|
+ If view=-1
|
|
|
|
+ For view=0 Until views.length
|
|
|
|
+ Open view
|
|
|
|
+ Next
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ v=GetView(view)
|
|
|
|
+ If v.state<>OPENSTATE
|
|
|
|
+ v.state=OPENSTATE
|
|
|
|
+ RefreshView view
|
|
|
|
+' If v.node ExpandTreeViewNode v.node
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Close(view=0)
|
|
|
|
+ Local v:TView = GetView(view)
|
|
|
|
+ If v.state<>CLOSEDSTATE
|
|
|
|
+ v.state=CLOSEDSTATE
|
|
|
|
+' If v.node CollapseTreeViewNode v.node
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method GetState(view=0)
|
|
|
|
+ Return GetView(view).state
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method GetView:TView(view=0)
|
|
|
|
+ If view>=views.length
|
|
|
|
+ views=views[..view+1]
|
|
|
|
+ EndIf
|
|
|
|
+ If Not views[view] views[view] = New TView
|
|
|
|
+ Return views[view]
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method GetIndex()
|
|
|
|
+ Local node:TNode
|
|
|
|
+ Local i
|
|
|
|
+ If parent
|
|
|
|
+ For node=EachIn parent.kids
|
|
|
|
+ If node=Self Return i
|
|
|
|
+ i:+1
|
|
|
|
+ Next
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Refresh()
|
|
|
|
+ For Local i:Int = 0 Until views.length
|
|
|
|
+ RefreshView i
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RefreshView(view=0)
|
|
|
|
+ Local n:TNode,quick,nodeToOpen:TGadget
|
|
|
|
+ Local v:TView,vv:TView
|
|
|
|
+ Local node
|
|
|
|
+ If parent And parent.getstate(view)=CLOSEDSTATE quick=True
|
|
|
|
+ v=getview(view)
|
|
|
|
+ If v.node And parent
|
|
|
|
+ If GadgetText(v.node) <> name Then
|
|
|
|
+ ModifyTreeViewNode v.node,name
|
|
|
|
+ LocalizeGadget(v.node,name,"")
|
|
|
|
+ EndIf
|
|
|
|
+ If v.state=OPENSTATE nodeToOpen = v.node;quick = False
|
|
|
|
+ Else
|
|
|
|
+ If parent And name
|
|
|
|
+ vv=parent.getview(view)
|
|
|
|
+ If vv.node
|
|
|
|
+ v.node=InsertTreeViewNode(GetIndex(),name,vv.node)
|
|
|
|
+ If v.state=HIDESTATE v.state=CLOSEDSTATE
|
|
|
|
+ If vv.state=OPENSTATE nodeToOpen = vv.node
|
|
|
|
+ quick=False
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ If quick Return
|
|
|
|
+ If Not kids Return
|
|
|
|
+ For n=EachIn kids
|
|
|
|
+ n.RefreshView view
|
|
|
|
+ Next
|
|
|
|
+ If nodeToOpen Then ExpandTreeViewNode nodeToOpen
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method NodeAfter:TNode(node:TNode)
|
|
|
|
+ Local link:TLink
|
|
|
|
+ If node link=kids.FindLink(node)
|
|
|
|
+ If link link=link.NextLink()
|
|
|
|
+ If link Return TNode(link.Value())
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Sync(snap:TNode)
|
|
|
|
+ Local snapkid:TNode
|
|
|
|
+ Local currentkid:TNode
|
|
|
|
+ Local kid:TNode
|
|
|
|
+ Local t:TNode
|
|
|
|
+ Local link:TLink
|
|
|
|
+
|
|
|
|
+ If snap.name<>name Return
|
|
|
|
+ If kids.Count() currentkid=TNode(kids.First())
|
|
|
|
+ For snapkid=EachIn snap.kids
|
|
|
|
+' if same name in list
|
|
|
|
+ kid=currentkid
|
|
|
|
+ While kid
|
|
|
|
+ If kid.name=snapkid.name Exit
|
|
|
|
+ kid=NodeAfter(kid)
|
|
|
|
+ Wend
|
|
|
|
+' then remove entries in front
|
|
|
|
+ If kid
|
|
|
|
+ While currentkid<>kid
|
|
|
|
+ t=currentkid
|
|
|
|
+ currentkid=NodeAfter(currentkid)
|
|
|
|
+ t.free()
|
|
|
|
+ Wend
|
|
|
|
+ EndIf
|
|
|
|
+' if same name sync else insert
|
|
|
|
+ If currentkid And currentkid.name=snapkid.name 'merge values if same name
|
|
|
|
+ currentkid.Sync snapkid
|
|
|
|
+ currentkid=NodeAfter(currentkid)
|
|
|
|
+ Else
|
|
|
|
+ snapkid.detach
|
|
|
|
+ If currentkid
|
|
|
|
+ link=kids.FindLink(currentkid)
|
|
|
|
+ kids.InsertBeforeLink snapkid,link
|
|
|
|
+ Else
|
|
|
|
+ kids.AddLast snapkid
|
|
|
|
+ EndIf
|
|
|
|
+ snapkid.parent=Self
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+' remove any entries at end
|
|
|
|
+ While currentkid
|
|
|
|
+ t=currentkid
|
|
|
|
+ currentkid=NodeAfter(currentkid)
|
|
|
|
+ t.free()
|
|
|
|
+ Wend
|
|
|
|
+ Refresh()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetName(n$)
|
|
|
|
+ name=n
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddNode:TNode(name$)
|
|
|
|
+ Local v:TNode
|
|
|
|
+ v=New TNode
|
|
|
|
+ v.setname name
|
|
|
|
+ Append v
|
|
|
|
+ Return v
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Append(v:TNode)
|
|
|
|
+ v.parent=Self
|
|
|
|
+ kids.AddLast v
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function CreateNode:TNode(name$)
|
|
|
|
+ Local node:TNode
|
|
|
|
+ node=New TNode
|
|
|
|
+ node.setname name
|
|
|
|
+ Return node
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type THelpPanel Extends TToolPanel
|
|
|
|
+
|
|
|
|
+ Field host:TCodePlay
|
|
|
|
+ Field htmlview:TGadget
|
|
|
|
+
|
|
|
|
+ Method AddLink:TNode(parent:TNode,name$,href$)
|
|
|
|
+ Local n:TNode
|
|
|
|
+ If parent
|
|
|
|
+ n=parent.AddNode(name)
|
|
|
|
+ Else
|
|
|
|
+ n=host.helproot
|
|
|
|
+ EndIf
|
|
|
|
+ If href href=RealPath(href)
|
|
|
|
+ n.SetAction(Self,TOOLNAVIGATE,href)
|
|
|
|
+ Return n
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ImportLinks( node:TNode,path$ )
|
|
|
|
+
|
|
|
|
+ Local t$=path+"/index.html"
|
|
|
|
+ If FileType( t )<>FILETYPE_FILE Return
|
|
|
|
+
|
|
|
|
+ node=AddLink( node,StripDir( path ),t )
|
|
|
|
+
|
|
|
|
+ Local map:TMap=New TMap
|
|
|
|
+
|
|
|
|
+ 'scan for html files
|
|
|
|
+ For Local e$=EachIn LoadDir( path )
|
|
|
|
+ If e="index.html" Continue
|
|
|
|
+ Local p$=path+"/"+e
|
|
|
|
+ Select FileType( p )
|
|
|
|
+ Case FILETYPE_DIR
|
|
|
|
+ ImportLinks node,p
|
|
|
|
+ Case FILETYPE_FILE
|
|
|
|
+ If Not e.StartsWith( "_" ) And ExtractExt( e ).Tolower()="html"
|
|
|
|
+ map.Insert StripExt( e ),p
|
|
|
|
+ EndIf
|
|
|
|
+ End Select
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ 'scan for anchors in index.html...
|
|
|
|
+ '
|
|
|
|
+ 'note: anchors must be quote enclosed and of simple form <a name="blah">
|
|
|
|
+ Local c$=CacheAndLoadText( t ),i
|
|
|
|
+ Repeat
|
|
|
|
+ i=c.Find( "<a name=~q",i )
|
|
|
|
+ If i=-1 Exit
|
|
|
|
+ i:+9
|
|
|
|
+ Local i2=c.Find( "~q>",i )
|
|
|
|
+ If i2=-1 Exit
|
|
|
|
+ Local q$=c[i..i2]
|
|
|
|
+ If q.StartsWith( "_" ) Continue
|
|
|
|
+ map.Insert q,t+"#"+q
|
|
|
|
+ i=i2+1
|
|
|
|
+ Forever
|
|
|
|
+
|
|
|
|
+ For Local kv:TKeyValue=EachIn map
|
|
|
|
+ AddLink node,String( kv.Key() ),String( kv.Value() )
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SyncDocs()
|
|
|
|
+ host.helproot.FreeKids
|
|
|
|
+
|
|
|
|
+ ImportLinks Null,host.bmxpath+"/docs/html"
|
|
|
|
+
|
|
|
|
+ Local link:TNode
|
|
|
|
+ For Local m$=EachIn EnumModules()
|
|
|
|
+ If m.StartsWith( "brl." ) Or m.StartsWith( "pub." ) Or m.StartsWith("maxgui.") Continue
|
|
|
|
+ Local p$=ModulePath( m )+"/doc/commands.html"
|
|
|
|
+ If FileType( p )<>FILETYPE_FILE Continue
|
|
|
|
+ If Not link link=AddLink( host.helproot,"{{navnode_thirdpartymods}}","" )
|
|
|
|
+ AddLink link,m,p
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ link=AddLink( host.helproot,"{{navnode_moduleindex}}","" )
|
|
|
|
+
|
|
|
|
+ If FileType( host.bmxpath+"/docs/html/Modules/commands.txt" )=FILETYPE_FILE
|
|
|
|
+ Local comm$=CacheAndLoadText( host.bmxpath+"/docs/html/Modules/commands.txt" )
|
|
|
|
+ For Local line$=EachIn comm.Split( "~n" )
|
|
|
|
+ Local bits$[]=line.Split( "|" )
|
|
|
|
+ If bits.length<>2 Continue
|
|
|
|
+ Local i=bits[0].Find( " : " )
|
|
|
|
+ If i<>-1 bits[0]=bits[0][..i]
|
|
|
|
+ AddLink link,bits[0],host.bmxpath+bits[1]
|
|
|
|
+ Next
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ host.helproot.Refresh
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ Local href$
|
|
|
|
+ If Not htmlview Return
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLCUT
|
|
|
|
+ GadgetCut htmlview
|
|
|
|
+ Case TOOLCOPY
|
|
|
|
+ GadgetCopy htmlview
|
|
|
|
+ Case TOOLPASTE
|
|
|
|
+ GadgetPaste htmlview
|
|
|
|
+ Case TOOLSHOW
|
|
|
|
+ ActivateGadget htmlview
|
|
|
|
+ host.SetTitle
|
|
|
|
+ Case TOOLNAVIGATE
|
|
|
|
+ href$=String(argument)
|
|
|
|
+ If href Go href
|
|
|
|
+ Case TOOLPRINT
|
|
|
|
+ GadgetPrint htmlview
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method OnEvent()
|
|
|
|
+ Local url$,p,t$
|
|
|
|
+ If EventSource()=htmlview
|
|
|
|
+ Select EventID()
|
|
|
|
+ Case EVENT_GADGETACTION 'NAVIGATEREQUEST
|
|
|
|
+ url$=String( EventExtra() )
|
|
|
|
+ If url[..5]="http:"
|
|
|
|
+ OpenURL url
|
|
|
|
+ Else
|
|
|
|
+ p=url.findlast(".")
|
|
|
|
+ If p>-1
|
|
|
|
+ t$=url[p..].tolower()
|
|
|
|
+ If t$=".bmx"
|
|
|
|
+ If url.Find( "file://" )=0
|
|
|
|
+ url=url[7..]
|
|
|
|
+ ?Win32
|
|
|
|
+ url=url[1..]
|
|
|
|
+ ?
|
|
|
|
+ EndIf
|
|
|
|
+ url=url.Replace("%20"," ")
|
|
|
|
+ Local source:TOpenCode=host.OpenSource(url)
|
|
|
|
+ If source source.MakePathTemp
|
|
|
|
+ Else
|
|
|
|
+ url=url.Replace("\","/")
|
|
|
|
+ url=url.Replace("user/index","user/welcome")
|
|
|
|
+ url=url.Replace("lang/index","lang/welcome")
|
|
|
|
+ url=url.Replace("mods/index","mods/welcome")
|
|
|
|
+ Go url$
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ End Select
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Go(url$,internal=False)
|
|
|
|
+ Local node:TNode
|
|
|
|
+
|
|
|
|
+ If host.options.externalhelp And Not internal
|
|
|
|
+ PollSystem
|
|
|
|
+ OpenURL url
|
|
|
|
+ MinimizeWindow host.window
|
|
|
|
+ PollSystem
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ HtmlViewGo htmlview,url
|
|
|
|
+ host.SelectPanel Self
|
|
|
|
+ node=host.helproot.FindArgument(RealPath(url))
|
|
|
|
+ If node
|
|
|
|
+ node.Highlight
|
|
|
|
+' Else
|
|
|
|
+' print "node not found"
|
|
|
|
+ EndIf
|
|
|
|
+ ActivateGadget htmlview
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Home()
|
|
|
|
+ Go host.bmxpath+HOMEPAGE,True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Forward()
|
|
|
|
+ HtmlViewForward htmlview
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Back()
|
|
|
|
+ HtmlViewBack htmlview
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:THelpPanel(host:TCodePlay)
|
|
|
|
+ Local root,style
|
|
|
|
+ Local p:THelpPanel = New THelpPanel
|
|
|
|
+ p.host=host
|
|
|
|
+ p.name="{{tab_help}}"
|
|
|
|
+ codeplay.addpanel(p)
|
|
|
|
+ style=HTMLVIEW_NONAVIGATE 'HTMLVIEW_NOCONTEXTMENU
|
|
|
|
+ p.htmlview=CreateHTMLView(0,0,ClientWidth(p.panel),ClientHeight(p.panel),p.panel,style)
|
|
|
|
+ SetGadgetLayout p.htmlview,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
|
|
|
|
+' p.Home
|
|
|
|
+ p.SyncDocs
|
|
|
|
+ Return p
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TSearchResult
|
|
|
|
+
|
|
|
|
+ Field filepath$
|
|
|
|
+ Field char%, line%
|
|
|
|
+ Field linestring$
|
|
|
|
+
|
|
|
|
+ Method AddToListbox( pGadget:TGadget )
|
|
|
|
+ AddGadgetItem pGadget, "[" + line + ", " + char + "] " + filepath, 0, -1, StripWhitespace(linestring,char), Self
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method Set:TSearchResult(pFilePath$,pChar%,pLine%,pLineString$)
|
|
|
|
+ filepath = pFilePath
|
|
|
|
+ char = pChar
|
|
|
|
+ line = pLine
|
|
|
|
+ linestring = pLineString
|
|
|
|
+ Return Self
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Function StripWhitespace$(pString$,pChar%)
|
|
|
|
+ If pString.length < pChar Then Return pString
|
|
|
|
+ Local outString$
|
|
|
|
+ For Local i:Int = 0 Until pString.length
|
|
|
|
+ Select pString[i]
|
|
|
|
+ Case Asc(" "), Asc("~t"), Asc("~n"), Asc("~r")
|
|
|
|
+ If outString And Not outString.EndsWith(" ") Then outString:+" "
|
|
|
|
+ Default
|
|
|
|
+ outString:+pString[i..i+1]
|
|
|
|
+ EndSelect
|
|
|
|
+ Next
|
|
|
|
+ Return outString
|
|
|
|
+ EndFunction
|
|
|
|
+
|
|
|
|
+EndType
|
|
|
|
+
|
|
|
|
+Type TSearchRequester Extends TRequester
|
|
|
|
+
|
|
|
|
+ Const strSearchText$ = "{{search_btn_startsearch}}", strStopSearchText$ = "{{search_btn_stopsearch}}"
|
|
|
|
+
|
|
|
|
+ Global strFileExts$[][] = [["bmx"],filetypes.Split(","),String[](Null)]
|
|
|
|
+
|
|
|
|
+ Field findbox:TGadget,typebox:TGadget,pathbox:TGadget,pathbutton:TGadget,pathsubdir:TGadget,results:TGadget
|
|
|
|
+ Field lstSearchResults:TList = New TList
|
|
|
|
+
|
|
|
|
+ Field safetyCount% = -1, safetyThreshold = 500, safetyResetCount% = 0
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Local id:Int = EventID()
|
|
|
|
+ Local data:Int = EventData()
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case results
|
|
|
|
+ Select id
|
|
|
|
+ Case EVENT_GADGETACTION
|
|
|
|
+ Local tmpSearchResult:TSearchResult = TSearchResult(EventExtra())
|
|
|
|
+ If tmpSearchResult Then
|
|
|
|
+ host.DebugSource( tmpSearchResult.filepath, tmpSearchResult.line, tmpSearchResult.char )
|
|
|
|
+ 'Hide()
|
|
|
|
+ EndIf
|
|
|
|
+ EndSelect
|
|
|
|
+ Case pathbutton
|
|
|
|
+ If EventID()=EVENT_GADGETACTION
|
|
|
|
+ Local tmpString$ = RequestDir( LocalizeString("{{search_requestfolder_title}}"),GadgetText(pathbox))
|
|
|
|
+ If tmpString Then SetGadgetText(pathbox,tmpString)
|
|
|
|
+ EndIf
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE Then Hide()
|
|
|
|
+ Case findbox
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then
|
|
|
|
+ If GadgetText(findbox) Then EnableGadget(ok) Else DisableGadget(ok)
|
|
|
|
+ EndIf
|
|
|
|
+ Case ok
|
|
|
|
+ If EventID()=EVENT_GADGETACTION
|
|
|
|
+ If safetyCount < 0 Then StartSearch() Else safetyCount = -2
|
|
|
|
+ EndIf
|
|
|
|
+ Case cancel
|
|
|
|
+ If EventID()=EVENT_GADGETACTION Then Hide()
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Hide()
|
|
|
|
+ safetyCount = -2
|
|
|
|
+ Super.Hide()
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method ShowWithPath( pPath$ )
|
|
|
|
+ If pPath Then SetGadgetText( pathbox, pPath )
|
|
|
|
+ Show()
|
|
|
|
+ ActivateGadget( findbox )
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method StartSearch()
|
|
|
|
+
|
|
|
|
+ PollSystem()
|
|
|
|
+
|
|
|
|
+ Select FileType(RealPath(GadgetText(pathbox)))
|
|
|
|
+ Case FILETYPE_NONE
|
|
|
|
+ Notify LocalizeString("{{search_error_pathnotfound}}"),True
|
|
|
|
+ ActivateGadget(pathbox)
|
|
|
|
+ Return
|
|
|
|
+ Case FILETYPE_FILE
|
|
|
|
+ Notify LocalizeString("{{search_error_pathisfile}}"),True
|
|
|
|
+ ActivateGadget(pathbox)
|
|
|
|
+ Return
|
|
|
|
+ EndSelect
|
|
|
|
+
|
|
|
|
+ If Not GadgetText(findbox) Then
|
|
|
|
+ Notify LocalizeString("{{search_error_nosearchstring}}"),True
|
|
|
|
+ ActivateGadget(findbox);Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ safetyResetCount = 0;safetyCount = 0
|
|
|
|
+ LocalizeGadget ok, strStopSearchText;ClearGadgetItems results
|
|
|
|
+ SearchPath( GadgetText(pathbox), strFileExts[SelectedGadgetItem(typebox)], GadgetText(findbox).ToLower(), ButtonState(pathsubdir) )
|
|
|
|
+ LocalizeGadget ok, strSearchText;safetyCount = -1
|
|
|
|
+ SetStatusText window, LocalizeString("{{search_msg_complete}}").Replace("%1",CountGadgetItems(results))
|
|
|
|
+
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method SearchPath(pPath$,pFileType$[],pString$,pRecurse% = True)
|
|
|
|
+
|
|
|
|
+ pPath$ = RealPath(pPath) 'Make sure we are using a real path
|
|
|
|
+
|
|
|
|
+ Local tmpSearchDir$[] = LoadDir(pPath,True) 'Load directors contents into string array
|
|
|
|
+ If Not tmpSearchDir Then Return 'Return if the directory is invalid
|
|
|
|
+ tmpSearchDir.Sort() 'Sort the contents alphabetically
|
|
|
|
+
|
|
|
|
+ SetStatusText window, LocalizeString("{{search_msg_searchingdir}}").Replace("%1", pPath) 'And let user know which directory is being searched
|
|
|
|
+
|
|
|
|
+ Local tmpFullPath$
|
|
|
|
+
|
|
|
|
+ For Local tmpItem$ = EachIn tmpSearchDir
|
|
|
|
+
|
|
|
|
+ tmpFullPath = pPath + "/" + tmpItem
|
|
|
|
+
|
|
|
|
+ Select FileType(tmpFullPath)
|
|
|
|
+ Case FILETYPE_NONE;Continue 'Skip item if, for whatever reason, it doesn't exist
|
|
|
|
+ Case FILETYPE_FILE 'If file, then check extension and search if valid
|
|
|
|
+ If Not pFileType
|
|
|
|
+ SearchFile(tmpFullPath,pString)
|
|
|
|
+ Else
|
|
|
|
+ Local tmpExt$ = ExtractExt(tmpFullPath).ToLower$()
|
|
|
|
+ For Local tmpValidExt$ = EachIn pFileType
|
|
|
|
+ If tmpExt = tmpValidExt Then SearchFile(tmpFullPath,pString)
|
|
|
|
+ Next
|
|
|
|
+ EndIf
|
|
|
|
+ Case FILETYPE_DIR 'If folder, then we might have to search recursively
|
|
|
|
+ If pRecurse Then SearchPath(tmpFullPath,pFileType,pString,pRecurse)
|
|
|
|
+ EndSelect
|
|
|
|
+
|
|
|
|
+ If Not ShouldContinue() Then Return
|
|
|
|
+
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ PollSystem();If PeekEvent() Then host.Poll() 'Let the system update as we could be searching a while
|
|
|
|
+
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method SearchFile(pPath$,pString$)
|
|
|
|
+ Local tmpText$ = CacheAndLoadText( pPath ), tmpLines$[], tmpFindPos%, tmpCharCount%, tmpLineNo%
|
|
|
|
+ Local tmpStringLength% = pString.length, tmpChunkLines$[], tmpPrevLines$
|
|
|
|
+
|
|
|
|
+ If tmpText Then
|
|
|
|
+ tmpLines = tmpText.Split("~n")
|
|
|
|
+ tmpText = tmpText.ToLower()
|
|
|
|
+ tmpFindPos = tmpText.Find(pString)
|
|
|
|
+ While ShouldContinue() And tmpFindPos > -1
|
|
|
|
+ tmpChunkLines = tmpText[..tmpFindPos].Split("~n")
|
|
|
|
+ tmpPrevLines = "~n".Join(tmpChunkLines[..tmpChunkLines.length-1])
|
|
|
|
+ tmpLineNo:+(tmpChunkLines.length)-1
|
|
|
|
+ Local tmpSearchResult:TSearchResult = New TSearchResult.Set(pPath,tmpFindPos-tmpPrevLines.length,tmpLineNo+1,tmpLines[tmpLineNo])
|
|
|
|
+ tmpSearchResult.AddToListbox(results);safetyCount:+1
|
|
|
|
+ tmpCharCount:+tmpFindPos+tmpStringLength
|
|
|
|
+ tmpText = tmpText[tmpFindPos+tmpStringLength..]
|
|
|
|
+ tmpFindPos = tmpText.Find(pString)
|
|
|
|
+ Wend
|
|
|
|
+ EndIf
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method ShouldContinue()
|
|
|
|
+ If safetyCount < 0 Then Return False
|
|
|
|
+ If safetyCount >= safetyThreshold Then
|
|
|
|
+ If Confirm( LocalizeString("{{search_safetynotification}}").Replace("%1",(safetyResetCount*safetyThreshold)+safetyCount) ) Then
|
|
|
|
+ safetyCount = 0
|
|
|
|
+ safetyResetCount:+1
|
|
|
|
+ Else
|
|
|
|
+ safetyCount = -1
|
|
|
|
+ Return False
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Return True
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Function Create:TSearchRequester(host:TCodePlay)
|
|
|
|
+ Local search:TSearchRequester = New TSearchRequester
|
|
|
|
+ search.initrequester(host,"{{search_window_title}}",440,280,STYLE_CANCEL|STYLE_DIVIDER|STYLE_OK|STYLE_STATUS|STYLE_RESIZABLE,strSearchText)
|
|
|
|
+ DisableGadget(search.ok)
|
|
|
|
+
|
|
|
|
+ SetGadgetLayout(CreateLabel("{{search_label_find}}:",6,8+4,95,24,search.window),EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED)
|
|
|
|
+ search.findbox=CreateTextField(103,8,ClientWidth(search.window)-(103+6),21,search.window);SetGadgetLayout(search.findbox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ SetGadgetLayout(CreateLabel("{{search_label_filetypes}}:",6,42,95,24,search.window),EDGE_ALIGNED,EDGE_CENTERED,EDGE_ALIGNED,EDGE_CENTERED)
|
|
|
|
+ search.typebox=CreateComboBox(103,38,ClientWidth(search.window)-(103+6),24,search.window);SetGadgetLayout(search.typebox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
|
|
|
|
+
|
|
|
|
+ AddGadgetItem( search.typebox, "{{search_type_bmaxfiles}}",GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED,-1,"*.bmx" )
|
|
|
|
+ AddGadgetItem( search.typebox, "{{search_type_codefiles}}",GADGETITEM_LOCALIZED,-1,fileTypes )
|
|
|
|
+ AddGadgetItem( search.typebox, "{{search_type_allfiles}}",GADGETITEM_LOCALIZED,-1,"*")
|
|
|
|
+
|
|
|
|
+ SetGadgetLayout(CreateLabel("{{search_label_searchpath}}:",6,72,95,48,search.window),1,0,1,0)
|
|
|
|
+ search.pathbox=CreateTextField(103,68,ClientWidth(search.window)-(103+6+30+6),21,search.window);SetGadgetLayout(search.pathbox,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
|
|
|
|
+ search.pathbutton=CreateButton("..",ClientWidth(search.window)-(34+6),65,34,26,search.window);SetGadgetLayout(search.pathbutton,EDGE_CENTERED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
|
|
|
|
+ SetGadgetText(search.pathbox, CurrentDir())
|
|
|
|
+
|
|
|
|
+ search.pathsubdir=CreateButton("{{search_btn_searchsubfolders}}",103,98,ClientWidth(search.window)-(103+6),20,search.window,BUTTON_CHECKBOX);SetGadgetLayout(search.pathsubdir,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_CENTERED)
|
|
|
|
+ SetButtonState(search.pathsubdir,True)
|
|
|
|
+
|
|
|
|
+ search.results=CreateListBox(6,128,ClientWidth(search.window)-12,280-(128+6),search.window);SetGadgetLayout(search.results,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
|
|
|
|
+
|
|
|
|
+ Return search
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Type TProjectRequester Extends TRequester
|
|
|
|
+ Field projects:TProjects
|
|
|
|
+ Field listbox:TGadget
|
|
|
|
+ Field add:TGadget
|
|
|
|
+ Field remove:TGadget
|
|
|
|
+ Field props:TGadget
|
|
|
|
+ Field moveup:TGadget
|
|
|
|
+ Field movedown:TGadget
|
|
|
|
+ Field Current:TProjectFolderNode
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,arg:Object=Null)
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLACTIVATE
|
|
|
|
+ Refresh
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetCurrent(i)
|
|
|
|
+ If i=-1
|
|
|
|
+ DisableGadget remove
|
|
|
|
+ DisableGadget moveup
|
|
|
|
+ DisableGadget movedown
|
|
|
|
+ DisableGadget props
|
|
|
|
+ Current=Null
|
|
|
|
+ Else
|
|
|
|
+ Current=TProjectFolderNode(GadgetItemExtra(listbox,i))
|
|
|
|
+ If Current
|
|
|
|
+ EnableGadget remove
|
|
|
|
+ EnableGadget props
|
|
|
|
+ EnableGadget moveup
|
|
|
|
+ EnableGadget movedown
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ Local index
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE Then Hide()
|
|
|
|
+ Case add
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then
|
|
|
|
+ projects.NewProject
|
|
|
|
+ Refresh
|
|
|
|
+ EndIf
|
|
|
|
+ Case remove
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then
|
|
|
|
+ projects.RemoveProject SelectedGadgetItem(listbox)
|
|
|
|
+ Refresh
|
|
|
|
+ EndIf
|
|
|
|
+ Case cancel
|
|
|
|
+ If EventID() = EVENT_GADGETACTION Then Hide
|
|
|
|
+ Case props
|
|
|
|
+ If EventID() = EVENT_GADGETACTION And Current
|
|
|
|
+ host.projectprops.Open(Current)
|
|
|
|
+ EndIf
|
|
|
|
+ Case listbox
|
|
|
|
+ If EventID()=EVENT_GADGETSELECT
|
|
|
|
+ SetCurrent SelectedGadgetItem(listbox) 'EventData()
|
|
|
|
+ ElseIf EventID()=EVENT_GADGETACTION
|
|
|
|
+ SetCurrent SelectedGadgetItem(listbox)
|
|
|
|
+ host.projectprops.Open(Current)
|
|
|
|
+ EndIf
|
|
|
|
+ Case moveup
|
|
|
|
+ If EventID()=EVENT_GADGETACTION Then
|
|
|
|
+ index=projects.MoveProject(SelectedGadgetItem(listbox),-1)
|
|
|
|
+ Refresh
|
|
|
|
+ SelectGadgetItem listbox,index
|
|
|
|
+ SetCurrent(index)
|
|
|
|
+ EndIf
|
|
|
|
+ Case movedown
|
|
|
|
+ If EventID()=EVENT_GADGETACTION Then
|
|
|
|
+ index=projects.MoveProject(SelectedGadgetItem(listbox),1)
|
|
|
|
+ Refresh
|
|
|
|
+ SelectGadgetItem listbox,index
|
|
|
|
+ SetCurrent(index)
|
|
|
|
+ EndIf
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Refresh()
|
|
|
|
+ ClearGadgetItems listbox
|
|
|
|
+ For Local node:TNode = EachIn projects.kids
|
|
|
|
+ If TFolderNode(node)'node.argument
|
|
|
|
+ AddGadgetItem listbox,node.name,0,-1,"",node
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+ SetCurrent -1
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Open(projnode:TProjects)
|
|
|
|
+ projects=projnode
|
|
|
|
+ Refresh
|
|
|
|
+ Show
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TProjectRequester(host:TCodePlay)
|
|
|
|
+ Local x,y
|
|
|
|
+ Local proj:TProjectRequester = New TProjectRequester
|
|
|
|
+
|
|
|
|
+ proj.initrequester(host,"{{projman_window_title}}",400,168,STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
|
|
|
|
+ proj.listbox=CreateListBox( 6,8,244,154,proj.window )
|
|
|
|
+
|
|
|
|
+ x=ClientWidth(proj.window)-144
|
|
|
|
+ proj.add=CreateButton("{{projman_btn_addproj}}",x,8,138,26,proj.window)
|
|
|
|
+ proj.remove=CreateButton("{{projman_btn_delproj}}",x,40,138,26,proj.window)
|
|
|
|
+
|
|
|
|
+ proj.moveup=CreateButton("{{projman_btn_moveup}}",x,72,138,26,proj.window)
|
|
|
|
+ proj.movedown=CreateButton("{{projman_btn_movedn}}",x,104,138,26,proj.window)
|
|
|
|
+
|
|
|
|
+ proj.props=CreateButton("{{projman_btn_properties}}",x,136,138,26,proj.window)
|
|
|
|
+
|
|
|
|
+ DisableGadget proj.remove
|
|
|
|
+ DisableGadget proj.moveup
|
|
|
|
+ DisableGadget proj.movedown
|
|
|
|
+ DisableGadget proj.props
|
|
|
|
+ Return proj
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TProjectProperties Extends TRequester
|
|
|
|
+ Field proj:TProjectFolderNode
|
|
|
|
+ Field newproj:Int = False 'If 'True' then cancel/close deletes project.
|
|
|
|
+ Field localname:TGadget
|
|
|
|
+ Field localpath:TGadget
|
|
|
|
+ Field pathbutton:TGadget
|
|
|
|
+ Field path:TGadget
|
|
|
|
+ Field user:TGadget
|
|
|
|
+ Field password:TGadget
|
|
|
|
+ Field checkout:TGadget
|
|
|
|
+' Field update:TGadget
|
|
|
|
+' Field commit:TGadget
|
|
|
|
+ Field poprequester:TRequester 'hack for restoring to projectmanager requester
|
|
|
|
+ Field dirty
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,arg:Object=Null)
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLACTIVATE
|
|
|
|
+ Refresh
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Tidy()
|
|
|
|
+ newproj = False
|
|
|
|
+ If dirty
|
|
|
|
+ proj.Set GadgetText(localname),GadgetText(localpath),GadgetText(path),GadgetText(user),GadgetText(password)
|
|
|
|
+ dirty=False
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Poll()
|
|
|
|
+ If (EventID() <> EVENT_GADGETACTION) And (EventID() <> EVENT_WINDOWCLOSE) Then Return
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case localname,localpath,path,user,password
|
|
|
|
+ dirty=True
|
|
|
|
+ Case pathbutton
|
|
|
|
+ Local dir$=RequestDir(LocalizeString("{{project_requestfolder_title}}"))
|
|
|
|
+ If dir
|
|
|
|
+ If dir[dir.length-1..]="/" 'fltk hack
|
|
|
|
+ dir=dir[..dir.length-1]
|
|
|
|
+ EndIf
|
|
|
|
+ SetGadgetText localpath,dir
|
|
|
|
+ If GadgetText(localname)=""
|
|
|
|
+ SetGadgetText localname,StripDir(dir)
|
|
|
|
+ EndIf
|
|
|
|
+ dirty=True
|
|
|
|
+ EndIf
|
|
|
|
+ Case checkout
|
|
|
|
+ Tidy()
|
|
|
|
+ Hide()
|
|
|
|
+ proj.CheckoutVersion()
|
|
|
|
+Rem
|
|
|
|
+ Case commit
|
|
|
|
+ Tidy
|
|
|
|
+ Hide
|
|
|
|
+ proj.CommitVersion
|
|
|
|
+ Case update
|
|
|
|
+ Tidy
|
|
|
|
+ Hide
|
|
|
|
+ proj.UpdateVersion
|
|
|
|
+EndRem
|
|
|
|
+ Case ok
|
|
|
|
+ Tidy()
|
|
|
|
+ Hide()
|
|
|
|
+ Case cancel
|
|
|
|
+ Hide()
|
|
|
|
+ Case window
|
|
|
|
+ If EventID()=EVENT_WINDOWCLOSE
|
|
|
|
+ Hide()
|
|
|
|
+ EndIf
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Hide()
|
|
|
|
+ If proj And newproj Then proj.Free()
|
|
|
|
+ EnableGadget host.window
|
|
|
|
+ HideGadget window
|
|
|
|
+ host.UnhookRequester Self'poprequester
|
|
|
|
+ If poprequester poprequester.Show
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Refresh()
|
|
|
|
+ SetGadgetText localname,proj.name
|
|
|
|
+ SetGadgetText localpath,proj.path
|
|
|
|
+ SetGadgetText path,proj.svnpath
|
|
|
|
+ SetGadgetText user,proj.svnuser
|
|
|
|
+ SetGadgetText password,proj.svnpass
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Open(projnode:TProjectFolderNode, newproject:Int = False)
|
|
|
|
+ newproj=newproject
|
|
|
|
+ proj=projnode
|
|
|
|
+ Refresh()
|
|
|
|
+ Show()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TProjectProperties(host:TCodePlay)
|
|
|
|
+ Local proj:TProjectProperties = New TProjectProperties
|
|
|
|
+ proj.initrequester(host,"{{project_window_title}}",480,250,STYLE_OK|STYLE_CANCEL|STYLE_DIVIDER|STYLE_MODAL)
|
|
|
|
+ proj.modal = True
|
|
|
|
+
|
|
|
|
+ Local projectdetails:TGadget = CreatePanel(6,8,ClientWidth(proj.window)-12,85,proj.window,PANEL_GROUP,"{{project_group_details}}")
|
|
|
|
+
|
|
|
|
+ Local i,n,y
|
|
|
|
+ y=4
|
|
|
|
+
|
|
|
|
+ CreateLabel("{{project_label_name}}:",6,y+4,72,24,projectdetails)
|
|
|
|
+ proj.localname=CreateTextField(88,y,ClientWidth(projectdetails)-(88+6),21,projectdetails)
|
|
|
|
+' proj.pathbutton=CreateButton("..",434,y,34,28,projectdetails)
|
|
|
|
+ y:+30
|
|
|
|
+
|
|
|
|
+ CreateLabel("{{project_label_path}}:",8,y+4,72,24,projectdetails)
|
|
|
|
+ proj.localpath=CreateTextField(88,y,ClientWidth(projectdetails)-(88+34+6+6),21,projectdetails)
|
|
|
|
+ proj.pathbutton=CreateButton("..",ClientWidth(projectdetails)-(34+6),y-3,34,26,projectdetails)
|
|
|
|
+ y:+30
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ Local svnbox:TGadget = CreatePanel(6,101,ClientWidth(proj.window)-12,144,proj.window,PANEL_GROUP,"{{project_group_svn}}")
|
|
|
|
+ y=4
|
|
|
|
+ CreateLabel("{{project_label_url}}:",8,y+LABELOFFSET,72,24,svnbox)
|
|
|
|
+ proj.path=CreateTextField(88,y,ClientWidth(svnbox)-92,21,svnbox)
|
|
|
|
+ y:+30
|
|
|
|
+ CreateLabel("{{project_label_username}}:",8,y+LABELOFFSET,72,24,svnbox)
|
|
|
|
+ proj.user=CreateTextField(88,y,ClientWidth(svnbox)-92,21,svnbox)
|
|
|
|
+ y:+30
|
|
|
|
+ CreateLabel("{{project_label_password}}:",8,y+LABELOFFSET,72,24,svnbox)
|
|
|
|
+ proj.password=CreateTextField(88,y,ClientWidth(svnbox)-92,21,svnbox,TEXTFIELD_PASSWORD)
|
|
|
|
+ y:+30
|
|
|
|
+ proj.checkout=CreateButton("{{project_btn_checkout}}",ClientWidth(svnbox)-154,ClientHeight(svnbox)-32,150,28,svnbox)
|
|
|
|
+' proj.update=CreateButton("{{project_btn_update}}",180,y+10,150,28,svnbox)
|
|
|
|
+' proj.commit=CreateButton("{{project_btn_commit}}",340,y+10,150,28,svnbox)
|
|
|
|
+ y:+40
|
|
|
|
+
|
|
|
|
+ Return proj
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Function GetInfo$(a$ Var)
|
|
|
|
+ Local p,r$
|
|
|
|
+ p=a.Find("|")+1
|
|
|
|
+ If p=0 p=a.length+1
|
|
|
|
+ r$=a$[..p-1]
|
|
|
|
+ a$=a$[p..]
|
|
|
|
+ Return r$
|
|
|
|
+End Function
|
|
|
|
+
|
|
|
|
+Type TFolderNode Extends TNode
|
|
|
|
+ Field owner:TNode
|
|
|
|
+ Field path$
|
|
|
|
+ Field scanned
|
|
|
|
+ Field version
|
|
|
|
+ Field foldertype
|
|
|
|
+
|
|
|
|
+ Const PROJECTFOLDER=0
|
|
|
|
+ Const DIRECTORYFOLDER=1
|
|
|
|
+ Const FILEFOLDER=2
|
|
|
|
+
|
|
|
|
+ Method FindFolderFromPath:TFolderNode(dir$)
|
|
|
|
+ Local result:TFolderNode
|
|
|
|
+ If path=dir Return Self
|
|
|
|
+ For Local folder:TFolderNode = EachIn kids
|
|
|
|
+ result=folder.FindFolderFromPath(dir)
|
|
|
|
+ If result Return result
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetName(n$)
|
|
|
|
+ If version Then n:+"("+version+")"
|
|
|
|
+ Super.SetName( n )
|
|
|
|
+ Refresh
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetVersion(ver)
|
|
|
|
+ version=ver
|
|
|
|
+ SetName StripDir(path)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Write(stream:TStream)
|
|
|
|
+ Local isopen
|
|
|
|
+ If GetState()=OPENSTATE isopen=True
|
|
|
|
+ If version Or isopen
|
|
|
|
+ stream.WriteLine "proj_data="+path+"|"+isopen+"|"+version+"|"
|
|
|
|
+ EndIf
|
|
|
|
+ For Local folder:TFolderNode = EachIn kids
|
|
|
|
+ folder.Write(stream)
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ProjectHost:TCodePlay()
|
|
|
|
+ Local n:TNode = Self
|
|
|
|
+ While n
|
|
|
|
+ If TProjects(n) Return TProjects(n).host
|
|
|
|
+ n=n.parent
|
|
|
|
+ Wend
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ProjectNode:TProjectFolderNode()
|
|
|
|
+ Local n:TNode = Self
|
|
|
|
+ While n
|
|
|
|
+ If TProjectFolderNode(n) Return TProjectFolderNode(n)
|
|
|
|
+ n=n.parent
|
|
|
|
+ Wend
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RunSVN(cmd$,about$,refresh)
|
|
|
|
+
|
|
|
|
+ Local host:TCodePlay = ProjectHost()
|
|
|
|
+ If Not host Notify LocalizeString("{{svn_notification_nodehostnotfound}}");Return
|
|
|
|
+
|
|
|
|
+ Local project:TProjectFolderNode = ProjectNode()
|
|
|
|
+ If Not project Notify LocalizeString("{{svn_notification_nodeprojectnotfound}}");Return
|
|
|
|
+
|
|
|
|
+ If project.svnuser
|
|
|
|
+ cmd:+" --username "+project.svnuser
|
|
|
|
+ If project.svnpass cmd:+" --password "+project.svnpass
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If refresh
|
|
|
|
+ host.execute cmd,about,MENUREFRESH,True,Self
|
|
|
|
+ Else
|
|
|
|
+ host.execute cmd,about,0,0,Self
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method UpdateVersion()
|
|
|
|
+ Local cmd$=svncmd+" update"
|
|
|
|
+ cmd:+" "+quote(path)
|
|
|
|
+ RunSVN cmd,LocalizeString("{{svn_msg_updating}}").Replace("%1",path),True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method CommitVersion()
|
|
|
|
+ Local cmd$=svncmd+" commit"
|
|
|
|
+ cmd:+" -m ~qmy comment~q"
|
|
|
|
+ cmd:+" "+quote(path)
|
|
|
|
+ RunSVN cmd,LocalizeString("{{svn_msg_committing}}").Replace("%1",path),False
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Open(view=-1)
|
|
|
|
+ Update(True)
|
|
|
|
+ Super.Open view
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddFileNode:TNode(file$)
|
|
|
|
+ Local n:TNode
|
|
|
|
+ Local ext$
|
|
|
|
+ If (","+FileTypes+",").Contains(","+ExtractExt(file).toLower()+",") Then
|
|
|
|
+ n=AddNode(StripDir(file))
|
|
|
|
+ n.SetAction(owner,TOOLOPEN,file)
|
|
|
|
+ ext=ExtractExt(file$).ToLower()
|
|
|
|
+ n.sortname=ext+n.name
|
|
|
|
+ Return n
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddFolderNode:TNode(path$)
|
|
|
|
+ Local n:TFolderNode = TFolderNode.CreateFolderNode(path,DIRECTORYFOLDER)
|
|
|
|
+ n.owner = owner
|
|
|
|
+ n.sortname=" "+n.name
|
|
|
|
+ Append n
|
|
|
|
+ Return n
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Scan(o:TNode)
|
|
|
|
+ Local p$
|
|
|
|
+ Local flist:TList = New TList
|
|
|
|
+
|
|
|
|
+ owner=o
|
|
|
|
+
|
|
|
|
+ For Local f$ = EachIn LoadDir(path,True)
|
|
|
|
+ If f[..1] = "." Then Continue
|
|
|
|
+ p$=path+"/"+f
|
|
|
|
+ Select FileType(p$)
|
|
|
|
+ Case FILETYPE_FILE
|
|
|
|
+ AddFileNode p$
|
|
|
|
+ Case FILETYPE_DIR
|
|
|
|
+ AddFolderNode p$
|
|
|
|
+ End Select
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ SortKids
|
|
|
|
+ scanned = True
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ScanKids()
|
|
|
|
+ For Local f:TFolderNode = EachIn kids
|
|
|
|
+ f.owner = owner
|
|
|
|
+ f.Update(False)
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Rescan()
|
|
|
|
+ scanned = False
|
|
|
|
+ Update()
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method Update( alwaysScanKids:Int = False )
|
|
|
|
+ If Not scanned Then
|
|
|
|
+ FreeKids()
|
|
|
|
+ Scan owner
|
|
|
|
+ EndIf
|
|
|
|
+ If alwaysScanKids Or Not IsHidden() Then ScanKids()
|
|
|
|
+ Refresh()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ Local host:TCodePlay
|
|
|
|
+ Local cmd,p
|
|
|
|
+ Local line$
|
|
|
|
+
|
|
|
|
+ host=ProjectHost()
|
|
|
|
+ If Not host Notify LocalizeString("{{svn_notification_nodehostnotfound}}");Return
|
|
|
|
+
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLOUTPUT
|
|
|
|
+ line$=String(argument)
|
|
|
|
+ p=line.find(" revision ")
|
|
|
|
+ If p>-1
|
|
|
|
+ SetVersion Int(line[p+10..])
|
|
|
|
+ EndIf
|
|
|
|
+' If line[..12]="At revision "
|
|
|
|
+' DebugLog "TOOLOUTPUT:"+line
|
|
|
|
+ Return
|
|
|
|
+ Case TOOLERROR
|
|
|
|
+ line$=String(argument)
|
|
|
|
+' DebugLog "TOOLERROR:"+line
|
|
|
|
+ Return
|
|
|
|
+ Case TOOLMENU
|
|
|
|
+ cmd=Int(String(argument))
|
|
|
|
+ Select cmd
|
|
|
|
+ Case 0 'special toolmenu-command=0 fired by rightbutton node context
|
|
|
|
+ Highlight
|
|
|
|
+ Local menu:TGadget
|
|
|
|
+ menu=host.projects.projmenu
|
|
|
|
+ PopupWindowMenu host.window,menu,Self
|
|
|
|
+ Case MENUREFRESH
|
|
|
|
+ Rescan()
|
|
|
|
+ Case MENUBROWSE
|
|
|
|
+ OpenURL RealPath(path)
|
|
|
|
+ Case MENUSHELL
|
|
|
|
+ Local cd$=CurrentDir()
|
|
|
|
+ ChangeDir RealPath(path)
|
|
|
|
+?MacOS
|
|
|
|
+ host.execute "/bin/bash","Shell Terminal"
|
|
|
|
+?Linux
|
|
|
|
+ host.execute "/bin/bash","Shell Terminal"
|
|
|
|
+?Win32
|
|
|
|
+ host.execute "cmd","Shell Terminal - Type Exit To End"
|
|
|
|
+?
|
|
|
|
+ ChangeDir cd
|
|
|
|
+ Case MENUUPDATE
|
|
|
|
+ UpdateVersion
|
|
|
|
+ Case MENUCOMMIT
|
|
|
|
+ CommitVersion
|
|
|
|
+' Case MENUPROPS
|
|
|
|
+' host.projectprops.Open(Self)
|
|
|
|
+ Case MENUFINDINFILES
|
|
|
|
+ host.searchreq.ShowWithPath( RealPath(path) )
|
|
|
|
+ End Select
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function CreateFolderNode:TFolderNode(path$,foldertype)
|
|
|
|
+ Local n:TFolderNode = New TFolderNode
|
|
|
|
+' n.host=host
|
|
|
|
+ n.SetName( StripDir(path) )
|
|
|
|
+ n.path = path
|
|
|
|
+ n.foldertype = foldertype
|
|
|
|
+ Return n
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TProjectFolderNode Extends TFolderNode
|
|
|
|
+
|
|
|
|
+ Field owner:TProjects
|
|
|
|
+ Field svnpath$,svnuser$,svnpass$,svnversion
|
|
|
|
+ Field svnerr$
|
|
|
|
+
|
|
|
|
+ Method CheckoutVersion() 'to do - needs to move old version to temp?
|
|
|
|
+ Local cmd$ = svncmd+" checkout"
|
|
|
|
+ cmd:+" "+quote(svnpath)
|
|
|
|
+ cmd:+" "+quote(path)
|
|
|
|
+ RunSVN cmd,LocalizeString("{{svn_msg_checkingout}}").Replace("%1",svnpath).Replace("%2",path),True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Crypt$(a$)
|
|
|
|
+ Local b$,c
|
|
|
|
+ For Local i:Int = 0 Until a.length
|
|
|
|
+ c=a[i]
|
|
|
|
+ If c>31 c:~((i*-5)&31)
|
|
|
|
+ b:+Chr(c&255)
|
|
|
|
+ Next
|
|
|
|
+ Return b
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method ToString$()
|
|
|
|
+ Local prj$
|
|
|
|
+ Local isopen
|
|
|
|
+ If GetState()&OPENSTATE isopen=True
|
|
|
|
+ prj=name+"|"+path+"|"+svnpath+"|"+svnuser+"|"+crypt(svnpass)+"|"+isopen+"|"+version
|
|
|
|
+ Return prj
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Write(stream:TStream)
|
|
|
|
+ stream.WriteLine "proj_node="+ToString()
|
|
|
|
+ For Local folder:TFolderNode = EachIn kids
|
|
|
|
+ folder.Write(stream)
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FromString(info$)
|
|
|
|
+ Local n$ = GetInfo(info)
|
|
|
|
+ If Not n Then n = "Unknown"
|
|
|
|
+ SetName( n )
|
|
|
|
+ path=GetInfo(info)
|
|
|
|
+ If path path=owner.host.FullPath(path)
|
|
|
|
+ svnpath=GetInfo(info)
|
|
|
|
+ svnuser=GetInfo(info)
|
|
|
|
+ svnpass=GetInfo(info)
|
|
|
|
+ Scan(owner)
|
|
|
|
+ Local isopen,vers
|
|
|
|
+ isopen=Int(GetInfo(info))
|
|
|
|
+ If isopen
|
|
|
|
+ Open
|
|
|
|
+ EndIf
|
|
|
|
+ vers=Int(GetInfo(info))
|
|
|
|
+ If vers
|
|
|
|
+ SetVersion vers
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ Local cmd
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLMENU
|
|
|
|
+ cmd=Int(String(argument))
|
|
|
|
+ Select cmd
|
|
|
|
+ Case MENUPROPS
|
|
|
|
+ Return owner.host.projectprops.Open(Self)
|
|
|
|
+ End Select
|
|
|
|
+ End Select
|
|
|
|
+ Return Super.Invoke(command,argument)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Set(n$,p$,s$,user$,pass$)
|
|
|
|
+ path=owner.host.FullPath(p)
|
|
|
|
+ setname n
|
|
|
|
+ svnpath=s
|
|
|
|
+ svnuser=user
|
|
|
|
+ svnpass=pass
|
|
|
|
+ Rescan()
|
|
|
|
+ owner.host.projectreq.Refresh()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function CreateProjectNode:TProjectFolderNode(projects:TProjects,info$)
|
|
|
|
+ Local n:TProjectFolderNode = New TProjectFolderNode
|
|
|
|
+ n.owner=projects
|
|
|
|
+ n.FromString(info)
|
|
|
|
+ n.foldertype=PROJECTFOLDER
|
|
|
|
+ Return n
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TProjects Extends TNode
|
|
|
|
+ Field host:TCodePlay
|
|
|
|
+ Field addproj:TNode
|
|
|
|
+ Field projmenu:TGadget
|
|
|
|
+ Field projmenuprops:TGadget
|
|
|
|
+
|
|
|
|
+ Method RemoveProject(index)
|
|
|
|
+ Local node:TNode
|
|
|
|
+ If index<0 Or index>=kids.Count() Return
|
|
|
|
+ node=TNode(kids.ValueAtIndex(index))
|
|
|
|
+ If node node.Free
|
|
|
|
+ Refresh
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method MoveProject(index,dir)
|
|
|
|
+ Local node:TNode
|
|
|
|
+ Local link:TLink
|
|
|
|
+ If index<0 Or index>=kids.Count() Return index
|
|
|
|
+ node=TNode(kids.ValueAtIndex(index))
|
|
|
|
+ If node
|
|
|
|
+ addproj.Detach
|
|
|
|
+ node.Hide
|
|
|
|
+ link=kids.FindLink(node)
|
|
|
|
+ If dir>0
|
|
|
|
+ If link link=link._succ
|
|
|
|
+ If link
|
|
|
|
+ kids.Remove node
|
|
|
|
+ kids.InsertAfterLink node,link
|
|
|
|
+ index:+1
|
|
|
|
+ EndIf
|
|
|
|
+ Else
|
|
|
|
+ If link link=link._pred
|
|
|
|
+ If link
|
|
|
|
+ kids.Remove node
|
|
|
|
+ kids.InsertBeforeLink node,link
|
|
|
|
+ index:-1
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Append addproj
|
|
|
|
+ Refresh
|
|
|
|
+ EndIf
|
|
|
|
+ Return index
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method NewProject()
|
|
|
|
+ addproj.Detach
|
|
|
|
+ Local proj:TProjectFolderNode = TProjectFolderNode.CreateProjectNode(Self,LocalizeString("{{project_defaultname}}"))
|
|
|
|
+' proj.scan(Self)
|
|
|
|
+ Append proj
|
|
|
|
+ Append addproj
|
|
|
|
+ host.projectprops.Open(proj, True)
|
|
|
|
+ Refresh
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddProject(data:TList)
|
|
|
|
+ Local project:TProjectFolderNode
|
|
|
|
+ Local folder:TFolderNode
|
|
|
|
+ For Local info$ = EachIn data
|
|
|
|
+ If Not project
|
|
|
|
+ addproj.Detach
|
|
|
|
+ project=TProjectFolderNode.CreateProjectNode(Self,info)
|
|
|
|
+ Append project
|
|
|
|
+ Append addproj
|
|
|
|
+ Refresh
|
|
|
|
+ Else
|
|
|
|
+ Local path$
|
|
|
|
+ Local popen
|
|
|
|
+ Local pversion
|
|
|
|
+ path=GetInfo(info)
|
|
|
|
+ popen=Int(GetInfo(info))
|
|
|
|
+ pversion=Int(GetInfo(info))
|
|
|
|
+ folder=project.FindFolderFromPath(path)
|
|
|
|
+ If folder
|
|
|
|
+ folder.SetVersion pversion
|
|
|
|
+ folder.ReScan()
|
|
|
|
+ If popen Then folder.Open()
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Write(stream:TStream)
|
|
|
|
+ For Local project:TProjectFolderNode = EachIn kids
|
|
|
|
+ project.Write(stream)
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLNEW
|
|
|
|
+ NewProject
|
|
|
|
+ Case TOOLOPEN
|
|
|
|
+ host.OpenSource String(argument)
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function CreateProjects:TProjects(host:TCodePlay)
|
|
|
|
+ Local p:TProjects = New TProjects
|
|
|
|
+ p.SetName("{{navnode_projects}}")
|
|
|
|
+ p.host=host
|
|
|
|
+ p.addproj=p.AddNode("{{navnode_addproject}}")
|
|
|
|
+ p.addproj.SetAction p,TOOLNEW
|
|
|
|
+
|
|
|
|
+ p.projmenu=CreateMenu("{{popup_nav_proj}}",0,Null)
|
|
|
|
+ CreateMenu "{{popup_nav_proj_refresh}}",MENUREFRESH,p.projmenu
|
|
|
|
+ CreateMenu "{{popup_nav_proj_findinfiles}}",MENUFINDINFILES,p.projmenu
|
|
|
|
+ CreateMenu "{{popup_nav_proj_explore}}",MENUBROWSE,p.projmenu
|
|
|
|
+ CreateMenu "{{popup_nav_proj_shell}}",MENUSHELL,p.projmenu
|
|
|
|
+ CreateMenu "",0,p.projmenu
|
|
|
|
+ CreateMenu "{{popup_nav_proj_svnupdate}}",MENUUPDATE,p.projmenu
|
|
|
|
+ CreateMenu "{{popup_nav_proj_svncommit}}",MENUCOMMIT,p.projmenu
|
|
|
|
+ CreateMenu "",0,p.projmenu
|
|
|
|
+ p.projmenuprops=CreateMenu("{{popup_nav_proj_properties}}",MENUPROPS,p.projmenu)
|
|
|
|
+ host.projectreq.projects=p
|
|
|
|
+ Return p
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TByteBuffer Extends TStream
|
|
|
|
+ Field bytes:Byte[]
|
|
|
|
+ Field readpointer
|
|
|
|
+
|
|
|
|
+ Method Read( buf:Byte Ptr,count )
|
|
|
|
+ If count>readpointer count=readpointer
|
|
|
|
+ If Not count Return
|
|
|
|
+ MemCopy buf,bytes,count
|
|
|
|
+ readpointer:-count
|
|
|
|
+ If readpointer MemMove bytes,Varptr bytes[count],readpointer
|
|
|
|
+ Return count
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ReadLine$()
|
|
|
|
+ For Local i:Int = 0 Until readpointer
|
|
|
|
+ If bytes[i]=10 Or bytes[i] = 0 Then
|
|
|
|
+ Local tmpBytes:Byte[] = New Byte[i+1]
|
|
|
|
+ If i And bytes[i-1] = 13 Then i:-1
|
|
|
|
+ Read(tmpBytes,tmpBytes.length)
|
|
|
|
+ Return String.FromBytes(tmpBytes, i)
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method WriteFromPipe( pipe:TPipeStream )
|
|
|
|
+ Local n,m,count = pipe.ReadAvail()
|
|
|
|
+ n=readpointer+count
|
|
|
|
+ If n>bytes.length
|
|
|
|
+ m=Max(bytes.length*1.5,n)
|
|
|
|
+ bytes=bytes[..m]
|
|
|
|
+ EndIf
|
|
|
|
+ pipe.Read( Varptr bytes[readpointer], count )
|
|
|
|
+ readpointer=n
|
|
|
|
+ Return count
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method Write( buf:Byte Ptr,count )
|
|
|
|
+ Local n,m
|
|
|
|
+ n=readpointer+count
|
|
|
|
+ If n>bytes.length
|
|
|
|
+ m=Max(bytes.length*1.5,n)
|
|
|
|
+ bytes=bytes[..m]
|
|
|
|
+ EndIf
|
|
|
|
+ MemCopy Varptr bytes[readpointer],buf,count
|
|
|
|
+ readpointer=n
|
|
|
|
+ Return count
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method LineAvail()
|
|
|
|
+ For Local i:Int = 0 Until readpointer
|
|
|
|
+ If bytes[i]=10 Return True
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FlushBytes:Byte[]()
|
|
|
|
+ Local res:Byte[] = bytes[..readpointer]
|
|
|
|
+ readpointer = 0
|
|
|
|
+ Return res
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TObj
|
|
|
|
+ Field addr$,sync,refs,syncnext
|
|
|
|
+ Method ShouldSync( pDebugTree:TDebugTree )
|
|
|
|
+ If sync < pDebugTree.sync Then pDebugTree.QueueSync( Self )
|
|
|
|
+ EndMethod
|
|
|
|
+ Method HasSynced( pSync% )
|
|
|
|
+ sync = pSync;syncnext = False
|
|
|
|
+ EndMethod
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TVar Extends TNode
|
|
|
|
+
|
|
|
|
+ Field owner:TDebugTree
|
|
|
|
+ Field obj:Object
|
|
|
|
+
|
|
|
|
+ Method Free()
|
|
|
|
+ If TObj(obj) owner.RemoveObj TObj(obj)
|
|
|
|
+ obj=Null
|
|
|
|
+ Super.Free()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetVarName(n$)
|
|
|
|
+ Local p
|
|
|
|
+ name=n
|
|
|
|
+' if object ref set addr$ field
|
|
|
|
+ If name.find("$=")=-1 And name.find( ":String=" )=-1 And name.find(")=$")=-1
|
|
|
|
+ p=name.find("=$")
|
|
|
|
+ If p<>-1
|
|
|
|
+ If TObj(obj) Then
|
|
|
|
+ If TObj(obj).addr <> name[p+2..] Then
|
|
|
|
+ TDebugTree.RemoveObj TObj(obj)
|
|
|
|
+ Else
|
|
|
|
+ TObj(obj).refs:-1
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ obj=TDebugTree.AddObj(name[p+2..])
|
|
|
|
+ 'Request object dump if we are visible now that
|
|
|
|
+ 'we have updated our own object pointer.
|
|
|
|
+ If Not IsHidden() Then Request()
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ p=name.find("=Null")
|
|
|
|
+ If p<>-1
|
|
|
|
+ FreeKids
|
|
|
|
+ TDebugTree.RemoveObj TObj(obj)
|
|
|
|
+ obj=Null
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddVar(name$)
|
|
|
|
+ Local v:TVar=New TVar
|
|
|
|
+ v.owner=owner
|
|
|
|
+ Append v
|
|
|
|
+ v.setvarname name
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetValue(val:TVar)
|
|
|
|
+ Local v:TVar,w:TVar,i,kidsarray:Object[]
|
|
|
|
+' if this is a reference to same object refresh values
|
|
|
|
+ If obj And obj=val.obj
|
|
|
|
+ If kids.IsEmpty()
|
|
|
|
+ For v=EachIn val.kids
|
|
|
|
+ AddVar v.name
|
|
|
|
+ Next
|
|
|
|
+ Else
|
|
|
|
+ kidsarray = kids.ToArray()
|
|
|
|
+ For v=EachIn val.kids
|
|
|
|
+ If i<kidsarray.length
|
|
|
|
+ w=TVar(kidsarray[i])
|
|
|
|
+ If w w.SetVarName v.name
|
|
|
|
+ Else
|
|
|
|
+ AddVar v.name
|
|
|
|
+ EndIf
|
|
|
|
+ i:+1
|
|
|
|
+ Next
|
|
|
|
+ kidsarray = Null
|
|
|
|
+ EndIf
|
|
|
|
+ Refresh
|
|
|
|
+ EndIf
|
|
|
|
+' recurse so all references are updated
|
|
|
|
+ If IsHidden() Then Return 'parent And parent.state=CLOSEDSTATE Return
|
|
|
|
+ For v=EachIn kids
|
|
|
|
+ v.SetValue val
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Open(open=-1)
|
|
|
|
+ For Local kid:TVar = EachIn kids
|
|
|
|
+ kid.Request()
|
|
|
|
+ Next
|
|
|
|
+ Super.Open(open)
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method Request()
|
|
|
|
+ If TObj(obj) Then TObj(obj).ShouldSync(owner)
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TScope Extends TVar
|
|
|
|
+ Field tree:TDebugTree
|
|
|
|
+ Field file$,line,column
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLACTIVATE
|
|
|
|
+ tree.SelectScope Self,True
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetScope(s:TScope)
|
|
|
|
+ Local v:TVar
|
|
|
|
+ file=s.file
|
|
|
|
+ line=s.line
|
|
|
|
+ column=s.column
|
|
|
|
+ s.obj=Self
|
|
|
|
+ SetValue s
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetFile(debugtree:TDebugTree,f$)
|
|
|
|
+ tree=debugtree
|
|
|
|
+ Local p=f.Find("<")+1
|
|
|
|
+ Local q=f.Find(">")+1
|
|
|
|
+ Local r=f.Find(",")+1
|
|
|
|
+ If p And q And r
|
|
|
|
+ file=f[..p-1]
|
|
|
|
+ line=Int(f[p..r-1])
|
|
|
|
+ column=Int(f[r..q-1])
|
|
|
|
+ EndIf
|
|
|
|
+ obj=Self
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Request()
|
|
|
|
+ For Local kid:TVar = EachIn kids
|
|
|
|
+ kid.Request()
|
|
|
|
+ Next
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TDebugTree Extends TVar
|
|
|
|
+ Global sync
|
|
|
|
+ Global objmap:TMap = CreateMap()
|
|
|
|
+ Field host:TCodePlay
|
|
|
|
+ Field instack:TList
|
|
|
|
+ Field inscope:TScope
|
|
|
|
+ Field invar:TVar
|
|
|
|
+ Field infile$
|
|
|
|
+ Field inexception$
|
|
|
|
+ Field firststop
|
|
|
|
+ Field cancontinue
|
|
|
|
+
|
|
|
|
+ Method Reset()
|
|
|
|
+' host.SetMode host.DEBUGMODE
|
|
|
|
+ SetStack( New TList )
|
|
|
|
+ ClearMap objmap
|
|
|
|
+ instack=Null
|
|
|
|
+ inscope=Null
|
|
|
|
+ invar=Null
|
|
|
|
+ infile=""
|
|
|
|
+ inexception=""
|
|
|
|
+ sync=0
|
|
|
|
+ firststop=True
|
|
|
|
+ cancontinue=False
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function AddObj:TObj(addr$)
|
|
|
|
+ Local o:TObj = TObj(MapValueForKey( objmap, addr ))
|
|
|
|
+ If o Then
|
|
|
|
+ o.refs:+1
|
|
|
|
+ Else
|
|
|
|
+ o=New TObj
|
|
|
|
+ o.addr=addr
|
|
|
|
+ o.refs=1
|
|
|
|
+ MapInsert objmap, addr, o
|
|
|
|
+ EndIf
|
|
|
|
+ Return o
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function FindObj:TObj(addr$)
|
|
|
|
+ Return TObj(MapValueForKey( objmap, addr ))
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function RemoveObj(obj:TObj) ':TObj
|
|
|
|
+ If obj Then
|
|
|
|
+ obj.refs:-1
|
|
|
|
+ If Not obj.refs Then MapRemove objmap, obj.addr
|
|
|
|
+ EndIf
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method SyncVars()
|
|
|
|
+ sync:+1
|
|
|
|
+ For Local tmpVar:TVar = EachIn kids
|
|
|
|
+ tmpVar.Request()
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method QueueSync( pObj:TObj )
|
|
|
|
+ If Not pObj Then Return
|
|
|
|
+ 'Sync as soon as the debug pipe is clear
|
|
|
|
+ '(see TOuputPanel.SendDumpRequests()).
|
|
|
|
+ pObj.syncnext = True
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method SetStack(list:TList)
|
|
|
|
+ Local openscope:TScope
|
|
|
|
+ Local s:TScope
|
|
|
|
+ Local count,i
|
|
|
|
+
|
|
|
|
+ count=kids.count() 'root.varlist.count()
|
|
|
|
+ For Local scope:TScope = EachIn list
|
|
|
|
+ If i>=count
|
|
|
|
+ Append scope 'root.Append scope
|
|
|
|
+ s=scope
|
|
|
|
+ Else
|
|
|
|
+ s=TScope(kids.ValueAtIndex(i))
|
|
|
|
+' simon was here
|
|
|
|
+ If s.name=scope.name
|
|
|
|
+ s.SetScope scope
|
|
|
|
+ scope.Free
|
|
|
|
+ Else
|
|
|
|
+ While kids.count()>i
|
|
|
|
+ s=TScope(kids.Last())
|
|
|
|
+ s.free
|
|
|
|
+ Wend
|
|
|
|
+ Append scope
|
|
|
|
+ s=scope
|
|
|
|
+ count=i+1
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ EndIf
|
|
|
|
+ If firststop
|
|
|
|
+ If host.IsSourceOpen(s.file) openscope=s
|
|
|
|
+ Else
|
|
|
|
+ openscope=s
|
|
|
|
+ EndIf
|
|
|
|
+ i:+1
|
|
|
|
+ Next
|
|
|
|
+ While kids.count()>i
|
|
|
|
+ s=TScope(kids.Last())
|
|
|
|
+ s.free
|
|
|
|
+ Wend
|
|
|
|
+ If list.IsEmpty() Return
|
|
|
|
+ If Not openscope openscope=TScope(list.First())
|
|
|
|
+ If openscope SelectScope openscope,True
|
|
|
|
+ Refresh
|
|
|
|
+ firststop=False
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SelectScope(scope:TScope,open)
|
|
|
|
+ If Not scope Return
|
|
|
|
+ host.SetMode host.DEBUGMODE ' simon was here, smoved from reset
|
|
|
|
+ If scope.file host.DebugSource scope.file,scope.line,scope.column
|
|
|
|
+ scope.Open()
|
|
|
|
+' If open
|
|
|
|
+' SelectTreeViewNode scope.node
|
|
|
|
+' scope.open
|
|
|
|
+' EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ProcessError$(line$)
|
|
|
|
+ Local p
|
|
|
|
+
|
|
|
|
+ While p < line.length
|
|
|
|
+ If line[p]=$3E Then p:+1 Else Exit '">"
|
|
|
|
+ Wend
|
|
|
|
+
|
|
|
|
+ If p = line.length Return
|
|
|
|
+ If p Then line = line[p..]
|
|
|
|
+
|
|
|
|
+ If Not line.StartsWith("~~>") Return line
|
|
|
|
+ line=line[2..]
|
|
|
|
+
|
|
|
|
+ If invar
|
|
|
|
+ If line="}"
|
|
|
|
+ SetValue invar 'root
|
|
|
|
+ invar.Free
|
|
|
|
+ invar=Null
|
|
|
|
+ Else
|
|
|
|
+' If Not invar.name
|
|
|
|
+' invar.name=line
|
|
|
|
+' Else
|
|
|
|
+ invar.AddVar line
|
|
|
|
+' EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If instack
|
|
|
|
+ If line="}"
|
|
|
|
+
|
|
|
|
+ SetStack instack
|
|
|
|
+ instack=Null
|
|
|
|
+ inscope=Null
|
|
|
|
+ 'Request first object dumps, and bump sync count
|
|
|
|
+ SyncVars
|
|
|
|
+ If inexception
|
|
|
|
+ Notify inexception
|
|
|
|
+ inexception=""
|
|
|
|
+ EndIf
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If infile
|
|
|
|
+ If line="Local <local>"
|
|
|
|
+ Else
|
|
|
|
+ inscope=New TScope
|
|
|
|
+' Print "inscope.line="+line
|
|
|
|
+ inscope.name=line
|
|
|
|
+ inscope.owner=Self
|
|
|
|
+ instack.AddLast inscope
|
|
|
|
+ EndIf
|
|
|
|
+ If inscope inscope.setfile Self,infile
|
|
|
|
+ infile=""
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If line.StartsWith("@") And line.Contains("<")
|
|
|
|
+ infile=line[1..]
|
|
|
|
+ Else
|
|
|
|
+ If inscope inscope.AddVar line
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If line.StartsWith("Unhandled Exception:")
|
|
|
|
+ inexception=line
|
|
|
|
+ host.output.WritePipe "t"
|
|
|
|
+ cancontinue=False
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If line="StackTrace{"
|
|
|
|
+ instack=New TList
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If line="Debug:" Or line="DebugStop:"
|
|
|
|
+ host.output.WritePipe "t"
|
|
|
|
+ If Not cancontinue Then
|
|
|
|
+ cancontinue=True
|
|
|
|
+ host.RefreshToolbar()
|
|
|
|
+ EndIf
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If line.StartsWith("ObjectDump@")
|
|
|
|
+ p=line.find("{",11)
|
|
|
|
+ If p=-1 Return line
|
|
|
|
+ line=line[11..p]
|
|
|
|
+ invar=New TVar
|
|
|
|
+ invar.obj=FindObj(line)
|
|
|
|
+ invar.owner=Self
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function CreateDebugTree:TDebugTree(host:TCodePlay)
|
|
|
|
+ Local d:TDebugTree = New TDebugTree
|
|
|
|
+ d.owner=d
|
|
|
|
+ d.SetName "{{navtab_debug}}"
|
|
|
|
+ d.host=host
|
|
|
|
+ d.Open
|
|
|
|
+ Return d
|
|
|
|
+ End Function
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TNodeView
|
|
|
|
+ Field owner:TNavBar
|
|
|
|
+ Field root:TNode
|
|
|
|
+ Field treeview:TGadget
|
|
|
|
+ Field index
|
|
|
|
+
|
|
|
|
+ Method NewView()
|
|
|
|
+ Local n:TNode,hnode:TGadget
|
|
|
|
+ hnode=SelectedTreeViewNode(treeview)
|
|
|
|
+ n=root.Find(hnode,index)
|
|
|
|
+ If n And n.parent owner.AddView n
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method OnEvent()
|
|
|
|
+ Local n:TNode = root.Find(TGadget(EventExtra()),index)
|
|
|
|
+ If Not n Return 'probably an eventgadgetselect -1 Notify("could not find in root");Return
|
|
|
|
+
|
|
|
|
+ Select EventID()
|
|
|
|
+ Case EVENT_GADGETSELECT
|
|
|
|
+ n.invoke(TOOLSELECT)
|
|
|
|
+ Case EVENT_GADGETACTION
|
|
|
|
+ n.invoke(TOOLACTIVATE)
|
|
|
|
+ Case EVENT_GADGETMENU
|
|
|
|
+ n.invoke(TOOLMENU,Self)
|
|
|
|
+ Case EVENT_GADGETOPEN
|
|
|
|
+ n.open index
|
|
|
|
+ Case EVENT_GADGETCLOSE
|
|
|
|
+ n.close index
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TNavBar Extends TEventHandler
|
|
|
|
+ Field host:TCodePlay
|
|
|
|
+ Field tabber:TGadget
|
|
|
|
+ Field viewlist:TList=New TList
|
|
|
|
+ Field selected:TNodeView
|
|
|
|
+ Field navmenu:TGadget
|
|
|
|
+
|
|
|
|
+ Method SelectedView()
|
|
|
|
+ If selected Return selected.index
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SelectView(index)
|
|
|
|
+ Local n:TNodeView
|
|
|
|
+ If index>=viewlist.count() Return
|
|
|
|
+ n=TNodeView(viewlist.ValueAtIndex(index))
|
|
|
|
+ If Not n Print "selectview failed";Return
|
|
|
|
+ If n<>selected
|
|
|
|
+ If selected HideGadget selected.treeview
|
|
|
|
+ selected=n
|
|
|
|
+ EndIf
|
|
|
|
+ ShowGadget n.treeview
|
|
|
|
+ SelectGadgetItem tabber,index
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddView(node:TNode)
|
|
|
|
+ Local n:TNodeView
|
|
|
|
+ Local index,root:TGadget
|
|
|
|
+ For n=EachIn viewlist
|
|
|
|
+ If n.root=node SelectView n.index;Return
|
|
|
|
+ Next
|
|
|
|
+ n=New TNodeView
|
|
|
|
+ n.owner=Self
|
|
|
|
+ n.root=node
|
|
|
|
+ n.treeview=CreateTreeView(0,0,ClientWidth(tabber),ClientHeight(tabber),tabber)
|
|
|
|
+ host.options.navstyle.Apply n.treeview
|
|
|
|
+ SetGadgetLayout n.treeview,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
|
|
|
|
+ HideGadget n.treeview
|
|
|
|
+
|
|
|
|
+ n.index=viewlist.Count()
|
|
|
|
+ viewlist.AddLast n
|
|
|
|
+
|
|
|
|
+ AddGadgetItem tabber,node.name,GADGETITEM_LOCALIZED
|
|
|
|
+ root=TreeViewRoot(n.treeview)
|
|
|
|
+ node.setnode root,n.index
|
|
|
|
+ SelectView n.index
|
|
|
|
+ Return n.index
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method OnEvent()
|
|
|
|
+ If EventSource()=tabber
|
|
|
|
+ SelectView SelectedGadgetItem(tabber)
|
|
|
|
+ End If
|
|
|
|
+ If selected And EventSource()=selected.treeview
|
|
|
|
+ selected.OnEvent
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Refresh()
|
|
|
|
+ For Local view:TNodeView = EachIn viewlist
|
|
|
|
+ host.options.navstyle.Apply view.treeview
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ If command=TOOLREFRESH Refresh()
|
|
|
|
+ If command=TOOLNEWVIEW And selected selected.NewView
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function CreateNavMenu:TGadget()
|
|
|
|
+ Local edit:TGadget = CreateMenu("&Nav",0,Null)
|
|
|
|
+ CreateMenu "&New View",MENUNEWVIEW,edit
|
|
|
|
+ Return edit
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function Create:TNavBar(host:TCodePlay, parent:TGadget) ',root:TNode)
|
|
|
|
+ Local n:TNavBar = New TNavBar
|
|
|
|
+ n.host=host
|
|
|
|
+ n.tabber=CreateTabber(0,0,ClientWidth(parent),ClientHeight(parent),parent)
|
|
|
|
+ SetGadgetLayout(n.tabber,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
|
|
|
|
+' n.AddView root
|
|
|
|
+ n.navmenu=CreateNavMenu()
|
|
|
|
+ Return n
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TOutputPanel Extends TToolPanel 'used build and run
|
|
|
|
+
|
|
|
|
+ Field host:TCodePlay
|
|
|
|
+ Field output:TGadget
|
|
|
|
+
|
|
|
|
+ Field process:TProcess
|
|
|
|
+ Field pipe:TStream
|
|
|
|
+
|
|
|
|
+ Field wpipe:TTextStream
|
|
|
|
+
|
|
|
|
+ Field user$,cmdline$,err$,post$
|
|
|
|
+ Field errbuffer:TByteBuffer
|
|
|
|
+ Field outputmenu:TGadget
|
|
|
|
+ Field posttool:TTool
|
|
|
|
+
|
|
|
|
+ Method ClearDumpRequests()
|
|
|
|
+ For Local o:TObj = EachIn MapValues(host.debugtree.objmap)
|
|
|
|
+ o.HasSynced(o.sync)
|
|
|
|
+ Next
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method SendDumpRequests()
|
|
|
|
+ For Local o:TObj = EachIn MapValues(host.debugtree.objmap)
|
|
|
|
+ If o.syncnext Then
|
|
|
|
+ If o.addr <> "00000000" Then WritePipe "d"+o.addr
|
|
|
|
+ o.HasSynced( host.debugtree.sync )
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method Clear()
|
|
|
|
+ If Not output Open()
|
|
|
|
+ SetGadgetText output,""
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method WriteAscii(mess$)
|
|
|
|
+ If Not output Open()
|
|
|
|
+ AddTextAreaText output,mess.Replace("~0","")
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Write(mess$)
|
|
|
|
+ If Not output Open()
|
|
|
|
+ AddTextAreaText output,mess.Replace("~0","")
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Execute(cmd$,mess$="",exe$="",home=True,owner:TTool=Null)
|
|
|
|
+ If Not output Open()
|
|
|
|
+ If Not mess$ mess$=cmd$
|
|
|
|
+ err$=""
|
|
|
|
+ post$=exe
|
|
|
|
+ posttool=owner
|
|
|
|
+ host.SelectPanel Self
|
|
|
|
+ host.debugtree.Reset
|
|
|
|
+
|
|
|
|
+ If process And ProcessStatus(process)
|
|
|
|
+ Delay 500
|
|
|
|
+ If ProcessStatus(process)
|
|
|
|
+ Notify LocalizeString("{{output_notification_stillbusy}}").Replace("%1",cmdline)
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ cmd=cmd.Trim()
|
|
|
|
+ process=CreateProcess(cmd$,HIDECONSOLE)
|
|
|
|
+ If Not process Then Notify LocalizeString("{{output_notification_processfailure}}").Replace("%1",cmd);Return
|
|
|
|
+ If Not process.status() Then Notify LocalizeString("{{output_notification_failedstart}}").Replace("%1",cmd);process=Null;Return
|
|
|
|
+ pipe=Process.pipe
|
|
|
|
+ wpipe=TTextStream.Create(pipe,TTextStream.UTF8)
|
|
|
|
+
|
|
|
|
+ cmdline=cmd
|
|
|
|
+ If home Clear
|
|
|
|
+ Write( mess+"~n" )
|
|
|
|
+ errbuffer = New TByteBuffer
|
|
|
|
+ host.RefreshToolbar
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method WritePipe(l$)
|
|
|
|
+ Try
|
|
|
|
+ If pipe pipe.WriteLine(l)
|
|
|
|
+ Catch ex:TStreamWriteException
|
|
|
|
+ Write LocalizeString("{{output_msg_debugfailure}}~n").Replace("%1",l)
|
|
|
|
+ Stop
|
|
|
|
+ EndTry
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Go()
|
|
|
|
+ WritePipe "r"
|
|
|
|
+ host.debugtree.cancontinue = False
|
|
|
|
+ host.SelectPanel Self
|
|
|
|
+ host.RefreshToolbar()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method StepOver()
|
|
|
|
+ ClearDumpRequests()
|
|
|
|
+ WritePipe "s"
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method StepIn()
|
|
|
|
+ ClearDumpRequests()
|
|
|
|
+ WritePipe "e"
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method StepOut()
|
|
|
|
+ ClearDumpRequests()
|
|
|
|
+ WritePipe "l"
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Stop()
|
|
|
|
+ If Not process Return
|
|
|
|
+ process.Terminate()
|
|
|
|
+ FlushPipes process.pipe,process.err
|
|
|
|
+ process.Close()
|
|
|
|
+ process=Null
|
|
|
|
+ Write LocalizeString("~n{{output_msg_processterminated}}~n")
|
|
|
|
+ host.DebugExit()
|
|
|
|
+ Close()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Wait()
|
|
|
|
+ While process And process.status()
|
|
|
|
+ PollSystem
|
|
|
|
+ Wend
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLSHOW
|
|
|
|
+ host.SetTitle()
|
|
|
|
+ If output ActivateGadget output
|
|
|
|
+ Case TOOLCLOSE
|
|
|
|
+ host.RemovePanel Self
|
|
|
|
+ output=Null
|
|
|
|
+ Case TOOLCUT
|
|
|
|
+ GadgetCut output
|
|
|
|
+ Case TOOLCOPY
|
|
|
|
+ GadgetCopy output
|
|
|
|
+ Case TOOLPASTE
|
|
|
|
+ GadgetPaste output
|
|
|
|
+ Case TOOLSELECTALL
|
|
|
|
+ If output SelectTextAreaText output
|
|
|
|
+ Case TOOLREFRESH
|
|
|
|
+ host.options.outputstyle.apply output
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Close()
|
|
|
|
+ host.SelectPanel host.activepanel
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Escape()
|
|
|
|
+ Stop
|
|
|
|
+ Close
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function outputfilter(event:TEvent,context:Object)
|
|
|
|
+ Local out:TOutputPanel=TOutputPanel(context)
|
|
|
|
+ If Not out Return
|
|
|
|
+ Select event.id
|
|
|
|
+ Case EVENT_KEYDOWN
|
|
|
|
+ If event.data=27
|
|
|
|
+ out.Escape()
|
|
|
|
+ Return 0
|
|
|
|
+ EndIf
|
|
|
|
+ Case EVENT_KEYCHAR
|
|
|
|
+' Print "output_keychar "+event.data
|
|
|
|
+ out.writechar(event.data)
|
|
|
|
+ End Select
|
|
|
|
+ Return 1
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method OnEvent()
|
|
|
|
+ If EventSource()=output
|
|
|
|
+ If EventID()=EVENT_GADGETMENU
|
|
|
|
+ PopupWindowMenu host.window,outputmenu
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+' Case EVENT_TIMERTICK
|
|
|
|
+ If Not process Return
|
|
|
|
+
|
|
|
|
+ ReadPipes process.pipe,process.err
|
|
|
|
+
|
|
|
|
+ If Not process.status()
|
|
|
|
+ process.terminate
|
|
|
|
+ FlushPipes process.pipe,process.err
|
|
|
|
+ process.close()
|
|
|
|
+ process = Null
|
|
|
|
+ Write LocalizeString("~n{{output_msg_processcomplete}}~n")
|
|
|
|
+ host.DebugExit
|
|
|
|
+ host.SelectPanel Self
|
|
|
|
+
|
|
|
|
+ If err
|
|
|
|
+ host.ParseError err
|
|
|
|
+ Else
|
|
|
|
+ If post$
|
|
|
|
+ Local menuaction=Int(post)
|
|
|
|
+ If menuaction
|
|
|
|
+ host.OnMenu menuaction,posttool
|
|
|
|
+' Else
|
|
|
|
+' Execute post$,"","",False,0
|
|
|
|
+ EndIf
|
|
|
|
+ Else
|
|
|
|
+ If host.options.hideoutput Close()
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FlushPipes(pipe:TPipeStream,errpipe:TPipeStream)
|
|
|
|
+ ReadPipes(pipe,errpipe)
|
|
|
|
+ Local bytes:Byte[] = errbuffer.flushbytes()
|
|
|
|
+ If bytes
|
|
|
|
+ Local line$=String.FromBytes(bytes,Len bytes)
|
|
|
|
+ line=line.Replace(Chr(13),"")
|
|
|
|
+ If line<>">" Write line
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ReadPipes(pipe:TPipeStream,errpipe:TPipeStream)
|
|
|
|
+ Local status
|
|
|
|
+ Local bytes:Byte[],line$
|
|
|
|
+
|
|
|
|
+ bytes=pipe.ReadPipe()
|
|
|
|
+ If bytes
|
|
|
|
+ line$=String.FromBytes(bytes,Len bytes)
|
|
|
|
+ line=line.Replace(Chr(13),"")
|
|
|
|
+ Write line
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If errpipe.ReadAvail() Then
|
|
|
|
+ errbuffer.WriteFromPipe(errpipe)
|
|
|
|
+ Else
|
|
|
|
+ SendDumpRequests()
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+' If bytes Write String.FromBytes(bytes,bytes.length)
|
|
|
|
+ While errbuffer.LineAvail()
|
|
|
|
+ line$=errbuffer.ReadLine()
|
|
|
|
+ line=host.debugtree.ProcessError(line)
|
|
|
|
+ If line
|
|
|
|
+ Write line+"~n"
|
|
|
|
+ err:+line+"~n"
|
|
|
|
+ EndIf
|
|
|
|
+ Wend
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method WriteChar(char)
|
|
|
|
+ Local pipe:TPipeStream
|
|
|
|
+
|
|
|
|
+ If Not process Return
|
|
|
|
+ pipe=process.pipe
|
|
|
|
+ If char=3 'CTRL-C
|
|
|
|
+ Stop()
|
|
|
|
+ EndIf
|
|
|
|
+ If char=13 'ENTER
|
|
|
|
+' Write Chr(10)
|
|
|
|
+ pipe.WriteLine user$
|
|
|
|
+ user=""
|
|
|
|
+ EndIf
|
|
|
|
+ If char=8 And user.length 'DELETE
|
|
|
|
+' Local pos=TextAreaLen(output)
|
|
|
|
+' If pos SetTextAreaText output,"",pos-1,1,TEXTAREA_CHARS
|
|
|
|
+ user=user[..user.length-1]
|
|
|
|
+ EndIf
|
|
|
|
+ If char>31
|
|
|
|
+' Write Chr(char)
|
|
|
|
+ user:+Chr(char)
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Open()
|
|
|
|
+ If output Then
|
|
|
|
+ codeplay.SelectPanel Self
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ codeplay.addpanel(Self)
|
|
|
|
+ output=CreateTextArea(0,0,ClientWidth(panel),ClientHeight(panel),panel,TEXTAREA_WORDWRAP)
|
|
|
|
+ DelocalizeGadget output
|
|
|
|
+ SetGadgetLayout output,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
|
|
|
|
+ SetGadgetFilter output,outputfilter,Self
|
|
|
|
+ SetGadgetText output," " 'simon was here
|
|
|
|
+ host.options.outputstyle.apply output
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function CreateOutputMenu:TGadget()
|
|
|
|
+ Local edit:TGadget = CreateMenu("{{popup_output}}",0,Null)
|
|
|
|
+ CreateMenu "{{popup_output_cut}}",MENUCUT,edit
|
|
|
|
+ CreateMenu "{{popup_output_copy}}",MENUCOPY,edit
|
|
|
|
+ CreateMenu "{{popup_output_paste}}",MENUPASTE,edit
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{popup_output_stop}}",MENUSTOP,edit
|
|
|
|
+ Return edit
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function Create:TOutputPanel(host:TCodePlay)
|
|
|
|
+ Local o:TOutputPanel = New TOutputPanel
|
|
|
|
+ o.host=host
|
|
|
|
+ o.name="{{tab_output}}"
|
|
|
|
+ o.outputmenu=CreateOutputMenu()
|
|
|
|
+' o.Open
|
|
|
|
+ Return o
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TCodeNode Extends TNode
|
|
|
|
+ Field owner:TOpenCode
|
|
|
|
+ Field pos,count
|
|
|
|
+ 'Field groups:TMap=New TMap
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLACTIVATE
|
|
|
|
+ owner.ShowPos(pos)
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Sync(snap:TNode)
|
|
|
|
+ If snap.name<>name SetName(snap.name)
|
|
|
|
+ Local n:TCodeNode = TCodeNode(snap)
|
|
|
|
+ If n pos=n.pos;count=n.count
|
|
|
|
+ Super.Sync(snap)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetName(n$)
|
|
|
|
+ Local p = n.find("'")
|
|
|
|
+ If p<>-1 n=n[..p]
|
|
|
|
+ name=n.Trim()
|
|
|
|
+' If owner.host.options.sortcode
|
|
|
|
+ sortname=n
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Free()
|
|
|
|
+ owner = Null
|
|
|
|
+ Super.Free()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddCodeNode:TCodeNode(n$,p0,p1)
|
|
|
|
+
|
|
|
|
+ Local t$
|
|
|
|
+ Local i:Int = n.find(" ") 'if space then group
|
|
|
|
+
|
|
|
|
+ If i>0
|
|
|
|
+ t=n[..i]
|
|
|
|
+ n=n[i+1..]
|
|
|
|
+Rem
|
|
|
|
+ p=TNode(groups.ValueForKey(t))
|
|
|
|
+ If Not p
|
|
|
|
+ p=AddNode(t+"s")
|
|
|
|
+ p.Open
|
|
|
|
+ groups.insert t,p
|
|
|
|
+ EndIf
|
|
|
|
+EndRem
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ Local c:TCodeNode = New TCodeNode
|
|
|
|
+ c.owner=owner
|
|
|
|
+ c.setname n$
|
|
|
|
+ c.pos=p0
|
|
|
|
+ c.count=p1-p0
|
|
|
|
+ Append(c)
|
|
|
|
+
|
|
|
|
+ Return c
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TDiff
|
|
|
|
+ Field pos,count,del$,add$,pos0,count0,pos1,textchange = True
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TOpenCode Extends TToolPanel
|
|
|
|
+
|
|
|
|
+ Global msgHighlightingStatus$ = "Highlighting"
|
|
|
|
+
|
|
|
|
+ Field host:TCodePlay
|
|
|
|
+ Field textarea:TGadget
|
|
|
|
+ Field dirty=True
|
|
|
|
+ Field filesrc$,cleansrc$,cleansrcl$
|
|
|
|
+ Field Current:TDiff
|
|
|
|
+ Field undolist:TList=New TList
|
|
|
|
+ Field redolist:TList=New TList
|
|
|
|
+ Field helpcmd$,helpstring$
|
|
|
|
+ Field seek$
|
|
|
|
+ Field cursorpos,cursorlen,cursorline
|
|
|
|
+ Field oldpos,oldlen
|
|
|
|
+ Field isbmx,isc,iscpp,ishtml
|
|
|
|
+ Field deferpos = -1
|
|
|
|
+ Field tidyqueue1 = -1, tidyqueue2 = -1
|
|
|
|
+ Field editmenu:TGadget
|
|
|
|
+ Field codenode:TCodeNode
|
|
|
|
+ Field dirtynode,uc
|
|
|
|
+
|
|
|
|
+ Function RefreshHighlightingMsg()
|
|
|
|
+ msgHighlightingStatus = LocalizeString("{{msg_highlightingcode}}")
|
|
|
|
+ EndFunction
|
|
|
|
+
|
|
|
|
+ Function IsNotAlpha(c)
|
|
|
|
+ If c<48 Return True
|
|
|
|
+ If c>=58 And c<65 Return True
|
|
|
|
+ If c>=91 And c<95 Return True
|
|
|
|
+ If c>=96 And c<97 Return True
|
|
|
|
+ If c>=123 Return True
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function WordAtPos$(a$,p)
|
|
|
|
+ Local c,q,r,n
|
|
|
|
+ ' string literal
|
|
|
|
+ q=a.findlast(EOL$,a.length-p)
|
|
|
|
+ If q=-1 q=0
|
|
|
|
+ For q=q To p-1
|
|
|
|
+ If a[q]=34 Then
|
|
|
|
+ n=Not n
|
|
|
|
+ r=q
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+ If n
|
|
|
|
+ q=a.Find("~q",r+1)+1
|
|
|
|
+ If q=0 q=a.length
|
|
|
|
+ Return a[r..q]
|
|
|
|
+ EndIf
|
|
|
|
+ ' alphanumeric
|
|
|
|
+ p=Min(p,a.length-1) 'simon was here - crash when checking at last char
|
|
|
|
+ For p=p Until 0 Step -1 'simon was here unto->to
|
|
|
|
+ If IsNotAlpha(a$[p]) Continue
|
|
|
|
+ Exit
|
|
|
|
+ Next
|
|
|
|
+ For q=p-1 To 0 Step -1
|
|
|
|
+ If IsNotAlpha(a$[q]) Exit
|
|
|
|
+ Next
|
|
|
|
+ For r=p To a.length-1
|
|
|
|
+ If IsNotAlpha(a$[r]) Exit
|
|
|
|
+ Next
|
|
|
|
+ Return a[q+1..r]
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function FirstDiff(s0$,s1$)
|
|
|
|
+ Local n = Min(s0.length,s1.length)
|
|
|
|
+ For Local i:Int = 0 Until n
|
|
|
|
+ If s0[i]<>s1[i] Return i
|
|
|
|
+ Next
|
|
|
|
+ Return n
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function LastDiff(s0$,s1$)
|
|
|
|
+ Local n = Min(s0.length,s1.length)
|
|
|
|
+ Local i = s0.length-1
|
|
|
|
+ Local j = s1.length-1
|
|
|
|
+ While n>0
|
|
|
|
+ If s0[i]<>s1[j] Exit
|
|
|
|
+ i:-1;j:-1;n:-1
|
|
|
|
+ Wend
|
|
|
|
+ Return i+1
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method parsebmx(n:TCodeNode)
|
|
|
|
+ Local src$,line,col
|
|
|
|
+ Local p,p1,r,t,m,f,l,e
|
|
|
|
+
|
|
|
|
+ src=cleansrcl
|
|
|
|
+ p1=src.length
|
|
|
|
+ p=-1;r=-1;t=-1;m=-1;f=-1;l=-1
|
|
|
|
+ While p<p1 'update rem,type,method,function,label pointers
|
|
|
|
+ While r<=p
|
|
|
|
+ r=FindToken("rem",src,r+1)
|
|
|
|
+ Wend
|
|
|
|
+ While t<=p
|
|
|
|
+ t=FindToken("type",src,t+1)
|
|
|
|
+ Wend
|
|
|
|
+ While m<=p
|
|
|
|
+ m=FindToken("method",src,m+1)
|
|
|
|
+ Wend
|
|
|
|
+ While f<=p
|
|
|
|
+ f=FindToken("function",src,f+1)
|
|
|
|
+ Wend
|
|
|
|
+ While l<=p
|
|
|
|
+ l=FindLabel(src,l+1)
|
|
|
|
+ Wend
|
|
|
|
+ If r<t And r<m And r<f And r<l
|
|
|
|
+ p=FindEndToken("rem",src,r+1,True)
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+ p=Min(t,Min(m,Min(f,l)))
|
|
|
|
+ If p=src.length Exit
|
|
|
|
+ While (n And n.parent And p>n.pos+n.count)
|
|
|
|
+ If Not TCodeNode(n.parent)
|
|
|
|
+ If n.parent.parent
|
|
|
|
+ n = TCodeNode(n.parent.parent)
|
|
|
|
+ Else
|
|
|
|
+ n = Null
|
|
|
|
+ EndIf
|
|
|
|
+ Else
|
|
|
|
+ n=TCodeNode(n.parent)
|
|
|
|
+ EndIf
|
|
|
|
+ Wend
|
|
|
|
+ If t<m And t<f And t<l
|
|
|
|
+ e=src.find(EOL,t)
|
|
|
|
+ n=n.AddCodeNode(cleansrc[t..e],t,FindEndToken("type",src,t,True))
|
|
|
|
+ p=t+1
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+ If m<f And m<l
|
|
|
|
+ e=src.find(EOL,m)
|
|
|
|
+ n.AddCodeNode(cleansrc[m..e],m,e)
|
|
|
|
+ p=m+1
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+ If f<l
|
|
|
|
+ e=src.find(EOL,f)
|
|
|
|
+ n.AddCodeNode(cleansrc[f..e],f,e)
|
|
|
|
+ p=f+1
|
|
|
|
+ Continue
|
|
|
|
+ Else
|
|
|
|
+ e=src.find(EOL,l)
|
|
|
|
+ n.AddCodeNode(cleansrc[l..e],l,e)
|
|
|
|
+ p=l+1
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+ Wend
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method GetNode:TNode()
|
|
|
|
+ Local root:TCodeNode = New TCodeNode
|
|
|
|
+ root.name = StripDir(path)
|
|
|
|
+ root.owner = Self
|
|
|
|
+ root.count = cleansrc.length
|
|
|
|
+ If isbmx parsebmx(root) ' stopped code view parse on non bmx files
|
|
|
|
+ If codenode
|
|
|
|
+ If host.options.sortcode root.sortkids
|
|
|
|
+ codenode.Sync(root)
|
|
|
|
+ root.Free()
|
|
|
|
+ Else
|
|
|
|
+ codenode=root
|
|
|
|
+ EndIf
|
|
|
|
+ Return codenode
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method HighlightLine(line,column = 0)
|
|
|
|
+ Local i:Int, tmpCharLineStart% = TextAreaChar(textarea,line)
|
|
|
|
+ Local tmpLine$ = TextAreaText( textarea, line, 1, TEXTAREA_LINES ).Replace("~r","").Replace("~n","")
|
|
|
|
+ For i = column Until tmpLine.length
|
|
|
|
+ If IsNotAlpha(tmpLine[i]) Then tmpCharLineStart:+1 Else Exit
|
|
|
|
+ Next
|
|
|
|
+ SelectTextAreaText textarea,line-1,0,TEXTAREA_LINES
|
|
|
|
+ SelectTextAreaText textarea,line+1,0,TEXTAREA_LINES
|
|
|
|
+ If i = tmpLine.length Or ..
|
|
|
|
+ ( TextAreaCharX( textarea, tmpCharLineStart + tmpLine.length-i ) - TextAreaCharX( textarea, tmpCharLineStart ) >= ClientWidth(textarea) ) Then
|
|
|
|
+ SelectTextAreaText textarea,line,1,TEXTAREA_LINES
|
|
|
|
+ Else
|
|
|
|
+ SelectTextAreaText textarea,tmpCharLineStart,tmpLine.length-i,TEXTAREA_CHARS
|
|
|
|
+ EndIf
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method ShowPos(pos)
|
|
|
|
+ host.SelectPanel( Self )
|
|
|
|
+ HighlightLine( TextAreaLine(textarea,pos) )
|
|
|
|
+ UpdateCursor()
|
|
|
|
+ ActivateGadget( textarea )
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Debug(line,column)
|
|
|
|
+ HighlightLine( line-1 )
|
|
|
|
+ UpdateCursor()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Edit()
|
|
|
|
+ SelectTextAreaText( textarea,cursorpos,0,TEXTAREA_CHARS )
|
|
|
|
+ ActivateGadget( textarea )
|
|
|
|
+ UpdateStatus()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method UpdateStatus()
|
|
|
|
+ Local c = cursorpos+cursorlen
|
|
|
|
+ If cursorline Then c:-TextAreaChar(textarea,cursorline-1)
|
|
|
|
+ host.SetStatus helpstring+"~t~t"+LocalizeString("{{status_line_char}}").Replace("%1",cursorline).Replace("%2",(c+1))
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method UpdateCursor()
|
|
|
|
+ oldpos=cursorpos
|
|
|
|
+ oldlen=cursorlen
|
|
|
|
+ cursorpos=TextAreaCursor(textarea,TEXTAREA_CHARS)
|
|
|
|
+ cursorlen=TextAreaSelLen(textarea,TEXTAREA_CHARS)
|
|
|
|
+ If cursorpos<>oldpos Or cursorlen<>oldlen
|
|
|
|
+ Local l = TextAreaLine(textarea,cursorpos)+1
|
|
|
|
+ If l<>cursorline And dirtynode
|
|
|
|
+ GetNode().Refresh
|
|
|
|
+ dirtynode=False
|
|
|
|
+ If (deferpos>=0) UpdateCode 'SetCode cleansrc
|
|
|
|
+ EndIf
|
|
|
|
+ cursorline=l
|
|
|
|
+ UpdateStatus()
|
|
|
|
+ BracketMatching(cleansrcl)
|
|
|
|
+ If (tidyqueue1 >= 0 Or tidyqueue2 >= 0) Then UpdateCode()
|
|
|
|
+ PollSystem
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+' tdiff - pos del$ add$
|
|
|
|
+
|
|
|
|
+ Method CalcDiff:TDiff(src$)
|
|
|
|
+ Local d:TDiff
|
|
|
|
+ If src.length<>cleansrc.length
|
|
|
|
+ d=New TDiff
|
|
|
|
+ d.pos0=cursorpos
|
|
|
|
+ d.count0=cursorlen
|
|
|
|
+ d.pos=oldpos
|
|
|
|
+ d.count=oldlen
|
|
|
|
+ If cursorlen And oldlen 'block modified
|
|
|
|
+ d.del=cleansrc[oldpos..oldpos+oldlen]
|
|
|
|
+ d.add=src[oldpos..cursorpos+cursorlen]
|
|
|
|
+ d.pos1=oldpos
|
|
|
|
+ Else
|
|
|
|
+ If cursorpos<=oldpos And cursorlen<=oldlen 'backspace
|
|
|
|
+ d.del=cleansrc[cursorpos..cursorpos+cleansrc.length-src.length]
|
|
|
|
+ d.pos1=cursorpos
|
|
|
|
+ Else 'insert
|
|
|
|
+ d.del=cleansrc[oldpos..oldpos+oldlen]
|
|
|
|
+ d.add=src[oldpos..cursorpos+cursorlen]
|
|
|
|
+ d.pos1=oldpos
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Else
|
|
|
|
+ If cursorpos>oldpos 'overwrite
|
|
|
|
+ d=New TDiff
|
|
|
|
+ d.pos0=cursorpos
|
|
|
|
+ d.count0=cursorlen
|
|
|
|
+ d.pos=oldpos
|
|
|
|
+ d.count=oldlen
|
|
|
|
+ d.del=cleansrc[oldpos..cursorpos]
|
|
|
|
+ d.add=src[oldpos..cursorpos]
|
|
|
|
+ d.pos1=oldpos
|
|
|
|
+ If d.del = d.add Then d.textchange=False
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ Return d
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method UpdateCode(makeundo=True)
|
|
|
|
+ Local cpos
|
|
|
|
+ Local src$ = TextAreaText(textarea)
|
|
|
|
+ Local d:TDiff = CalcDiff(src)
|
|
|
|
+ If d
|
|
|
|
+ If makeundo And d.textchange
|
|
|
|
+ undolist.AddLast d
|
|
|
|
+ redolist.Clear
|
|
|
|
+ EndIf
|
|
|
|
+ SetCode src,d
|
|
|
|
+ If d.textchange Then dirtynode=True
|
|
|
|
+ EndIf
|
|
|
|
+ If (deferpos >= 0) Or (tidyqueue1 >= 0) Or (tidyqueue2 >= 0) Then SetCode src
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Undo()
|
|
|
|
+ Local d:TDiff
|
|
|
|
+ If undolist.IsEmpty() Return
|
|
|
|
+ d=TDiff(undolist.RemoveLast())
|
|
|
|
+ redolist.AddLast d
|
|
|
|
+ SetTextAreaText textarea,d.del,d.pos1,d.add.length
|
|
|
|
+ SelectTextAreaText(textarea,d.pos,d.count)
|
|
|
|
+ SetCode TextAreaText(textarea),d
|
|
|
|
+ UpdateCursor
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Redo()
|
|
|
|
+ Local d:TDiff
|
|
|
|
+ If redolist.IsEmpty() Return
|
|
|
|
+ d=TDiff(redolist.RemoveLast())
|
|
|
|
+ undolist.AddLast d
|
|
|
|
+ SetTextAreaText textarea,d.add,d.pos,d.del.length
|
|
|
|
+ SelectTextAreaText(textarea,d.pos0,d.count0)
|
|
|
|
+ UpdateCursor
|
|
|
|
+ SetCode TextAreaText(textarea),d
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RefreshStyle()
|
|
|
|
+ Local rgb:TColor
|
|
|
|
+ Local src$
|
|
|
|
+ Local charwidth
|
|
|
|
+ charwidth=host.options.editfont.CharWidth(32)
|
|
|
|
+ SetTextAreaTabs textarea,host.options.tabsize*charwidth
|
|
|
|
+ SetMargins textarea,4
|
|
|
|
+ SetTextAreaFont textarea,host.options.editfont
|
|
|
|
+ rgb=host.options.editcolor
|
|
|
|
+ SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,True
|
|
|
|
+ rgb=host.options.styles[0].color
|
|
|
|
+ SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,False
|
|
|
|
+ src=cleansrc
|
|
|
|
+ cleansrc=""
|
|
|
|
+ cleansrcl=""
|
|
|
|
+ cursorpos=0
|
|
|
|
+ SetCode(src)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function IsntAlphaNumeric(c) 'lowercase test only
|
|
|
|
+ If c<48 Return True
|
|
|
|
+ If c>=58 And c<95 Return True
|
|
|
|
+ If c=96 Return True
|
|
|
|
+ If c>=123 Return True
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function IsntAlphaNumericOrQuote(c) 'lowercase test only
|
|
|
|
+ If c=34 Return False
|
|
|
|
+ If c<48 Return True
|
|
|
|
+ If c>=58 And c<95 Return True
|
|
|
|
+ If c=96 Return True
|
|
|
|
+ If c>=123 Return True
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function IsCode(src$,p)
|
|
|
|
+ Local n
|
|
|
|
+ Local l = src.FindLast(EOL$,src.length-p)
|
|
|
|
+ If l=-1 l=0
|
|
|
|
+ Local q = src.Find("'",l)
|
|
|
|
+ If q<>-1 And q<p Return
|
|
|
|
+ q=l
|
|
|
|
+ While q<p
|
|
|
|
+ q=src.Find(QUOTES$,q)+1
|
|
|
|
+ If q=0 Exit
|
|
|
|
+ If q<=p n:+1
|
|
|
|
+ Wend
|
|
|
|
+ Return Not(n&1)
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function FindLabel(src$,pos)
|
|
|
|
+ Local p,q,c
|
|
|
|
+ While pos>=0
|
|
|
|
+ p=src.Find("#",pos)
|
|
|
|
+ If p=-1 Exit
|
|
|
|
+ q=p
|
|
|
|
+ While q>0
|
|
|
|
+ q:-1
|
|
|
|
+ c=src[q]
|
|
|
|
+ If c=13 Return p
|
|
|
|
+ If c=10 Return p
|
|
|
|
+ If c=32 Or c=9 Continue
|
|
|
|
+ Exit
|
|
|
|
+ Wend
|
|
|
|
+ If q<0 Return p
|
|
|
|
+ pos=p+1
|
|
|
|
+ Wend
|
|
|
|
+ Return src.length
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function FindToken(token$,src$,pos) 'lowercase src only!
|
|
|
|
+ Local p,c
|
|
|
|
+ Local n=token.length
|
|
|
|
+ While pos>=0
|
|
|
|
+ p=src.Find(token,pos)
|
|
|
|
+ If p=-1 Exit
|
|
|
|
+ c=10 If p>0 c=src[p-1]
|
|
|
|
+ If isntalphanumeric(c)
|
|
|
|
+ If p+n<src.length c=src[p+n]
|
|
|
|
+ If isntalphanumeric(c)
|
|
|
|
+ If iscode(src,p)
|
|
|
|
+ If p<4 Or src[p-4..p]<>"end " Return p
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ pos=p+1
|
|
|
|
+ Wend
|
|
|
|
+ Return src.length
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function FindEndToken(token$,src$,pos,returnlast=False) 'if true returns first character after endtoken
|
|
|
|
+ Local p,q,e$,n
|
|
|
|
+
|
|
|
|
+ p=pos
|
|
|
|
+ e$="end"+token
|
|
|
|
+ n=e.length
|
|
|
|
+ While p<src.length
|
|
|
|
+ p=src.Find(e$,p)
|
|
|
|
+ If p=-1 Exit
|
|
|
|
+ If p+n=src.length Or isntalphanumeric(src[p+n])
|
|
|
|
+ If iscode(src,p)
|
|
|
|
+ If p=0 Or isntalphanumeric(src[p-1]) Exit
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ p=p+n
|
|
|
|
+ Wend
|
|
|
|
+ If p=-1 p=src.length Else If returnlast p:+n
|
|
|
|
+ q=pos
|
|
|
|
+ e$="end "+token
|
|
|
|
+ n=e.length
|
|
|
|
+ While q<src.length
|
|
|
|
+ q=src.Find(e$,q)
|
|
|
|
+ If q=-1 Exit
|
|
|
|
+ If q+n=src.length Or isntalphanumeric(src[q+n])
|
|
|
|
+ If iscode(src,q)
|
|
|
|
+ If q=0 Or isntalphanumeric(src[q-1]) Exit
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ q=q+n
|
|
|
|
+ Wend
|
|
|
|
+ If q=-1 q=src.length Else If returnlast q:+n
|
|
|
|
+ Return Min(p,q)
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function IsFirstCharOnLine(src$,pos)
|
|
|
|
+ Local c
|
|
|
|
+ For Local i:Int = 1 To pos
|
|
|
|
+ c=src[pos-i]
|
|
|
|
+ If c=10 Or c=13 Return True
|
|
|
|
+ If c>32 Return False
|
|
|
|
+ Next
|
|
|
|
+ Return True
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+' rem and endrem must be first nonwhitespace on line - following funcs are for lowercase src only
|
|
|
|
+
|
|
|
|
+ Function FindRem(src$,pos)
|
|
|
|
+ While pos<src.length
|
|
|
|
+ pos=FindToken("rem",src,pos)
|
|
|
|
+ If pos=src.length Exit
|
|
|
|
+ If IsFirstCharOnLine(src,pos) Return pos
|
|
|
|
+ pos:+1
|
|
|
|
+ Wend
|
|
|
|
+ Return pos
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function FindEndRem(src$,pos,returnlast=False)
|
|
|
|
+ Local i,c
|
|
|
|
+ While pos<src.length
|
|
|
|
+ pos=FindEndToken("rem",src,pos)
|
|
|
|
+ If pos=src.length Exit
|
|
|
|
+ If IsFirstCharOnLine(src,pos)
|
|
|
|
+ If returnlast
|
|
|
|
+ If src[pos+5]=Asc("e") Or src[pos+5]=Asc("E") pos:+1
|
|
|
|
+ pos:+6
|
|
|
|
+ EndIf
|
|
|
|
+ Return pos
|
|
|
|
+ EndIf
|
|
|
|
+ pos:+1
|
|
|
|
+ Wend
|
|
|
|
+ Return src.length
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Function FindPrevRem(src$,pos) 'lowercase src only!
|
|
|
|
+ Local p,c
|
|
|
|
+ While pos>0
|
|
|
|
+ If pos>src.length Exit 'fixed endrem on lastline overrun
|
|
|
|
+ p=src.FindLast("rem",src.length-pos)
|
|
|
|
+ If p=-1 Exit
|
|
|
|
+ If isntalphanumeric(src[p+3]) And IsFirstCharOnLine(src,p) Return p
|
|
|
|
+ pos=p-1
|
|
|
|
+ Wend
|
|
|
|
+ Return -1
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method IsRemmed(pos,src$)
|
|
|
|
+ Local p = FindPrevRem(src$,Min(pos+3,src.length))
|
|
|
|
+ If p<0 Return
|
|
|
|
+ p=FindEndRem(src$,p)
|
|
|
|
+ If p<0 Or pos<p Return True
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method WasRemmed(pos,src$)
|
|
|
|
+ Local s$ = cleansrcl
|
|
|
|
+ Local p = (src.length-s.length)
|
|
|
|
+ If p<0 pos:-p
|
|
|
|
+ p=FindPrevRem(s$,Min(pos+3,s.length))
|
|
|
|
+ If p<0 Return
|
|
|
|
+ p=FindEndRem(s$,p)
|
|
|
|
+ If pos<p Return True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method CheckDirty(src$)
|
|
|
|
+ SetDirty (Not (src=filesrc And undolist.IsEmpty()))
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method HasTidyQueue()
|
|
|
|
+ Return ((deferpos >= 0) Or (tidyqueue1 >= 0) Or (tidyqueue2 >= 0))
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method ClearTidyQueue(start,endpos)
|
|
|
|
+ If start<=deferpos And deferpos < endpos Then deferpos = -1
|
|
|
|
+ If start<=tidyqueue1 And tidyqueue1 < endpos Then tidyqueue1 = -1
|
|
|
|
+ If start<=tidyqueue2 And tidyqueue2 < endpos Then tidyqueue2 = -1
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method SetCode(src$,diff:TDiff=Null)
|
|
|
|
+ Local same,i,p,startp,p1,q,r,a,t$,h$,lsrc$,r0,r1,cpos,autocap
|
|
|
|
+ Local style:TTextStyle[5],s:TTextStyle
|
|
|
|
+' update dirty flag
|
|
|
|
+ CheckDirty src
|
|
|
|
+ same = Not ((diff) Or (src<>cleansrc))
|
|
|
|
+ If same And Not (diff Or HasTidyQueue()) Then Return
|
|
|
|
+ If Not isbmx Or Not host.quickhelp Or Not host.options.syntaxhighlight
|
|
|
|
+ If Not same Then
|
|
|
|
+ cleansrc=src
|
|
|
|
+ cleansrcl=src.ToLower()
|
|
|
|
+ EndIf
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+' doit
|
|
|
|
+ autocap=host.options.autocapitalize
|
|
|
|
+ If same Then lsrc = cleansrcl Else lsrc=src.ToLower()
|
|
|
|
+ cpos=TextAreaCursor(textarea,TEXTAREA_CHARS)
|
|
|
|
+ LockTextArea textarea
|
|
|
|
+ style=host.options.styles
|
|
|
|
+' calculate highlight region
|
|
|
|
+
|
|
|
|
+ If diff
|
|
|
|
+ p=diff.pos
|
|
|
|
+ p1=p+diff.add.length
|
|
|
|
+ If Not diff.add.length Then
|
|
|
|
+ p:-diff.del.length
|
|
|
|
+ EndIf
|
|
|
|
+ ElseIf HasTidyQueue()
|
|
|
|
+ p=src.length
|
|
|
|
+ If (deferpos>=0) Then
|
|
|
|
+ p = Min(p,deferpos)
|
|
|
|
+ p1 = Max(p1,deferpos+1)
|
|
|
|
+ EndIf
|
|
|
|
+ If (tidyqueue1>=0) Then
|
|
|
|
+ p = Min(p,tidyqueue1)
|
|
|
|
+ p1 = Max(p1, tidyqueue1+1)
|
|
|
|
+ EndIf
|
|
|
|
+ If (tidyqueue2>=0) Then
|
|
|
|
+ p = Min(p,tidyqueue2)
|
|
|
|
+ p1 = Max(p1, tidyqueue2+1)
|
|
|
|
+ EndIf
|
|
|
|
+ Else
|
|
|
|
+ p=firstdiff(src,cleansrc)
|
|
|
|
+ p1=lastdiff(src,cleansrc)
|
|
|
|
+ EndIf
|
|
|
|
+ q=src.length-cleansrc.length
|
|
|
|
+ If p1-p<q p1=p+q
|
|
|
|
+ If p1<p p1=p
|
|
|
|
+
|
|
|
|
+' round region to line breaks
|
|
|
|
+ 'Print "p="+p+" p1="+p1
|
|
|
|
+ If p>src.length p=src.length
|
|
|
|
+ p=src.findlast(EOL,src.length-(p-1))+1
|
|
|
|
+ p1=src.find(EOL,p1)+1
|
|
|
|
+ If p1=0 p1=src.length
|
|
|
|
+' if endrem between p0,p1 and next rem after p1 move p1 forwards
|
|
|
|
+ r1=FindEndRem(lsrc,p)
|
|
|
|
+ If r1<p1 And wasremmed(r1+6,lsrc)
|
|
|
|
+ r0=FindRem(lsrc,r1+6)
|
|
|
|
+ If r0>p1 p1=r0
|
|
|
|
+ EndIf
|
|
|
|
+' if rem between p0,p1 and matching endrem after p1 move p1 forewards
|
|
|
|
+ r0=FindPrevRem(lsrc,p1)
|
|
|
|
+ If r0>=p And r0+3<>cpos 'defer fix
|
|
|
|
+ r1=FindEndRem(lsrc,r0,True)
|
|
|
|
+ If r1>p1 p1=r1
|
|
|
|
+ EndIf
|
|
|
|
+' if rem before p0 and matching endrem after p0 highlight to endrem and move p0 forwards
|
|
|
|
+ r0=FindPrevRem(lsrc,p)
|
|
|
|
+ If r0<>-1 And r0<p
|
|
|
|
+ r1=FindEndRem(lsrc,r0,True)
|
|
|
|
+ If r1>p
|
|
|
|
+ s=style[COMMENT]
|
|
|
|
+ If r1>p s.Format(textarea,p,r1-p)
|
|
|
|
+ If autocap And r1<src.length
|
|
|
|
+ If lsrc[r1-6..r1]="endrem" And src[r1-6..r1]<>"EndRem" SetTextAreaText textarea,"EndRem",r1-6,6
|
|
|
|
+ If lsrc[r1-7..r1]="end rem" And src[r1-7..r1]<>"End Rem" SetTextAreaText textarea,"End Rem",r1-7,7
|
|
|
|
+ EndIf
|
|
|
|
+ ClearTidyQueue(p,r1)
|
|
|
|
+ p=r1
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+' if was remmed and now isn't move p1 down to nearest rem or endrem
|
|
|
|
+ If WasRemmed(p,lsrc)
|
|
|
|
+ r0=FindRem(lsrc,p)
|
|
|
|
+ r1=FindEndRem(lsrc,r0,True)
|
|
|
|
+ p1=Max(p1,Min(r0,r1))
|
|
|
|
+ EndIf
|
|
|
|
+' highlight code
|
|
|
|
+ ClearTidyQueue(p,p1)
|
|
|
|
+
|
|
|
|
+ s=style[NORMAL]
|
|
|
|
+ If p1>p s.format(textarea,p,p1-p)
|
|
|
|
+ startp = p
|
|
|
|
+
|
|
|
|
+ While p<p1
|
|
|
|
+ host.UpdateProgress(msgHighlightingStatus,(p*100)/p1)
|
|
|
|
+ a=src[p]
|
|
|
|
+' quoted strings
|
|
|
|
+ If a=34
|
|
|
|
+ q=p1
|
|
|
|
+ r=src.Find(Chr(34),p+1)
|
|
|
|
+ If r>-1 And r<q q=r+1
|
|
|
|
+ r=src.Find(EOL,p+1)
|
|
|
|
+ If r>-1 And r<q q=r
|
|
|
|
+ s=style[QUOTED]
|
|
|
|
+ s.format(textarea,p,q-p)
|
|
|
|
+ p=q
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+' single line comments
|
|
|
|
+ If a=39
|
|
|
|
+ q=p1
|
|
|
|
+ r=src.Find(EOL,p+1)
|
|
|
|
+ If r>-1 And r<q q=r
|
|
|
|
+ s=style[COMMENT]
|
|
|
|
+ s.format(textarea,p,q-p)
|
|
|
|
+ p=q
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+' tokens
|
|
|
|
+ If (a>=65 And a<91) Or (a>=97 And a<123) Or (a=95)
|
|
|
|
+ q=p+1
|
|
|
|
+ While q<p1
|
|
|
|
+ a=src[q]
|
|
|
|
+ If a<48 Exit 'changed to include dot (chr 47)
|
|
|
|
+ If a>=58 And a<65 Exit
|
|
|
|
+ If a>=91 And a<95 Exit
|
|
|
|
+ If a=96 Exit
|
|
|
|
+ If a>122 Exit
|
|
|
|
+ q:+1
|
|
|
|
+ Wend
|
|
|
|
+ t$=src[p..q]
|
|
|
|
+ h$=host.quickhelp.token(t$)
|
|
|
|
+ If h$
|
|
|
|
+ If h$<>t$ And autocap
|
|
|
|
+ If cpos<p Or cpos>q
|
|
|
|
+ SetTextAreaText textarea,h,p,h.length
|
|
|
|
+ Else
|
|
|
|
+ deferpos=q
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ s=style[KEYWORD]
|
|
|
|
+ If h$="Rem" And IsFirstCharOnLine(lsrc,p) ' Not (p>4 And lsrc[p-4..p]="end ")
|
|
|
|
+ If q<>cpos
|
|
|
|
+ q=FindEndRem(lsrc,p,True)
|
|
|
|
+ s=style[COMMENT]
|
|
|
|
+ Else
|
|
|
|
+ deferpos=q
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ s.format(textarea,p,q-p)
|
|
|
|
+ EndIf
|
|
|
|
+ p=q
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+' numbers
|
|
|
|
+ If (p=0 Or IsntAlphaNumeric(lsrc[p-1])) And ((a>=$30 And a<$3A) Or (a=$24) Or (a=$25) Or (a=$2E)) '0-9, $, %, .
|
|
|
|
+ q=p+1
|
|
|
|
+ Local hexed:Int = (a=$24), binaried:Int = (a=$25), dots:Int = (a=$2E)
|
|
|
|
+ Local valid:Int = Not(hexed Or binaried Or dots)
|
|
|
|
+
|
|
|
|
+ While q<(p1)
|
|
|
|
+ a=lsrc[q]
|
|
|
|
+ q:+1
|
|
|
|
+ If (a>=$30 And a<$3A) Then
|
|
|
|
+ valid = True
|
|
|
|
+ Continue '0-9
|
|
|
|
+ EndIf
|
|
|
|
+ If hexed
|
|
|
|
+ If (a>=$61 And a<$67) Then 'a-f (only test lower as 'a' var is from lsrc)
|
|
|
|
+ valid = True
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ If (a=$2E) Then
|
|
|
|
+ 'Hex or Binary literals don't support decimal points
|
|
|
|
+ If Not (hexed Or binaried) Then
|
|
|
|
+ dots:+1
|
|
|
|
+ 'Fix for slicing '..' syntax
|
|
|
|
+ If src[q-2] = $2E Then
|
|
|
|
+ dots:-2
|
|
|
|
+ q:-2
|
|
|
|
+ Exit
|
|
|
|
+ EndIf
|
|
|
|
+ 'End Fix
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ If Not IsntAlphaNumeric(a) Then valid = False
|
|
|
|
+ q:-1
|
|
|
|
+ Exit
|
|
|
|
+ Wend
|
|
|
|
+ If valid And dots < 2 Then style[NUMBER].format(textarea,p,(q-p))
|
|
|
|
+ 'Fix for slicing '..' syntax
|
|
|
|
+ If q<src.length And (src[q]=Asc(".")) Then q:+1
|
|
|
|
+ If q<src.length And (src[q]=Asc(".")) Then q:+1
|
|
|
|
+ 'End Fix
|
|
|
|
+ p=q
|
|
|
|
+ Continue
|
|
|
|
+ EndIf
|
|
|
|
+ p:+1
|
|
|
|
+ Wend
|
|
|
|
+ BracketMatching(lsrc,startp,p1,True)
|
|
|
|
+ UnlockTextArea textarea
|
|
|
|
+ If Not same
|
|
|
|
+ cleansrc=src
|
|
|
|
+ cleansrcl=lsrc
|
|
|
|
+ EndIf
|
|
|
|
+' CheckDirty src simon was here
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Field currentbrackets:Int[]
|
|
|
|
+
|
|
|
|
+ Method BracketMatching(lsrc$,cln1=-1,cln2=-1,alwaysfind:Int = False)
|
|
|
|
+
|
|
|
|
+ Local check:Int, depth:Int, style:TTextStyle[] = host.options.styles
|
|
|
|
+ Local otherchar:Int = 0, absotherchar:Int = 0, othercharpos:Int = 0, limit:Int
|
|
|
|
+ Local currentchar:Int = 0, currentcharpos:Int = Max(cursorpos-1,0)
|
|
|
|
+
|
|
|
|
+ If cursorlen Then Return
|
|
|
|
+
|
|
|
|
+ If currentbrackets Then
|
|
|
|
+ If Not(cln2 > currentbrackets[0] And cln1 <= currentbrackets[0]) Then
|
|
|
|
+ If currentbrackets[0]>-1 Then tidyqueue1 = currentbrackets[0]
|
|
|
|
+ EndIf
|
|
|
|
+ If Not(cln2 > currentbrackets[1] And cln1 <= currentbrackets[1]) Then
|
|
|
|
+ If currentbrackets[1]>-1 Then tidyqueue2 = currentbrackets[1]
|
|
|
|
+ EndIf
|
|
|
|
+ currentbrackets = Null
|
|
|
|
+ If Not alwaysfind Then Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If host.options.bracketmatching And isbmx And Not IsRemmed(currentcharpos,lsrc) Then
|
|
|
|
+
|
|
|
|
+ limit = Min(lsrc.length,currentcharpos+2)
|
|
|
|
+
|
|
|
|
+ While currentcharpos >= 0 And currentcharpos < limit
|
|
|
|
+ If IsCode(lsrc,currentcharpos) Then
|
|
|
|
+ Select lsrc[currentcharpos]
|
|
|
|
+ Case Asc("(");otherchar = Asc(")");Exit
|
|
|
|
+ Case Asc("{");otherchar = Asc("}");Exit
|
|
|
|
+ Case Asc("[");otherchar = Asc("]");Exit
|
|
|
|
+ ' Negate char code to search backwards
|
|
|
|
+ Case Asc(")");otherchar = -Asc("(");Exit
|
|
|
|
+ Case Asc("}");otherchar = -Asc("{");Exit
|
|
|
|
+ Case Asc("]");otherchar = -Asc("[");Exit
|
|
|
|
+ EndSelect
|
|
|
|
+ EndIf
|
|
|
|
+ currentcharpos:+1
|
|
|
|
+ Wend
|
|
|
|
+
|
|
|
|
+ If otherchar Then
|
|
|
|
+
|
|
|
|
+ absotherchar = (Abs otherchar)
|
|
|
|
+ currentchar = lsrc[currentcharpos]
|
|
|
|
+
|
|
|
|
+ LockTextArea textarea
|
|
|
|
+ style[MATCHING].format(textarea, currentcharpos, 1)
|
|
|
|
+ currentbrackets = [currentcharpos,-1]
|
|
|
|
+
|
|
|
|
+ othercharpos = currentcharpos+(otherchar/absotherchar)
|
|
|
|
+
|
|
|
|
+ While othercharpos < lsrc.length And othercharpos >= 0
|
|
|
|
+
|
|
|
|
+ If IsCode(lsrc,othercharpos) Then
|
|
|
|
+ Select lsrc[othercharpos]
|
|
|
|
+ Case Asc(" "), Asc("~t")
|
|
|
|
+ 'Do nothing
|
|
|
|
+ Case Asc("'")
|
|
|
|
+ Exit
|
|
|
|
+ Case absotherchar
|
|
|
|
+ If check < 0 Then Exit Else check = 0
|
|
|
|
+ If depth Then
|
|
|
|
+ depth:-1
|
|
|
|
+ Else
|
|
|
|
+ style[MATCHING].format(textarea, othercharpos, 1)
|
|
|
|
+ currentbrackets[1] = othercharpos
|
|
|
|
+ UnlockTextArea textarea
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ Case Asc("~n")
|
|
|
|
+ If (otherchar/absotherchar) > 0 Then
|
|
|
|
+ If check = 2 Then check = 0 Else Exit
|
|
|
|
+ Else
|
|
|
|
+ If check < 0 Then Exit Else check = -2
|
|
|
|
+ EndIf
|
|
|
|
+ Case Asc(".")
|
|
|
|
+ check:+1
|
|
|
|
+ Default
|
|
|
|
+ If check < 0 Then Exit Else check = 0
|
|
|
|
+ If lsrc[othercharpos] = lsrc[currentcharpos] Then depth:+1
|
|
|
|
+ EndSelect
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ othercharpos:+(otherchar/absotherchar)
|
|
|
|
+
|
|
|
|
+ Wend
|
|
|
|
+
|
|
|
|
+ UnlockTextArea textarea
|
|
|
|
+
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method AutoIndent()
|
|
|
|
+ Local p,q
|
|
|
|
+ Local c = TextAreaCursor(textarea,TEXTAREA_CHARS)
|
|
|
|
+ Local n = TextAreaSelLen(textarea,TEXTAREA_CHARS)
|
|
|
|
+ If c<cleansrc.length
|
|
|
|
+ p=cleansrc.FindLast(EOL,cleansrc.length-(c-1))+1
|
|
|
|
+ q=p
|
|
|
|
+ While cleansrc[q]=9 And q<c
|
|
|
|
+ q:+1
|
|
|
|
+ Wend
|
|
|
|
+ If q>c q=c
|
|
|
|
+ EndIf
|
|
|
|
+ SetTextAreaText textarea,EOL$+cleansrc[p..q],c,n
|
|
|
|
+ SelectTextAreaText textarea,c+1+q-p,0
|
|
|
|
+ UpdateCursor
|
|
|
|
+ UpdateCode
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method IndentCode()
|
|
|
|
+ Local a$
|
|
|
|
+' blockindent
|
|
|
|
+ Local p0 = TextAreaCursor(textarea,TEXTAREA_LINES)
|
|
|
|
+ Local p1 = TextAreaSelLen(textarea,TEXTAREA_LINES)
|
|
|
|
+' v122: make sure the entire block is selected (start cursor pos may in the middle of the line)
|
|
|
|
+ SelectTextAreaText textarea , p0 , p1 , TEXTAREA_LINES
|
|
|
|
+ UpdateCursor
|
|
|
|
+ For Local i:Int = 0 Until p1
|
|
|
|
+ a$="~t"+TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
|
|
|
|
+ SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
|
|
|
|
+ Next
|
|
|
|
+ SelectTextAreaText textarea,p0,p1,TEXTAREA_LINES
|
|
|
|
+ UpdateCursor
|
|
|
|
+ UpdateCode
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method OutdentCode()
|
|
|
|
+ Local a$,modified
|
|
|
|
+' blockoutdent
|
|
|
|
+ Local p0 = TextAreaCursor(textarea,TEXTAREA_LINES)
|
|
|
|
+ Local p1 = TextAreaSelLen(textarea,TEXTAREA_LINES)
|
|
|
|
+' v122: make sure the entire block is selected (start cursor pos may in the middle of the line)
|
|
|
|
+ SelectTextAreaText textarea , p0 , p1 , TEXTAREA_LINES
|
|
|
|
+ UpdateCursor
|
|
|
|
+ For Local i:Int = 0 Until p1
|
|
|
|
+ a$=TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
|
|
|
|
+ If a[0]=9 a$=a$[1..];modified=True
|
|
|
|
+ SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
|
|
|
|
+ Next
|
|
|
|
+ If Not modified
|
|
|
|
+ For Local i:Int = 0 Until p1
|
|
|
|
+ a$=TextAreaText(textarea,p0+i,1,TEXTAREA_LINES)
|
|
|
|
+ If a[0]=32 a$=a$[1..]
|
|
|
|
+ SetTextAreaText textarea,a$,p0+i,1,TEXTAREA_LINES
|
|
|
|
+ Next
|
|
|
|
+ EndIf
|
|
|
|
+ SelectTextAreaText textarea,p0,p1,TEXTAREA_LINES
|
|
|
|
+ UpdateCursor
|
|
|
|
+ UpdateCode
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function FilterKey(event:TEvent,context:Object)
|
|
|
|
+' If event.id<>EVENT_KEYCHAR Return 1
|
|
|
|
+ Local id=event.id
|
|
|
|
+ Local key=event.data
|
|
|
|
+ Local mods=event.mods
|
|
|
|
+ Local this:TOpenCode=TOpenCode(context)
|
|
|
|
+?MacOS
|
|
|
|
+ If key=25 And mods=MODIFIER_SHIFT key=KEY_TAB
|
|
|
|
+?
|
|
|
|
+ If id=EVENT_KEYCHAR And this And key=KEY_TAB And TextAreaSelLen( this.textarea,TEXTAREA_CHARS )
|
|
|
|
+ Select mods
|
|
|
|
+ Case MODIFIER_NONE
|
|
|
|
+ this.IndentCode
|
|
|
|
+ Case MODIFIER_SHIFT
|
|
|
|
+ this.OutdentCode
|
|
|
|
+ End Select
|
|
|
|
+ Return 0
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If id=EVENT_KEYDOWN And key=KEY_ENTER And this And this.host.options.autoindent
|
|
|
|
+ this.AutoIndent()
|
|
|
|
+ Return 0
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ Return 1
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method OnEvent()
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case textarea
|
|
|
|
+ Select EventID()
|
|
|
|
+ Case EVENT_GADGETMENU
|
|
|
|
+ PopupWindowMenu host.window,editmenu
|
|
|
|
+ Case EVENT_GADGETACTION
|
|
|
|
+ UpdateCode
|
|
|
|
+ Case EVENT_GADGETSELECT
|
|
|
|
+ UpdateCursor
|
|
|
|
+ End Select
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetDirty( bool )
|
|
|
|
+ If dirty=bool Return
|
|
|
|
+ dirty=bool
|
|
|
|
+ name=StripDir(path)
|
|
|
|
+ If (dirty) name:+"*"
|
|
|
|
+ If (host.lockedpanel=Self) name=LocalizeString("{{tab_locked:%1}}").Replace("%1",name)
|
|
|
|
+ host.RefreshPanel Self
|
|
|
|
+ PollSystem
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetLocked( bool )
|
|
|
|
+ Local locked:TOpenCode = TOpenCode(host.lockedpanel)
|
|
|
|
+ If locked And locked<>Self locked.SetLocked False
|
|
|
|
+ name=StripDir(path)
|
|
|
|
+ If (dirty) name:+"*"
|
|
|
|
+ If (bool)
|
|
|
|
+ name=LocalizeString("{{tab_locked:%1}}").Replace("%1",name)
|
|
|
|
+ host.lockedpanel=Self
|
|
|
|
+ Else
|
|
|
|
+ host.lockedpanel=Null
|
|
|
|
+ EndIf
|
|
|
|
+ host.RefreshPanel Self
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Help()
|
|
|
|
+ If Not host.quickhelp Return
|
|
|
|
+ Local p = TextAreaCursor(textarea,TEXTAREA_CHARS)
|
|
|
|
+ Local a$ = WordAtPos(cleansrc,p)
|
|
|
|
+ If a=helpcmd
|
|
|
|
+ Local l$ = host.quickhelp.link(a$)
|
|
|
|
+ If l
|
|
|
|
+ host.helppanel.go host.bmxpath+l$
|
|
|
|
+ EndIf
|
|
|
|
+ Else
|
|
|
|
+ helpcmd=a$
|
|
|
|
+ helpstring$=host.quickhelp.help(a$)
|
|
|
|
+ UpdateStatus 'host.setstatus helpstring$
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Find()
|
|
|
|
+ host.findreq.ShowFind WordAtPos(cleansrc,TextAreaCursor(textarea,TEXTAREA_CHARS))
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FindNext(s$)
|
|
|
|
+ If s seek=s Else s=seek
|
|
|
|
+ Local p = TextAreaCursor(textarea,TEXTAREA_CHARS)
|
|
|
|
+ p:+TextAreaSelLen(textarea,TEXTAREA_CHARS)
|
|
|
|
+' case insensitive
|
|
|
|
+ Local l$ = s.toLower()
|
|
|
|
+ p=cleansrcl.Find(l$,p)
|
|
|
|
+ If p=-1 p=cleansrcl.Find(l$)
|
|
|
|
+' case sensitive
|
|
|
|
+' p=cleansrc.Find(s$,p+1)
|
|
|
|
+' if p=-1 p=cleansrc.Find(s$)
|
|
|
|
+ If p=-1
|
|
|
|
+ Notify LocalizeString("{{find_notification_cannotfind}}").Replace("%1",s)
|
|
|
|
+ Return False
|
|
|
|
+ Else
|
|
|
|
+ SelectTextAreaText textarea,p,Len s,TEXTAREA_CHARS
|
|
|
|
+ UpdateCursor
|
|
|
|
+ Return True
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ReplaceAll(s$,r$)
|
|
|
|
+ Local t$ = TextAreaText( textarea ).ToLower()
|
|
|
|
+ Local c = TextAreaCursor(textarea,TEXTAREA_CHARS),i,p
|
|
|
|
+ s = s.ToLower()
|
|
|
|
+ Repeat
|
|
|
|
+ Local i2=t.Find( s,i )
|
|
|
|
+ If i2=-1 Exit
|
|
|
|
+ p:+i2-i
|
|
|
|
+ i=i2+s.length
|
|
|
|
+ SelectTextAreaText textarea,p,s.length
|
|
|
|
+ UpdateCursor
|
|
|
|
+ UpdateCode
|
|
|
|
+ SetTextAreaText textarea,r,p,s.length
|
|
|
|
+ If p<c c=c+r.length-s.length
|
|
|
|
+ p:+r.length
|
|
|
|
+ SelectTextAreaText textarea,p,0
|
|
|
|
+ UpdateCursor
|
|
|
|
+ UpdateCode
|
|
|
|
+ Forever
|
|
|
|
+ SelectTextAreaText textarea,c,0
|
|
|
|
+ UpdateCursor
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FindReplace(r$)
|
|
|
|
+ Local n, f$, x$
|
|
|
|
+ Local p = r.Find("~0")
|
|
|
|
+ If p>0
|
|
|
|
+ f$=r[..p]
|
|
|
|
+ r$=r[p+1..]
|
|
|
|
+ ReplaceAll f$,r$
|
|
|
|
+ Else
|
|
|
|
+ p=TextAreaCursor(textarea,TEXTAREA_CHARS)
|
|
|
|
+ n=TextAreaSelLen(textarea,TEXTAREA_CHARS)
|
|
|
|
+ If Not n Return
|
|
|
|
+ SetTextAreaText textarea,r$,p,n
|
|
|
|
+ SelectTextAreaText textarea,p+r.length,0
|
|
|
|
+ UpdateCursor
|
|
|
|
+ UpdateCode
|
|
|
|
+ EndIf
|
|
|
|
+ Return True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ReadSource(path$)
|
|
|
|
+ Local src$
|
|
|
|
+ src=CacheAndLoadText(path)
|
|
|
|
+ src=src.Replace(Chr(13),"")
|
|
|
|
+ src=src.Replace(Chr(11),"")
|
|
|
|
+ LockTextArea textarea
|
|
|
|
+ SetTextAreaText textarea,src
|
|
|
|
+ UnlockTextArea textarea
|
|
|
|
+ filesrc=TextAreaText(textarea)
|
|
|
|
+ cleansrc=""
|
|
|
|
+ cleansrcl=""
|
|
|
|
+ ActivateGadget textarea
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SaveSource(file$)
|
|
|
|
+ If host.options.autobackup
|
|
|
|
+ DeleteFile file+".bak"
|
|
|
|
+ RenameFile file,file+".bak"
|
|
|
|
+ EndIf
|
|
|
|
+ Local src$ = TextAreaText(textarea)
|
|
|
|
+ filesrc=src
|
|
|
|
+ src=src.Replace(Chr(13),Chr(10))
|
|
|
|
+ src=src.Replace(Chr(11),"")
|
|
|
|
+ Local txt$ = src.Replace$(Chr(10),Chr(13)+Chr(10))
|
|
|
|
+
|
|
|
|
+ Try
|
|
|
|
+ SaveText txt,file
|
|
|
|
+ Catch exception:Object
|
|
|
|
+ Local err$=String(exception)
|
|
|
|
+ Notify "Save Error~n"+err
|
|
|
|
+ Return False
|
|
|
|
+ EndTry
|
|
|
|
+
|
|
|
|
+ path=host.FullPath$(file)
|
|
|
|
+ dirty=True
|
|
|
|
+ SetDirty False
|
|
|
|
+ host.AddRecent(path$)
|
|
|
|
+ Return True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method BuildSource(quick,debug,threaded,gui,run)
|
|
|
|
+ Local cmd$,out$,arg$
|
|
|
|
+ If isbmx Or isc Or iscpp
|
|
|
|
+ cmd$=quote(host.bmkpath)
|
|
|
|
+ cmd$:+" makeapp"
|
|
|
|
+ If run cmd$:+" -x"
|
|
|
|
+ If debug cmd$:+" -d" Else cmd$:+" -r" '-v
|
|
|
|
+ If threaded cmd$:+" -h"
|
|
|
|
+ If gui cmd$:+" -t gui"
|
|
|
|
+ If Not quick cmd$:+" -a"
|
|
|
|
+ If debug Or threaded
|
|
|
|
+ out=StripExt(host.FullPath(path))
|
|
|
|
+ If debug out:+".debug"
|
|
|
|
+ If threaded out:+".mt"
|
|
|
|
+ cmd:+" -o "+quote(out$)+" "
|
|
|
|
+ EndIf
|
|
|
|
+ cmd$:+" "+quote(host.FullPath(path))
|
|
|
|
+ If run
|
|
|
|
+ arg$=host.GetCommandLine()
|
|
|
|
+ If arg cmd$:+" "+arg
|
|
|
|
+ EndIf
|
|
|
|
+ host.execute cmd,"Building "+StripExt(StripDir(path)) ',exe$
|
|
|
|
+ Else
|
|
|
|
+ If ishtml
|
|
|
|
+ host.helppanel.Go "file://"+path
|
|
|
|
+ Else
|
|
|
|
+'see what the system shell thinks of the file
|
|
|
|
+ Local cd$=CurrentDir()
|
|
|
|
+ ChangeDir ExtractDir(path)
|
|
|
|
+ cmd=StripDir(path)
|
|
|
|
+ host.execute cmd,"Building "+cmd
|
|
|
|
+ ChangeDir cd
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+' print cmd
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Save()
|
|
|
|
+ Local file$ = path
|
|
|
|
+ If host.IsTempPath(path)
|
|
|
|
+ file=RequestFile(LocalizeString("{{request_saveas_title}}"),FileTypeFilters,True,"")
|
|
|
|
+ If file="" Return False
|
|
|
|
+ If ExtractExt(file)="" file=file+".bmx"
|
|
|
|
+ dirty=True
|
|
|
|
+ EndIf
|
|
|
|
+ If dirty SaveSource(file)
|
|
|
|
+ Return True
|
|
|
|
+ End Method
|
|
|
|
+' common command interface
|
|
|
|
+
|
|
|
|
+ Method Invoke(command,argument:Object=Null)
|
|
|
|
+ Local file$,ex$
|
|
|
|
+ Local p,res
|
|
|
|
+ Select command
|
|
|
|
+ Case TOOLSHOW
|
|
|
|
+ host.SetCodeNode GetNode()
|
|
|
|
+ host.SetTitle path
|
|
|
|
+' simon was here If textarea Edit
|
|
|
|
+ If textarea ActivateGadget textarea
|
|
|
|
+
|
|
|
|
+ Case TOOLCLOSE
|
|
|
|
+ If dirty 'Or host.IsTempPath(path)
|
|
|
|
+ Invoke(TOOLSHOW)
|
|
|
|
+ p=Proceed(LocalizeString("{{request_savechanges}}").Replace("%1",name)) 'the current file?
|
|
|
|
+ If p=-1 Return True
|
|
|
|
+ If p=1
|
|
|
|
+ If Not Save() Return True
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ If codenode Then
|
|
|
|
+ codenode.Free()
|
|
|
|
+ codenode=Null
|
|
|
|
+ EndIf
|
|
|
|
+ 'Added just in case MaxGUI driver doesn't handle properly.
|
|
|
|
+ SetGadgetFilter textarea,Null,Null
|
|
|
|
+ 'Seb gone.
|
|
|
|
+ host.RemovePanel Self
|
|
|
|
+ FreeGadget(editmenu)
|
|
|
|
+ Case TOOLSAVE
|
|
|
|
+ Save
|
|
|
|
+ Case TOOLQUICKSAVE
|
|
|
|
+ file=path
|
|
|
|
+ If dirty SaveSource(file)
|
|
|
|
+ Case TOOLSAVEAS
|
|
|
|
+ file=path
|
|
|
|
+ If host.IsTempPath(path) file$=""
|
|
|
|
+ file=RequestFile(LocalizeString("{{request_saveas_title}}"),FileTypeFilters,True,file)
|
|
|
|
+ If file="" Return
|
|
|
|
+ ex$=ExtractExt(file)
|
|
|
|
+ If ex$=""
|
|
|
|
+ file=file+".bmx"
|
|
|
|
+ isbmx=True
|
|
|
|
+ Else
|
|
|
|
+ isbmx=(ex.ToLower()="bmx")
|
|
|
|
+ ishtml=(ex.ToLower()="html")
|
|
|
|
+ isc=(ex.ToLower()="c")
|
|
|
|
+ iscpp=(ex.ToLower()="cpp" Or ex.ToLower()="cxx")
|
|
|
|
+ EndIf
|
|
|
|
+ SaveSource(file$)
|
|
|
|
+ RefreshStyle()
|
|
|
|
+ GetNode().Refresh
|
|
|
|
+ SetDirty False
|
|
|
|
+ host.SetTitle path
|
|
|
|
+ Case TOOLGOTO
|
|
|
|
+ Local line=Int(String(argument))
|
|
|
|
+ SelectTextAreaText textarea,line-1,0,TEXTAREA_LINES
|
|
|
|
+ UpdateCursor
|
|
|
|
+ ActivateGadget textarea
|
|
|
|
+ Case TOOLFIND
|
|
|
|
+ Find
|
|
|
|
+ Case TOOLFINDNEXT
|
|
|
|
+ Return FindNext(String(argument))
|
|
|
|
+ Case TOOLREPLACE
|
|
|
|
+ Return FindReplace(String(argument))
|
|
|
|
+ Case TOOLBUILD
|
|
|
|
+ BuildSource host.quickenabled,host.debugenabled,host.threadedenabled,host.guienabled,False
|
|
|
|
+ Case TOOLRUN
|
|
|
|
+ BuildSource host.quickenabled,host.debugenabled,host.threadedenabled,host.guienabled,True
|
|
|
|
+ Case TOOLLOCK
|
|
|
|
+ SetLocked True
|
|
|
|
+ Case TOOLUNLOCK
|
|
|
|
+ SetLocked False
|
|
|
|
+ Case TOOLHELP
|
|
|
|
+ Help()
|
|
|
|
+ Case TOOLUNDO
|
|
|
|
+ Undo()
|
|
|
|
+ Case TOOLREDO
|
|
|
|
+ Redo()
|
|
|
|
+ Case TOOLREFRESH
|
|
|
|
+ RefreshStyle()
|
|
|
|
+ Case TOOLCUT
|
|
|
|
+ GadgetCut textarea
|
|
|
|
+ UpdateCursor()
|
|
|
|
+ UpdateCode()
|
|
|
|
+ Case TOOLCOPY
|
|
|
|
+ GadgetCopy textarea
|
|
|
|
+ Case TOOLPASTE
|
|
|
|
+ GadgetPaste textarea
|
|
|
|
+ UpdateCursor()
|
|
|
|
+ UpdateCode()
|
|
|
|
+ Case TOOLSELECTALL
|
|
|
|
+ SelectTextAreaText textarea
|
|
|
|
+ UpdateCursor()
|
|
|
|
+ Case TOOLINDENT
|
|
|
|
+ IndentCode()
|
|
|
|
+ Case TOOLOUTDENT
|
|
|
|
+ OutdentCode()
|
|
|
|
+ Case TOOLPRINT
|
|
|
|
+ GadgetPrint textarea
|
|
|
|
+ End Select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function CreateEditMenu:TGadget()
|
|
|
|
+ Local edit:TGadget = CreateMenu("{{popup_edit}}",0,Null)
|
|
|
|
+ CreateMenu "{{popup_edit_quickhelp}}",MENUQUICKHELP,edit
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{popup_edit_cut}}",MENUCUT,edit
|
|
|
|
+ CreateMenu "{{popup_edit_copy}}",MENUCOPY,edit
|
|
|
|
+ CreateMenu "{{popup_edit_paste}}",MENUPASTE,edit
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{popup_edit_selectall}}",MENUSELECTALL,edit
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{popup_edit_blockindent}}",MENUINDENT,edit
|
|
|
|
+ CreateMenu "{{popup_edit_blockoutdent}}",MENUOUTDENT,edit
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{popup_edit_find}}",MENUFIND,edit
|
|
|
|
+ CreateMenu "{{popup_edit_findnext}}",MENUFINDNEXT,edit
|
|
|
|
+ CreateMenu "{{popup_edit_replace}}",MENUREPLACE,edit
|
|
|
|
+ CreateMenu "{{popup_edit_goto}}",MENUGOTO,edit
|
|
|
|
+ Return edit
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method MakePathTemp()
|
|
|
|
+' prepends "." to file name with code borrowed from SaveAs
|
|
|
|
+ Local file$=ExtractDir(path)+"/."+StripDir(path)
|
|
|
|
+ SaveSource(file$)
|
|
|
|
+' Refresh
|
|
|
|
+ GetNode().Refresh
|
|
|
|
+' setdirty False
|
|
|
|
+ host.SetTitle path
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function Create:TOpenCode(path$,host:TCodePlay)
|
|
|
|
+ Local code:TOpenCode
|
|
|
|
+ Local stream:TStream
|
|
|
|
+ Local isnew
|
|
|
|
+ If path
|
|
|
|
+ If FileType(path)<>FILETYPE_FILE
|
|
|
|
+ Return Null
|
|
|
|
+ EndIf
|
|
|
|
+ stream=ReadFile(path)
|
|
|
|
+ If Not stream
|
|
|
|
+' Notify "Open could not read from "+path
|
|
|
|
+ Return Null
|
|
|
|
+ EndIf
|
|
|
|
+ CloseFile stream
|
|
|
|
+ Else
|
|
|
|
+ TEMPCOUNT:+1
|
|
|
|
+ path=host.bmxpath+"/tmp/untitled"+TEMPCOUNT+".bmx"
|
|
|
|
+ isnew=True
|
|
|
|
+ EndIf
|
|
|
|
+ code=New TOpenCode
|
|
|
|
+ code.host=host
|
|
|
|
+ code.active=True
|
|
|
|
+ code.path=host.FullPath(path)
|
|
|
|
+ code.editmenu=CreateEditMenu()
|
|
|
|
+ codeplay.addpanel(code)
|
|
|
|
+ code.textarea=CreateTextArea(0,0,ClientWidth(code.panel),ClientHeight(code.panel),code.panel,0)
|
|
|
|
+ DelocalizeGadget code.textarea
|
|
|
|
+ SetGadgetFilter code.textarea,code.FilterKey,code
|
|
|
|
+ SetTextAreaText code.textarea,"~n"
|
|
|
|
+ SetGadgetLayout code.textarea,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
|
|
|
|
+ code.RefreshStyle()
|
|
|
|
+
|
|
|
|
+ If isnew
|
|
|
|
+ code.SaveSource path
|
|
|
|
+ code.filesrc="~n"
|
|
|
|
+ ActivateGadget code.textarea
|
|
|
|
+ Else
|
|
|
|
+ host.UpdateProgress "Reading Stream"
|
|
|
|
+ code.ReadSource(path)
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If ExtractExt(path).toLower()="bmx" code.isbmx=True
|
|
|
|
+ If ExtractExt(path).toLower()="c" code.isc=True
|
|
|
|
+ If ExtractExt(path).toLower()="cpp" code.iscpp=True
|
|
|
|
+ If ExtractExt(path).toLower()="cxx" code.iscpp=True
|
|
|
|
+ If ExtractExt(path).toLower()="html" code.ishtml=True
|
|
|
|
+ If ExtractExt(path).toLower()="htm" code.ishtml=True
|
|
|
|
+ code.UpdateCode False
|
|
|
|
+ code.filesrc=TextAreaText(code.textarea)
|
|
|
|
+ Return code
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TRect
|
|
|
|
+ Field x,y,w,h
|
|
|
|
+
|
|
|
|
+ Method Set(xpos,ypos,width,height)
|
|
|
|
+ x=xpos;y=ypos;w=width;h=height
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ToString$()
|
|
|
|
+ Return ""+x+","+y+","+w+","+h
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FromString(s$)
|
|
|
|
+ Local p,q,r
|
|
|
|
+ p=s.Find(",")+1;If Not p Return
|
|
|
|
+ q=s.Find(",",p)+1;If Not q Return
|
|
|
|
+ r=s.Find(",",q)+1;If Not r Return
|
|
|
|
+ x=Int(s[..p-1])
|
|
|
|
+ y=Int(s[p..q-1])
|
|
|
|
+ w=Int(s[q..r-1])
|
|
|
|
+ h=Int(s[r..])
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method IsOutside(tx,ty,tw,th)
|
|
|
|
+ If x+w<=tx Or y+h<=ty Return True
|
|
|
|
+ If x>=tx+tw Or y>=ty+th Return True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+End Type
|
|
|
|
+
|
|
|
|
+Type TCodePlay
|
|
|
|
+
|
|
|
|
+ Const EDITMODE=1
|
|
|
|
+ Const DEBUGMODE=2
|
|
|
|
+
|
|
|
|
+ Field bmxpath$,bmkpath$
|
|
|
|
+ Field panels:TToolPanel[]
|
|
|
|
+ Field helppanel:THelpPanel
|
|
|
|
+ Field currentpanel:TToolPanel
|
|
|
|
+ Field output:TOutputPanel
|
|
|
|
+ Field lockedpanel:TToolPanel
|
|
|
|
+ Field activepanel:TToolPanel
|
|
|
|
+
|
|
|
|
+ Field cmdlinereq:TCmdLineRequester
|
|
|
|
+ Field cmdline$
|
|
|
|
+ 'Field syncmodsreq:TSyncModsRequester
|
|
|
|
+ Field gotoreq:TGotoRequester
|
|
|
|
+ Field findreq:TFindRequester
|
|
|
|
+ Field replacereq:TReplaceRequester
|
|
|
|
+ Field options:TOptionsRequester
|
|
|
|
+' Field progress:TProgressRequester
|
|
|
|
+ Field activerequesters:TList = New TList
|
|
|
|
+ Field projectreq:TProjectRequester
|
|
|
|
+ Field projectprops:TProjectProperties
|
|
|
|
+ Field searchreq:TSearchRequester
|
|
|
|
+ Field aboutreq:TAboutRequester
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ Field eventhandlers:TList=New TList
|
|
|
|
+ Field window:TGadget,menubar:TGadget,toolbar:TGadget,client:TGadget,tabbar:TGadget
|
|
|
|
+ Field split:TSplitter
|
|
|
|
+ Field debugtree:TDebugTree
|
|
|
|
+
|
|
|
|
+ Field root:TNode
|
|
|
|
+ Field helproot:TNode
|
|
|
|
+ Field projects:TProjects
|
|
|
|
+ Field coderoot:TNode
|
|
|
|
+ Field navbar:TNavBar
|
|
|
|
+
|
|
|
|
+ Field mode
|
|
|
|
+ Field debugcode:TOpenCode
|
|
|
|
+
|
|
|
|
+ Field quickenable:TGadget,quickenabled 'menu,state
|
|
|
|
+ Field debugenable:TGadget,debugenabled 'menu,state
|
|
|
|
+ Field threadedenable:TGadget,threadedenabled
|
|
|
|
+ Field guienable:TGadget,guienabled 'menu,state
|
|
|
|
+ Field quickhelp:TQuickHelp
|
|
|
|
+ Field running
|
|
|
|
+ Field recentmenu:TGadget
|
|
|
|
+ Field recentfiles:TList=New TList
|
|
|
|
+ Field recentmenus:TGadget[]
|
|
|
|
+ Field openlist:TList=New TList
|
|
|
|
+ Field openlock$
|
|
|
|
+ Field projlist:TList=New TList
|
|
|
|
+ Field winsize:TRect=New TRect
|
|
|
|
+ Field winmax,tooly,splitpos,debugview,navtab
|
|
|
|
+ Field progress,splitorientation
|
|
|
|
+
|
|
|
|
+?MacOS
|
|
|
|
+ Method RanlibMods()
|
|
|
|
+
|
|
|
|
+ Local cmd$=Quote( bmxpath+"/bin/bmk" )+" ranlibdir "+Quote( bmxpath+"/mod" )
|
|
|
|
+ system_ cmd
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+?
|
|
|
|
+
|
|
|
|
+ Method CheckVersion$()
|
|
|
|
+ Local process:TProcess
|
|
|
|
+ Local bytes:Byte[]
|
|
|
|
+ Local cmd$,version$
|
|
|
|
+
|
|
|
|
+ cmd$=bmxpath+"/bin/bcc"
|
|
|
|
+
|
|
|
|
+?win32
|
|
|
|
+ cmd:+".exe"
|
|
|
|
+?
|
|
|
|
+
|
|
|
|
+ cmd=Quote(cmd)
|
|
|
|
+ process=CreateProcess(cmd$,HIDECONSOLE)
|
|
|
|
+ If process
|
|
|
|
+ Repeat
|
|
|
|
+ Delay 10
|
|
|
|
+ bytes=process.pipe.ReadPipe()
|
|
|
|
+ If bytes
|
|
|
|
+ version:+String.FromBytes(bytes,bytes.length)
|
|
|
|
+ EndIf
|
|
|
|
+ Until Not process.Status()
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If version=""
|
|
|
|
+ Notify "Unable to determine BlitzMax version.~n~nPlease reinstall BlitzMax to repair this problem."
|
|
|
|
+ End
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ BCC_VERSION=version.Trim()
|
|
|
|
+
|
|
|
|
+' print "bcc version="+version
|
|
|
|
+
|
|
|
|
+ If version.find("(expired)")>-1 'Demo timed out
|
|
|
|
+ Notify "This demo version of BlitzMax has expired.~n~nPlease visit www.blitzbasic.com to buy the full version."
|
|
|
|
+ End
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ If version.find("Demo Version")>-1 'Valid demo version
|
|
|
|
+ is_demo=True
|
|
|
|
+ Notify version+"~nTo purchase the full version please visit www.blitzbasic.com."
|
|
|
|
+ Notify ABOUTDEMO
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method OpenProgress(message$)
|
|
|
|
+' progress.Open message
|
|
|
|
+ DisableGadget window
|
|
|
|
+ SetStatus message
|
|
|
|
+ progress=-1
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method CloseProgress()
|
|
|
|
+' progress.Hide
|
|
|
|
+ SetStatus ""
|
|
|
|
+ EnableGadget window
|
|
|
|
+ progress=0
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method UpdateProgress(message$,value=0) 'returns false if cancelled
|
|
|
|
+' Return progress.Update(message,value)
|
|
|
|
+ If progress
|
|
|
|
+ If progress/5<>value/5
|
|
|
|
+ SetStatus message+" "+value+"%"
|
|
|
|
+ progress=value
|
|
|
|
+' Pollsystem
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method FullPath$(path$)
|
|
|
|
+ If path[..8]="$BMXPATH" path=bmxpath+path[8..]
|
|
|
|
+ If Not path.Contains("::") Then path = RealPath(path)
|
|
|
|
+?win32
|
|
|
|
+ path=path.Replace("\","/")
|
|
|
|
+?
|
|
|
|
+ Return path
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method IsTempPath(path$)
|
|
|
|
+ If path[..bmxpath.length+5]=bmxpath+"/tmp/" Return True
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddDefaultProj(p$)
|
|
|
|
+ Local projdata:TList = New TList
|
|
|
|
+ projdata.AddLast p
|
|
|
|
+ projlist.AddLast projdata
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ReadConfig()
|
|
|
|
+ Local stream:TStream
|
|
|
|
+ Local f$,p,a$,b$
|
|
|
|
+' defaults
|
|
|
|
+ Local wh=GadgetHeight(Desktop())-80'32
|
|
|
|
+ Local ww=wh
|
|
|
|
+ Local wx=(GadgetWidth(Desktop())-ww)/2
|
|
|
|
+ Local wy=(GadgetHeight(Desktop())-wh)/2
|
|
|
|
+ winsize.set( wx,wy,ww,wh )
|
|
|
|
+ quickenabled=False
|
|
|
|
+ debugenabled=True
|
|
|
|
+ threadedenabled=False
|
|
|
|
+ guienabled=True
|
|
|
|
+ splitpos=200;splitorientation = SPLIT_VERTICAL
|
|
|
|
+' read ini
|
|
|
|
+ stream=ReadFile(bmxpath+"/cfg/ide.ini")
|
|
|
|
+ If Not stream
|
|
|
|
+ AddDefaultProj "Samples|samples"
|
|
|
|
+ If Not is_demo
|
|
|
|
+ AddDefaultProj "Modules Source|mod"
|
|
|
|
+ AddDefaultProj "BlitzMax Source|src"
|
|
|
|
+ EndIf
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ options.read(stream)
|
|
|
|
+ options.Snapshot
|
|
|
|
+
|
|
|
|
+ Local projdata:TList
|
|
|
|
+
|
|
|
|
+ While Not stream.Eof()
|
|
|
|
+ f$=stream.ReadLine()
|
|
|
|
+ p=f.find("=")
|
|
|
|
+ If p=-1 Continue
|
|
|
|
+ a$=f[..p]
|
|
|
|
+ b$=f[p+1..]
|
|
|
|
+ Select a$
|
|
|
|
+ Case "ide_version"
|
|
|
|
+
|
|
|
|
+ Case "file_recent"
|
|
|
|
+ recentfiles.addlast b$
|
|
|
|
+ Case "file_open"
|
|
|
|
+ openlist.addlast b$
|
|
|
|
+ Case "prg_quick"
|
|
|
|
+ quickenabled=Int(b$)
|
|
|
|
+ Case "prg_debug"
|
|
|
|
+ debugenabled=Int(b$)
|
|
|
|
+ Case "prg_threaded"
|
|
|
|
+ threadedenabled=Int(b$)
|
|
|
|
+ Case "prg_gui"
|
|
|
|
+ guienabled=Int(b$)
|
|
|
|
+ Case "cmd_line"
|
|
|
|
+ cmdline=b$
|
|
|
|
+ Case "prg_locked"
|
|
|
|
+ openlock=b$
|
|
|
|
+ Case "win_size"
|
|
|
|
+ winsize.FromString(b$)
|
|
|
|
+ Case "win_max"
|
|
|
|
+ winmax=Int(b$)
|
|
|
|
+ Case "split_position"
|
|
|
|
+ splitpos=Int(b$)
|
|
|
|
+ Case "split_orientation"
|
|
|
|
+ splitorientation=Int(b$)
|
|
|
|
+ Case "proj_node"
|
|
|
|
+ projdata=New TList
|
|
|
|
+ projdata.AddLast b
|
|
|
|
+ projlist.AddLast projdata
|
|
|
|
+ Case "proj_data"
|
|
|
|
+ If projdata projdata.AddLast b
|
|
|
|
+ 'Case "sync_state"
|
|
|
|
+ 'syncmodsreq.FromString b$
|
|
|
|
+ End Select
|
|
|
|
+ Wend
|
|
|
|
+ stream.close()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method WriteConfig()
|
|
|
|
+ Local panel:TToolPanel
|
|
|
|
+ Local node:TNode
|
|
|
|
+ Local f$
|
|
|
|
+
|
|
|
|
+ Local stream:TStream = WriteFile(bmxpath+"/cfg/ide.ini")
|
|
|
|
+ If Not stream Return
|
|
|
|
+' options
|
|
|
|
+ options.write(stream)
|
|
|
|
+' defaults
|
|
|
|
+ stream.WriteLine "[Defaults]"
|
|
|
|
+ stream.WriteLine "ide_version="+IDE_VERSION$
|
|
|
|
+ stream.WriteLine "prg_quick="+quickenabled
|
|
|
|
+ stream.WriteLine "prg_debug="+debugenabled
|
|
|
|
+ stream.WriteLine "prg_threaded="+threadedenabled
|
|
|
|
+ stream.WriteLine "prg_gui="+guienabled
|
|
|
|
+ stream.WriteLine "win_size="+winsize.ToString()
|
|
|
|
+ stream.WriteLine "win_max="+winmax
|
|
|
|
+ stream.WriteLine "split_position="+SplitterPosition(split)
|
|
|
|
+ stream.WriteLine "split_orientation="+SplitterOrientation(split)
|
|
|
|
+ stream.WriteLine "cmd_line="+cmdline
|
|
|
|
+ 'stream.WriteLine "sync_state="+syncmodsreq.ToString()
|
|
|
|
+ If lockedpanel stream.WriteLine "prg_locked="+lockedpanel.path
|
|
|
|
+ For f$=EachIn recentfiles
|
|
|
|
+ stream.WriteLine "file_recent="+f$
|
|
|
|
+ Next
|
|
|
|
+ For Local panel:TToolPanel = EachIn panels
|
|
|
|
+ f$=panel.path
|
|
|
|
+ If f$ And Not IsTempPath(f$) stream.WriteLine "file_open="+f$
|
|
|
|
+ Next
|
|
|
|
+ projects.write(stream)
|
|
|
|
+ stream.close
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method CloseAll(dontask,inccurrent=True) 'returns true if successful
|
|
|
|
+ Local count, cancel
|
|
|
|
+ For Local panel:TToolPanel = EachIn panels
|
|
|
|
+ If TOpenCode(panel) And (inccurrent Or currentpanel <> panel) count:+1
|
|
|
|
+ Next
|
|
|
|
+ If (Not count) Or dontask Or Confirm(LocalizeString("{{request_closeall}}"))
|
|
|
|
+ For Local panel:TToolPanel = EachIn panels[..] 'Use a copy of the original array for iterating.
|
|
|
|
+ If (inccurrent Or currentpanel <> panel) And panel.invoke(TOOLCLOSE) Then
|
|
|
|
+ cancel=True
|
|
|
|
+ Exit
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+ Return Not cancel
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Quit()
|
|
|
|
+ WriteConfig()
|
|
|
|
+ If CloseAll(True) running=False
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method DebugExit()
|
|
|
|
+ If debugcode
|
|
|
|
+ debugtree.cancontinue = False
|
|
|
|
+ debugcode.Edit 'restore cursor etc.
|
|
|
|
+ debugcode=Null
|
|
|
|
+ EndIf
|
|
|
|
+ SetMode EDITMODE
|
|
|
|
+ RefreshToolbar()
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method DebugSource(path$,line,column)
|
|
|
|
+ Local code:TOpenCode
|
|
|
|
+ path=FullPath(path)
|
|
|
|
+ code=OpenSource(path)
|
|
|
|
+ If Not code Then
|
|
|
|
+ Notify(LocalizeString("{{loaderror_failed}}").Replace("%1",path), True)
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ If debugcode And debugcode<>code Then debugcode.Edit() 'restore cursor etc.
|
|
|
|
+ debugcode=code
|
|
|
|
+ debugcode.debug(line,column)
|
|
|
|
+ ActivateWindow window
|
|
|
|
+ PollSystem
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetMode(m)
|
|
|
|
+ If mode=m Return
|
|
|
|
+ ActivateWindow window
|
|
|
|
+ Select m
|
|
|
|
+ Case DEBUGMODE
|
|
|
|
+ navtab=navbar.SelectedView()
|
|
|
|
+ navbar.SelectView debugview
|
|
|
|
+ Case EDITMODE
|
|
|
|
+ navbar.SelectView navtab
|
|
|
|
+ End Select
|
|
|
|
+ mode=m
|
|
|
|
+ RefreshToolbar
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RefreshMenu()
|
|
|
|
+ TOpenCode.RefreshHighlightingMsg()
|
|
|
|
+ UpdateWindowMenu window
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method RefreshToolbar()
|
|
|
|
+ Local i
|
|
|
|
+' sourceedit buttons
|
|
|
|
+ If THelpPanel(CurrentPanel)
|
|
|
|
+ DisableGadgetItem toolbar,TB_CLOSE
|
|
|
|
+ Else
|
|
|
|
+ EnableGadgetItem toolbar,TB_CLOSE
|
|
|
|
+ EndIf
|
|
|
|
+ If TOpenCode(CurrentPanel)
|
|
|
|
+ EnableGadgetItem toolbar,TB_SAVE
|
|
|
|
+ For i=TB_CUT To TB_FIND
|
|
|
|
+ EnableGadgetItem toolbar,i
|
|
|
|
+ Next
|
|
|
|
+ Else
|
|
|
|
+ DisableGadgetItem toolbar,TB_SAVE
|
|
|
|
+ For i=TB_CUT To TB_FIND
|
|
|
|
+ DisableGadgetItem toolbar,i
|
|
|
|
+ Next
|
|
|
|
+ EndIf
|
|
|
|
+' debug buttons
|
|
|
|
+ If mode = DEBUGMODE And debugtree.cancontinue Then
|
|
|
|
+ If GadgetItemIcon( toolbar, TB_BUILDRUN ) = TB_BUILDRUN Then
|
|
|
|
+ ModifyGadgetItem( toolbar, TB_BUILDRUN, "", GADGETITEM_LOCALIZED, TB_CONTINUE, "{{tb_continue}}" )
|
|
|
|
+ EndIf
|
|
|
|
+ Else
|
|
|
|
+ If GadgetItemIcon( toolbar, TB_BUILDRUN ) <> TB_BUILDRUN Then
|
|
|
|
+ ModifyGadgetItem( toolbar, TB_BUILDRUN, "", GADGETITEM_LOCALIZED, TB_BUILDRUN, "{{tb_buildrun}}" )
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ For i=TB_STEP To TB_STEPOUT
|
|
|
|
+ If mode=DEBUGMODE And debugtree.cancontinue Then
|
|
|
|
+ EnableGadgetItem toolbar,i
|
|
|
|
+ Else
|
|
|
|
+ DisableGadgetItem toolbar,i
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+' stop button
|
|
|
|
+ If output And output.process
|
|
|
|
+ EnableGadgetItem toolbar,TB_STOP
|
|
|
|
+ Else
|
|
|
|
+ DisableGadgetItem toolbar,TB_STOP
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method IsSourceOpen(path$)
|
|
|
|
+ Local p$ = FullPath(path)
|
|
|
|
+ For Local panel:TToolPanel = EachIn panels
|
|
|
|
+ If panel.path=p Return True
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method OpenSource:TOpenCode(path$)
|
|
|
|
+ Local code:TOpenCode
|
|
|
|
+ Local ext$,p$
|
|
|
|
+ If path$="."
|
|
|
|
+ path$=RequestFile(LocalizeString("{{request_openfile}}"),FileTypeFilters )
|
|
|
|
+ If path$="" Return
|
|
|
|
+ EndIf
|
|
|
|
+' check if already open
|
|
|
|
+ p$=FullPath(path).ToLower()
|
|
|
|
+ For Local panel:TToolPanel = EachIn panels
|
|
|
|
+ If panel.path.ToLower()=p
|
|
|
|
+ SelectPanel panel
|
|
|
|
+ Return TOpenCode(panel)
|
|
|
|
+ EndIf
|
|
|
|
+ Next
|
|
|
|
+' open based on extension
|
|
|
|
+' Select ExtractExt(Upper(path$))
|
|
|
|
+' Case "BMX","TXT","BB","CPP","C","S","I","H","HTML","CSS","BAT","FS","VS","README",""
|
|
|
|
+ OpenProgress LocalizeString("{{msg_loading}}").Replace("%1",StripDir(path))
|
|
|
|
+ code=TOpenCode.Create(path,Self)
|
|
|
|
+ If code
|
|
|
|
+ AddRecent code.path
|
|
|
|
+ EndIf
|
|
|
|
+ CloseProgress
|
|
|
|
+ If code
|
|
|
|
+ ActivateGadget code.textarea
|
|
|
|
+ code.GetNode().Refresh
|
|
|
|
+ EndIf
|
|
|
|
+ Return code
|
|
|
|
+' end select
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddRecent(path$)
|
|
|
|
+ For Local f$ = EachIn recentfiles
|
|
|
|
+ If f$=path$ recentfiles.Remove(f$);Exit
|
|
|
|
+ Next
|
|
|
|
+ recentfiles.AddFirst(path$)
|
|
|
|
+ RefreshRecentFiles
|
|
|
|
+ UpdateWindowMenu window
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RefreshRecentFiles()
|
|
|
|
+ Local n
|
|
|
|
+ For Local m:TGadget = EachIn recentmenus
|
|
|
|
+ FreeMenu m
|
|
|
|
+ Next
|
|
|
|
+ n=Min(recentfiles.count(),16)
|
|
|
|
+ recentmenus=New TGadget[n]
|
|
|
|
+ n=0
|
|
|
|
+ For Local f$ = EachIn recentfiles
|
|
|
|
+ recentmenus[n]=CreateMenu(f$,MENURECENT+n,recentmenu)
|
|
|
|
+ n:+1
|
|
|
|
+ If n=16 Exit
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method BuildModules(buildall)
|
|
|
|
+ Local cmd$,out$,exe$
|
|
|
|
+ output.Stop
|
|
|
|
+ SaveAll
|
|
|
|
+ cmd$=quote(bmkpath)
|
|
|
|
+ cmd$:+" makemods "
|
|
|
|
+
|
|
|
|
+ If buildall cmd$:+"-a "
|
|
|
|
+ If threadedenabled cmd:+"-h "
|
|
|
|
+
|
|
|
|
+ Execute cmd,LocalizeString("{{output_msg_buildingmods}}")
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ImportBB()
|
|
|
|
+ Local f$ = RequestFile(LocalizeString("{{request_importbb_title}}"),"bb" )
|
|
|
|
+ If Not f$ Return
|
|
|
|
+ Local cmd$ = Quote(bmkpath$)
|
|
|
|
+ cmd$:+" convertbb "
|
|
|
|
+ cmd$:+quote(FullPath(f$))
|
|
|
|
+ Execute cmd,LocalizeString("{{output_msg_converting}}").Replace("%1",StripExt(StripDir(f$)))
|
|
|
|
+ output.wait
|
|
|
|
+ OpenSource(StripExt(f$)+".bmx")
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method GetCommandLine$()
|
|
|
|
+ Return cmdline
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetCommandLine(text$)
|
|
|
|
+ cmdline=text
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SetStatus(text$)
|
|
|
|
+ SetStatusText window,text
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Execute(cmd$,mess$="",post$="",home=True,tool:TTool=Null)
|
|
|
|
+ If Not output output=TOutputPanel.Create(Self)
|
|
|
|
+ output.execute cmd$,mess$,post$,home,tool
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SelectError(path$,column,line)
|
|
|
|
+ Local panel:TOpenCode,found
|
|
|
|
+ For panel=EachIn panels
|
|
|
|
+ If panel.path=path found=True;Exit
|
|
|
|
+ Next
|
|
|
|
+ If Not found panel=OpenSource(path)
|
|
|
|
+ If panel
|
|
|
|
+ SelectPanel panel
|
|
|
|
+ panel.Debug line,column
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method ParseError(err$)
|
|
|
|
+ Local mess$,file$,p,q
|
|
|
|
+ Local line,column
|
|
|
|
+' bcc error
|
|
|
|
+ If err$[..13]="Compile Error"
|
|
|
|
+ err=err[14..]
|
|
|
|
+ p=err.find(EOL$)
|
|
|
|
+ If p=-1 p=err.length
|
|
|
|
+ mess=err[..p]
|
|
|
|
+ err=err[p+1..]
|
|
|
|
+ If err[..1]="["
|
|
|
|
+ p=err.find("]")
|
|
|
|
+ If p=-1 p=err.length
|
|
|
|
+ file$=err[1..p]
|
|
|
|
+ p=file.find(";")+1
|
|
|
|
+ If p=0 p=err.length
|
|
|
|
+ q=file.find(";",p)+1
|
|
|
|
+ If q=0 q=err.length
|
|
|
|
+ line=Int(file[p..q-1])
|
|
|
|
+ column=Int(file[q..])
|
|
|
|
+ file=FullPath(file[..p-1])
|
|
|
|
+ SelectError file,column,line
|
|
|
|
+ EndIf
|
|
|
|
+ Notify LocalizeString("{{output_error_compileerror}}").Replace("%1",mess)
|
|
|
|
+ SetStatus mess
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+' gcc error
|
|
|
|
+ err=err.Replace(EOL+" "," ")
|
|
|
|
+ While err
|
|
|
|
+ p=err.find(EOL)
|
|
|
|
+ If p=-1 p:+err.length 'equiv. to p=err.length-1 ;-)
|
|
|
|
+ mess=err[..p]
|
|
|
|
+ err=err[p+1..]
|
|
|
|
+ p=0
|
|
|
|
+ Repeat
|
|
|
|
+ p=mess.Find(":",p)+1
|
|
|
|
+ If p=0 Exit
|
|
|
|
+ q=mess.Find(":",p)
|
|
|
|
+ If q<>-1
|
|
|
|
+ file=mess[..p-1]
|
|
|
|
+ line=Int(mess[p..q])
|
|
|
|
+ If line
|
|
|
|
+ mess=mess[q+1..]
|
|
|
|
+ SelectError file,column,line
|
|
|
|
+ Notify LocalizeString("{{output_error_compileerror}}").Replace("%1",mess)
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ p=q+1
|
|
|
|
+ EndIf
|
|
|
|
+ Forever
|
|
|
|
+ Wend
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddPanel(tabpanel:TToolPanel)
|
|
|
|
+ Local panel:TGadget,index
|
|
|
|
+ index=CountGadgetItems(tabbar)
|
|
|
|
+ If panels.length<=index panels=panels[..index+1]
|
|
|
|
+ AddGadgetItem(tabbar,tabpanel.name$,GADGETITEM_DEFAULT|GADGETITEM_LOCALIZED)
|
|
|
|
+
|
|
|
|
+ panel=CreatePanel(0,0,ClientWidth(tabbar),ClientHeight(tabbar),tabbar,0) 'name
|
|
|
|
+ SetGadgetLayout panel,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED
|
|
|
|
+ tabpanel.panel=panel
|
|
|
|
+
|
|
|
|
+ tabpanel.index=index
|
|
|
|
+ panels[index]=tabpanel
|
|
|
|
+ SelectPanel tabpanel
|
|
|
|
+ AddHandler tabpanel
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method AddHandler(handler:TEventHandler)
|
|
|
|
+ eventhandlers.addlast handler
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RemovePanel(tabpanel:TToolPanel)
|
|
|
|
+ Local p:TToolPanel[]
|
|
|
|
+ Local index
|
|
|
|
+ eventhandlers.remove tabpanel
|
|
|
|
+' unset debugcode
|
|
|
|
+ If debugcode=tabpanel debugcode=Null
|
|
|
|
+' activate next panel
|
|
|
|
+ If tabpanel=activepanel activepanel=helppanel
|
|
|
|
+ If tabpanel=lockedpanel lockedpanel=Null
|
|
|
|
+ If tabpanel=currentpanel
|
|
|
|
+ index=tabpanel.index+1
|
|
|
|
+ If index>=panels.length index=panels.length-2
|
|
|
|
+ SelectPanel panels[index]
|
|
|
|
+ EndIf
|
|
|
|
+' remove from array
|
|
|
|
+ p=panels
|
|
|
|
+ panels=panels[..panels.length-1]
|
|
|
|
+ For index=tabpanel.index To panels.length-1
|
|
|
|
+ panels[index]=p[index+1]
|
|
|
|
+ panels[index].index=index
|
|
|
|
+ Next
|
|
|
|
+' remove gadget - simon come here, placing before remove needs fix in fltk
|
|
|
|
+ FreeGadget tabpanel.panel
|
|
|
|
+ RemoveGadgetItem tabbar,tabpanel.index
|
|
|
|
+ tabpanel.panel=Null
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method HookRequester(req:TRequester)
|
|
|
|
+ If Not activerequesters.Contains(req) Then
|
|
|
|
+ If req.IsModal() Then
|
|
|
|
+ For Local tmpRequester:TRequester = EachIn activerequesters
|
|
|
|
+ DisableGadget tmpRequester.window
|
|
|
|
+ Next
|
|
|
|
+ DisableGadget window
|
|
|
|
+ EndIf
|
|
|
|
+ activerequesters.AddFirst(req)
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method UnhookRequester(req:TRequester)
|
|
|
|
+ If activerequesters.Contains(req) Then
|
|
|
|
+ activerequesters.Remove(req)
|
|
|
|
+ If req.IsModal() Then
|
|
|
|
+ For Local tmpRequester:TRequester = EachIn activerequesters
|
|
|
|
+ EnableGadget tmpRequester.window
|
|
|
|
+ Next
|
|
|
|
+ EnableGadget window
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+ Method SetTitle(title$="")
|
|
|
|
+ If title title=" - "+title
|
|
|
|
+ SetGadgetText window,"MaxIDE"+title
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SelectPanel(panel:TToolPanel)
|
|
|
|
+ Local curr:TToolPanel = currentpanel
|
|
|
|
+ currentpanel=panel
|
|
|
|
+ If curr And curr<>currentpanel
|
|
|
|
+ SelectGadgetItem tabbar,panel.index
|
|
|
|
+ ShowGadget panel.panel
|
|
|
|
+ If panel.active activepanel=panel
|
|
|
|
+ HideGadget curr.panel
|
|
|
|
+ RefreshToolbar
|
|
|
|
+ EndIf
|
|
|
|
+ currentpanel.Invoke TOOLSHOW
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RefreshPanel(panel:TToolPanel) 'call after a name change
|
|
|
|
+ ModifyGadgetItem( tabbar,panel.index,panel.name,GADGETITEM_LOCALIZED )
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Function OutsideDesktop(winrect:TRect)
|
|
|
|
+ Local x,y,w,h
|
|
|
|
+ Local desk:TGadget = Desktop()
|
|
|
|
+ x=GadgetX(desk)
|
|
|
|
+ y=GadgetY(desk)
|
|
|
|
+ w=GadgetWidth(desk)
|
|
|
|
+ h=GadgetHeight(desk)
|
|
|
|
+ Return winrect.IsOutside(x,y,w,h)
|
|
|
|
+ End Function
|
|
|
|
+
|
|
|
|
+ Method SetCodeNode(code:TNode)
|
|
|
|
+ Local node:TNode
|
|
|
|
+ If coderoot.kids.count() node=TNode(coderoot.kids.First())
|
|
|
|
+ If node=code Return
|
|
|
|
+ If node node.Detach
|
|
|
|
+ If code
|
|
|
|
+ coderoot.Append code
|
|
|
|
+ coderoot.Refresh
|
|
|
|
+ coderoot.Open
|
|
|
|
+ code.Open
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Initialize()
|
|
|
|
+ Local open:TOpenCode, splash:TGadget
|
|
|
|
+ Local dir$,nomods,pname$,p
|
|
|
|
+ Local stream:TStream
|
|
|
|
+
|
|
|
|
+ Try
|
|
|
|
+ bmxpath=BlitzMaxPath()
|
|
|
|
+ Catch err$
|
|
|
|
+ Notify "Unable to determine BlitzMax installation directory."
|
|
|
|
+ End
|
|
|
|
+ EndTry
|
|
|
|
+
|
|
|
|
+ CreateDir bmxpath+"/tmp"
|
|
|
|
+ If FileType( bmxpath+"/tmp" )<>FILETYPE_DIR
|
|
|
|
+ Notify "Unable to create BlitzMax 'tmp' directory."
|
|
|
|
+ End
|
|
|
|
+ EndIf
|
|
|
|
+?Win32
|
|
|
|
+ CreateFile bmxpath+"/tmp/t.exe"
|
|
|
|
+ If FileType( bmxpath+"/tmp/t.exe" ) <> FILETYPE_FILE
|
|
|
|
+ Notify "Unable to write to BlitzMax installation directory.~n"+..
|
|
|
|
+ "Please run MaxIDE as administrator, or reinstall BlitzMax to a different directory."
|
|
|
|
+ End
|
|
|
|
+ EndIf
|
|
|
|
+ DeleteFile bmxpath+"/tmp/t.exe"
|
|
|
|
+?
|
|
|
|
+ bmkpath=bmxpath+"/bin/bmk"
|
|
|
|
+?Win32
|
|
|
|
+ bmkpath:+".exe"
|
|
|
|
+?
|
|
|
|
+ dir$=bmxpath+"/mod"
|
|
|
|
+ If FileType(dir)=FILETYPE_NONE
|
|
|
|
+ If Not CreateDir(dir)
|
|
|
|
+ Notify "Failed to create %1 directory:~n%2".Replace("%1","Module").Replace("%2",dir)
|
|
|
|
+ End
|
|
|
|
+ EndIf
|
|
|
|
+ nomods=True
|
|
|
|
+ EndIf
|
|
|
|
+ dir$=bmxpath+"/tmp"
|
|
|
|
+ If FileType(dir)=FILETYPE_NONE
|
|
|
|
+ If Not CreateDir(dir)
|
|
|
|
+ Notify "Failed to create %1 directory:~n%2".Replace("%1","Temp").Replace("%2",dir)
|
|
|
|
+ End
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ dir$=bmxpath+"/cfg"
|
|
|
|
+ If FileType(dir)=FILETYPE_NONE
|
|
|
|
+ If Not CreateDir(dir)
|
|
|
|
+ Notify "Failed to create %1 directory:~n%2".Replace("%1","Config").Replace("%2",dir)
|
|
|
|
+ End
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ CheckVersion()
|
|
|
|
+
|
|
|
|
+ splash=CreateWindow("MaxIDE",200,200,400,140,Null,WINDOW_CLIENTCOORDS|WINDOW_HIDDEN|WINDOW_CENTER)
|
|
|
|
+ Local panel:TGadget = CreatePanel(0,0,ClientWidth(splash),ClientHeight(splash),splash,0)
|
|
|
|
+ SetPanelColor panel,255,255,255;SetPanelPixmap panel, LoadPixmapPNG("incbin::splash.png"), PANELPIXMAP_FIT2
|
|
|
|
+ Local progress:TGadget = CreateProgBar(2,ClientHeight(panel)-22,ClientWidth(panel)-4,20,panel)
|
|
|
|
+ ShowGadget splash;PollSystem
|
|
|
|
+
|
|
|
|
+ window=CreateWindow("MaxIDE",20,20,760,540,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_STATUS|WINDOW_HIDDEN|WINDOW_ACCEPTFILES|WINDOW_MENU)
|
|
|
|
+
|
|
|
|
+ ?Linux
|
|
|
|
+ SetGadgetPixmap(window, LoadPixmapPNG("incbin::window_icon.png"), GADGETPIXMAP_ICON )
|
|
|
|
+ ?
|
|
|
|
+
|
|
|
|
+ cmdlinereq=TCmdLineRequester.Create(Self)
|
|
|
|
+ 'syncmodsreq=TSyncModsRequester.Create(Self)
|
|
|
|
+ gotoreq=TGotoRequester.Create(Self)
|
|
|
|
+ findreq=TFindRequester.Create(Self)
|
|
|
|
+ replacereq=TReplaceRequester.Create(Self)
|
|
|
|
+ options=TOptionsRequester.Create(Self)
|
|
|
|
+' progress=TProgressRequester.Create(Self)
|
|
|
|
+ projectreq=TProjectRequester.Create(Self)
|
|
|
|
+ projectprops=TProjectProperties.Create(Self)
|
|
|
|
+ searchreq=TSearchRequester.Create(Self)
|
|
|
|
+ aboutreq=TAboutRequester.Create(Self)
|
|
|
|
+
|
|
|
|
+ UpdateProgBar progress, 0.1;PollSystem
|
|
|
|
+
|
|
|
|
+ ReadConfig()
|
|
|
|
+
|
|
|
|
+ toolbar=CreateToolbar("incbin::toolbar.png",0,0,0,0,window )
|
|
|
|
+
|
|
|
|
+ RemoveGadgetItem toolbar, TB_CONTINUE
|
|
|
|
+
|
|
|
|
+ Rem
|
|
|
|
+ SetToolbarTips toolbar, ["{{tb_new}}","{{tb_open}}","{{tb_close}}","{{tb_save}}","","{{tb_cut}}","{{tb_copy}}","{{tb_paste}}","{{tb_find}}","",..
|
|
|
|
+ "{{tb_build}}","{{tb_buildrun}}","{{tb_step}}","{{tb_stepin}}","{{tb_stepout}}","{{tb_stop}}","","{{tb_home}}","{{tb_back}}","{{tb_forward}}"]
|
|
|
|
+ End Rem
|
|
|
|
+
|
|
|
|
+ If Not options.showtoolbar Then HideGadget toolbar
|
|
|
|
+
|
|
|
|
+ If OutsideDesktop(winsize)
|
|
|
|
+ winsize.set(20,20,760,540)
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ UpdateProgBar progress, 0.2;PollSystem
|
|
|
|
+
|
|
|
|
+ SetGadgetShape(window, winsize.x, winsize.y, winsize.w, winsize.h)
|
|
|
|
+
|
|
|
|
+ client=window
|
|
|
|
+
|
|
|
|
+ split=CreateSplitter(0,0,ClientWidth(client),ClientHeight(client),client,SPLIT_VERTICAL)
|
|
|
|
+ SetGadgetLayout(split,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
|
|
|
|
+
|
|
|
|
+ tabbar=CreateTabber(0,0,ClientWidth(SplitterPanel(split,SPLITPANEL_MAIN)),ClientHeight(SplitterPanel(split,SPLITPANEL_MAIN)),SplitterPanel(split,SPLITPANEL_MAIN))
|
|
|
|
+ SetGadgetLayout(tabbar,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
|
|
|
|
+
|
|
|
|
+ debugtree=TDebugTree.CreateDebugTree(Self)
|
|
|
|
+
|
|
|
|
+ root=TNode.CreateNode("{{navtab_home}}")
|
|
|
|
+
|
|
|
|
+ helproot=root.AddNode("{{navnode_help}}")
|
|
|
|
+
|
|
|
|
+ projects=TProjects.CreateProjects(Self)
|
|
|
|
+ root.Append projects
|
|
|
|
+
|
|
|
|
+' opencoderoot=root.AddNode("Open")
|
|
|
|
+ coderoot=TNode.CreateNode("{{navtab_code}}")
|
|
|
|
+ coderoot.Open()
|
|
|
|
+
|
|
|
|
+ navbar=TNavBar.Create(Self,SplitterPanel(split,SPLITPANEL_SIDEPANE))
|
|
|
|
+
|
|
|
|
+ navbar.AddView root
|
|
|
|
+ navbar.AddView coderoot
|
|
|
|
+ debugview=navbar.AddView(debugtree)
|
|
|
|
+ navbar.SelectView 0
|
|
|
|
+
|
|
|
|
+ helproot.Open
|
|
|
|
+ projects.Open
|
|
|
|
+
|
|
|
|
+ AddHandler navbar
|
|
|
|
+
|
|
|
|
+ SetMode EDITMODE
|
|
|
|
+
|
|
|
|
+ UpdateProgBar progress, 0.3;PollSystem
|
|
|
|
+
|
|
|
|
+ quickhelp=TQuickHelp.LoadCommandsTxt(bmxpath)
|
|
|
|
+
|
|
|
|
+ helppanel=THelpPanel.Create(Self)
|
|
|
|
+
|
|
|
|
+ output=TOutputPanel.Create(Self)
|
|
|
|
+
|
|
|
|
+ activepanel=helppanel
|
|
|
|
+ InitMenu
|
|
|
|
+ InitHotkeys
|
|
|
|
+
|
|
|
|
+ RefreshAll
|
|
|
|
+
|
|
|
|
+ UpdateProgBar progress, 0.4;PollSystem 'allow repaint
|
|
|
|
+
|
|
|
|
+ Local mkdocs
|
|
|
|
+ If FileType( bmxpath+"/docs/html/User Guide/index.html" )<>FILETYPE_FILE
|
|
|
|
+ CreateDir bmxpath+"/docs/html"
|
|
|
|
+ CreateFile bmxpath+"/docs/html/index.html"
|
|
|
|
+ mkdocs=True
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ helppanel.Home()
|
|
|
|
+
|
|
|
|
+ UpdateProgBar progress, 0.5;PollSystem
|
|
|
|
+
|
|
|
|
+' scan projects in projlist
|
|
|
|
+ For Local pdata:TList = EachIn projlist
|
|
|
|
+ projects.AddProject pdata
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ UpdateProgBar progress, 0.6;PollSystem
|
|
|
|
+
|
|
|
|
+ Local tmpProgValue# = 0.6
|
|
|
|
+ Local tmpProgStep#
|
|
|
|
+
|
|
|
|
+'open files from .ini restorelist
|
|
|
|
+ If options.restoreopenfiles
|
|
|
|
+ If Not openlist.IsEmpty() Then tmpProgStep = (0.3/openlist.Count())
|
|
|
|
+ For Local f$=EachIn openlist
|
|
|
|
+ open=OpenSource(f$)
|
|
|
|
+ If open And f$=openlock open.SetLocked(True)
|
|
|
|
+ tmpProgValue:+tmpProgStep;UpdateProgBar progress,tmpProgValue
|
|
|
|
+ Next
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ tmpProgValue = 0.9
|
|
|
|
+ If AppArgs.length > 1 Then tmpProgStep = (0.1/(AppArgs.length-1)) Else tmpProgValue = 1.0
|
|
|
|
+ UpdateProgBar progress,tmpProgValue;PollSystem
|
|
|
|
+
|
|
|
|
+' open files specified in command line
|
|
|
|
+ For Local i:Int = 1 Until AppArgs.length
|
|
|
|
+ open=OpenSource(AppArgs[i])
|
|
|
|
+ tmpProgValue:+tmpProgStep;UpdateProgBar progress,tmpProgValue;PollSystem
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ HideGadget splash;FreeGadget splash
|
|
|
|
+ PollSystem
|
|
|
|
+
|
|
|
|
+ SetSplitterPosition(split,splitpos);SetSplitterOrientation(split,splitorientation)
|
|
|
|
+
|
|
|
|
+ If winmax MaximizeWindow(window)
|
|
|
|
+ ShowGadget window
|
|
|
|
+
|
|
|
|
+ PollSystem
|
|
|
|
+ running=True
|
|
|
|
+
|
|
|
|
+ CreateTimer(TIMER_FREQUENCY)
|
|
|
|
+
|
|
|
|
+ 'If nomods syncmodsreq.Show
|
|
|
|
+
|
|
|
|
+'build docs if not there
|
|
|
|
+ If mkdocs
|
|
|
|
+ If Confirm( LocalizeString("{{loaderror_docsnotfound}}") ) And CloseAll( False ) DocMods
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method DocMods()
|
|
|
|
+ Local cmd$=quote(bmxpath+"/bin/makedocs")
|
|
|
|
+ execute cmd,LocalizeString("{{output_msg_rebuildingdocs}}"),MENUTRIGGERSYNCDOCS
|
|
|
|
+ ?MacOS
|
|
|
|
+ RanLibMods()
|
|
|
|
+ ?
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SyncDocs()
|
|
|
|
+ helppanel.SyncDocs()
|
|
|
|
+ quickhelp=TQuickHelp.LoadCommandsTxt(bmxpath)
|
|
|
|
+ helppanel.Home
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method InitMenu()
|
|
|
|
+ Local menu:TGadget,file:TGadget,edit:TGadget,program:TGadget,tools:TGadget
|
|
|
|
+ Local help:TGadget,buildoptions:TGadget
|
|
|
|
+ Local buildmods:TGadget,buildallmods:TGadget,syncmods:TGadget,docmods:TGadget
|
|
|
|
+
|
|
|
|
+ Local MENUMOD=MODIFIER_COMMAND
|
|
|
|
+
|
|
|
|
+ If options.systemkeys
|
|
|
|
+ MENUMOD=MODIFIER_CONTROL
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ menu=WindowMenu(window)
|
|
|
|
+
|
|
|
|
+ file=CreateMenu("{{menu_file}}",0,menu)
|
|
|
|
+ CreateMenu "{{menu_file_new}}",MENUNEW,file,KEY_N,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_file_open}}",MENUOPEN,file,KEY_O,MENUMOD
|
|
|
|
+ recentmenu=CreateMenu("{{menu_file_open_recent}}",0,file)
|
|
|
|
+ CreateMenu "",0,file
|
|
|
|
+ CreateMenu "{{menu_file_closetab}}",MENUCLOSE,file,KEY_W,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_file_closealltabs}}",MENUCLOSEALL,file,KEY_W,MENUMOD|MODIFIER_SHIFT
|
|
|
|
+ CreateMenu "{{menu_file_closeothertabs}}",MENUCLOSEOTHERS,file,KEY_W,MENUMOD|MODIFIER_ALT
|
|
|
|
+ CreateMenu "",0,file
|
|
|
|
+ CreateMenu "{{menu_file_save}}",MENUSAVE,file,KEY_S,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_file_saveas}}",MENUSAVEAS,file,KEY_S,MENUMOD|MODIFIER_SHIFT
|
|
|
|
+ CreateMenu "{{menu_file_saveall}}",MENUSAVEALL,file
|
|
|
|
+ CreateMenu "",0,file
|
|
|
|
+
|
|
|
|
+ If options.systemkeys
|
|
|
|
+?MacOS
|
|
|
|
+ CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MENUMOD
|
|
|
|
+?Not MacOS
|
|
|
|
+ CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MODIFIER_ALT
|
|
|
|
+ CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MODIFIER_ALT
|
|
|
|
+?
|
|
|
|
+ Else
|
|
|
|
+ CreateMenu "{{menu_file_nexttab}}",MENUNEXT,file,KEY_RIGHT,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_file_prevtab}}",MENUPREV,file,KEY_LEFT,MENUMOD
|
|
|
|
+ EndIf
|
|
|
|
+ CreateMenu "",0,file
|
|
|
|
+ CreateMenu "{{menu_file_importbb}}",MENUIMPORTBB,file
|
|
|
|
+ CreateMenu "",0,file
|
|
|
|
+ CreateMenu "{{menu_file_ideoptions}}",MENUOPTIONS,file
|
|
|
|
+ CreateMenu "{{menu_file_projectmanager}}",MENUPROJECTMANAGER,file
|
|
|
|
+ CreateMenu "",0,file
|
|
|
|
+ CreateMenu "{{menu_file_print}}",MENUPRINT,file,KEY_P,MENUMOD
|
|
|
|
+?Not MacOS
|
|
|
|
+ CreateMenu "",0,file
|
|
|
|
+ CreateMenu "{{menu_file_exit}}",MENUQUIT,file
|
|
|
|
+?
|
|
|
|
+ edit=CreateMenu("{{menu_edit}}",0,menu)
|
|
|
|
+ CreateMenu "{{menu_edit_undo}}",MENUUNDO,edit,KEY_Z,MENUMOD
|
|
|
|
+?MacOS
|
|
|
|
+ CreateMenu "{{menu_edit_redo}}",MENUREDO,edit,KEY_Z,MENUMOD|MODIFIER_SHIFT
|
|
|
|
+?Not MacOS
|
|
|
|
+ CreateMenu "{{menu_edit_redo}}",MENUREDO,edit,KEY_Y,MENUMOD
|
|
|
|
+?
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{menu_edit_cut}}",MENUCUT,edit,KEY_X,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_edit_copy}}",MENUCOPY,edit,KEY_C,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_edit_paste}}",MENUPASTE,edit,KEY_V,MENUMOD
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{menu_edit_selectall}}",MENUSELECTALL,edit,KEY_A,MENUMOD
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{menu_edit_blockindent}}",MENUINDENT,edit,KEY_CLOSEBRACKET,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_edit_blockoutdent}}",MENUOUTDENT,edit,KEY_OPENBRACKET,MENUMOD
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{menu_edit_find}}",MENUFIND,edit,KEY_F,MENUMOD
|
|
|
|
+?MacOS
|
|
|
|
+ CreateMenu "{{menu_edit_findnext}}",MENUFINDNEXT,edit,KEY_G,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_edit_replace}}",MENUREPLACE,edit,KEY_H,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_edit_gotoline}}",MENUGOTO,edit,KEY_L,MENUMOD
|
|
|
|
+?Not MacOS
|
|
|
|
+ CreateMenu "{{menu_edit_findnext}}",MENUFINDNEXT,edit,KEY_F3
|
|
|
|
+ CreateMenu "{{menu_edit_replace}}",MENUREPLACE,edit,KEY_H,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_edit_gotoline}}",MENUGOTO,edit,KEY_G,MENUMOD
|
|
|
|
+?
|
|
|
|
+ CreateMenu "",0,edit
|
|
|
|
+ CreateMenu "{{menu_edit_findinfiles}}",MENUFINDINFILES,edit,KEY_F,MENUMOD|MODIFIER_SHIFT
|
|
|
|
+
|
|
|
|
+ program=CreateMenu("{{menu_program}}",0,menu)
|
|
|
|
+ CreateMenu "{{menu_program_build}}",MENUBUILD,program,KEY_B,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_program_buildandrun}}",MENURUN,program,KEY_R,MENUMOD
|
|
|
|
+ CreateMenu "{{menu_program_commandline}}",MENUCOMMANDLINE,program
|
|
|
|
+ CreateMenu "",0,program
|
|
|
|
+ CreateMenu "{{menu_program_step}}",MENUSTEP,program,KEY_F9
|
|
|
|
+ CreateMenu "{{menu_program_stepin}}",MENUSTEPIN,program,KEY_F10
|
|
|
|
+ CreateMenu "{{menu_program_stepout}}",MENUSTEPOUT,program,KEY_F11
|
|
|
|
+ CreateMenu "{{menu_program_terminate}}",MENUSTOP,program
|
|
|
|
+ buildoptions=CreateMenu("{{menu_program_buildoptions}}",0,program)
|
|
|
|
+ quickenable=CreateMenu("{{menu_program_buildoptions_quick}}",MENUQUICKENABLED,buildoptions)
|
|
|
|
+ debugenable=CreateMenu("{{menu_program_buildoptions_debug}}",MENUDEBUGENABLED,buildoptions)
|
|
|
|
+ If (FileType( BlitzMaxPath()+"/mod/brl.mod/blitz.mod/blitz_gc_ms.c" )=FILETYPE_FILE) ..
|
|
|
|
+ Or (FileType( BlitzMaxpath()+"/mod/brl.mod/blitz.mod/bdwgc" )=FILETYPE_DIR)
|
|
|
|
+ threadedenable=CreateMenu("{{menu_program_buildoptions_threaded}}",MENUTHREADEDENABLED,buildoptions)
|
|
|
|
+ EndIf
|
|
|
|
+ guienable=CreateMenu("{{menu_program_buildoptions_guiapp}}",MENUGUIENABLED,buildoptions)
|
|
|
|
+ CreateMenu "",0,program
|
|
|
|
+ CreateMenu "{{menu_program_lockbuildfile}}",MENULOCKBUILD,program
|
|
|
|
+ CreateMenu "{{menu_program_unlockbuildfile}}",MENUUNLOCKBUILD,program
|
|
|
|
+ CreateMenu "",0,program
|
|
|
|
+ 'syncmods=CreateMenu("{{menu_program_syncmods}}",MENUSYNCMODS,program)
|
|
|
|
+ 'CreateMenu "",0,program
|
|
|
|
+ buildmods=CreateMenu("{{menu_program_buildmods}}",MENUBUILDMODULES,program,KEY_D,MENUMOD)
|
|
|
|
+ buildallmods=CreateMenu("{{menu_program_rebuildallmods}}",MENUBUILDALLMODULES,program)
|
|
|
|
+ docmods=CreateMenu("{{menu_program_rebuilddocs}}",MENUDOCMODS,program)
|
|
|
|
+
|
|
|
|
+ help=CreateMenu("{{menu_help}}",0,menu)
|
|
|
|
+ CreateMenu "{{menu_help_home}}",MENUHOME,help
|
|
|
|
+ CreateMenu "{{menu_help_back}}",MENUBACK,help
|
|
|
|
+ CreateMenu "{{menu_help_forward}}",MENUFORWARD,help
|
|
|
|
+ CreateMenu "{{menu_help_quickhelp}}",MENUQUICKHELP,help,KEY_F1
|
|
|
|
+ CreateMenu "{{menu_help_aboutmaxide}}",MENUABOUT,help
|
|
|
|
+
|
|
|
|
+ If quickenabled CheckMenu quickenable
|
|
|
|
+ If debugenabled CheckMenu debugenable
|
|
|
|
+ If threadedenabled CheckMenu threadedenable
|
|
|
|
+ If guienabled CheckMenu guienable
|
|
|
|
+
|
|
|
|
+?Win32
|
|
|
|
+ Local mingw$=getenv_("MINGW")
|
|
|
|
+ If Not mingw
|
|
|
|
+ DisableMenu buildmods
|
|
|
|
+ DisableMenu buildallmods
|
|
|
|
+ EndIf
|
|
|
|
+?
|
|
|
|
+' If is_demo
|
|
|
|
+' DisableMenu syncmods
|
|
|
|
+' EndIf
|
|
|
|
+
|
|
|
|
+ RefreshRecentFiles
|
|
|
|
+ UpdateWindowMenu window
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RunCode()
|
|
|
|
+ If mode=DEBUGMODE And debugtree.cancontinue
|
|
|
|
+ output.Go()
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ output.Stop()
|
|
|
|
+ SaveAll()
|
|
|
|
+ If lockedpanel
|
|
|
|
+ lockedpanel.invoke TOOLRUN
|
|
|
|
+ Else
|
|
|
|
+ activepanel.invoke TOOLRUN
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method BuildCode()
|
|
|
|
+ output.Stop()
|
|
|
|
+ SaveAll()
|
|
|
|
+ If lockedpanel
|
|
|
|
+ lockedpanel.invoke TOOLBUILD
|
|
|
|
+ Else
|
|
|
|
+ activepanel.invoke TOOLBUILD
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ Method AddEventHotKey(key,mods,id,data)
|
|
|
|
+ SetHotKeyEvent key,mods,CreateEvent(id,Null,data)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method InitHotkeys()
|
|
|
|
+ AddEventHotKey KEY_F5,MODIFIER_NONE,EVENT_MENUACTION,MENURUN
|
|
|
|
+ AddEventHotKey KEY_F7,MODIFIER_NONE,EVENT_MENUACTION,MENUBUILD
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SaveAll()
|
|
|
|
+ For Local panel:TToolPanel = EachIn panels
|
|
|
|
+ panel.invoke TOOLQUICKSAVE
|
|
|
|
+ Next
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method Restart()
|
|
|
|
+ If Confirm(LocalizeString("{{request_restart}}"))
|
|
|
|
+ Quit
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method RefreshAll()
|
|
|
|
+' hide/show toolbar
|
|
|
|
+ If options.showtoolbar Then ShowGadget toolbar Else HideGadget toolbar
|
|
|
|
+' refresh panels
|
|
|
|
+ For Local panel:TToolPanel = EachIn panels
|
|
|
|
+ panel.invoke TOOLREFRESH
|
|
|
|
+ Next
|
|
|
|
+' refresh navbar
|
|
|
|
+ navbar.invoke TOOLREFRESH
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method SnapshotWindow()
|
|
|
|
+ If WindowMaximized(window)
|
|
|
|
+ winmax=True
|
|
|
|
+ Else
|
|
|
|
+ If Not WindowMinimized(window)
|
|
|
|
+ winmax=False
|
|
|
|
+ winsize.x=GadgetX(window)
|
|
|
|
+ winsize.y=GadgetY(window)
|
|
|
|
+ winsize.w=GadgetWidth(window)
|
|
|
|
+ winsize.h=GadgetHeight(window)
|
|
|
|
+ EndIf
|
|
|
|
+ EndIf
|
|
|
|
+ options.showtoolbar = Not GadgetHidden(toolbar)
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method OnMenu(menu,extra:Object=Null)
|
|
|
|
+ Local index
|
|
|
|
+
|
|
|
|
+ Local tool:TTool = TTool(extra)
|
|
|
|
+ If tool
|
|
|
|
+ tool.invoke(TOOLMENU,""+menu)
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ Select menu
|
|
|
|
+ Case MENUNEW
|
|
|
|
+ OpenSource ""
|
|
|
|
+ Case MENUOPEN
|
|
|
|
+ OpenSource "."
|
|
|
|
+ Case MENUCLOSE
|
|
|
|
+ currentpanel.invoke TOOLCLOSE
|
|
|
|
+ Case MENUCLOSEALL
|
|
|
|
+ CloseAll True
|
|
|
|
+ Case MENUCLOSEOTHERS
|
|
|
|
+ CloseAll True, False
|
|
|
|
+ Case MENUSAVE
|
|
|
|
+ currentpanel.invoke TOOLSAVE
|
|
|
|
+ Case MENUSAVEAS
|
|
|
|
+ currentpanel.invoke TOOLSAVEAS
|
|
|
|
+ Case MENUSAVEALL
|
|
|
|
+ SaveAll()
|
|
|
|
+ Case MENUPRINT
|
|
|
|
+ currentpanel.invoke TOOLPRINT
|
|
|
|
+ Case MENUQUIT
|
|
|
|
+ Quit()
|
|
|
|
+
|
|
|
|
+ Case MENUGOTO
|
|
|
|
+ gotoreq.Show()
|
|
|
|
+ Case MENUFIND
|
|
|
|
+ currentpanel.invoke TOOLFIND
|
|
|
|
+ Case MENUFINDNEXT
|
|
|
|
+ currentpanel.invoke TOOLFINDNEXT
|
|
|
|
+ Case MENUREPLACE
|
|
|
|
+ replacereq.Show()
|
|
|
|
+
|
|
|
|
+ Case MENUUNDO currentpanel.invoke TOOLUNDO
|
|
|
|
+ Case MENUREDO currentpanel.invoke TOOLREDO
|
|
|
|
+
|
|
|
|
+ Case MENUCUT currentpanel.invoke TOOLCUT
|
|
|
|
+ Case MENUCOPY currentpanel.invoke TOOLCOPY
|
|
|
|
+ Case MENUPASTE currentpanel.invoke TOOLPASTE
|
|
|
|
+ Case MENUSELECTALL currentpanel.invoke TOOLSELECTALL
|
|
|
|
+
|
|
|
|
+ Case MENUBUILD
|
|
|
|
+ BuildCode()
|
|
|
|
+ Case MENURUN
|
|
|
|
+ RunCode()
|
|
|
|
+
|
|
|
|
+ Case MENUBUILDMODULES
|
|
|
|
+ If CheckDemo() BuildModules False
|
|
|
|
+ Case MENUBUILDALLMODULES
|
|
|
|
+ If CheckDemo() BuildModules True
|
|
|
|
+ 'Case MENUSYNCMODS
|
|
|
|
+ ' If CheckDemo() And CloseAll(False) syncmodsreq.Show
|
|
|
|
+ Case MENUDOCMODS
|
|
|
|
+ If CheckDemo() And CloseAll(False) DocMods
|
|
|
|
+ Case MENUTRIGGERDOCMODS
|
|
|
|
+ DocMods()
|
|
|
|
+ Case MENUTRIGGERSYNCDOCS
|
|
|
|
+ SyncDocs()
|
|
|
|
+
|
|
|
|
+ Case MENUSTEP If output output.StepOver()
|
|
|
|
+ Case MENUSTEPIN If output output.StepIn()
|
|
|
|
+ Case MENUSTEPOUT If output output.StepOut()
|
|
|
|
+ Case MENUSTOP If output output.Stop()
|
|
|
|
+
|
|
|
|
+ Case MENULOCKBUILD
|
|
|
|
+ activepanel.invoke TOOLLOCK
|
|
|
|
+ Case MENUUNLOCKBUILD
|
|
|
|
+ If lockedpanel lockedpanel.invoke TOOLUNLOCK
|
|
|
|
+
|
|
|
|
+ Case MENUCOMMANDLINE cmdlinereq.Show
|
|
|
|
+
|
|
|
|
+ Case MENUQUICKENABLED
|
|
|
|
+ If quickenabled
|
|
|
|
+ quickenabled=False
|
|
|
|
+ UncheckMenu quickenable
|
|
|
|
+ Else
|
|
|
|
+ quickenabled=True
|
|
|
|
+ CheckMenu quickenable
|
|
|
|
+ EndIf
|
|
|
|
+ UpdateWindowMenu window
|
|
|
|
+
|
|
|
|
+ Case MENUDEBUGENABLED
|
|
|
|
+ If debugenabled
|
|
|
|
+ debugenabled=False
|
|
|
|
+ UncheckMenu debugenable
|
|
|
|
+ Else
|
|
|
|
+ debugenabled=True
|
|
|
|
+ CheckMenu debugenable
|
|
|
|
+ EndIf
|
|
|
|
+ UpdateWindowMenu window
|
|
|
|
+
|
|
|
|
+ Case MENUTHREADEDENABLED
|
|
|
|
+ If threadedenabled
|
|
|
|
+ threadedenabled=False
|
|
|
|
+ UncheckMenu threadedenable
|
|
|
|
+ Else
|
|
|
|
+ threadedenabled=True
|
|
|
|
+ CheckMenu threadedenable
|
|
|
|
+ EndIf
|
|
|
|
+ UpdateWindowMenu window
|
|
|
|
+
|
|
|
|
+ Case MENUGUIENABLED
|
|
|
|
+ If guienabled
|
|
|
|
+ guienabled=False
|
|
|
|
+ UncheckMenu guienable
|
|
|
|
+ Else
|
|
|
|
+ guienabled=True
|
|
|
|
+ CheckMenu guienable
|
|
|
|
+ EndIf
|
|
|
|
+ UpdateWindowMenu window
|
|
|
|
+
|
|
|
|
+ Case MENUIMPORTBB
|
|
|
|
+ ImportBB
|
|
|
|
+
|
|
|
|
+ Case MENUFINDINFILES
|
|
|
|
+ If activepanel Then searchreq.ShowWithPath( ExtractDir(activepanel.path) ) Else searchreq.Show()
|
|
|
|
+
|
|
|
|
+ Case MENUPROJECTMANAGER
|
|
|
|
+ projectreq.Open projects
|
|
|
|
+ Case MENUSHOWCONSOLE
|
|
|
|
+ If output Then output.Open()
|
|
|
|
+
|
|
|
|
+ Case MENUOPTIONS
|
|
|
|
+ options.Show()
|
|
|
|
+
|
|
|
|
+ Case MENUNEXT
|
|
|
|
+ If Not currentpanel Return
|
|
|
|
+ index=currentpanel.index+1
|
|
|
|
+ If index=panels.length index=0
|
|
|
|
+ SelectPanel panels[index]
|
|
|
|
+
|
|
|
|
+ Case MENUPREV
|
|
|
|
+ If Not currentpanel Return
|
|
|
|
+ index=currentpanel.index-1
|
|
|
|
+ If index<0 index=panels.length-1
|
|
|
|
+ SelectPanel panels[index]
|
|
|
|
+
|
|
|
|
+ Case MENUQUICKHELP
|
|
|
|
+ currentpanel.invoke TOOLHELP
|
|
|
|
+
|
|
|
|
+ Case MENUHOME
|
|
|
|
+ helppanel.Home()
|
|
|
|
+ SelectPanel helppanel
|
|
|
|
+ Case MENUBACK
|
|
|
|
+ helppanel.Back()
|
|
|
|
+ SelectPanel helppanel
|
|
|
|
+ Case MENUFORWARD
|
|
|
|
+ helppanel.Forward()
|
|
|
|
+ SelectPanel helppanel
|
|
|
|
+ Case MENUABOUT
|
|
|
|
+ aboutreq.Show()
|
|
|
|
+ 'Notify (ABOUT.Replace( "{bcc_version}",BCC_VERSION ))
|
|
|
|
+ Case MENUINDENT
|
|
|
|
+ currentpanel.invoke TOOLINDENT
|
|
|
|
+ Case MENUOUTDENT
|
|
|
|
+ currentpanel.invoke TOOLOUTDENT
|
|
|
|
+
|
|
|
|
+ Case MENUNEWVIEW
|
|
|
|
+ navbar.invoke TOOLNEWVIEW
|
|
|
|
+
|
|
|
|
+ End Select
|
|
|
|
+
|
|
|
|
+ If menu>=MENURECENT
|
|
|
|
+ Local f:String = String(recentfiles.ValueAtIndex(menu-MENURECENT))
|
|
|
|
+ If f$ OpenSource f$
|
|
|
|
+ EndIf
|
|
|
|
+ End Method
|
|
|
|
+
|
|
|
|
+ Method poll()
|
|
|
|
+
|
|
|
|
+ Local src:TGadget
|
|
|
|
+ Local event = WaitEvent()
|
|
|
|
+
|
|
|
|
+ If Not activerequesters.IsEmpty()
|
|
|
|
+ Select event
|
|
|
|
+ Case EVENT_MENUACTION
|
|
|
|
+ src = ActiveGadget()
|
|
|
|
+ If src And (GadgetClass(src) = GADGET_TEXTFIELD) Then
|
|
|
|
+ Select EventData()
|
|
|
|
+ Case MENUSELECTALL
|
|
|
|
+ ActivateGadget(src)
|
|
|
|
+ Case MENUCOPY
|
|
|
|
+ GadgetCopy(src)
|
|
|
|
+ Case MENUPASTE
|
|
|
|
+ GadgetPaste(src)
|
|
|
|
+ Case MENUCUT
|
|
|
|
+ GadgetCut(src)
|
|
|
|
+ EndSelect
|
|
|
|
+ Return
|
|
|
|
+ EndIf
|
|
|
|
+ src = Null
|
|
|
|
+ Case EVENT_MOUSEENTER,EVENT_MOUSELEAVE,EVENT_GADGETLOSTFOCUS
|
|
|
|
+ Return
|
|
|
|
+ End Select
|
|
|
|
+ 'DebugLog CurrentEvent.ToString()
|
|
|
|
+ For Local activerequester:TRequester = EachIn activerequesters
|
|
|
|
+ If activerequester.Poll() Then Return
|
|
|
|
+ Next
|
|
|
|
+ EndIf
|
|
|
|
+
|
|
|
|
+ For Local handler:TEventHandler = EachIn eventhandlers
|
|
|
|
+ handler.OnEvent()
|
|
|
|
+ Next
|
|
|
|
+
|
|
|
|
+ src = TGadget(EventSource())
|
|
|
|
+
|
|
|
|
+ Select event
|
|
|
|
+ Case EVENT_GADGETACTION
|
|
|
|
+ Select EventSource()
|
|
|
|
+ Case toolbar
|
|
|
|
+ Select EventData()
|
|
|
|
+ Case TB_NEW OpenSource ""
|
|
|
|
+ Case TB_OPEN OpenSource "."
|
|
|
|
+ Case TB_CLOSE currentpanel.invoke TOOLCLOSE
|
|
|
|
+ Case TB_SAVE currentpanel.invoke TOOLSAVE
|
|
|
|
+ Case TB_CUT currentpanel.invoke TOOLCUT
|
|
|
|
+ Case TB_COPY currentpanel.invoke TOOLCOPY
|
|
|
|
+ Case TB_PASTE currentpanel.invoke TOOLPASTE
|
|
|
|
+ Case TB_FIND currentpanel.invoke TOOLFIND
|
|
|
|
+ Case TB_BUILD BuildCode
|
|
|
|
+ Case TB_BUILDRUN RunCode
|
|
|
|
+ Case TB_STEP If output output.stepover
|
|
|
|
+ Case TB_STEPIN If output output.stepin
|
|
|
|
+ Case TB_STEPOUT If output output.stepout
|
|
|
|
+ Case TB_STOP If output output.Stop
|
|
|
|
+ Case TB_HOME helppanel.Home;SelectPanel helppanel
|
|
|
|
+ Case TB_BACK helppanel.Back;SelectPanel helppanel
|
|
|
|
+ Case TB_FORWARDS helppanel.Forward;SelectPanel helppanel
|
|
|
|
+ End Select
|
|
|
|
+
|
|
|
|
+ Case tabbar
|
|
|
|
+ Local index = EventData()
|
|
|
|
+ If index>=0 And index<panels.length
|
|
|
|
+ SelectPanel panels[index]
|
|
|
|
+ EndIf
|
|
|
|
+ End Select
|
|
|
|
+
|
|
|
|
+ Case EVENT_WINDOWACCEPT, EVENT_APPOPENFILE
|
|
|
|
+ OpenSource EventText()
|
|
|
|
+
|
|
|
|
+ Case EVENT_APPTERMINATE
|
|
|
|
+ Quit()
|
|
|
|
+
|
|
|
|
+ Case EVENT_WINDOWACTIVATE
|
|
|
|
+ If (src=window) Then SelectPanel currentpanel
|
|
|
|
+
|
|
|
|
+ Case EVENT_WINDOWCLOSE
|
|
|
|
+ If (src=window) Then Quit()
|
|
|
|
+
|
|
|
|
+ Case EVENT_WINDOWMOVE, EVENT_WINDOWSIZE
|
|
|
|
+ If (src=window) Then SnapshotWindow()
|
|
|
|
+
|
|
|
|
+ Case EVENT_MENUACTION
|
|
|
|
+ OnMenu EventData(),EventExtra()
|
|
|
|
+
|
|
|
|
+ EndSelect
|
|
|
|
+ EndMethod
|
|
|
|
+
|
|
|
|
+EndType
|
|
|
|
+
|
|
|
|
+Function CacheAndLoadText$(url:Object)
|
|
|
|
+ Local tmpResult$
|
|
|
|
+ Local tmpBytes:Byte[] = LoadByteArray(url)
|
|
|
|
+ url = CreateRamStream( tmpBytes, tmpBytes.length, True, False )
|
|
|
|
+ tmpResult = LoadText(url)
|
|
|
|
+ TRamStream(url).Close()
|
|
|
|
+ Return tmpResult
|
|
|
|
+EndFunction
|