rexx-things/modules/windows/oodialog/ooRexxTry/ooRexxTry.rex
2025-03-12 20:50:48 +00:00

984 lines
35 KiB
Rexx
Executable File

/*----------------------------------------------------------------------------*/
/* */
/* Copyright (c) 2007-2019 Rexx Language Association. All rights reserved. */
/* */
/* This program and the accompanying materials are made available under */
/* the terms of the Common Public License v1.0 which accompanies this */
/* distribution. A copy is also available at the following address: */
/* https://www.oorexx.org/license.html */
/* */
/* Redistribution and use in source and binary forms, with or */
/* without modification, are permitted provided that the following */
/* conditions are met: */
/* */
/* Redistributions of source code must retain the above copyright */
/* notice, this list of conditions and the following disclaimer. */
/* Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in */
/* the documentation and/or other materials provided with the distribution. */
/* */
/* Neither the name of Rexx Language Association nor the names */
/* of its contributors may be used to endorse or promote products */
/* derived from this software without specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/*----------------------------------------------------------------------------*/
/* oorexxtry.rex */
/*
What: 21st Century version of Rexxtry
Who: Lee Peedin
See documentation for version control
10/04/07 Extended fileNameDialog mask for open (*.*)
10/05/07 Added charout method to sayCatcher class
Added lineout method to sayCatcher class
10/15/07 Directives now work - return values aren't captured
10/16/07 Added header to copy all
11/29/07 Modified ~getText for occasions when lines should not be stripped.
Place in the incubator
04/19/09 Removed deprecated createFont() and replaced it with createFontEx().
04/19/09 Enhanced the menu to use check marks for font name, size, and silent.
*/
-- Capture the location of our source code program
discard = locate()
parse arg isDefault
.local~useDefault = .false
if isDefault~translate = 'DEFAULT' then
.local~useDefault = .true
call LoadEnvironment -- Set up the environment to work with
code = .oort_dialog~new() -- Create the dialog
if code~initCode \= 0 then
do
call errorDialog 'Error creating code dialog. initCode:' code~initCode
exit
end
say
say "This console will receive the output of your system commands."
say "Try 'dir' for example."
say
code~execute('ShowTop') -- Execute the dialog
exit
::requires "ooDialog.cls" -- Needed for the dialog
::requires 'winsystm.cls' -- Needed for the Windows clipboard
::class oort_dialog subclass userdialog
::method init
self~init:super
rc = self~create(.dx,.dy,.dwidth,.dheight,.title,'ThickFrame MinimizeBox MaximizeBox')
self~initCode = (rc=0)
self~fontMenuHelper
::method defineDialog
expose u menuBar
u = .dlgAreaU~new(self)
if .nil \= u~lastError then
call errorDialog u~lastError
---------- Arguments title & dialog area
at = .dlgArea~new(0,0,u~w,10)
self~createStaticText(17,at~x,at~y,at~w,at~h,'CENTER','Arguments')
ad = .dlgArea~new(0,at~y + 10,u~w,u~h('15%'))
self~createEdit(12,ad~x,ad~y,ad~w,ad~h,'multiline hscroll vscroll','args_data')
---------- Code title & dialog area
ct = .dlgArea~new(0,ad~y + ad~h,u~w,10)
self~addText(ct~x,ct~y,ct~w,ct~h,'Code','CENTER',18)
cd = .dlgArea~new(0,ct~y + ct~h,u~w,u~h('40%'))
self~addEntryLine(13,'code_data',cd~x,cd~y,cd~w,cd~h,'multiline hscroll vscroll')
---------- Says title & dialog area
st = .dlgArea~new(0,cd~y + cd~h,u~w('50%'),10)
self~createStaticText(19,st~x,st~y,st~w,st~h,'CENTER','Says')
sd = .dlgArea~new(0,st~y + st~h,u~w('50%'),u~h('43%'))
self~createEdit(14,sd~x,sd~y,sd~w,sd~h,'notab readonly multiline hscroll vscroll','say_data')
---------- Returns title & dialog area
rt = .dlgArea~new(sd~x + sd~w,cd~y + cd~h,u~w('50%'),10)
self~createStaticText(20,rt~x,rt~y,rt~w,rt~h,'CENTER','Returns')
rd = .dlgArea~new(rt~x,st~y + st~h,u~w('50%'),u~h('15%'))
self~createEdit(15,rd~x,rd~y,rd~w,rd~h,'notab readonly multiline hscroll vscroll','results_data')
---------- Errors/Information title & dialog area
et = .dlgArea~new(rt~x,rd~y + rd~h,u~w('50%'),10)
self~createStaticText(21,et~x,et~y,et~w,et~h,'CENTER','Errors / Information')
ed = .dlgArea~new(rt~x,et~y + et~h,u~w('50%'),u~h('17%'))
self~createEdit(16,ed~x,ed~y,ed~w,ed~h,'notab readonly multiline hscroll vscroll','error_data')
---------- Run & Exit buttons for easier execution
self~createPushButton(80,ed~x ,ed~y + ed~h + 2,35,10,,'&Run','RunIt')
self~createPushButton(IDCANCEL,ed~x + 40,ed~y + ed~h + 2,35,10,,'E&xit')
----------
menuBar = .UserMenuBar~new(500,0,65)
menuBar~addPopup(510, '&File')
menuBar~addItem(22,'&Run' , ,'RunIt')
menuBar~addItem(23,'&SaveAs', ,'FileDialog')
menuBar~addItem(25,'&Open' , ,'FileDialog')
menuBar~addItem(24,'E&xit' ,'END','Cancel')
menuBar~addPopup(520,'&Edit')
menuBar~addPopup(530,'Font&Name')
menuBar~addItem(30,'&Lucida Console', ,'onFontMenuClick')
menuBar~addItem(31,'&Courier New' ,'END','onFontMenuClick')
menuBar~addSeparator(535)
menuBar~addPopup(540,'Font&Size','END')
menuBar~addItem(40,'&8' , ,'onFontMenuClick')
menuBar~addItem(41,'1&0', ,'onFontMenuClick')
menuBar~addItem(42,'1&2', ,'onFontMenuClick')
menuBar~addItem(43,'1&4', ,'onFontMenuClick')
menuBar~addItem(44,'1&6', ,'onFontMenuClick')
menuBar~addItem(45,'1&8','END','onFontMenuClick')
menuBar~addPopup(550,'&Tools')
menuBar~addPopup(560,'&Copy')
menuBar~addItem(50,'&Args' , ,'Clipboard')
menuBar~addItem(51,'&Code' , ,'Clipboard')
menuBar~addItem(52,'&Says' , ,'ClipBoard')
menuBar~addItem(53,'&Returns', ,'ClipBoard')
menuBar~addItem(54,'&Errors' , ,'ClipBoard')
menuBar~addItem(55,'A&ll' ,'END','ClipBoard')
menuBar~addSeparator(565)
menuBar~addPopup(570,'C&lear')
menuBar~addItem(60,'&Args' , ,'ClearAll')
menuBar~addItem(61,'&Code' , ,'ClearAll')
menuBar~addItem(62,'&Says' , ,'ClearAll')
menuBar~addItem(63,'&Returns', ,'ClearAll')
menuBar~addItem(64,'&Errors' , ,'ClearAll')
menuBar~addItem(65,'A&ll' ,'END','ClearAll')
menuBar~addSeparator(575)
menuBar~addPopup(580,'&Silent')
menuBar~addItem(66,'&No' , ,'Silent')
menuBar~addItem(67,'&Yes' ,'END','Silent')
menuBar~addSeparator(585)
menuBar~addPopup(590,'Sa&ve Settings','END')
menuBar~addItem(72,'Sa&ve' ,'END','SaveSettings')
menuBar~addPopup(600,'&Help','END')
menuBar~addItem(71,'Current &Settings', ,'Settings')
menuBar~addItem(70,'&About' ,'END','Help')
if \ menuBar~complete then
statusText = 'User menu bar completion error:' .SystemErrorCode SysGetErrortext(.SystemErrorCode)
::method initDialog unguarded
expose args_input code_input result_input say_input errors_input menuBar
-- Use font data from .ini file or defaults if .ini not present yet
-- FW_EXTRALIGHT == 200
d = .Directory~new
d~weight = 200
hfont = self~createFontEx(.fontname,.fontsize,d)
if menuBar \== .nil then menuBar~attachTo(self)
-- Set the font and silent menu item check marks.
self~setFontMenuChecks
if .silent then menuBar~check(67)
else menuBar~check(66)
-- Get the controls for all dialog elements that will need to be adjusted
args_input = self~newEdit(12)
code_input = self~newEdit(13)
say_input = self~newEdit(14)
result_input = self~newEdit(15)
errors_input = self~newEdit(16)
args_title = self~newStatic(17)
code_title = self~newStatic(18)
say_title = self~newStatic(19)
result_title = self~newStatic(20)
errors_title = self~newStatic(21)
-- Set the color of the titles
args_title ~setColor(5,10)
code_title ~setColor(16,10)
say_title ~setColor(15,0)
result_title~setColor(14,0)
errors_title~setColor(13,10)
-- Set the font name/size to the default values
self~reDraw
if \.useDefault then
do
-- Read oorexxtry.ini position & size the dialog based on its values
sd = .application~srcDir
k1 = SysIni(sd'oorexxtry.ini','oorexxtry','k1')
k2 = SysIni(sd'oorexxtry.ini','oorexxtry','k2')
k3 = SysIni(sd'oorexxtry.ini','oorexxtry','k3')
k4 = SysIni(sd'oorexxtry.ini','oorexxtry','k4')
if k1 = 'ERROR:' | k2 = 'ERROR:' | k3 = 'ERROR:' | k4 = 'ERROR:' then
nop -- First exection will not find the ini file
else
do
r = .Rect~new(k1,k2,k3-k1,k4-k2)
self~setWindowPos(TOP,r)
self~ensureVisible
end
end
self~connectResize('onResize', 'sync')
-- Run menu option
::method RunIt
expose args_input code_input result_input say_input errors_input
-- Calculate the center point of the code_input edit control, in screen
-- co-ordinates.
r = code_input~clientRect
centerPoint = .Point~new((r~right - r~left) % 2, (r~bottom - r~top) % 2)
code_input~client2screen(centerPoint)
-- Get and save the current mouse position.
mouse = .Mouse~new(code_input)
oldCursorPos = mouse~getCursorPos
-- Set the cursor to the busy symbol / move the cursor to our center point
oldCursor = mouse~wait
mouse~setCursorPos(centerPoint)
arg_array = self~getText(args_input,.true)
.local~si = say_input
w1 = code_input~selected~word(1)
w2 = code_input~selected~word(2)
code_array = self~getText(code_input,.true)
if (w1 = .max_length & w2 = .max_length) | (w1 = w2) then
nop -- we've already loaded our code_array
else
do
code_string = code_array~makeString
code_array = code_string~substr(w1,w2-w1)~makearray
end
-- Clear any previous error data
self~error_data = ''
errors_input~title = self~error_data
-- Clear any previous say data
self~say_data = ''
say_input~title = self~say_data
-- Clear any previous returns data
self~results_data = ''
result_input~title = self~results_data
.local~emsg = ''
.local~imsg = ''
self~error_data = 'Code Is Executing'
errors_input~title = self~error_data
.local~Error? = .false
.local~badarg = ''
-- Interpret each argument so that expressions can be used
signal on syntax name ArgSyntax
do i = 1 to arg_array~items
.local~badarg = i arg_array[i]
interpret 'arg_array['i'] =' arg_array[i]
end
signal off syntax
exec = .executor~new('oorexxtry.code',code_array)
exec~run(arg_array)
if .emsg \= '' then
do
if \.silent then
call beep 600,100
self~error_data = .emsg
errors_input~title = self~error_data
self~results_data = ''
result_input~title = self~results_data
end
else
do
self~error_data = 'Code Execution Complete'
errors_input~title = self~error_data
end
if .nil \= .run_results['returns'] then
do
self~results_data = .run_results['returns']
result_input~title = self~results_data
end
if \.silent then -- Let the user know when code execution is complete
call beep 150,150
mouse~restoreCursor(oldCursor)
mouse~setCursorPos(oldCursorPos)
self~returnFocus
return
ArgSyntax:
msg = 'Trapped In'~right(11)'..: ArgSyntax'
obj = condition('o')
msg = msg||.endOfLine||'Message'~right(11)'..:' obj['MESSAGE']
msg = msg||.endOfLine||'ErrorText'~right(11)'..:' obj['ERRORTEXT']
msg = msg||.endOfLine||'Code'~right(11)'..:' obj['CODE']
msg = msg||.endOfLine||('Argument' .badarg~word(1))~right(11)'..:' .badarg~subword(2)
.local~emsg = msg
if \.silent then
call beep 600,100
self~error_data = .emsg
errors_input~title = self~error_data
self~results_data = ''
result_input~title = self~results_data
.local~emsg = ''
self~focusItem(12)
args_input~select(1,1)
mouse~restoreCursor(oldCursor)
mouse~setCursorPos(oldCursorPos)
return
::method cancel
r = self~windowRect
-- Write out the size,position,fontname,fontsize, & silent to the .ini file
sd = .application~srcDir
if \self~isMinimized & \self~isMaximized then
do
rv = SysIni(sd'oorexxtry.ini','oorexxtry','k1',r~left)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','k2',r~top)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','k3',r~right)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','k4',r~bottom)
end
rv = SysIni(sd'oorexxtry.ini','oorexxtry','fn',.fontname)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','fs',.fontsize)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','sl',.silent)
return self~ok:super
-- Clipboard menu option
::method ClipBoard
expose args_input errors_input code_input say_input result_input
use arg msg, args
cp = .WindowsClipBoard~new
select
when msg = 50 then
do
cp_array = self~getText(args_input,.false)
cp_string = cp_array~makestring
cp~copy(cp_string)
.local~imsg = 'Arguments Are On ClipBoard'
end
when msg = 51 then
do
cp_array = self~getText(code_input,.false)
cp_string = cp_array~makestring
cp~Copy(cp_string)
.local~imsg = 'Code Is On ClipBoard'
end
when msg = 52 then
do
cp_array = self~getText(say_input,.false)
cp_string = cp_array~makestring
cp~copy(cp_string)
.local~imsg = 'Says Are On The ClipBoard'
end
when msg = 53 then
do
cp_array = self~getText(result_input,.false)
cp_string = cp_array~makestring
cp~Copy(cp_string)
.local~imsg = 'Returns Are On ClipBoard'
end
when msg = 54 then
do
cp_array = self~getText(errors_input,.false)
cp_string = cp_array~makestring
cp~copy(cp_string)
.local~imsg = 'Errors Are On ClipBoard'
end
when msg = 55 then
do
allData = 'The Following Output Was Generated With ooRexxTry'.endOfLine||.endOfLine
cp_array = self~getText(args_input,.false)
cp_string = cp_array~makestring
allData = alldata||'Arguments'||.endOfLine||cp_string||.endOfLine||'-'~copies(20)||.endOfLine
cp_array = self~getText(code_input,.false)
cp_string = cp_array~makestring
allData = allData||'Code'||.endOfLine||cp_string||.endOfLine||'-'~copies(20)||.endOfLine
cp_array = self~getText(say_input,.false)
cp_string = cp_array~makestring
allData = allData||'Says'||.endOfLine||cp_string||.endOfLine||'-'~copies(20)||.endOfLine
cp_array = self~getText(result_input,.false)
cp_string = cp_array~makestring
allData = allData||'Results'||.endOfLine||cp_string||.endOfLine||'-'~copies(20)||.endOfLine
cp_array = self~getText(errors_input,.false)
cp_string = cp_array~makestring
allData = allData||'Errors/Information'||.endOfLine||cp_string||.endOfLine||'-'~copies(20)||.endOfLine
cp~copy(allData)
.local~imsg = 'All Data Is On ClipBoard'
end
otherwise
nop
end
self~error_data = .imsg
errors_input~title = self~error_data
self~returnFocus
-- Code2File menu option
::method FileDialog
expose code_input errors_input
use arg msg, args
if msg = 23 then
do
c_array = self~getText(code_input,.false)
c_string = c_array~makestring
action = 'S'
dtitle = 'ooRexxTry File Save'
end
else
do
action = 'L'
dtitle = 'ooRexxTry File Open'
end
delimiter = '0'x
filemask = 'ooRexx Files (*.rex)'delimiter'*.rex'delimiter||-
'All Files (*.*)'delimiter'*.*'delimiter
handle = self~getSelf
a_file = FileNameDialog(.preferred_path,handle,filemask,action,dtitle,'.rex')
if a_file \= 0 then
do
ostream = .stream~new(a_file)
if msg = 23 then
do
ostream~open('Write Replace')
ostream~lineout(c_string)
ostream~close
.local~imsg = 'Code Saved As' a_file
self~error_data = .imsg
errors_input~title = self~error_data
end
else
do
oarray = ostream~charin(,ostream~chars)~makearray
ostream~close
mycode = ''
do i = 1 to oarray~items
mycode = mycode||oarray[i]
if i < oarray~items then
mycode = mycode||.endOfLine
end
self~code_data = mycode
code_input~title = self~code_data
.local~imsg = 'Code From' a_file 'In Code Dialog'
self~error_data = .imsg
errors_input~title = self~error_data
end
end
self~returnFocus
-- ClearAll menu option
::method ClearAll
expose args_input code_input result_input say_input errors_input
use arg msg, args
select
when msg = 60 then
do
self~args_data = ''
args_input~title = self~args_data
end
when msg = 61 then
do
self~code_data = ''
code_input~title = self~code_data
end
when msg = 62 then
do
self~say_data = ''
say_input~title = self~say_data
end
when msg = 63 then
do
self~results_data = ''
result_input~title = self~results_data
end
when msg = 64 then
do
self~error_data = ''
errors_input~title = self~error_data
end
when msg = 65 then
do
self~args_data = ''
args_input~title = self~args_data
self~code_data = ''
code_input~title = self~code_data
self~results_data = ''
result_input~title = self~results_data
self~say_data = ''
say_input~title = self~say_data
self~error_data = ''
errors_input~title = self~error_data
end
otherwise
nop
end
self~returnFocus
::method Silent
expose menuBar
use arg msg, args
select
when msg = 66 then do
.local~silent = .false
menuBar~check(66)
menuBar~unCheck(67)
end
when msg = 67 then do
.local~silent = .true
menuBar~check(67)
menuBar~unCheck(66)
end
otherwise
nop
end
self~returnFocus
::method SaveSettings
use arg msg, args
r = self~windowRect
select
when msg = 72 then
do
sd = .application~srcDir
if \self~isMinimized & \self~isMaximized then
do
rv = SysIni(sd'oorexxtry.ini','oorexxtry','k1',r~left)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','k2',r~top)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','k3',r~right)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','k4',r~bottom)
end
rv = SysIni(sd'oorexxtry.ini','oorexxtry','fn',.fontname)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','fs',.fontsize)
rv = SysIni(sd'oorexxtry.ini','oorexxtry','sl',.silent)
end
otherwise
nop
end
self~returnFocus
::method ReturnFocus
expose code_input
w1 = code_input~selected~word(1)
w2 = code_input~selected~word(2)
code_array = self~getText(code_input,.true)
if w1 = .max_length & w2 = .max_length then
do
sel_start = .max_length
sel_end = .max_length
end
else
do
sel_start = w1
sel_end = w2
end
self~focusItem(13)
code_input~select(sel_start,sel_end)
-- Method to handle all the resizing
::method onResize
expose u
use arg dummy,sizeinfo
u~resize(self,sizeinfo)
::method Help
expose code_input u
handle = self~getSelf
parse value self~GetWindowRect(handle) with var1 var2 var3 var4
.local~dw = (var3 - var1) / self~factorX
.local~dh = (var4 - var2) / self~factorY
parse value self~GetPos with dx dy
.local~dx = dx
.local~dy = dy
help = .help_dialog~new()
if help~initCode \= 0 then
do
call errorDialog 'Error creating help dialog. initCode:' help~initCode
exit
end
help~execute('ShowTop')
::method Settings
expose code_input u
handle = self~getSelf
parse value self~getWindowRect(handle) with var1 var2 var3 var4
.local~dw = (var3 - var1) / self~factorX
.local~dh = (var4 - var2) / self~factorY
parse value self~getPos with dx dy
.local~dx = dx
.local~dy = dy
settings = .settings_dialog~new()
if settings~initCode \= 0 then
do
call errorDialog 'Error creating help dialog. initCode:' settings~initCode
exit
end
settings~execute('ShowTop')
-- Redraw applicable areas of the dialog based on the font menu choice
::method ReDraw
expose args_input code_input say_input result_input errors_input
-- FW_EXTRALIGHT == 200
d = .Directory~new
d~weight = 200
hfont = self~createFontEx(.fontname,.fontsize,d)
args_input ~setFont(hfont)
code_input ~setFont(hfont)
say_input ~setFont(hfont)
result_input~setFont(hfont)
errors_input~setFont(hfont)
::method getText
use arg the_input,stripIt
iarray = .array~new()
max_length = 0
do i = 1 to the_input~lines
if stripIt then
do
if the_input~getLine(i)~strip() \= '' then
do
iarray~append(the_input~getLine(i))
max_length += iarray[iarray~last]~length
end
end
else
do
iarray~append(the_input~getLine(i))
max_length += iarray[iarray~last]~length
end
end
.local~max_length = max_length + 1
return iarray
-- This method is invoked whenever the user clicks on one of the font menu items.
-- The first arg to the method is the resource id of the menu id that was clicked.
::method onFontMenuClick
expose fontMenuIDs
use arg id
-- Map the menu item id to a font setting. Could be size of name.
item = fontMenuIDs~index(id)
-- If item is a number, then it is a font size menu item, otherwis a font name.
if item~datatype('W') then .local~fontSize = item
else .local~fontname = item
-- Reset the menu item check marks and redraw in the new font.
self~setFontMenuChecks
self~reDraw
-- This method sets the appropriate font menu item check state. Checked for selected
-- and unchecked for unselected.
::method setFontMenuChecks private
expose fontMenuIDs menuBar
-- Iterate over all items in the table unchecking each menu item. Brute force,
-- but easy, and there are not many items. The alternative is to keep track of
-- which items are checked and uncheck / check the correct ones.
do id over fontMenuIDs~allItems
menuBar~unCheck(id)
end
-- Now check the menu item that matches what font name and size is currently
-- in use.
menuBar~check(fontMenuIDs[.fontname])
menuBar~check(fontMenuIDs[.fontsize])
-- A private help method that sets up things to make working with the font menu easier
::method fontMenuHelper private
expose fontMenuIDs
-- Create a table that maps menu item IDs to the matching font setting. Since
-- the Table class has the index() method, the mapping works both ways.
fontMenuIDs = .Table~new
fontMenuIDs["Lucida Console"] = 30
fontMenuIDs["Courier New"] = 31
fontMenuIDs[ 8] = 40
fontMenuIDs[10] = 41
fontMenuIDs[12] = 42
fontMenuIDs[14] = 43
fontMenuIDs[16] = 44
fontMenuIDs[18] = 45
-- Class that dynamically creates a method to take the arguments and execute the code
::class executor public
::method init
expose rt_routine
use arg routine_name,code
.local~Error? = .false
signal on syntax name ExecSyntax
rt_routine = .routine~new(routine_name, code)
return
-- Syntax trap similiar to rexxc.exe
ExecSynTax:
msg = 'Trapped In'~right(11)'..: ExecSyntax'
obj = condition('o')
msg = msg||.endOfLine||'Message'~right(11)'..:' obj['MESSAGE']
msg = msg||.endOfLine||'ErrorText'~right(11)'..:' obj['ERRORTEXT']
msg = msg||.endOfLine||'Code'~right(11)'..:' obj['CODE']
msg = msg||.endOfLine||'Line #'~right(11)'..:' obj['POSITION']
.local~emsg = msg
.local~Error? = .true
return
-- Method that actually runs our code
::method run
expose rt_routine say_string
signal on syntax name RunSyntax
.local~run_results = .directory~new
.local~say_stg = ''
my_result = ''
if \.Error? then
do
-- Redirect STDOUT for say statements
scrnOut = .SayCatcher~New('STDOUT')~~Command('open write nobuffer')
theSayMonitor = .monitor~New(scrnOut)
.output~destination(theSayMonitor)
-- Run the Code
args = arg(1)
rt_routine~callWith(args)
-- Test if there was anything returned by the code
if symbol('result') = 'VAR' then
my_result = result
-- Load the says and returns into environment variables for updating the dialog areas
.local~run_results['returns'] = my_result
-- Redirect STDOUT back to what it was (probably the screen)
.output~Destination()
end
return .run_results
-- Syntax trap for errors in the code
RunSyntax:
msg = 'Trapped In'~right(11)'..: RunSyntax'
obj = condition('o')
msg = msg||.endOfLine||'Message'~right(11)'..:' obj['MESSAGE']
msg = msg||.endOfLine||'ErrorText'~right(11)'..:' obj['ERRORTEXT']
msg = msg||.endOfLine||'Code'~right(11)'..:' obj['CODE']
msg = msg||.endOfLine||'Line #'~right(11)'..:' obj['POSITION']
.local~emsg = msg
return
-- Class to "catch" all say,charout,lineout statements in the code
-- Will not catch charout & lineout if the first argument is supplied
::class SayCatcher subclass stream
::method say
use arg input
.local~say_stg = .say_stg||input||.endOfLine
.si~title = .say_stg
return
::method charout
use arg input
.local~say_stg = .say_stg||input
.si~title = .say_stg
return 0
::method lineout
use arg input
.local~say_stg = .say_stg||input||.endOfLine
.si~title = .say_stg
return 0
::class help_dialog subclass userdialog
::method init
self~init:super
lp = (.dx + (.dw / 2) - 50)~format( , 0)
tp = (.dy + (.dh / 2) - 30)~format( , 0)
rc = self~create(lp,tp,100,60,.title,"THICKFRAME")
self~initCode = (rc=0)
::method defineDialog
expose h sizing
h = .dlgAreaU~new(self)
if .nil \= h~lastError then
call errorDialog h~lastError
h~updateOnResize = .false
sizing = .false
vt = .dlgArea~new(h~x,0,h~w,10)
self~createStaticText(20,vt~x,vt~y,vt~w,vt~h,'CENTER','Version')
vd = .dlgArea~new(h~x,vt~y + vt~h,h~w,10)
self~createStaticText(21,vd~x,vd~y,vd~w,vd~h,'CENTER',.version)
at = .dlgArea~new(h~x,vd~y + vd~h,h~w,10)
self~createStaticText(22,at~x,at~y,at~w,at~h,'CENTER','Author')
ad = .dlgArea~new(h~x,at~y + at~h,h~w,10)
self~createStaticText(23,ad~x,ad~y,ad~w,ad~h,'CENTER','Lee Peedin')
dt = .dlgArea~new(h~x,ad~y + ad~h,h~w,10)
self~createStaticText(24,dt~x,dt~y,dt~w,dt~h,'CENTER','Documentation')
dd = .dlgArea~new(h~x,dt~y + dt~h,h~w,10)
self~createPushButton(25,dd~x,dd~y,dd~w,10,,'&PDF','Help')
::method initDialog unguarded
v_title = self~newStatic(20)
a_title = self~newStatic(22)
d_title = self~newStatic(24)
v_title~setColor(5,10)
a_title~setColor(5,10)
d_title~setColor(5,10)
self~connectResize('onResize', 'sync')
self~connectSizeMoveEnded('onSizeMoveEnded')
::method help
-- The help doc is supposed to be in the 'doc' subdirectory, but we will also check the
-- current directory, then the Rexx home directory.
if SysFileExists('doc\ooRexxTry.pdf') then do
helpDoc = 'doc\ooRexxTry.pdf'
end
else if SysFileExists('ooRexxTry.pdf') then do
helpDoc = 'ooRexxTry.pdf'
end
else if SysfileExists(value("REXX_HOME",,"ENVIRONMENT")||"\doc\ooRexxTry.pdf") then do
helpDoc = value("REXX_HOME",,"ENVIRONMENT")||"\doc\ooRexxTry.pdf"
end
else do
msg = "The ooRexxTry.pdf help documentation could not be located." || .endOfLine -
|| .endOfLine || -
"Tried:" || .endOfLine -
" doc subdirectory: "||directory()||"\doc\ooRexxTry.pdf" || .endOfLine -
" current directory: "||directory()||"\ooRexxTry.pdf" || .endOfLine -
" Rexx home: "||value("REXX_HOME",,"ENVIRONMENT")||"\doc\ooRexxTry.pdf" || .endOfLine -
|| .endOfLine || -
"Sorry, no help is available"
title = 'ooRexx Try for the 21st Century - Error'
j = MessageDialog(msg, self~hwnd, title, 'Ok', 'WARNING')
return
end
'start "ooRexxTry Online Documentation"' '"'||helpDoc||'"'
::method onResize unguarded
expose h sizing
use arg sizingType, sizeinfo
sizing = .true
h~resize(self, sizeinfo)
::method onSizeMoveEnded unguarded
expose sizing
-- If we were resizing, force the dialog controls to redraw themselves.
if sizing then self~update
-- We are not resizing anymore.
sizing = .false
return 0
::class settings_dialog subclass userdialog
::method Init
self~init:super
lp = (.dx + (.dw / 2) - 50)~format( , 0)
tp = (.dy + (.dh / 2) - 30)~format( , 0)
rc = self~Create(lp,tp,100,60,.title)
self~InitCode = (rc=0)
::method DefineDialog
expose h
h = .dlgAreaU~new(self)
if .nil \= h~lastError then
call errorDialog h~lastError
vt = .dlgArea~new(h~x,0,h~w,10)
self~addText(vt~x,vt~y,vt~w,vt~h,'Font Name','CENTER',20)
vd = .dlgArea~new(h~x,vt~y + vt~h,h~w,10)
self~addText(vd~x,vd~y,vd~w,vd~h,.fontname,'CENTER',21)
at = .dlgArea~new(h~x,vd~y + vd~h,h~w,10)
self~addText(at~x,at~y,at~w,at~h,'Font Size','CENTER',22)
ad = .dlgArea~new(h~x,at~y + at~h,h~w,10)
self~addText(ad~x,ad~y,ad~w,ad~h,.fontsize,'CENTER',23)
dt = .dlgArea~new(h~x,ad~y + ad~h,h~w,10)
self~addText(dt~x,dt~y,dt~w,dt~h,'Silent','CENTER',24)
dd = .dlgArea~new(h~x,dt~y + dt~h,h~w,10)
self~addText(dd~x,dd~y,dd~w,dd~h,.silent,'CENTER',23)
::method InitDialog
v_title = self~newStatic(20)
a_title = self~newStatic(22)
d_title = self~newStatic(24)
v_title~setColor(14,0)
a_title~setColor(14,0)
d_title~setColor(14,0)
::routine LoadEnvironment
.local~px = ScreenSize()[3]
.local~py = ScreenSize()[4]
-- Establish dialog area sizes based of the user's screen resolution - will only be used for the first
-- execution - from then on data is retrieved from the .ini file, unless user specifies default as an
-- execution argument from the command line
.local~dwidth = ((.px / 2.5) * .65)~format(,0)
.local~dheight = ((.py / 2.5) * .65)~format(,0)
.local~dx = 0
.local~dy = 0
-- Need a few generic variables
.local~version = '1.0' -- Internal version control
.local~preferred_path = '' -- Default starting path for Save As dialog - will be either
-- the folder ooRexxTry is executed from or the last folder that
-- was accessed using the Windows File Dialog
.local~title = 'ooRexxTry' -- Title to use for the dialogs
-- If the .ini file is present, use it for font/silent variables
sd = .application~srcDir
.local~fontname = SysIni(sd'oorexxtry.ini','oorexxtry','fn')
.local~fontsize = SysIni(sd'oorexxtry.ini','oorexxtry','fs')
.local~silent = SysIni(sd'oorexxtry.ini','oorexxtry','sl')
-- Else use some defaults
if .fontname = 'ERROR:' | .useDefault then
.local~fontname = 'Lucida Console'
if .fontsize = 'ERROR:' | .useDefault then
.local~fontsize = 12
if .silent = 'ERROR:' | .useDefault then
.local~silent = .false
return