Recent Posts

Pages: [1] 2 3 ... 8
1
SB2020 / Re: SB2020 Open Source Accounting
« Last post by John Spikowski on December 23, 2018, 01:41:08 PM »
I can be as busy as everyone else if folks don't join the forum and show some interest. I have nothing to sell you but you're own salvaton.

Have a great Christmas and New Year!
2
SB2020 / Re: SB2020 Open Source Accounting
« Last post by John Spikowski on December 19, 2018, 02:06:54 AM »
I've installed Front Accounting on the site to play with. The paperless reporting is great.

LOGIN

User name: demo

Password: demo

3
SB2020 / Re: SB2020 Open Source Accounting
« Last post by John Spikowski on December 18, 2018, 08:47:03 PM »
I think the best approach to the SB2020 project is to use the framework in Front Accounting which is a PHP/MySQL based open source distribution package that does a great job with code reuse in a modular form.

If it had more of a 100 flow and maturity, it would be natural migration path for a cloud native direction. This path could accelerate something useable before 2020.

I think once I start posting examples, the concept will become more clear. In the mean time have fun playing with Script BASIC.  Soon you will see it in action.
4
SB2020 / Re: SB2020 Open Source Accounting
« Last post by John Spikowski on December 18, 2018, 01:49:20 PM »
This forum is about extending 100 via its open COM/OLE automation BOI API and fostering an open source community version to continue the tradition of customizable accounting software that meets your unique needs.

I feel the best direction for the SB2020 project is a cloud native web browser client interface using the multi-threaded Script BASIC application server. This direction provides unlimited seamless expansion in an environment 100 developers can feel at home with.

The plan is to get a Script BASIC application development server running on the OpenSage.org site and a Git repository setup for source control and documentation.
5
SB2020 / Session Module
« Last post by John Spikowski on December 17, 2018, 02:41:50 PM »
I would like to start the SB2020 project off by defining the Session MODULE. I will be posting a link to the Sage online docs for this object as reference. I will also write a Script BASIC BOI script to show how the object works and the properties it exposes.

This has a duel benefit as it helps those wishing to use the BOI API to extend 100 affordably without investing in unsupportable (by Sage) source code mods.

We can discuss what is essential and what is legacy defining the new Session MODULE as folks join in with the project.

6
SB2020 / Re: Sage 100 Data Access
« Last post by John Spikowski on December 16, 2018, 03:07:10 PM »
This is an example of using the Sage 100 COM/OLE automation BOI API to read the Customer file.

Note:  The BB_PAD function is from a library I built of common ProvideX specific functions that might be helpful for programmers making the transition to Script BASIC.

Code: Script BASIC
  1. ' Script BASIC BOI - READ AR_Customer RECORD
  2.  
  3. IMPORT COM.sbi
  4.  
  5. oscript = COM::CREATE(:Set, "ProvideX.Script")
  6. COM::CBN oScript,"Init",:CALL,"C:\\Sage\\Sage 100 Standard\\MAS90\\Home"
  7. osession = COM::CBN(oscript, "NewObject", :SET, "SY_Session")
  8. COM::CBN osession, "nSetUser", :CALL, "JRS", "*PASSWORD*"
  9. COM::CBN osession, "nsetcompany", :CALL, "ABC"
  10. COM::CBN osession, "nSetDate", :CALL, "A/R", "20171218"
  11. COM::CBN osession, "nSetModule", :CALL, "A/R"
  12. ocust = COM::CBN(oscript, "NewObject", :SET, "AR_Customer_svc", osession)
  13.  
  14. COM::CBN ocust,"nMoveFirst"
  15. DO UNTIL COM::CBN(ocust, "nEOF", :GET)
  16.   PRINT COM::BB_PAD(COM::CBN(ocust, "sCUSTOMERNO", :GET), 7, "R", " "), " | ", _
  17.         COM::BB_PAD(COM::CBN(ocust, "sCUSTOMERNAME", :GET), 30, "R", " "), " | ", _
  18.         COM::CBN(ocust, "sTELEPHONENO", :GET), "\n"
  19.   COM::CBN ocust, "nMoveNext"
  20. LOOP
  21.  
  22. COM::CBN ocust, "DropObject"
  23. COM::CBN osession, "DropObject"
  24. COM::RELEASE oscript
  25.  


C:\ScriptBASIC\boi>scriba custlist.sb
ABF     | American Business Futures      | (414) 555-4787
ABS     | ABS - Sage cloud for invoices  | (949) 555-7814
AVNET   | Avnet Processing Corp          | (414) 555-2635
BRESLIN | Breslin Parts Supply           | (414) 555-9654
HILLSB  | Hillsboro Service Center       | (414) 555-6599
INACTIV | Inactive Customer **INACTIVE** | (414) 555--8747
MAVRK   | Maverick Papers                | (312) 861-1200
RSSUPPL | R & S Supply Corp.             | (414) 555-5587
SHEPARD | Shepard Motorworks             | (414) 555-6544
ALLENAP | Allen's Appliance Repair       | (714) 555-3121
AMERCON | American Concrete Service      | (714) 555-2134
ATOZ    | A To Z Carpet Supply           | (714) 555-2231
AUTOCR  | Autocraft Accessories          | (714) 555-0101
BAYPYRO | Bay Pyrotronics Corp.          | (415) 555-9654
CAPRI   | Capri Sailing Ships            | (714) 555-4421
CUSTOM  | Custom Craft Products          | (714) 555-7848
GREALAR | Greater Alarm Company          | (714) 555-5531
JELLCO  | Jellco Packing                 | (714) 555-9451
ORANGE  | Orange Door & Window Co.       | (714) 555-7823

C:\ScriptBASIC\boi>

7
SB2020 / Re: SB2020 Open Source Accounting
« Last post by Root on December 15, 2018, 07:59:01 PM »
I would like to clarify the direction of the Open Sage forum and the SB2020 Script BASIC open source accounting project, I have been involved with MAS90 since its inception. I introduced ProvideX to SOTA/Best initially as a license agreement before they bought Mike's company and hired him for a short period. I have worked with many of the resellers / master developers as a sub-contract programming resource. Sage even paid me to present a proof of concept of extending 100 with a browser based interface. With Stephen Kelly leaving and an the acquisition of Intacct, going from proof of concept to a project failed to happen. :-[

Now that Sage has declared themselves a cloud company with only one cloud native product with the rest rebranded as generic hosting by subscription. Crippling features for those wishing to stay on-premise with with their sometimes modified version and not supporting mods with cloud hosting doesn't leave M/D's much room to grow. The high cost of developer fees force developers to be non-competitive with their pricing / support models.

The first step to stop the bleeding is take advantage of the open BOI API Sage offers their customers which is very close to source code access without the developer fees. Sage has also done a great job documenting the BOI API which is accessible using Microsoft's COM/OLE automation interface. (extensively used with Office integration)  For those already being hosted in the cloud with a RDP connection, Sage does support enhancements based on their open BOI API which is why this forum and direction is so important for continued use of the product line.

The SB2020 project is an insurance and long term goal to migrate to an open source model. Today we can extend 100 affordably and supported by the 100 community. Sage still gets their by the seat licensing fees if the extensions are written in ProvideX or something else. The benefit to something else is it builds a library of community derived solutions developers own or contribute to the open source pool.

My function on the Open Sage forum is to facilitate an open approach to Sage 100 software using Script BASIC which I have done the same for since 2005. I will offer peer support for community based projects and I'm available for special projects members (Sage Partner's) may need done for their customers. I'm affordable and easy to work with. I normally will do projects for a fixed fee if defined and not ongoing.

I hope to see more of the Sage developer community join us here on the forum. It's FREE and puts the fun back into programming.


8
SB2020 / Re: Modules - Inheritance
« Last post by John Spikowski on December 15, 2018, 01:14:39 PM »
Here is an example of how MODULE Inheritance could be done to promote code reuse.

Session Module (our first MODULE example)
Code: Script BASIC
  1. MODULE Session
  2.  
  3.   PROP{"CompanyCode"} = "ABC"
  4.   PROP{"CompanyName"} = DefaultName()
  5.   PROP{"Version"} = 1.0
  6.  
  7.   FUNCTION DefaultName
  8.     DefaultName = "Acme Distribution Company"
  9.   END FUNCTION
  10.  
  11.   FUNCTION TimeJulian(y, m, d, m, s)
  12.     TimeJulian = TimeValue(y, m, d, m, s)
  13.   END FUNCTION
  14.  
  15. END MODULE
  16.  

New Object that inherits Session
Code: Script BASIC
  1. MODULE Inherited
  2.  
  3. ' Session MODULE
  4. IMPORT "module.sb"
  5.  
  6. PROP{"DefaultCompanyCode"} = Session::PROP{"CompanyCode"}
  7.  
  8. END MODULE
  9.  

Test new object MODULE.
Code: Script BASIC
  1. IMPORT "newobj.sb"
  2.  
  3. PRINT Inherited::PROP{"DefaultCompanyCode"},"\n"
  4.  

Output:


jrs@jrs-laptop:~/SB2020$ time scriba testobj.sb
ABC

real   0m0.006s
user   0m0.005s
sys   0m0.001s
jrs@jrs-laptop:~/SB2020$



9
SB2020 / Desktop GUI Options
« Last post by John Spikowski on December 15, 2018, 12:40:54 PM »
Good news is we have a couple of options beyond NOMADS to extend 100's GUI functionality using the COM/OLE BOI API.  (see examples on the forum)

I have had good success using VB6 and a common controls replacement to create modern / supported OCX intelligent forms that call back to Script BASIC to process events. It is truly the fastest way to produce professional grade UI solutions with minimal effort. The following is an example of creating an online dictionary GUI program using a form OCX and Script BASIC.



VB6 OCX form running under WIndows 10  using an updated common controls library providing use of current controls and theme standards.



Script BASIC OCX form load and event processing.
Code: Script BASIC
  1. IMPORT COM.sbi
  2. IMPORT NT.sbi
  3.  
  4. servers[0]="dict.org"
  5. servers[1]="dict1.us.dict.org"
  6. servers[2]="all.dict.org"
  7.  
  8. FUNCTION btnFetch_Clicked
  9.   LOCAL dat, total, count
  10.   ON ERROR GOTO G_NetError
  11.   server_selection = COM::CBN(obj, "CurrentServer")
  12.   OPEN server_selection & ":2628" FOR SOCKET AS #1
  13.   PRINT#1,"SHOW DB\n"
  14.   LINE INPUT#1, dat
  15.   LINE INPUT#1, dat
  16.   count = 0
  17.   WHILE LEFT(dat, 1) <> "."
  18.     LINE INPUT#1, dat
  19.     IF LEFT(dat, 1) <> "." THEN total[count] = TRIM(dat)
  20.     count+=1
  21.   WEND
  22.   PRINT#1,"QUIT\n"
  23.   CLOSE(#1)
  24.   FOR cnt = 0 TO count - 2
  25.     COM::CBN obj, "AddDictionaries", :CALL, total[cnt]
  26.   NEXT
  27.   COM::CBN obj, "DefaultDictionary"
  28.   btnFetch_Clicked = TRUE
  29.   EXIT FUNCTION
  30.  
  31.   G_NetError:
  32.   NT::MsgBox "Server " & server_selection & " not available. (" & ERROR & ")", "OLD Error", "OK","Info", 1
  33. END FUNCTION
  34.  
  35. FUNCTION btnSearch_clicked
  36.   LOCAL dict, dat, total, info
  37.   ON ERROR GOTO L_NetError
  38.   whichDictionary = COM::CBN(obj, "CurrentDictionary")
  39.   searchword = COM::CBN(obj, "SearchWord", :GET)
  40.   dict = LEFT(whichDictionary, INSTR(whichDictionary, " "))
  41.   OPEN COM::CBN(obj, "CurrentServer") & ":2628" FOR SOCKET AS 1
  42.   IF COM::CBN(obj, "AllDict", :GET) THEN
  43.     PRINT#1,"DEFINE * " & searchword & "\n"
  44.   ELSE
  45.     PRINT#1,"DEFINE " & dict & " " & searchword & "\n"
  46.   END IF
  47.   REPEAT
  48.     LINE INPUT#1, dat
  49.     IF LEFT(dat, 3) = "151" THEN
  50.       total$ &= "------------------------------\r\n"
  51.       total$ &= RIGHT(dat, LEN(dat) - LEN(searchword) - LEN(dict))
  52.       total$ &= "------------------------------\r\n"
  53.       REPEAT
  54.         LINE INPUT#1, info
  55.         info = REPLACE(info, CHR(34), CHR(92) & CHR(34))
  56.         IF LEFT(info, 1) <> "." THEN total &= TRIM(info) & "\r\n"
  57.       UNTIL LEFT(info, 1) = "."
  58.       total &= "\r\n"
  59.     END IF
  60.   UNTIL LEFT(dat, 3) = "250" OR VAL(LEFT(dat, 3)) > 499
  61.   PRINT#1,"QUIT\n"
  62.   CLOSE(#1)
  63.   IF LEFT(dat, 3) = "552" THEN
  64.     total = "No match found."
  65.   ELSE IF LEFT(dat, 3) = "501" THEN
  66.     total = "Select a dictionary first!"
  67.   ELSE IF LEFT(dat, 3) = "550" THEN
  68.     total = "Invalid database!"
  69.   END IF
  70.   COM::CBN(obj, "SetTranslation", :CALL, total)
  71.   btnSearch_Clicked = TRUE
  72. EXIT FUNCTION
  73.  
  74. L_NetError:
  75.   dat[0] = "Could not lookup word! (" & ERROR & ")"
  76.   COM::CBN(obj, "SetTranslation", :CALL, dat)
  77. END FUNCTION
  78.  
  79. ' MAIN
  80.  
  81. obj = COM::CREATE(:SET, "OLD.OLDict")
  82. oCollection = COM::CBN(obj, "CallBackHandlers", :GET)
  83. COM::CBN oCollection, "Add", :CALL, ADDRESS(btnFetch_Clicked()), "win.btnFetch_Click"
  84. COM::CBN oCollection, "Add", :CALL, ADDRESS(btnSearch_Clicked()), "win.btnSearch_Click"
  85. FOR idx = 0 TO UBOUND(servers)
  86.   COM::CBN obj, "AddServer", :CALL, servers[idx]
  87. NEXT  
  88. COM::CBN obj, "DefaultServer"
  89. COM::CBN obj, "ShowOLD"
  90. COM::RELEASE obj
  91.  

VB6 OCX Form Code
Code: Visual Basic
  1. Private Declare Function ext_SBCallBack Lib "COM.dll" Alias "SBCallBack" (ByVal EntryPoint As Long, ByVal arg As Long) As Long
  2. Private Declare Function ext_SBCallBackEx Lib "COM.dll" Alias "SBCallBackEx" (ByVal EntryPoint As Long, ByRef v As Variant) As Variant
  3.  
  4. Private m_owner As OLDict
  5. Private Type ControlPositionType
  6.     Left As Single
  7.     Top As Single
  8.     Width As Single
  9.     Height As Single
  10.     FontSize As Single
  11. End Type
  12.  
  13. Private m_ControlPositions() As ControlPositionType
  14. Private m_FormWid As Single
  15. Private m_FormHgt As Single
  16.  
  17.  
  18. Function ShowMain(owner As OLDict) As Long
  19.     On Error Resume Next
  20.     Set m_owner = owner
  21.     Me.Show 1
  22.     Set m_owner = Nothing
  23.     ShowMain = 0
  24.     Unload Me
  25. End Function
  26.  
  27. Private Function TriggerCallBack(nodeID As Long, argValue As Long) As Long
  28.     TriggerCallBack = ext_SBCallBack(nodeID, argValue)
  29. End Function
  30.  
  31. Private Function TriggerCallBackEx(nodeID As Long, v() As Variant)
  32.     TriggerCallBackEx = ext_SBCallBackEx(nodeID, v)
  33. End Function
  34.  
  35. Public Sub btnClear_Click()
  36.     win.serverList.Clear
  37.     win.dictTB.Text = ""
  38.     win.entry.Text = ""
  39.     win.btnFetch.SetFocus
  40.     End Sub
  41.  
  42. Private Sub btnExit_Click()
  43.     Set m_owner = Nothing
  44.     btnExit = 0
  45.     Unload Me
  46. End Sub
  47.  
  48. Private Sub btnFetch_Click()
  49.     Dim nodeID As Long
  50.     Dim arg As Long
  51.     Dim rtnVal As Long
  52.    
  53.     win.serverList.Clear
  54.     nodeID = m_owner.CallBackHandlers("win.btnFetch_Click")
  55.     arg = False
  56.     rtnVal = TriggerCallBack(nodeID, arg)
  57. End Sub
  58.  
  59. Private Sub btnSearch_Click()
  60.     Dim nodeID As Long
  61.     Dim arg As Long
  62.     Dim rtnVal As Long
  63.    
  64.     nodeID = m_owner.CallBackHandlers("win.btnSearch_Click")
  65.     arg = False
  66.     rtnVal = TriggerCallBack(nodeID, arg)
  67. End Sub
  68.  
  69. Private Sub btnAbout_Click()
  70.     MsgBox "Script BASIC VB6" & vbCrLf & "On Line Dictionary", vbInformation, "About"
  71. End Sub
  72.  
  73.  
  74. ' Save the form's and controls' dimensions.
  75. Private Sub SaveSizes()
  76. Dim i As Integer
  77. Dim ctl As Control
  78.  
  79.     ' Save the controls' positions and sizes.
  80.    ReDim m_ControlPositions(1 To Controls.Count)
  81.     i = 1
  82.     For Each ctl In Controls
  83.         With m_ControlPositions(i)
  84.             If TypeOf ctl Is Line Then
  85.                 .Left = ctl.X1
  86.                 .Top = ctl.Y1
  87.                 .Width = ctl.X2 - ctl.X1
  88.                 .Height = ctl.Y2 - ctl.Y1
  89.             Else
  90.                 .Left = ctl.Left
  91.                 .Top = ctl.Top
  92.                 .Width = ctl.Width
  93.                 .Height = ctl.Height
  94.                 On Error Resume Next
  95.                 .FontSize = ctl.Font.Size
  96.                 On Error GoTo 0
  97.             End If
  98.         End With
  99.         i = i + 1
  100.     Next ctl
  101.  
  102.     ' Save the form's size.
  103.    m_FormWid = ScaleWidth
  104.     m_FormHgt = ScaleHeight
  105. End Sub
  106.  
  107. Private Sub Form_Load()
  108.     SaveSizes
  109. End Sub
  110.  
  111. Private Sub Form_Resize()
  112.     ResizeControls
  113. End Sub
  114.  
  115. ' Arrange the controls for the new size.
  116. Private Sub ResizeControls()
  117. Dim i As Integer
  118. Dim ctl As Control
  119. Dim x_scale As Single
  120. Dim y_scale As Single
  121.  
  122.     ' Don't bother if we are minimized.
  123.    If WindowState = vbMinimized Then Exit Sub
  124.  
  125.     ' Get the form's current scale factors.
  126.    x_scale = ScaleWidth / m_FormWid
  127.     y_scale = ScaleHeight / m_FormHgt
  128.  
  129.     ' Position the controls.
  130.    i = 1
  131.     For Each ctl In Controls
  132.         With m_ControlPositions(i)
  133.             If TypeOf ctl Is Line Then
  134.                 ctl.X1 = x_scale * .Left
  135.                 ctl.Y1 = y_scale * .Top
  136.                 ctl.X2 = ctl.X1 + x_scale * .Width
  137.                 ctl.Y2 = ctl.Y1 + y_scale * .Height
  138.             Else
  139.                 ctl.Left = x_scale * .Left
  140.                 ctl.Top = y_scale * .Top
  141.                 ctl.Width = x_scale * .Width
  142.                 If Not (TypeOf ctl Is ComboBox) Then
  143.                     ' Cannot change height of ComboBoxes.
  144.                    ctl.Height = y_scale * .Height
  145.                 End If
  146.                 On Error Resume Next
  147.                 ctl.Font.Size = y_scale * .FontSize
  148.                 On Error GoTo 0
  149.             End If
  150.         End With
  151.         i = i + 1
  152.     Next ctl
  153. End Sub
  154.  

VB6 Form OCX Property and Method Class
Code: Visual Basic
  1. Public CallBackHandlers As New Collection
  2.  
  3. Public Function ShowOLD() As Long
  4.     ShowOLD = win.ShowMain(Me)
  5. End Function
  6.  
  7. Public Sub AddServer(server_url As String)
  8.     win.serverCombo.AddItem server_url
  9. End Sub
  10.  
  11. Public Sub DefaultServer()
  12.     win.serverCombo.ListIndex = 0
  13. End Sub
  14.  
  15. Public Function CurrentServer() As String
  16.     CurrentServer = win.serverCombo.List(win.serverCombo.ListIndex)
  17. End Function
  18.  
  19. Public Sub AddDictionaries(dictionary As String)
  20.     win.serverList.AddItem dictionary
  21. End Sub
  22.  
  23. Public Function CurrentDictionary() As String
  24.     CurrentDictionary = win.serverList.List(win.serverList.ListIndex)
  25. End Function
  26.  
  27. Public Sub DefaultDictionary()
  28.     win.serverList.ListIndex = 0
  29. End Sub
  30.  
  31. Public Sub SetTranslation(translation_text As String)
  32.     win.dictTB.Text = translation_text
  33. End Sub
  34.  
  35. Public Property Get SearchWord() As String
  36.     win.dictTB.SetFocus
  37.     SearchWord = win.entry.Text
  38. End Property
  39.  
  40. Public Property Get AllDict() As Long
  41.     AllDict = win.chkAll.Value
  42. End Property
  43.  

The next option is using IUP (Portable User Interface) as a cross platform native desktop UI standard. I'm targeting the IUP library for the SB2020 project.



Code: Script BASIC
  1. IMPORT iup.bas
  2.  
  3. servers[0]="dict.org"
  4. servers[1]="dict1.us.dict.org"
  5. servers[2]="all.dict.org"
  6.  
  7. about="""This is a Demo
  8. of the IUP GUI Binding
  9. for Scriptbasic"""
  10.  
  11. ' Initialize IUP
  12. Iup::Open()
  13.  
  14. ' Create main window
  15.  
  16. win = Iup::Create("dialog")
  17.   Iup::SetAttributes(win, "TITLE=\"ScriptBasic IUP Online Dictionary\", SIZE=500x300")
  18.   Iup::SetCallback(win,"CLOSE_CB",ADDRESS(Win_exit()))
  19.  
  20. ' Create container to house ALL GUI objects
  21.  
  22. vbox = Iup::Create("vbox")
  23.   Iup::SetAttributes(vbox, "MARGIN=10x10")
  24.  
  25. ' Create server panel
  26.  
  27. topBox = Iup::Create("hbox")
  28.   Iup::SetAttributes(topBox, "GAP=10")
  29.   Iup::Append(vbox, topBox)
  30. serverFrame = Iup::Create("frame")
  31.   Iup::SetAttributes(serverFrame, "TITLE=Servers, EXPAND=YES")
  32.   Iup::Append(topBox, serverFrame)
  33. serverBox = Iup::Create("hbox")
  34.   Iup::SetAttributes(serverBox, "GAP=5")
  35.   Iup::Append(serverFrame, serverBox)
  36. serverCombo = Iup::Create("list")
  37.   Iup::SetAttributes(serverCombo, "DROPDOWN=YES, SIZE=120x, EXPAND=HORIZONTAL, VALUE=1")
  38.   Iup::Append(serverBox, serverCombo)
  39.   Iup::SetCallback(serverCombo, "ACTION", ADDRESS(serverCombo_selected()))
  40. btnFetch = Iup::Create("button")
  41.   Iup::SetAttributes(btnFetch, "TITLE=Fetch, SIZE = 50x")
  42.   Iup::Append(serverBox, btnFetch)
  43.   Iup::SetCallback(btnFetch, "ACTION", ADDRESS(btnFetch_clicked()))
  44.  
  45. ' Create control panel
  46.  
  47. controlFrame = Iup::Create("frame")
  48.   Iup::SetAttributes(controlFrame, "TITLE=Controls")
  49.   Iup::Append(topBox, controlFrame)
  50. controlBox = Iup::Create("hbox")
  51.   Iup::SetAttributes(controlBox, "GAP=5")
  52.   Iup::Append(controlFrame, controlBox)
  53. btnAbout = Iup::Create("button")
  54.   Iup::SetAttributes(btnAbout, "TITLE=About, SIZE = 50x")
  55.   Iup::Append(controlBox, btnAbout)
  56.   Iup::SetCallback(btnAbout, "ACTION", ADDRESS(btnAbout_clicked()))
  57. btnClear = Iup::Create("button")
  58.   Iup::SetAttributes(btnClear, "TITLE=Clear, SIZE = 50x")
  59.   Iup::Append(controlBox, btnClear)
  60.   Iup::SetCallback(btnClear, "ACTION", ADDRESS(btnClear_clicked()))
  61. btnExit = Iup::Create("button")
  62.   Iup::SetAttributes(btnExit, "TITLE=Exit, SIZE = 50x")
  63.   Iup::Append(controlBox, btnExit)
  64.   Iup::SetCallback(btnExit,"ACTION",ADDRESS(Win_exit()))
  65.  
  66. ' Create dictionary panel
  67.  
  68. dictFrame = Iup::Create("frame")
  69.   Iup::SetAttributes(dictFrame, "TITLE=Dictionaries")
  70.   Iup::Append(vbox, dictFrame)
  71. serverList = Iup::Create("list")
  72.   Iup::SetAttributes(serverList, "EXPAND=YES, VISIBLELINES=1")
  73.   Iup::Append(dictFrame, serverList)
  74.   Iup::SetCallback(serverList, "ACTION", ADDRESS(serverList_selected()))
  75.  
  76. ' Create text part
  77.  
  78. transFrame = IUP::Create("frame")
  79.   Iup::SetAttributes(transFrame, "TITLE=Translation")
  80.   Iup::Append(vbox, transFrame)
  81. text = Iup::Create("text")
  82.   Iup::SetAttributes(text, "MULTILINE=YES, EXPAND=YES")
  83.   Iup::Append(transFrame, text)
  84.  
  85. ' Create entry and search button
  86.  
  87. bottomBox = Iup::Create("hbox")
  88.   Iup::SetAttributes(bottomBox, "GAP=10")
  89.   Iup::Append(vbox, bottomBox)
  90. label = Iup::Create("label")
  91.   Iup::SetAttributes(label, "TITLE=\"Enter Word to Search For:\", SIZE=x12")
  92.   Iup::Append(bottomBox, label)
  93. entry = Iup::Create("text")
  94.   Iup::SetAttributes(entry, "EXPAND=HORIZONTAL")
  95.   Iup::Append(bottomBox, entry)
  96. btnSearch = Iup::Create("button")
  97.   Iup::SetAttributes(btnSearch,"TITLE=Search, SIZE=50x")
  98.   Iup::Append(bottomBox, btnSearch)
  99.   Iup::SetCallback(btnSearch, "ACTION", ADDRESS(btnSearch_clicked()))
  100. chkAll = Iup::Create("toggle")
  101.   Iup::SetAttributes(chkAll, "TITLE=ALL, SIZE=x12")
  102.   Iup::Append(bottomBox, chkAll)
  103. chkUTF = Iup::Create("toggle")
  104.   Iup::SetAttributes(chkUTF, "TITLE=UTF-8, SIZE=x12")
  105.   Iup::Append(bottomBox, chkUTF)
  106.  
  107. ' Add the main GUI container to the Window
  108.  
  109. Iup::Append(win, vbox)
  110.  
  111. ' Setup dialog defaults
  112.  
  113. Iup::Show(win)
  114. Iup::SetFocus(btnFetch)
  115. FOR i = 0 TO UBOUND(servers)
  116.   Iup::SetAttribute(serverCombo, "APPENDITEM", servers[i])
  117. NEXT
  118. Iup::SetAttribute(serverCombo, "VALUE", "1")
  119. Iup::Update(serverCombo)
  120. server_selection = servers[0]
  121.  
  122. ' Main processing loop
  123.  
  124. Iup::MainLoop()
  125. Iup::Close()
  126. END
  127.  
  128. ' Callback routines
  129.  
  130. SUB Win_exit
  131.   Iup::ExitLoop = TRUE
  132. END SUB
  133.  
  134. SUB btnAbout_clicked
  135.   Iup::Message("ABOUT", about)
  136. END SUB
  137.  
  138. SUB serverCombo_selected
  139.   server_selection = Iup::GetListText()
  140. END SUB
  141.  
  142. SUB serverList_selected
  143.   whichDictionary = Iup::GetListText()
  144. END SUB
  145.  
  146. SUB btnFetch_clicked
  147.   LOCAL dat, total, count
  148.   ON ERROR GOTO G_NetError
  149.   OPEN server_selection & ":2628" FOR SOCKET AS #1
  150.   PRINT#1,"SHOW DB\n"
  151.   LINE INPUT#1, dat
  152.   LINE INPUT#1, dat
  153.   count = 0
  154.   WHILE LEFT(dat, 1) <> "."
  155.     LINE INPUT#1, dat
  156.     IF LEFT(dat, 1) <> "." THEN total[count] = TRIM(dat)
  157.     count+=1
  158.   WEND
  159.   PRINT#1,"QUIT\n"
  160.   CLOSE(#1)
  161.   FOR cnt = 0 TO count - 2
  162.     Iup::SetAttribute(serverList, "APPENDITEM", total[cnt])
  163.   NEXT
  164.   Iup::SetAttribute(serverList, "VALUE", "1")
  165.   Iup::Update(serverCombo)
  166.   whichDictionary = total[0]
  167.   EXIT SUB
  168.  
  169.   G_NetError:
  170.   PRINT "Server ",server_selection," not available. (",ERROR,")\n"
  171. END SUB
  172.  
  173. SUB btnClear_clicked
  174.   Iup::ClearList(serverList)
  175.   Iup::SetAttribute(text, "VALUE", "")
  176.   Iup::SetAttribute(entry, "VALUE", "")
  177. END SUB
  178.  
  179. SUB btnSearch_clicked
  180.   LOCAL dict, dat, total, info
  181.   IUP::SetAttribute(text, "VALUE","Fetching....")
  182.   ON ERROR GOTO L_NetError
  183.   dict = LEFT(whichDictionary, INSTR(whichDictionary, " "))
  184.   OPEN server_selection & ":2628" FOR SOCKET AS 1
  185.   IF Iup::GetAttribute(chkAll, "VALUE") THEN
  186.     PRINT#1,"DEFINE * " & Iup::GetAttribute(entry,"VALUE") & "\n"
  187.   ELSE
  188.     PRINT#1,"DEFINE " & dict & " " & Iup::GetAttribute(entry,"VALUE") & "\n"
  189.   END IF
  190.   REPEAT
  191.     LINE INPUT#1, dat
  192.     IF LEFT(dat, 3) = "151" THEN
  193.       total$ &= "------------------------------\r\n"
  194.       total$ &= RIGHT(dat, LEN(dat) - LEN(Iup::GetAttribute(entry, "VALUE")) - LEN(dict))
  195.       total$ &= "------------------------------\r\n"
  196.       REPEAT
  197.         LINE INPUT#1, info
  198.         info = REPLACE(info, CHR(34), CHR(92) & CHR(34))
  199.         IF LEFT(info, 1) <> "." THEN total &= TRIM(info) & "\n"
  200.       UNTIL LEFT(info, 1) = "."
  201.       total &= "\n"
  202.     END IF
  203.   UNTIL LEFT(dat, 3) = "250" OR VAL(LEFT(dat, 3)) > 499
  204.   PRINT#1,"QUIT\n"
  205.   CLOSE(#1)
  206.   IF LEFT(dat, 3) = "552" THEN
  207.     total = "No match found."
  208.   ELSE IF LEFT(dat, 3) = "501" THEN
  209.     total = "Select a dictionary first!"
  210.   ELSE IF LEFT(dat, 3) = "550" THEN
  211.     total = "Invalid database!"
  212.   END IF
  213.   Iup::SetAttribute(text, "VALUE", total)
  214. EXIT SUB
  215.  
  216. L_NetError:
  217.   dat[0] = "Could not lookup word! (" & ERROR & ")"
  218.   Iup::SetAttribute(text, "VALUE", dat)
  219. END SUB
  220.  

Another advantage of using IUP is screens can be defined using the LED format. I'm using the LED format as a multi-line code string in the following example. It could be in text form in a separate file or compiled as a DLL or shared object under Linux.



Code: Script BASIC
  1. ' IUP LED Example
  2.  
  3. LED = """
  4. # ==============================================================================
  5. #cardfile
  6. # ==============================================================================
  7. btn_prior = BUTTON[SIZE = 50x15, IMAGE=IUP_ArrowLeft]("",NULL)
  8. btn_next =  BUTTON[SIZE = 50x15, IMAGE=IUP_ArrowRight]("",NULL)
  9. btn_find =   BUTTON[SIZE = 50x15, IMAGE=IUP_EditFind]("",NULL)
  10. btn_add  =   BUTTON[SIZE = 50x15, IMAGE=IUP_FileSave]("",NULL)
  11. btn_update =  BUTTON[SIZE = 50x15, IMAGE=IUP_NavigateRefresh]("",NULL)
  12. btn_delete =  BUTTON[SIZE = 50x15, IMAGE=IUP_EditErase]("",NULL)
  13. btn_print =  BUTTON[SIZE = 50x15, IMAGE=IUP_Print]("",NULL)
  14. btn_cancel = BUTTON[SIZE = 50x15, IMAGE=IUP_ActionCancel]("",NULL)
  15. # ==============================================================================
  16. id_index = LABEL[]("0 / 0")
  17. entry_company = TEXT[EXPAND = HORIZONTAL](NULL)
  18. entry_last = TEXT[EXPAND = HORIZONTAL](NULL)
  19. entry_first = TEXT[EXPAND = HORIZONTAL](NULL)
  20. entry_add1 = TEXT[EXPAND = HORIZONTAL](NULL)
  21. entry_add2 = TEXT[EXPAND = HORIZONTAL](NULL)
  22. entry_add3 = TEXT[EXPAND = HORIZONTAL](NULL)
  23. entry_city = TEXT[EXPAND = HORIZONTAL](NULL)
  24. entry_state = TEXT[SIZE = 120x](NULL)
  25. entry_zip = TEXT[SIZE = 80x](NULL)
  26. cbo_country = LIST[DROPDOWN=YES, SIZE=100x,VALUE=1](NULL)
  27. entry_phone = TEXT[SIZE=70x](NULL)
  28. entry_fax = TEXT[SIZE=70x](NULL)
  29. entry_email = TEXT[EXPAND = HORIZONTAL](NULL)
  30. entry_www = TEXT[EXPAND = HORIZONTAL](NULL)
  31. entry_comments = TEXT[MULTILINE=YES, EXPAND=YES](NULL)
  32. # ==============================================================================
  33. cardfile = DIALOG[TITLE = "Card File"]
  34. (
  35.    VBOX[MARGIN = 5x5]
  36.    (
  37.        HBOX[GAP = 5]
  38.        (
  39.            FILL(),
  40.            LABEL[TITLE = " Record No."](""),id_index
  41.        ),
  42.        FRAME[TITLE = Company]
  43.        (
  44.             entry_company
  45.        ),
  46.        HBOX[GAP = 5]
  47.        (
  48.            FRAME[TITLE = "Last Name"]
  49.            (
  50.                entry_last
  51.            ),
  52.            FRAME[TITLE = "First Name"]
  53.            (
  54.                entry_first
  55.            )
  56.        ),
  57.        FRAME[TITLE = "Address"]
  58.        (
  59.            VBOX[GAP = 5]
  60.            (
  61.                entry_add1,
  62.                entry_add2,
  63.                entry_add3
  64.            )
  65.        ),
  66.        HBOX[GAP = 5]
  67.        (
  68.            FRAME[TITLE = "City"]
  69.            (
  70.                entry_city
  71.            ),
  72.            FRAME[ TITLE = "State / Province"]
  73.            (
  74.                 entry_state
  75.            ),
  76.            FRAME[TITLE = "Zip or Postal Code"]
  77.            (
  78.                entry_zip
  79.            ),
  80.            FRAME[TITLE = "Country"]
  81.            (
  82.                 cbo_country
  83.            )
  84.        ),
  85.        HBOX[GAP = 5]
  86.        (
  87.            FRAME[TITLE = "Phone"]
  88.            (
  89.                entry_phone
  90.            ),
  91.            FRAME[TITLE = "Fax"]
  92.            (
  93.                entry_fax
  94.            ),
  95.            FRAME[TITLE = "Email"]
  96.            (
  97.                entry_email
  98.            ),
  99.            FRAME[TITLE = "www"]
  100.            (
  101.                entry_www
  102.            )
  103.        ),
  104.        FRAME[TITLE = "Comments"]
  105.        (
  106.            TEXT[EXPAND = YES,MULTILINE = YES,NAME = entry_comments](do_nothing)
  107.        ),
  108.        HBOX[GAP = 10]
  109.        (
  110.            FILL(),
  111.            btn_prior,btn_next,btn_find,btn_add,btn_update,btn_delete,btn_print,btn_cancel,
  112.            FILL()
  113.        )
  114.    )
  115. )
  116. """
  117.  
  118. SUB Win_exit
  119.   Iup::ExitLoop = TRUE
  120. END SUB
  121.  
  122. IMPORT iup.bas
  123.  
  124. Iup::Open
  125. Iup::ImageLibOpen
  126. Iup::SetGlobal("DEFAULTFONT", "Helvetica, 11")
  127. Iup::LoadBuffer(LED)
  128.  
  129. Iup::SetCallback(Iup::GetHandle("btn_cancel"), "ACTION", ADDRESS(Win_exit()))
  130.  
  131. Iup::Show(Iup::GetHandle("cardfile"))
  132.  
  133. Iup::MainLoop()
  134.  
  135. Iup::Close()
  136.  



10
SB2020 / Script BASIC Download
« Last post by John Spikowski on December 14, 2018, 09:07:11 PM »
I have attached the download links to the Windows 32 bit Inno installer and Ubuntu 64 bit run time image of Script BASIC if you would like to follow along and get up to speed with the BASIC.

Windows 32 bit Script BASIC Installer

Ubuntu 64 bit Script BASIC run time image


This is an example of using the Windows IDE/Debugger with the MODULE example in the previous post.



Windows Install

Download and unzip the installer. (single file) Run the installer.

Ubuntu Linux

Download the file to where you wish to install Script BASIC. It creates a sub-directory sb64 from where you are at.
Execute sb64.run.
In the sb64 sub-directory setup the environment by using this command in the console.  source sb.sh

Pages: [1] 2 3 ... 8