Tijd vergelijken, berekening met tijd

Als je een berekening moet doen met tijden, gebruik je best de ingebouwde DateDiff.

Bv. :

DateDiff(Settings["SomeTime/Start"], Time(Now()), gb.Minute) / 60

Dit geeft een negatieve waarde als tweede parameter kleiner is.

Fout is de tijd op zich proberen te vergelijken:

IF (Settings[“SomeTime/Start”] > Time(Now()))
IF (Settings[“SomeTime/Start”] > Format(Time(Now()), “hh:mm”))

Deze laatste is dubbel fout want minuten worden niet voorgesteld door mm maar door nn.

Zie ook Rekenen met tijd (dagen).

compile gambas app van de commandolijn

Compileren: gbc3
Ga in de projectdirectory staan. Tik daar:
gbc3 -a

upd: moet blijkbaar kleine a zijn gbc3 -A

Uitvoerbaar programma:
Het uitvoerbare programma maak je door de bestemming/naam op te geven bij gba3:
gba3 -o ~/mygambasprog.gambas

Link op de desktop etc
zie vorige posts …
Icoon: http://gambas.copyleft.be/blog/archives/112
Werking gambas: http://gambas.copyleft.be/blog/uitvoeren
Source archive uitpakken, compileren en draaien: http://gambas.copyleft.be/blog/archives/148

Ongewenst sluiten tegenhouden

Een gebruiker kan per vergissing op het x teken duwen boven in de balk van het venster, als hij bv het venster wil verkleinen of vergroten. Dan sluit de applicatie onherroepelijk af.
Je kan in het Close event wel eindprocedures opnemen die data bewaren en verbindingen sluiten en zo, maar kan je ook de “Close” tegenhouden?

Ja dat kan
Maak ergens een boolean die bepaalt of het venster gesloten (m.a.w. het programma gestopt) mag worden of niet. Je kan die bv zetten als je bepaalde verbindingen of bestanden geopend hebt, processen gestart hebt enz.).
ps: Zorg dat je ook ergens een situatie voorziet dat die teruggezet wordt. Normaal zal dat zijn na het sluiten van die dingen door een normaal eind-bevel, met quit-knop of menu.

Stop Event

MMain
Public bShowHasStarted as Boolean = FALSE ' indicates active use
Public Sub Form_Close()
  If MMain.bShowHasStarted 
    Message.Info("Please stop all processes first (close files, connections etc) ")
    Stop Event
  Else
    doClose()
  Endif
End

Settings[“sSlot/sKey”]=”value”

Terminologie
Een mooi voorbeeld van benoemen van de rubriektitels in het Settings bestand is “slot” en “key”. Slot is de titel, key is de variabele naam. Beiden zijn nodig om de waarde (value) op te vragen.
Ik probeer het bewaren van instellingen door middel van de module “Settings” een beetje te stroomlijnen, vooral in het kader van het bewaren van verschillende databank-toegang omgevingen waarin een gambas3 programma gedraaid wordt: ontwikkeling, test, ingebruik (development, testing, in production).

Veel van het gebruik van “Settings” zit vervat in deze code:

Dim sSlot, sKey as String
'
For Each sSlot In Settings.Keys
  Print sSlot
  For Each sKey In Settings.Keys[sSlot]
    Print sKey & ": " & Settings[sSlot &/ sKey]
  Next
Next

Een klasse kan helpen bij het beheren; bv CDataContext.

(wordt aan gewerkt)

In memorial: Domotiga

Spijtig genoeg voor iedereen die met Gambas3 en Raspberry Pi werkt, is Domotiga al een tijdje verdwenen, ik schat van ongeveer 2015. De website www.domotiga.nl ging ergens in de zomer van 2015 (mei?) over in de site van CyberJunky’s Blog, alter ego van een zekere Ron “RDNZL”, de auteur van Domotiga. Die naam herken je zeker als je op de Gambas mailinglist ingeschreven was, daar was hij erg aktief meen ik mij te herinneren, en daarmee ook een aanwinst voor Gambas gebruikers in het algemeen.
Op CyberJunky vond je nog links naar Domotiga en DomotiYii, maar ondertussen lijkt er enkel een wordpress reklamesite van één of ander netwerk op de domeinnaam domotiga.nl te staan.

Ergens las ik dat de maker van Domotiga zelf overstapte op een ander systeem voor zijn domotica toepassingen (ok, dat klinkt erg onwetenschappelijk) – ik zie op de cyberjunky github pagina allerlei “Home-assistant” werk.. dat terug te volgen is tot december 2016. Home Assistant draait op Python.

Je vindt nog wel resten van Domotiga terug, bv in web.archive.org, waar je op de about pagina kan terugvinden dat Domotiga startte als een eigen versie van ‘Misterhouse”.

De laatste updates aan de Domotiga github repository vermelden (op dit moment) “May 16, 2019”, dus mogelijk draait het hier en daar nog wel…

Gambas 3.14 start niet

openSUSE 15.1 + Education repository
De oorspronkelijke Gambas 3.10 werkt normaal.
Na een upgrade en wijziging van repository naar Education en Gambas 3.14 start gambas niet.

Op de commandolijn:

gambas

gbx3: unable to find startup file

En op een andere manier, met het hele pad:

/usr/bin/gambas3.gambas

~> /usr/bin/gambas3.gambas 
ERROR: #27: Cannot load component 'gb.jit': cannot find component

** 
** OOPS! INTERNAL ERROR. Program aborting, sorry! :-(
** Unable to find JIT._Abort() method
** 
** ERROR: Unable to find method _Abort in class Jit. Symbol not found
** 
** Please send a bug report to the gambas bugtracker [1] or to the gambas mailing-list [2].
** [1] http://gambaswiki.org/bugtracker
** [2] https://lists.gambas-basic.org/listinfo/user
** 

Daar staat alles in wat we nodig hebben:

..
Error: #27: Cannot load component ‘gb.jit’: cannot find component
..
Unable to find JIT._Abort() method

In Yast, software management, zoek “gambas3” zie je dat gb-jit niet aangevinkt staat in de lijst van gambas3 programma-onderdelen.
Dus bij-installeren:

gambas3-gb-jit

Klaar!

ps: er stonden, behalve al de debug packages, nog een paar paketten niet aangevinkt …

– gb-gtk3
– gb-inotify
– gb-media
– gb-option
– gb-scanner

Veilige verbinding met de databankserver door SSL, TLS

Eigen verbinding controleren:

login als mysql gebruiker op de server.
Checke met \s hoe de gebruikte verbinding verloopt; kijk naar “SSL”:

MariaDB [(none)]> \s
--------------
mysql Ver 15.1 Distrib 10.0.32-MariaDB, for Linux (x86_64) using readline 5.1

Connection id: 33
Current database:
Current user: copyleft@192.168.1.222
SSL: Not in use
Current pager: less
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.0.32-MariaDB SLE 12 SP1 package
Protocol version: 10
Connection: 192.168.1.111 via TCP/IP
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 32 min 34 sec

Er wordt dus geen veilige verbinding gebruikt (SSL: Not in use)

Log in op de server als root.
Kijk naar de instellingen ivm ssl :

MariaDB [(none)]> show variables like '%ssl';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| have_openssl | YES |
| have_ssl | DISABLED |
+---------------+----------+

De SSL mogelijkheden zijn mee gecompileerd, maar niet in gebruik.

Volgende stappen:
– SSL keys instellen met juiste user, en server herstarten om SSL gebruik te aktiveren.
– Server zo instellen dat hij van buitenaf enkel SSL verbindingen beantwoordt (van binnenuit kan het nog via unix sockets dan)

Engelstalig artikel (toegepast op ubuntu) op:

https://www.digitalocean.com/community/tutorials/how-to-configure-ssl-tls-for-mysql-on-ubuntu-16-04

Luie programmeurs: automatische naam voor button

Als je aan het programmeren bent en je snel wat knoppen in je vensters zet, is het belangrijk om die knoppen een relevante naam te geven.

Bv een nieuwe knop Button1 krijgt de naam buttonQuit of in mijn geval btQuit (ik kort de prefix voor het schermobjecttype af tot 2 of 4 lettertekens zoals bt, lsbx, cmbx, enz).

De knoppen hebben ook een functie naar de gebruiker, je moet ze dus ook een etiket geven voor de gebruiker, de Text property: Button1.Text of bij mij: btQuit.Text=”Quit”.

Zie je de luiheid al opkomen? In de nieuwere versies van Gambas (Gambas3) wordt de Button1.Name ook weergegeven op de knop als je zelf nog geen tekst erin zette; dit is bijzonder handig tijdens het programmeren.

Maar als die tekst eens ineens kan blijven staan als goede tekst? In mijn geval zou btQuit wel de opdruk “Quit” moeten krijgen, dus de twee letterjes prefix van het type moeten eraf. Right(Button1.Text, -2) als het ware.

Daar gaan we dus:

In een steeds in mijn projecten voorkomende schermfunctiesverzameling plant ik deze:

MForm

Public Sub doNameButtons(hMainObject As Object)
  '
  Dim hObject As Object
  Dim hButton As Button
  Dim iChildrenCount As Integer
  '
  Debug hMainObject.Name & " " & TypeOf(hMainObject)
  '
  Try iChildrenCount = hMainObject.Children.Count
  '
  If Not Error 
    '
    For Each hObject In hMainObject.Children
      '
      Try hButton = hObject
      '
      If Not Error
        If Left(hObject.Name, 2) = "bt" And hButton.Text = ""
          Debug "CHANGE TO " & Right(hObject.Name, -2)
          hButton.Text = Right(hObject.Name, -2)
        Else
          ' not named with naming convention of buttons, this is a way to let you exclude empty-text buttons from this auto-name 
          ' name not empty, so it stays as it is - and can be translated 
          Debug "NO CHANGE: " & hObject.Name
        Endif
      Else
        ' recursion
        Debug hObject.Name & " is no button; check for .children : "
        doNameButtons(hObject)
      Endif        
    Next
  Else
    Debug "Error hMainObject.Children.Count " & hMainObject.Name & " " & iChildrenCount
  Endif  
End
'

In mijn FMain (en alle andere schermen die ik snel in elkaar flikker) roep ik dat zo aan voor iedere container met buttons in (soms nog eens in een container – dus recursief):

FMain

Public Sub Form_Open()
'
  MForm.doNameButtons(HBox1)
' ...
End

Alle knoppen in de Form die al een opschrift hebben, houden die. De anderen krijgen één, afgeleid van de knopnaam.

Let op!
Dit is alleen handig tijdens het programmeren, als de knoppen nog van functie en naam veranderen enz.

Eens het project zo ver af is dat je het gaat vertalen zul je toch de Text properties van de knoppen moeten invullen, anders werkt het vertaalsysteem niet.

Check eerst of het een button is:

TypeOf(hObject) = TypeOf(hButton)

Dit is geen oplossing, omdat er niet zo’n fijn onderscheid wordt gemaakt tussen objecten in TypeOf; beiden zijn “16” (een constante voor gb.Object); ook een HBox of VBox behoort daartoe.

Ik vond geen andere methode dan het child object proberen toe te wijzen aan een button; bij fout is het geen button, anders wel.

Zelfs tussen buttons kan er een ander object staan zoals een leeg tekstveld om als “spacer” te gebruiken; tekst leeg maar expand=TRUE zodat het een knop aan de rechterkant naar rechts tot aan het einde van de container (bv HBox) duwt.

Hernoemen uitvoeren op button object met naam beginnend met “bt”, de anderen worden overgeslagen.

Recursie
Als het object geen button was, kan het altijd nog een container zijn die ook weer buttons bevat, dus wordt dat gecheckt en kan de hernoem-test opnieuw beginnen.
Daarom wordt de procedure zelf terug opgeroepen.

Ik vond ook geen mooie manier om te testen of het een container is, en als er geen children objecten zijn, crasht

For Each hObject In hMainObject.Children

Daarom test ik eerst of een Children.Count wel kan:

Try iChildrenCount += hMainObject.Children.Count

If Not Error

(het optellen heeft niet echt zin)

Upd 13092017: bug fix: crash bij ander object dan button en helemaal herwerkt.

Vormgevingconventies doorheen app

Om een concistente applicatie te krijgen moet je overal dezelfde conventies toepassen.

bv: titels (grootte), foutmeldingen, kleuren bij invulvelden, …

Form Textlabel Title : font, size, color, em.

Field Textlabel Title: font, size, color, bgcolor, em.

Field content: font, size, bgcolor
– vaste tekst : zwart
– invulveld (niet invul/wijzigbaar) color dark gray, background light gray
– invulveld (vast): color black
– wijzigbaar: color blue,
– gewijzigd: color light blue (darkcyan)
– bewaard na wijziging: dark blue
– geweigerde invoer: red
– nog niet bewaard: orange
– voorbeelden, help: green

Het handigst is in MForm een aantal procedures te maken voor het instellen van eigenschappen van velden en die van overal te gebruiken.