iConvert 4

Post Reply
User avatar
rbytes
Posts: 1808
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

iConvert 4

Post by rbytes » Wed Nov 14, 2018 10:23 pm

This is the release version of iConvert 4, replacing the alpha and beta versions. Due to a copying error, the code I posted yesterday was missing an important line. This code has been thoroughly checked.

Code: Select all

/*
iConvert 4
by rbytes and Dutchman, November 2018
Converts measurements in many categories.
A collaborative international project.

V4
- faster currency updates
- improved iPhone compatibility
- bug fixes
V4 Alpha
- Integrated with UpdateCurrencies.functions
  See https://kibernetik.pro/forum/viewtopic.php?f=20&t=2272
- Subroutine renamed to UpdateData
  • Prepares Interactivity field and browser
  • Calls Startfunction "Update(view,iField)"
- Page change removed. Convert screen stays.
V4 Beta
- The project continues as a single integrated program.
- The Update Currencies program code is now in a subroutine labelled Update:
  It and all of the subroutines and functions it calls are highlighted in yellow.

V3.6b
- now has a Settings button (gear symbol), left of the other buttons. This opens a
  popup Settings window with a switch to set the view for Update Currencies V2.1
  when the switch is off, the currency exchange file is updated without 
  interactivity.
  when the switch is on, the file is updated interactively with the user.
- file "viewstate1" stores the view setting.
V3.5b self
- Update Currencies code now embedded as a subroutine
- Fuel Economy category added by rbytes, November 2018
V3.4b
- Modified for my personal use
V3.4
- Acceleration category added by rbytes
- Update button added to launch "Update currencies.sb" 
  for updating currency exchange rates
V3.3
- Flow Rate category added by rbytes
V3.2
- Angle category added by rbytes
- Energy transition category added by Dutchman
- Error trap added for Currency
V3.1
- Temperature category added by Dutchman
V3
- Currency category added by Dutchman
  DATA generated with "Update currencies.sb"
V2
- animation added to title
  (plays only once, at launch)
- measures added in most categories
- scientific notation is now used for
  results larger than 100,000,000 or
  smaller than .00000001
V1.1
- added Horsepower (Metric) to
  Power category
- eliminated >>> button;
  calculation is now automatic
  when list selections or
  input values are changed.
- code efficiency improved
*/
OPTION BASE 1
SET ORIENTATION LANDSCAPE
SET BUTTONS CUSTOM
SET TOOLBAR OFF
laun$=LAUNCHER$()
GET SCREEN SIZE sw,sh

' set to 1 to test iPhone layout on iPad
iostest=0
IF iostest THEN
  sw=568
  sh=320
ENDIF
rw=sw/1024!rh=sh/740

'b'========= Constants ===================
'' *** Note - IP address may change if router is rebooted ***
'  run ipconfig on your PC to find its IP address.

URL$="192.170.61.43"   ' example of IP address
DIM h$(2)


' each line of a file sent to a PC print server must end with these characters:

cr$=CHR$(13)       ' carriage return character
lf$=CHR$(10)       ' line feed character


' interface object names

x$="guide"
y$="guide2"
n$="title"
o$="category"
p$="from"
q$="to"
pi$="from_in"
qi$="to_in"
qi2$="cover"


lf$=CHR$(10)
q$=CHR$(34)
cat=1          ' default category (angle)
invalue=1
upshift=7

' correction for iPad display only
IF rw=1 then shift=10

' correction for non-iPad display only
IF rw<1 THEN shift2=75 ELSE shift2=-6

fm$="##,###,###,###,###,###,###.#######"    ' formats the result with commas
fm2$="####################.#######"      ' formats the result without commas


' number of measures in each category

cats=17
DIM cat$(cats)
accel=7
angle=9
area=9
cook=9
dat=8
energ=12
EnergyTrans=28
flow=17
leng=13
prefix=21
pow=14
press=13
spd=11
Tscales=8 ! Tscale$="Temperature"
timing=10
vol=12
wgt=10

'g'
' User choice of interface when updating currency exchange rates:
' Silent: view=0
' Interactive: view=1

IF file_exists("viewstate1") then
  FILE "viewstate1" READLINE view$
  view$=LEFT$(view$,1)
  view=VAL(view$)
ELSE
  view=0
  view$=STR$(view)
END IF
FILE "viewstate1" DELETE
FILE "viewstate1" WRITELINE view$&"calling"
''



'b'============ Initialisation============
''
GRAPHICS
GRAPHICS CLEAR .9,1,1


 ' animate title if gif animation file exists

PAGE "title" FRAME 0,0,sw,80
PAGE "title" SET
PAGE "title" SHOW
A$="iconvert3.GIF"
IF FILE_EXISTS(A$) THEN
  SPRITE N$ LOAD A$
  SPRITE N$ AT sw/3-shift2,sh/60+3*shift scale 1*rh
  SPRITE N$ SHOW
ELSE
  DRAW IMAGE "iconvert.PNG" AT sw/2.8,sh/20 SCALE .8*rw
ENDIF
PAGE "" SET

' read categories

RESTORE TO Categories

GOSUB money
FOR t=1 TO cats
  READ cat$(t)
NEXT t

RESTORE TO acceleration     ' default category
items=accel
DIM measure$(items)
GOSUB setcategory


' create three lists

SET LISTS FONT SIZE 18*rw
LIST o$ TEXT cat$ AT sw*.1,260*rh SIZE 240*rw,310*rh
LIST o$ SELECT cat
LIST p$ TEXT measure$ AT sw*.385,260*rh SIZE 240*rw,310*rh
LIST p$ SELECT 1
LIST q$ TEXT measure$ AT sw*.672,260*rh SIZE 240*rw,310*rh
LIST q$ SELECT 1


' create fields and buttons

SET BUTTONS FONT SIZE 20*rw
DRAW COLOR 0,0,0
guide$="Pick from each list"&lf$&"Enter quantity here"
FILL COLOR 0,0,0
FILL CIRCLE sw*.39,168*rh SIZE 3*rw
FILL COLOR 1,1,1
FIELD x$ TEXT guide$ AT sw*.1,132*rh-upshift SIZE 250,60 RO ML
FIELD x$ FONT SIZE 18*rw
FIELD x$ BACK ALPHA 0
guide2$="All lists can be scrolled"
DRAW LINE sw*.26,168*rh TO sw*.392,168*rh
DRAW LINE sw*.096,618*rh TO sw*.38,618*rh
DRAW LINE sw*.63,618*rh TO sw*.91,618*rh
FIELD y$ TEXT guide2$ AT sw*.41,600*rh-upshift*.8 SIZE 250,60 RO ML
FIELD y$ FONT SIZE 18*rw
FIELD y$ BACK ALPHA 0
FIELD o$ TEXT "CATEGORY" AT sw*.115,210*rh SIZE 130,30 RO
FIELD o$ FONT SIZE 20*rw
FIELD o$ BACK ALPHA 0
FIELD p$ TEXT "FROM" AT sw*.405,210*rh SIZE 100,30 RO
FIELD p$ FONT SIZE 20*rw
FIELD p$ BACK ALPHA 0
FIELD q$ TEXT "TO" AT sw*.69,210*rh SIZE 70,30 RO
FIELD q$ FONT SIZE 20*rw
FIELD q$ BACK ALPHA 0
FILL ALPHA 0
SET BUTTONS FONT SIZE 24*rw
BUTTON "settings" TEXT CHR$(9881) AT 90*rw,648*rh SIZE 50*rw,50*rh
SET BUTTONS FONT SIZE 20*rw
BUTTON "update" TEXT "UPDATE" AT 190*rw,650*rh SIZE 100*rw,50*rh
BUTTON "copy" TEXT "COPY" AT 330*rw,650*rh SIZE 100*rw,50*rh
BUTTON "print" TEXT "PRINT" AT 470*rw,650*rh SIZE 100*rw,50*rh
BUTTON "save" TEXT "SAVE" AT 610*rw,650*rh SIZE 100*rw,50*rh
BUTTON "stop" TEXT "STOP" AT 750*rw,650*rh SIZE 100*rw,50*rh
FILL ALPHA 1
FIELD pi$ TEXT "1" AT sw*.400,150*rh SIZE 200*rw,30*rh
FIELD pi$ FONT SIZE 18*rw
FIELD qi$ TEXT "1" AT sw*.640,145*rh SIZE 280*rw,40*rh
FIELD qi$ FONT SIZE 22*rw
FIELD qi2$ TEXT "" AT sw*.640,145*rh SIZE 280*rw,40*rh RO
FIELD qi2$ BACK ALPHA 0
if rw<1 then vshift=2
FILL COLOR .6,.8,.8
FILL RECT sw*.395,145*rh TO sw*.6,185*rh-vshift
FILL COLOR .8,.8,.8
FILL RECT sw*.635,140*rh TO sw*.92,190*rh-vshift
DRAW RECT sw*.1-1,258*rh TO sw*.1+240*rw+1,258*rh+312*rh
DRAW RECT sw*.386-2,258*rh TO sw*.386+240*rw,258*rh+312*rh
DRAW RECT sw*.673-2,258*rh TO sw*.673+240*rw,258*rh+312*rh

timer=time ()    ' set timer to stop title anim after one cycle

'b'========== main program loop ===================
''
DO

' play once, then stop animation

IF time()-timer>1 AND time()-timer <2 and not noplay THEN
  IF FILE_EXISTS(A$) THEN SPRITE N$ PLAY
  noplay=1
ENDIF
IF time()-timer>6 AND time()-timer <7 THEN
  IF FILE_EXISTS(A$) THEN SPRITE N$ STOP
ENDIF


' check which category is selected

type=LIST_SELECTED(o$)


' choose and prepare a new category if necessary

IF type<>cat THEN
  oldcat=cat
  cat=type
  changed=1

  ON cat GOTO 5,10,15,20,25,30,40,45,50,55,60,70,80,90,95,100,110,120
  5 RESTORE TO acceleration
     items=accel
     GOTO skip
  10 RESTORE TO angle
     items=angle
     GOTO skip
  15 RESTORE TO area
     items=area
     GOTO skip
  20 RESTORE TO cooking
     items=cook
     GOTO skip
  25 'RESTORE TO currencies
     if curr=0 then
       list o$ select oldcat
       type=oldcat
       gosub notice
       goto skip2
     else
       items=curr
     endif
     GOTO skip
  30 RESTORE TO data
     items=dat
     GOTO skip
  40 RESTORE TO energy
     items=energ
     GOTO skip
  45 RESTORE TO EnergyTransition
     items=EnergyTrans
     GOTO skip
  50 RESTORE TO FlowRate
     items=flow
     GOTO skip
  55 RESTORE TO length
     items=leng
     GOTO skip
  60 RESTORE TO prefixes
     items=prefix
     GOTO skip
  70 RESTORE TO power
     items=pow
     GOTO skip
  80 RESTORE TO pressure
     items=press
     GOTO skip
  90 RESTORE TO speed
     items=SPD
     GOTO skip
  95 RESTORE TO Temperatures
     items=Tscales
     GOTO Skip
  100 RESTORE TO timing
     items=timing
     GOTO skip
  110 RESTORE TO volume
     items=vol
     GOTO skip
  120 RESTORE TO weight
     items=wgt
     GOTO skip

  skip:
  if cat=5 then
    GOSUB currcalc
  else
    GOSUB setcategory
  endif
  LIST p$ TEXT measure$
  LIST p$ SELECT 1
  LIST q$ TEXT measure$
  LIST q$ SELECT 1
  FIELD pi$ TEXT "1"
  skip2:
ENDIF

IF LIST_SELECTED(p$)<>selp or LIST_SELECTED(q$)<>selq then changed=1


' calculate the conversion

if VAL(FIELD_TEXT$(pi$))<>invalue or changed then
  invalue=VAL(FIELD_TEXT$(pi$))
  selp=LIST_SELECTED(p$)
  selq=LIST_SELECTED(q$)
  GOSUB Convert ' calculate OutValue
  if outvalue<100000000 and outvalue>.000000001 then 
    out$=STR$(outvalue,fm$)
    out2$=STR$(outvalue,fm2$)
    format(out$)!out$=format.form$
    format(out2$)!out2$=format.form$
  else
    out$=STR$(outvalue)
  endif
  fsize=22*rw
  FIELD qi$ FONT SIZE fsize
  FIELD qi$ TEXT out$
  FIELD qi2$ TEXT ""
ENDIF

IF bp("settings") THEN
  showswitch=1
  gosub settings
ENDIF

IF bp("update") THEN

/*
  ' for future update: delete all but the most recent currencies.html file
  DIR "" LIST FILES FILES$,n2
  FOR t=1 to n2
    temp=INSTR(FILES$(t),"currencies.html")
    IF temp<>-1 THEN FILE FILES$(t) DELETE
  NEXT t
*/

  gosub updatedata
  gosub money
  restore to categories
  FOR t=1 TO cats
    READ cat$(t)
  NEXT t
  LIST o$ TEXT cat$
  LIST p$ TEXT measure$
  LIST q$ TEXT measure$
ENDIF


' copy the conversion info to clipboard

IF bp("copy") THEN
  GOSUB compile
  IF cp=0 THEN!CLIPBOARD CLEAR!cp=1!ENDIF
  CLIPBOARD WRITE convert$
  BEEP
ENDIF


' print the conversion info

IF bp("print") THEN
GOSUB compile
h$(1) = "content-type:text/html"   ' make header info
h$(2) = "content-length:" & LEN(convert$)

' print convert$ using Henko print technique
HTTP URL$ HEADER H$ POST convert$   ' send doc to the print server
BEEP
ENDIF


' save the conversion info to a file

IF bp("save") THEN
  GOSUB compile
  fname$="converted.txt"
  IF FILE_EXISTS(fname$) THEN FILE fname$ DELETE
  FILE fname$ WRITELINE convert$
  BEEP
ENDIF


' end the program

IF bp("stop") THEN
 view$=STR$(view)
  FILE "viewstate1" DELETE
  FILE "viewstate1" WRITELINE view$&"idle"
  IF laun$="desktop" THEN
    IF FILE_EXISTS("/launch") THEN
      RUN "/-Launch.sb"
    ELSE
      EXIT
    ENDIF
  ENDIF
  END
ENDIF
SLOWDOWN
UNTIL 0
END

'g'========== Subroutines and Functions =============

Convert:
'--- Convert via formula
'  temperature
IF Cat$(cat)=Tscale$ THEN
  Outvalue=FromCelsius(Celsius(Invalue,measureval(selp)),measureval(selq))
  RETURN
ENDIF
'--- Convert via ratio
  outvalue=invalue*1/(measureval(selq)/measureval(selp))
RETURN

' temperature conversion

DEF FromCelsius(Value,UnitPointer)
'Converts Value on 'Unit'-scale to Celsius-scale
'  to newvalue in scale of Unitpointer
ON UnitPointer GOTO 1,2,3,4,5,6,7,8
  1 RETURN Value 'Celsius
  2 RETURN Value+273.15 'Kelvin
  3 RETURN Value*9/5+32 'Fahrenheit
  4 RETURN (Value+273.15)*9/5 'Rankine
  5 RETURN (100-Value)*3/2 'Delisle
  6 RETURN Value*33/100 'Newton
  7 RETURN Value*4/5 'Réamur
  8 RETURN Value*21/40+7.5 'Rømer
END DEF
'
DEF Celsius(Value,UnitPointer)
'Converts Value in 'Unit' to new value in Celsius
ON UnitPointer GOTO 1,2,3,4,5,6,7,8
  1 RETURN Value 'Celsius
  2 RETURN Value-273.15 'Kelvin
  3 RETURN (Value-32)*5/9 'Fahrenheit
  4 RETURN (Value-491.67)*5/9 'Rankine
  5 RETURN 100-Value*2/3 'Delisle
  6 RETURN Value*100/33 'Newton
  7 RETURN Value*5/4 'Réamur
  8 RETURN (Value-7.5)*40/21 'Rømer
END DEF


' read the data for a category

setcategory:
DIM measure$(items)
FOR t=1 TO items
  READ measure$(t)
NEXT t
DIM measureval(items)
FOR t=1 TO items
  READ measureval(t)
NEXT t
RETURN

currcalc:
DIM measure$(items)
FOR t=1 TO items
  measure$(t)=mname$(t)
NEXT t
DIM measureval(items)
FOR t=1 TO items
  measureval(t)=val(mvalue$(t))
NEXT t
RETURN

' prepare a string showing the conversion, for copying or saving to a file

compile:
  selp=LIST_SELECTED(p$)
  selq=LIST_SELECTED(q$)
  temp1$=measure$(selp)
  temp2$=measure$(selq)


  ' if a value is 1 or a fraction, change the name from plural to singular
  convin=val(FIELD_TEXT$(p$))
  temp1len=LEN(temp1$)
  IF convin=<1 AND RIGHT$(temp1$,1)="s" THEN temp1$=LEFT$(temp1$,temp1len-1)
  IF VAL(out2$)=<1 AND RIGHT$(temp2$,1)="s" THEN temp2$=LEFT$(temp2$,LEN(temp2$)-1)
  convert$&=FIELD_TEXT$(pi$)&" "&temp1$&" = "&FIELD_TEXT$(qi$)&" "&temp2$
  convert$&=cr$&lf$&FIELD_TEXT$(pi$)&" "&temp1$&" = "&out2$&" "&temp2$&cr$&lf$&cr$&lf$
RETURN


' settings window

settings:
a$=lf$&"When updating currency data, choose if you want interactive mode. When the switch is off, the currency exchange file is updated without interactivity. When the switch is on, the file is updated interactively with the user."
pw("notice","Settings",a$,sw/2-200*rw,sh/4,400*rw,400*rw,1,1,1,1)
goto message


' notice if user has not downloaded and run Update Currencies.sb

notice:
a$="To use this category, please do a currency update using the Update button. You will then have the most recent conversion data."
pw("notice","Notice!",a$,sw/2-200*rw,sh/4,400*rw,400*rw,1,1,1,1)

message:
wait: SLOWDOWN
IF SWITCH_CHANGED("inter") THEN
  .view=SWITCH_STATE("inter")
  view$=STR$(.view)
  FILE "viewstate1" DELETE
  FILE "viewstate1" WRITELINE view$&"calling"
ENDIF
IF BUTTON_PRESSED("close") THEN
  PAGE pw.NAME$ HIDE ! PAGE "" SET ! PAGE "" SHOW
  GOSUB drawscreen
ELSE 
  GOTO wait
ENDIF
RETURN

drawscreen:
  FILL COLOR .6,.8,.8
  FILL RECT sw*.395,145*rh TO sw*.6,185*rh-vshift
  FILL COLOR .8,.8,.8
  FILL RECT sw*.635,140*rh TO sw*.92,190*rh-vshift
  DRAW COLOR 0,0,0
  DRAW RECT sw*.1-1,258*rh TO sw*.1+240*rw+1,258*rh+312*rh
  DRAW RECT sw*.386-2,258*rh TO sw*.386+240*rw,258*rh+312*rh
  DRAW RECT sw*.673-2,258*rh TO sw*.673+240*rw,258*rh+312*rh
  DRAW LINE sw*.26,168*rh TO sw*.392,168*rh
  DRAW LINE sw*.096,618*rh TO sw*.38,618*rh
  DRAW LINE sw*.63,618*rh TO sw*.91,618*rh
  FILL COLOR 0,0,0
  FILL CIRCLE sw*.39,168*rh SIZE 3*rw
  FILL COLOR .8,.8,.8
RETURN


' import currencies.data if exists

money:
fname$="currencies.data"
q$=chr$(34)
mark=1

if file_exists(fname$) then
  void=0
  file fname$ setpos 0

  for t=1 to 5
  FILE fname$ READLINE hold$(t)
  next t

  ' read curr value
  temp$=hold$(1)
  fnd=INSTR(temp$,"=",mark)
  IF fnd<>-1 THEN
    stpt=INSTR(temp$,"=",fnd)                   ' start of condition string
    enpt=INSTR(temp$,"'",fnd)                   ' end of condition string
    curr$=MID$(temp$,stpt+1,enpt-stpt-2)
    curr=VAL(curr$)
  ENDIF

  ' read CurrDate$
  temp$=hold$(2)
  fnd=INSTR(temp$,"=",mark)
  IF fnd<>-1 THEN
    stpt=INSTR(temp$,"=",fnd)                   ' start of condition string
    enpt=INSTR(temp$,"'",fnd)                   ' end of condition string
    CurrDate$=MID$(temp$,stpt+2,enpt-stpt-4)
  ENDIF

  ' read measures array
  temp$=hold$(4)
  temp$=MID$(temp$,5,1000)

  SPLIT temp$ TO mname$,tot WITH ","
  for t=1 to curr
    temp$=mname$(t)
    ' trim quotation marks
    temp$=right$(temp$,len(temp$)-2)
    mname$(t)=temp$
    temp2$=left$(mname$(t),len(temp$)-1)
    mname$(t)=temp2$
  next t

  ' read measures values
  temp$=hold$(5)
  temp$=MID$(temp$,5,1000)

  SPLIT temp$ TO mvalue$,tot WITH ","
ELSE
  void=1
ENDIF
return

'y'
UpdateData:
' Update Currencies by Dutchman, October 2018
'==== Presets ====
IF NOT viewpreset THEN
  '--- presets
  Top=MAX(17,MIN(sw,sh)/32) ' top space
  YesNoPos=sw/2 ' x-position of buttons
  TopFont=0.7*top 'fontsize
  '--- Prepare browser
  SET BROWSERS SCALED
  BROWSER "a" AT 0,top SIZE sw,sh-top
  BROWSER "a" HIDE
  '--- make buttons
  SET BUTTONS FONT SIZE topfont
  SET BUTTONS FONT NAME "Menlo"
  DRAW COLOR 1,1,0
  FILL COLOR 1,0,0
  BUTTON "yes" TEXT "Yes" AT YesNoPos,0 SIZE 3*top,top
  BUTTON "yes" HIDE
  BUTTON "no" TEXT "No" AT YesNoPos+3*top,0 SIZE 3*top,top
  BUTTON "no" HIDE
  '--- Make Messagefield
  Top$="In" ' Field for input
  FIELD Top$ AT 0,0 SIZE sw/2,top
  FIELD Top$ FONT NAME "Menlo"
  FIELD Top$ FONT SIZE topfont
  FIELD Top$ FONT COLOR 1,1,0
  FIELD Top$ BACK COLOR 0,0,1
  FIELD Top$ HIDE
  '--- don't recall
  viewpreset=1
ENDIF
'
'==== Main Update Routine ====
IF Update(View,Top$) THEN
  FIELD Top$ BACK COLOR 0,0,1
  Field Top$ TEXT  "Data written to """&Update.DataFile$&"""."
ELSE
  FIELD Top$ BACK COLOR 1,0,0
  Field Top$ TEXT Update.Msg$
ENDIF
PAUSE 1
FIELD Top$ BACK COLOR 0,0,1
FIELD Top$ HIDE
BROWSER "a" HIDE
GOSUB drawscreen
RETURN
'
'========== Update Currencies Subroutines and Functions ===========
'r'
DEF Update(view,iField$)
'--- constants
Source$="https://www.x-rates.com/table/?from=USD&amount=1"
MaxCount=100 ' max number of currencies
WebPage$="currencies.html" ' undated webpage filename
'--- Output variables
DIM Data$(maxcount,2) ' array for extracted data
DataFile$="currencies.data" ' file with DATA-lines
'--- messagebar
IF view THEN
  FIELD iField$ SHOW
  FIELD iField$ BACK COLOR 0,0,1
ENDIF
'--- Select and store source
IF view THEN web$=LatestFile$(webpage$)
IF web$="" THEN web$=WebPage$
web$=MakeCurrencyHTML$(Source$,Web$,view,iField$,"a")
IF web$="" THEN 
  Msg$="Cancelled."
  RETURN 0
ENDIF
'---- Extract data from HTML-file
IF ExtractHtml(web$,Data$,iField$)=0 THEN
  Msg$=ExtractHtml.Msg$
  RETURN 0
ENDIF
'--- Sort and write to data-file
CALL SortAndStore(DataFile$,Data$,ExtractHtml.count)
RETURN 1
END DEF
''
'r'
DEF SortAndStore(File$,Data$(,),items)
Quicksort$(Data$,Extract.count,2,1)
IF FILE_EXISTS(File$) THEN FILE File$ DELETE
items+=1 'add 1 to include reference value US-dollar
FILE File$ PRINT "Curr="&items&" ' items in Currencies"
DateTime$= ExtractHtml.DataDate$
'DateTime$&="T"&RIGHT$("0"&CURRENT_HOUR(),2)&":" ' add hour
'DateTime$&=RIGHT$("0"&CURRENT_MINUTE(),2) ' add minutes
FILE File$ PRINT "CurrDate$="""&DateTime$&""" ' download date"
FILE File$ PRINT "Currencies:"
File File$ PRINT "DATA """&"US dollar"&"""";
FOR i=1 TO items-1
  File File$ PRINT ", """&Data$(i,1)&"""";
NEXT i
File File$ PRINT
File File$ PRINT "DATA 1";
FOR i=1 TO items-1
  File File$ PRINT ", "&Data$(i,2);
NEXT i
END DEF
''
'r'
DEF ExtractHtml(HtmlFile$,Data$(,),iField$)
/* single item in HTML-text to parse:
<tr>
<td>Argentine Peso</td>
<td class='rtRates'><a href='… url …/?from=USD&amp;to=ARS'>36.446414</a></td>
<td class='rtRates'><a href='… url …/?from=ARS&amp;to=USD'>0.027438</a></td> 
</tr>
*/
count=0
'--- Read body into a$
GOSUB ReadTableBody ' local subroutine
IF Msg$<>"" THEN RETURN 0
'--- Store HTML table-rows
p1=INSTR(a$,"<tr",1)
WHILE p1>0 AND count<update.maxcount
 p2=INSTR(a$,"/tr>",p1)
  first=p2 
  IF first>0 THEN
    count+=1
    Data$(count,1)=SUBSTR$(a$,p1,p2)
  ENDIF
  p1=INSTR(a$,"<tr",first)
END WHILE
'--- Check table-size
IF count>=update.maxcount THEN
  Msg$="Data-array is too small. Increase constant 'count'."
  RETURN 0
ENDIF
'--- extract valuta and value
FOR i=1 TO count
  p1=INSTR(Data$(i,1),"<td>",1)+4
  p2=INSTR(Data$(i,1),"<",p1)-1
  Valuta$=SUBSTR$(Data$(i,1),p1,p2)
  p1=INSTR(Data$(i,1),"to=USD'>",p2)+8
  p2=INSTR(Data$(i,1),"</a",p1)-1
  Value$= SUBSTR$(Data$(i,1),p1,p2)
  Data$(i,1)=Valuta$ ! Data$(i,2)=Value$
NEXT i
RETURN 1  ' all OK 
ReadTableBody: ' ------------ local subroutine
'--- Extract date from filename
DataDate$=RIGHT$(TRIM$(HtmlFile$),8)
'--- Find second table
FIELD iField$ SHOW
FIELD iField$ BACK COLOR 0,0,1
Field iField$ TEXT "Extracting second table."
FILE HtmlFile$ SETPOS 0
Msg$="Second marker """&"tbody"&""" not found."
FOR i=1 TO 2
  DO
    FILE HtmlFile$ READLINE Line$
    IF Line$<>"" THEN p1=INSTR(Line$,"<tbody",1)
  UNTIL p1>0 OR FILE_END(HtmlFile$)
  IF FILE_END(HtmlFile$) THEN RETURN 'Msg$ is set
NEXT i
IF p1<1  THEN RETURN' Msg$ is preset
'--- Read table-body
a$=Line$
DO
  FILE HtmlFile$ READLINE Line$
  a$&=Line$
  p2=INSTR(a$,"/tbody",1)
UNTIL FILE_END(HtmlFile$) OR p2>0
Msg$&=" (no end-marker)"
IF p2<1 THEN RETURN ' Msg$ is preset
Msg$=""
RETURN ' from local sub
END DEF
''
'r'
DEF MakeCurrencyHTML$(Url$,HtmlFile$,iview,iField$,Browser$)
'HtmlFile$ contains name of existing file or undated name
'returns filename if HtmlFile$ is updated
'If 'htm-file$' was not existing then name is extended with date
IF FILE_EXISTS(HtmlFile$) AND iView THEN
  prompt$ ="Latest date: "
  prompt$&= RIGHT$(HtmlFile$,8)
  prompt$&=". Download new?"
  Answer$=Input$(iField$, prompt$)
  FIELD iField$ BACK COLOR 0,0,1
  IF Answer$="n" THEN
    NewData=0
    FIELD iField$ BACK COLOR 0,0,1
    Field iField$ TEXT  "Reading data"
    BROWSER Browser$ SHOW
    BROWSER Browser$ TEXT PageContent$(HtmlFile$)
 ELSE ! NewData =1
  ENDIF
ELSE ! NewData =1
ENDIF
'----  Update webdata
IF NewData THEN
  SPLITE HtmlFile$ TO a$,n with " "
  HtmlFile$=a$(1)&" "&ISO_Date$
  FIELD iField$ BACK COLOR 0,0,1
  Field iField$ TEXT  "Collecting data"
  IF iView THEN
    BROWSER Browser$ URL Url$
    BROWSER Browser$ SHOW
  ENDIF
ENDIF
Inspect:
  '---- Continue or return
IF NOT iView THEN Download
prompt$= "Continue?"
Answer$=Input$(iField$, prompt$)
FIELD iField$ BACK COLOR 0,0,1
BROWSER Browser$ HIDE
IF Answer$="n" THEN RETURN ""
DownLoad:
FIELD iField$ BACK COLOR 0,0,1
'---- download binary contents
FIELD iField$ BACK COLOR 0,0,1
Field iField$ TEXT "Loading webpage"
IF NewData THEN
  HTTP Url$ GETDIM Bin
  FILE HtmlFile$ WRITEDIM Bin
ENDIF
RETURN HtmlFile$
END DEF
'r'
DEF LatestFile$(undated$) ' find latest datafile
File$=""
DIR "." LIST FILES A$,n
FOR i=1 TO n
  IF INSTR(a$(i),undated$,1)=1 THEN File$=a$(i)
NEXT i
Date$=RIGHT$(File$,8)
RETURN File$
END DEF
''
'r'
DEF ISO_Date$
Date$=STR$(CURRENT_YEAR()*10000+100*CURRENT_MONTH()+CURRENT_DATE(),"########")
ISO_Date$=Date$
END DEF ' ISO_Date$
''
'r'
DEF PageContent$(file$) ' read html-content
FILE file$ SETPOS 0
content$=""
WHILE NOT FILE_END(file$)
  FILE file$ READLINE line$
  content$&=Line$
END WHILE
RETURN content$
END DEF
''
'r'
DEF Input$(Field$,Prompt$)
' Input from buttons
FIELD Field$ BACK COLOR 1,0,0
FIELD Field$ SHOW
FIELD Field$ TEXT Prompt$
BUTTON "yes" SHOW
BUTTON "no" SHOW
T$=""
DO
  IF bp("yes") THEN T$="y"
  IF bp("no") THEN T$="n"
  SLOWDOWN
UNTIL T$<>""
BUTTON "yes" HIDE
BUTTON "no" HIDE
RETURN T$
END DEF
''
'r'
DEF Quicksort$(Array$(,),MaxRow,Rowsize,SortColumn)' for STRINGS
' by Dutchman
' Non-recursive version of the QuickSort algorithm
' This sortfunction operates on a 2-dimensional string-array
' Number of rows is <MaxRow> and number of columns is <RowSize>
' The variable <SortColumn> determines which column is sorted
ShowMaxStack=0 ' will display stack-usage if set to 1
MaxStackPtr=0
DIM SwapRow$(RowSize), Stack1$(30), Stack2$(30)
StackPtr=0 ! HeadPtr=1 ! TailPtr=MaxRow
Qlabel2:
IF HeadPtr>TailPtr THEN
  GOTO Qlabel4
ELSE
  Pivot$= CAPSTR$(Array$((HeadPtr+TailPtr)/2,SortColumn))
  qa=HeadPtr ! qb=TailPtr
  Qlabel1:
  IF CAPSTR$(Array$(qa,SortColumn))<Pivot$ THEN ' while2
    qa=qa+1
    GOTO Qlabel1
  END IF '1
Qlabel3:   
  IF CAPSTR$(Array$(qb, SortColumn))>Pivot$ THEN
    qb=qb-1
    GOTO Qlabel3
  END IF '2
  IF qa<qb THEN
  ' swap rows
    FOR qi=1 TO RowSize
      SwapRow$(qi)=Array$(qa,qi)'save row qa
      Array$(qa,qi)=Array$(qb,qi)'store row qb content in row qa
      Array$(qb,qi)=SwapRow$(qi)'restore content of row qa to row qb
    NEXT qi
    qa=qa+1
    qb=qb-1
    GOTO Qlabel1
   END IF '3
  IF qa=qb THEN
    qq = qb - 1
    qr = qa + 1
  ELSE
    qq = qb
    qr = qa
  END IF '4
  StackPtr = StackPtr + 1
  IF MaxStackPtr<StackPtr THEN
    MaxStackPtr=StackPtr        
  END IF '5      
  qp=HeadPtr
  qs=TailPtr
  IF (qq-qp)<(qs-qr) THEN
    Stack1$(StackPtr)=qr
    Stack2$(StackPtr)=qs
    HeadPtr=qp
    TailPtr=qq
  ELSE
    Stack1$(StackPtr) = qp
    Stack2$(StackPtr) = qq
    HeadPtr = qr
    TailPtr = qs
  END IF '6
  GOTO Qlabel2
END IF '7
Qlabel4:
IF StackPtr > 0 THEN
  HeadPtr = Stack1$(StackPtr)
  TailPtr = Stack2$(StackPtr)
  StackPtr = StackPtr - 1
  GOTO Qlabel2
END IF '8
IF ShowMaxStack THEN
  PRINT "Maximum stacksize=";MaxStackPtr
END IF '9
END DEF ' QuickSort$
' end of Update Currencies code
'g'

' shortcut for button press

DEF bp(a$) = BUTTON_PRESSED(a$)


' remove scientific notation before displaying result

DEF format(form$)
  WHILE LEFT$(form$,1)=" " OR LEFT$(form$,1)=","
    form$=RIGHT$(form$,LEN(form$)-1)
    ' trim leading spaces and separators
  ENDWHILE
  IF INSTR (form$, ".") THEN        ' if form$ has a decimal point
    IF NOT numpad.curr THEN
    ' trim trailing zeros
    WHILE RIGHT$(form$,1)="0"
      form$=LEFT$(form$,LEN(form$)-1)
    ENDWHILE
    IF RIGHT$(form$,1)="." THEN
      form$=LEFT$(form$,LEN(form$)-1)
    ENDIF
    ENDIF
  ENDIF
END DEF

DEF pw(NAME$,title$,a$,xs,ys,ww,hh,R,G,B,ALPHA)
GRAPHICS CLEAR .9,1,1
PAGE NAME$ SET
PAGE NAME$ SHOW
PAGE NAME$ FRAME xs,ys,ww,hh
PAGE NAME$ COLOR R,G,B,ALPHA
PAGE "" HIDE
FIELD NAME$ TEXT a$ at 20*.rw,50*.rh size 360*.rw,360*.rh ML RO
FIELD NAME$ FONT SIZE 18*.rw
IF .rw<1 THEN lshift=12 ELSE lshift=0
IF title$="Settings" THEN
  if .rw<1 THEN
    FIELD "labels" TEXT "OFF                        ON" at 108*.rw,307*.rh RO
  ELSE
    FIELD "labels" TEXT "OFF               ON" at 130*.rw,307*.rh RO
  ENDIF
  FIELD "labels" FONT SIZE 18*.rw
  SWITCH "inter" STATE .view AT 177*.rw-lshift,310*.rh
ENDIF
FILL ALPHA 0
BUTTON "close" title "❎" AT ww-30,5 SIZE 24,24
FILL ALPHA 1
BUTTON "bottom" title "" AT -6,hh-3 SIZE ww+12,3
BUTTON "left" title "" AT 0,-6 SIZE 3,hh+12*.rh
BUTTON "right" title "" AT ww-3,-6 SIZE 3,hh+12*.rh
BUTTON "upper1" title "" AT -6,0 SIZE ww+12,3
BUTTON "upper2" title "" AT -6,30 SIZE ww+12,3
BUTTON "title" title title$ AT ww/2-50*.rw,3+lshift/2 SIZE 100*.rw,28*.rw

'
' other UI objects
'
'
END DEF
''

/*
Conversion Data

The technique I use to calculate conversions is to choose a reference measure in the middle of the range and set its value to 1. All other measures are then assigned numbers representing the ratio of their value to the reference measure's value.
*/

Categories:

DATA "Acceleration", "Angle", "Area", "Cooking", "Currency "&CurrDate$ ,"Data", "Energy", "Energy Transition", "Flow Rate", "Length", "Prefixes", "Power", "Pressure", "Speed"
DATA Tscale$, "Time", "Volume", "Weight"

Acceleration:
DATA "Centimeters Per Sec²", "Inches per Second²", "Feet per Second²", "Meters Per Second²", "Galileos", "Leos", "Gravity"
DATA .01, 0.0254, 0.304800000001219,1,.01,10,9.80664999978774

Angle:
DATA "Degrees", "Radians", "Gradians", "Minutes", "Seconds", "Circles", "Quadrants", "Points", "Mils"
DATA 1, 57.2957795128962, .9, .0166666666666667, .000277777777777778, 360, 90, 11.25, .05625

Area:
DATA "Acres", "Square Kilometers", "Hectares", "Square Meters", "Square Centimeters", "Square Miles", "Square Yards", "Square Feet", "Square Inches"
DATA 4046.85642, 1000000, 10000, 1, .0001, 2589988.110266, .8361273, .0929030, .000645159722

Cooking:
DATA "Centiliters", "Cups (CD)", "Fluid Ounces (CD)", "Liters", "Milliliters", "Pints (CD)", "Quarts (CD)", "Tablespoons", "Teaspoons"
DATA .35195,8,1,35.195079,.035195,20,40,.520421,.1734737

Data:
DATA "Bits", "Bytes", "Words", "Kilobytes", "Megabytes", "Gigabytes", "Terabytes", "Petabytes"
DATA .000125, .001, .008, 1, 1000, 1000000, 1000000000, 1000000000000

Energy:
DATA "BTU", "Calories", "Cubic Mile of Oil", "Foot Pounds", "Horsepower Per Hr", "Joules", "KiloJoules", "KiloCalories", "Kilowatt Hours", "Kilotons", "MegaJoules", "Therms (US)"
DATA 251.99576, 1, 38334721315564331336, .32404825, 641615.559278, .23900573, 239.00573, 1000, 860420.6501033, 999999974320, 239005.7299999, 25210420.65043

EnergyTransition:
DATA "Watt", "Kilowatt", "Kwh/y", "Kg/y Coal", "Kg/y Brown coal", "Kg/y Peat dry", "Kg/y Wood", "Kg/y Fat", "Kg Battery Li-Po, Li-Hv", "m² Solar panel", "Liter/y petrol", "Liter/y diesel oil", "Liter/y heating oil", "Liter/y Hydrogen 700bar", "Liter/y Alcohol", "Liter/y LNG", "Liter/y LPG", "Liter/day heating oil", "Liter/day LNG", "Liter/day LPG", "m³/y natural gas", "m³/y natural gas NL", "m³/y Hydrogen", "m³/day natural gas", "m³/day natural gas NL", "m³/day Hydrogen", "m³/day water to ice", "g/y Thorium"
DATA 1, 1000, 0.114077, 0.7465713, 0.4753213, 0.4753213, 0.4753213, 1.1724592, 0.0570386, 31.6564, 1.0837326, 1.2231602, 1.1819657, 0.2905798, 0.7415013, 0.7034755, 0.8143839, 431.713, 256.944, 297.454, 1.234251, 1.0583821, 0.5357, 450.81, 386.574, 195.664, 3865.74, 2516.6679

FlowRate:
DATA "Cubic Meters per Sec", "Cubic Meters per Min", "Cubic Meters per Hour", "Liters per Second", "Liters per Minute", "Liters per Hour", "Cubic Feet per Sec", "Cubic Feet per Minute", "Cubic Feet per Hour", "Gallons (US) per Sec", "Gallons (US) per Min", "Gallons (US) per Hour", "Gallons (US) per Day", "Gallons (UK) per Sec", "Gallons (UK) per Min", "Gallons (UK) per Hour", "Gallons (UK) per Day"
DATA 951019.38852, 15850.323142, 264.172052366667, 951.01938852, 15.850323142, 0.264172052366667, 26929.870147125, 448.83116911875, 7.48051948531251, 3600, 60, 1, .0416666666675429, 4323.41973193896, 72.0569955323167, 1.20094992556893, .0500395802310909

Length:
DATA "Ångströms","Centimeters", "Fathoms", "Feet", "Furlongs (US)", "Inches", "Kilometers", "Meters","Mils", "Miles", "Millimeters", "Nanometers", "Yards"
DATA .00000001, 1, 182.88, 30.48, 20116.8, 2.54, 100000, 100, .00254, 160934.39999, .1, .0000001, 91.44

Power:
DATA "Watts","Kilowatts", "Megawatts", "Gigawatts", "Terawatts", "KWh/year", "MegaJoule/year (MJ/y)","Horsepower (IT)", "Horsepower (Metric)", "Moosepower", "Calories per Hour", "BTU per Hour", "Foot Pounds per Hr", "Tons Refrigeration"
DATA 1,1000, 1E6, 1E9, 1E12, 1000/(365.25*24), 1E6/(365.25*24*60*60),745.69987, 756.042476, 2438.4385749, 0.0011629, 2930710000, 3766160000, 3516.8

Prefixes:
DATA "yotta", "zetta", "exa", "peta", "tera", "giga", "mega", "kilo", "hecto", "deca", "none", "deci", "centi", "milli", "micro", "nano", "pico", "femto", "atto", "zepto", "yocto"
DATA 1000000000000000000000000, 1000000000000000000000, 1000000000000000000, 1000000000000000, 1000000000000, 1000000000, 1000000, 1000, 100, 10, 1, .1, .01, .001, .000001, .000000001, .000000000001, .000000000000001, .000000000000000001, .000000000000000000001, .000000000000000000000001

Pressure:
DATA "Bars", "Millibars", "Pascals", "HectoPascals", "KiloPascals", "MegaPascals", "Atmospheres", "Pounds per Sq. Foot", "Pounds per Sq. Inch", "Inches of Water", "Inches of Mercury", "Centimeters of Water", "Centimeters of Mercury"
DATA 1000, 1, .01, 1, 10, 10000, 1013.250099, .47880258, 68.947572, 2.490889, 33.864, .98066496, 13.332283459

Speed:
DATA "Feet per Second", "Feet per Minute", "Furlongs per Fortnight", "Inches per Second", "Kilometers per Hour", "Kilometers per Sec.", "Knots", "Miles per Hour", "Miles per Second", "Speed of Light", "Speed of Sound"
DATA 1.09728, .018288, .000598715, .09144, 1, 3600, 1.8519999, 1.609349, 5793.638399, 1079252848.794, 1225.0439999

Temperatures:
DATA "Celsius [°C]", "Delisle [°D]", "Fahrenheit [°F]", "Kelvin [K]", "Newton [°N]", "Rankine [°Ra]", "Réamur [°Re]", "Rømer [°Rø]"
DATA 1,5,3,2,6,4,7,8 ' unit-pointers

Timing:
DATA "Milliseconds", "Seconds", "Minutes", "Hours", "Days", "Weeks", "Fortnights", "Months", "Years", "Leap Years"
DATA .00001666666, .01666666, 1, 60, 1440, 10080, 20160, 43800, 525600, 527040

Volume:
DATA "Cubic Centimeters", "Cubic Feet", "Cubic Inches", "Cubic Yards", "Cups (CD)", "Fluid Ounces (CD)", "Gallons (CD)", "Gallons (US)", "Liters", "Milliliters", "Pints (CD)", "Quarts (CD)"
DATA 1,28316.84659,16.3871,764554,284.130625,28.4131,4546.08999,3785.411784,1000,1,568.26125,1136.5225

Weight:
DATA "Grams", "Kilograms", "Ounces", "Ounces (troy)", "Pounds", "Grains", "Tonnes (metric)", "Tons (US short)", "Long Tons (UK)", "Stones"
DATA .0022046226, 2.2046226, .0625, .0685714, 1, 10, 2204.62262184, 2000, 2240, 14

' this routine is used when adding a new category, until its data is entered.

TBA:
DATA "To Be Added","","","","","","","","",""
DATA 1,1,1,1,1,1,1,1,1,1
Attachments
iconvert3.GIF
iconvert3.GIF (222.71 KiB) Viewed 130 times
iconvert3.PNG
iconvert3.PNG (14.12 KiB) Viewed 130 times
Last edited by rbytes on Thu Nov 15, 2018 4:45 pm, edited 3 times in total.
####### Living the colorful life #######

User avatar
Dutchman
Posts: 855
Joined: Mon May 06, 2013 9:21 am
My devices: iMac, iPad Air, iPhone
Location: Netherlands
Flag: Netherlands

Re: iConvert 4

Post by Dutchman » Thu Nov 15, 2018 3:05 pm

I have extended iConvert with the option to create the currency data file if it is not present. The user can decide to have it created or not.
To do this, I have rearranged the code of interest and added subroutines.

The program still freezes if the currency data is not present and the "currency" item is selected in the list.
Maybe you should make that selection impossible if the data file does not exist.

Attached is the modified code.
iconvert 4.1.txt
(32.65 KiB) Downloaded 7 times
We consider it a refreshing mental exercise to figure out ways to circumvent foolishness (Quote from Richard)

User avatar
rbytes
Posts: 1808
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 4

Post by rbytes » Thu Nov 15, 2018 4:34 pm

Actually I had already programmed and tested code that would prevent selecting Currency if the data file was missing. Instead it popped up a window saying to first run Update to activate currency conversion. The category would then revert back to the previously-selected one. Now when I look at the iConvert 4 code I posted yesterday, I see that there is an error that has crept in!

Since I upgraded to iOS 12.1 this week, I am having a lot of difficulty copying large programs, whether in Smart Basic or on the Forum. I had already noticed in iOS 11 that after selecting an entire large program such as iConvert, it was taking 15-20 seconds to get the popup menu with the Copy option. Now, It takes over a minute! I can make it appear sooner if I select a smaller portion of code, although there is still a long delay before it appears. Does anyone else experience this problem?

I decided to select, copy and paste the code in sections. That is how I got iConvert 4 posted on the Forum, and perhaps that is how the error crept in. Now I will need to fix 4 and 4.1 both. :? I will do that today. In future I will select everything and wait as long as it takes.
####### Living the colorful life #######

User avatar
rbytes
Posts: 1808
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 4

Post by rbytes » Thu Nov 15, 2018 5:08 pm

iConvert 4 has been reposted. The error that crept in yesterday is fixed. Now the user can not select Currency until a currency.data file exists. If they try, they will get a popup advising them to press the Update button to activate currency conversion.

Ton, I have sent a private message re 4.1.
####### Living the colorful life #######

User avatar
Dutchman
Posts: 855
Joined: Mon May 06, 2013 9:21 am
My devices: iMac, iPad Air, iPhone
Location: Netherlands
Flag: Netherlands

Re: iConvert 4

Post by Dutchman » Thu Nov 15, 2018 5:59 pm

An elegant solution for the missing data.
I think everything is now as desired. Thanks :D
We consider it a refreshing mental exercise to figure out ways to circumvent foolishness (Quote from Richard)

User avatar
rbytes
Posts: 1808
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 4

Post by rbytes » Thu Nov 15, 2018 6:29 pm

I looked again at your 4.1 version (while meditating and walking my dog), and I think it has a better solution. If you remove the query at startup and just create the data file silently if it is missing, the user will get an even better experience.

They will be able to convert currencies immediately.
-They won't have to read my message telling them that the program is missing something (a data file) and that they have to do three more steps to activate Currency and re-select it! (Exit the message window, press Update, select Currency)
-They won't have to answer yes or no at startup to a question they may not understand.

If in the current 4.0 they see my message but don't Update, then they get my message again every time they try to select Currency. :o
If in the current 4.1 they answer NO to your startup message they get it again every time they run the program! :o

So 4.1 could solve both problems, and we could actually reduce some code. I hope you agree. :)
####### Living the colorful life #######

User avatar
rbytes
Posts: 1808
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 4

Post by rbytes » Fri Nov 16, 2018 12:46 am

After looking further at the 4.1 code, I realized that for a silent update, most of the needed changes could be made in the code sections I had written, so I did that. I have posted the code as a private message.
####### Living the colorful life #######

User avatar
rbytes
Posts: 1808
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone X
iPad 4
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: iConvert 4

Post by rbytes » Sun Nov 18, 2018 4:54 am

A new version of iConvert will be posted in the coming week. In the meantime, if you want to download and try it, please use only version 4.

Any versions posted of 4.1, including the beta and alpha versions, were for testing new features and were not fully debugged.
####### Living the colorful life #######

Post Reply