FreeBASIC and GTK Glade how work the glade Button? - gtk3

a few months ago I started programming with FreeBASIC using the GTK libraries so that the applications are operational on both Windows and Linux without the need to rewrite the code, but being a beginner I only managed to create the mask but I don't know how to handle pressing the button.
Could someone tell me what I need to do to handle the button press?
#INCLUDE ONCE "gtk/gtk.bi"
gtk_init(#__FB_ARGC__, #__FB_ARGV__)
DIM SHARED AS GtkBuilder PTR XML
DIM SHARED AS GObject PTR _
mainWindow, Main_CloseButton
XML = gtk_builder_new()
SCOPE
DIM AS GError PTR meld
VAR GUISTR = SADD( _
"<?xml version=""1.0"" encoding=""UTF-8""?>" _
"<!-- Generated with glade 3.38.2 -->" _
"<interface>" _
"<requires lib=""gtk+"" version=""3.24""/>" _
"<object class=""GtkWindow"" id=""mainWindow"">" _
"<property name=""can-focus"">False</property>" _
"<child>" _
"<object class=""GtkLayout"">" _
"<property name=""visible"">True</property>" _
"<property name=""can-focus"">False</property>" _
"<child>" _
"<object class=""GtkButton"" id=""Main_CloseButton"">" _
"<property name=""label"" translatable=""yes"">Close</property>" _
"<property name=""width-request"">80</property>" _
"<property name=""height-request"">30</property>" _
"<property name=""visible"">True</property>" _
"<property name=""can-focus"">True</property>" _
"<property name=""receives-default"">True</property>" _
"</object>" _
"<packing>" _
"<property name=""x"">350</property>" _
"<property name=""y"">200</property>" _
"</packing>" _
"</child>" _
"</object>" _
"</child>" _
"</object>" _
"</interface>" _
!"\0")
IF 0 = gtk_builder_add_from_string(XML, GUISTR, -1, #meld) THEN
WITH *meld
?"Error (GTK-Builder):"
?*.message
END WITH
g_error_free(meld)
END 2
END IF
END SCOPE
mainWindow = gtk_builder_get_object(XML, "mainWindow")
Main_CloseButton = gtk_builder_get_object(XML, "Main_CloseButton")
gtk_builder_connect_signals(XML, 0)
g_object_unref(XML)
gtk_widget_show_all(GTK_WIDGET(mainWindow))
gtk_main()

First of all you need to add a signal in the XML code that refers to pressing the button.
Ex.
"<property name=""receives-default"">True</property>" _
"<signal name=""clicked"" handler=""on_Main_CloseButton_clicked"" swapped=""no""/>" _
"</object>" _
Create a new file by calling it (on_Main_CloseButton_clicked.bas)
include it before the "gtk_builder_connect_signals(XML, 0)"
Sometimes during the compilation if it is included later it can give some errors (perhaps a compiler bug or the code too messy)
Main_CloseButton = gtk_builder_get_object(XML, "Main_CloseButton")
#INCLUDE "on_Main_CloseButton_clicked.bas"
gtk_builder_connect_signals(XML, 0)
g_object_unref(XML)
gtk_widget_show_all(GTK_WIDGET(mainWindow))
gtk_main()
And inside the new file write a sub that is activated by a handler
on_Main_CloseButton_clicked.bas
SUB on_Main_CloseButton_clicked CDECL ALIAS "on_Main_CloseButton_clicked" ( _
BYVAL widget AS GtkWidget PTR, _
BYVAL user_data AS gpointer) EXPORT ' Standard-Parameterliste
'Place your code here+
end
END SUB

Related

How to convert GTK keyboard event keys to English in any language layouts?

I want to use keyboard shortcuts (like Ctrl+Z/Ctrl+C/Ctrl+V and etc.) in my GTK-3 app. I get different keyboard events for different keyboard layouts.
For example my keyboard have English and Russian layouts and so my Russian key "Я" is at "Z".
There are many languages in world. How I can make app which works with any languages?
Now I translate keycodes only for Russian keyboard this way:
func main_event_listener(event *gdk.Event){
eventObject := &gdk.EventKey{event}
key := eventObject.KeyVal()
state := eventObject.State()
key, state = GTK_TranslateKeyLayoutEnglish(key, state)
if state == gdk.GDK_CONTROL_MASK {
if key == gdk.KEY_z {
//Ctrl+Z
}
if key == gdk.KEY_c {
//Ctrl+C
}
if key == gdk.KEY_v {
//Ctrl+V
}
} else {
if key == gdk.KEY_F5 {
//F5
}
if key == gdk.KEY_Delete {
//Delete
}
}
}
func GTK_TranslateKeyLayoutEnglish(key uint, state uint) (uint, uint) {
key2 := key
state2 := state
if state2 > 8192 { //RUSSIAN Ctrl 8196 == English Ctrl 4
state2 -= 8192
}
switch key {
case gdk.KEY_Cyrillic_ya: //RUSSIAN 'я'
key2 = gdk.KEY_z
case gdk.KEY_Cyrillic_ef: //RUSSIAN 'ф'
key2 = gdk.KEY_a
case gdk.KEY_Cyrillic_che: //RUSSIAN 'ч'
key2 = gdk.KEY_x
case gdk.KEY_Cyrillic_es: //RUSSIAN 'с'
key2 = gdk.KEY_c
case gdk.KEY_Cyrillic_em: //RUSSIAN 'м'
key2 = gdk.KEY_v
//etc
}
return key2, state2
}
I expect better realization of GTK_TranslateKeyLayoutEnglish() function

Picocli: how to show header/banner at all times

Picocli offers the ability to add a nice header in the #Command annotation, for example:
#Command(name = "git-star", header = {
"#|green _ _ _ |#",
"#|green __ _(_) |_ __| |_ __ _ _ _ |#",
"#|green / _` | | _(_-< _/ _` | '_| |#",
"#|green \\__, |_|\\__/__/\\__\\__,_|_| |#",
"#|green |___/ |#"},
description = "Shows GitHub stars for a project",
mixinStandardHelpOptions = true, version = "git-star 0.1")
How do I always show that header/banner when the program is running, without duplicating this banner in two places?
(See also https://github.com/remkop/picocli/issues/517)
There are two aspects to this:
How to get the banner text from the application?
How to render the ANSI colors and styles?
You can get the banner from the usage help message, either with new CommandLine(new App()).getCommandSpec().usageHelpMessage().header() or by injecting a #Spec annotated CommandSpec field in your application.
To render the ANSI styles, use CommandLine.Help.Ansi.AUTO.string(line) for each banner line.
Putting it all together:
#Command(name = "git-star", header = {
"#|green _ _ _ |#",
"#|green __ _(_) |_ __| |_ __ _ _ _ |#",
"#|green / _` | | _(_-< _/ _` | '_| |#",
"#|green \\__, |_|\\__/__/\\__\\__,_|_| |#",
"#|green |___/ |#"},
description = "Shows GitHub stars for a project",
mixinStandardHelpOptions = true, version = "git-star 0.1")
class GitStar implements Runnable {
#Option(names = "-c")
int count;
#Spec CommandSpec spec;
// prints banner every time the command is invoked
public void run() {
String[] banner = spec.usageHelpMessage().header();
// or: String[] banner = new CommandLine(new GitStar())
// .getCommandSpec().usageHelpMessage().header();
for (String line : banner) {
System.out.println(CommandLine.Help.Ansi.AUTO.string(line));
}
// business logic here...
}
public static void main(String[] args) {
CommandLine.run(new GitStar(), args);
}
}
For me in Picocli 4.5.2, works like that:
public void run() {
CommandLine cmd = new CommandLine(new App());
cmd.usage(System.out, Ansi.ON);
// business logic here...
}

What is the correct use of select statement in Go?

Good Day everyone
I have been learning the fundaments of go and how to use its channel-based concurrency paradigm.
However, while playing with some code I wrote focusing on the select statement I found a strange behavior:
func main() {
even := make(chan int)
odd := make(chan int)
quit := make(chan bool)
//send
go send(even, odd, quit)
//receive
receive(even, odd, quit)
fmt.Println("Exiting")
}
func send(e, o chan<- int, q chan<- bool) {
for i := 0; i < 100; i++ {
if i%2 == 0 {
e <- i
} else {
o <- i
}
}
close(e)
close(o)
q <- true
close(q)
}
func receive(e, o <-chan int, q <-chan bool) {
for cont, i := true, 0; cont; i++ {
fmt.Println("value of i", i, cont)
select {
case v := <-e:
fmt.Println("From even channel:", v)
case v := <-o:
fmt.Println("from odd channel:", v)
case v := <-q:
fmt.Println("Got exit message", v)
// return // have also tried this instead
cont = false
}
}
}
when I run this simple program sometimes the i accumulator ends up with more than a 100 being printed to the console, and instead of finishing up with a "from odd channel: 99", the for loop continues on outputting one or more zeroes from even/odd channels randomly, as if the quit channel's message was being somewhat being delayed onto its case and instead the odd/even channels were sending more integers thus quitting the for loop not exactly after the odd/even channels have been closed.
value of i 97 true
from odd channel: 97
value of i 98 true
From even channel: 98
value of i 99 true
from odd channel: 99
value of i 100 true
From even channel: 0
value of i 101 true
From even channel: 0
value of i 102 true
from odd channel: 0
value of i 103 true
From even channel: 0
value of i 104 true
Got exit message true
Exiting
I have tried to search for the correct use of the case statement but I haven´t been able to find the problem with my code.
It seems like the same behavior can be reproduced on the go playground: my code
thanks for your attention put on my question.
The program is printing 0 because receive on a closed channel returns the zero value. Here's one way to accomplish your goal.
First, eliminate the q channel. Closing the o and e channels is sufficient to indicate that the sender is done.
func send(e, o chan<- int, q chan<- bool) {
for i := 0; i < 100; i++ {
if i%2 == 0 {
e <- i
} else {
o <- i
}
}
close(e)
close(o)
}
When receiving values, use the two value receive to detect when the zero value is returned because the channel is closed. Set the channel to nil when the channel is closed. Receive on a nil channel does not yield a value. Loop until both channels are nil.
func receive(e, o <-chan int, q <-chan bool) {
for e != nil && o != nil {
select {
case v, ok := <-e:
if !ok {
e = nil
continue
}
fmt.Println("From even channel:", v)
case v, ok := <-o:
if !ok {
o = nil
continue
}
fmt.Println("From odd channel:", v)
}
}
}
playground example

Output unquoted Unicode in Go

I'm using goyaml as a YAML beautifier. By loading and dumping a YAML file, I can source-format it. I unmarshal the data from a YAML source file into a struct, marshal those bytes, and write the bytes to an output file. But the process morphs my Unicode strings into the literal version of the quoted strings, and I don't know how to reverse it.
Example input subtitle.yaml:
line: 你好
I've stripped everything down to the smallest reproducible problem. Here's the code, using _ to catch errors which don't pop-up:
package main
import (
"io/ioutil"
//"unicode/utf8"
//"fmt"
"gopkg.in/yaml.v1"
)
type Subtitle struct {
Line string
}
func main() {
filename := "subtitle.yaml"
in, _ := ioutil.ReadFile(filename)
var subtitle Subtitle
_ = goyaml.Unmarshal(in, &subtitle)
out, _ := goyaml.Marshal(&subtitle)
//for len(out) > 0 { // For debugging, see what the runes are
// r, size := utf8.DecodeRune(out)
// fmt.Printf("%c ", r)
// out = out[size:]
//}
_ = ioutil.WriteFile(filename, out, 0644)
}
Actual output subtitle.yaml:
line: "\u4F60\u597D"
I want to reverse the weirdness in goyaml after I get the variable out.
The commented-out rune-printing code block, which adds spaces between runes for clarity, outputs the following. It shows that Unicode runes like 你 aren't being decoded, but treated literally:
l i n e : " \ u 4 F 6 0 \ u 5 9 7 D "
How can I unquote out, before writing it to the output file, so that the output looks like the input (albeit beautified)?
Desired output subtitle.yaml:
line: "你好"
Temporary Solution
I've filed https://github.com/go-yaml/yaml/issues/11. In the meantime, #bobince's tip on yaml_emitter_set_unicode was helpful in unconvering the problem. It was defined as a C binding but never called (or given an option to set it)! I changed encode.go and added yaml_emitter_set_unicode(&e.emitter, true) to line 20, and everything works as expected. It would be better to make it optional, but that would require a change in the Marshal API.
Had a similar issue and could apply this to circumvent the bug in goyaml.Marshal(). (*Regexp) ReplaceAllFunc is your friend which you can use to expand the escaped Unicode runes in the byte array. A little bit too dirty for production maybe, but works for the example ;-)
package main
import (
"io/ioutil"
"unicode/utf8"
"regexp"
"strconv"
"launchpad.net/goyaml"
)
type Subtitle struct {
Line string
}
var reFind = regexp.MustCompile(`^\s*[^\s\:]+\:\s*".*\\u.*"\s*$`)
var reFindU = regexp.MustCompile(`\\u[0-9a-fA-F]{4}`)
func expandUnicodeInYamlLine(line []byte) []byte {
// TODO: restrict this to the quoted string value
return reFindU.ReplaceAllFunc(line, expandUnicodeRune)
}
func expandUnicodeRune(esc []byte) []byte {
ri, _:= strconv.ParseInt(string(esc[2:]), 16, 32)
r := rune(ri)
repr := make([]byte, utf8.RuneLen(r))
utf8.EncodeRune(repr, r)
return repr
}
func main() {
filename := "subtitle.yaml"
filenameOut := "subtitleout.yaml"
in, _ := ioutil.ReadFile(filename)
var subtitle Subtitle
_ = goyaml.Unmarshal(in, &subtitle)
out, _ := goyaml.Marshal(&subtitle)
out = reFind.ReplaceAllFunc(out, expandUnicodeInYamlLine)
_ = ioutil.WriteFile(filenameOut, out, 0644)
}

use outlook instead of gmail to send mails vb.net 2010

I have a class to send emails with multiple attachments, it uses gmail, but how can I use Outlook to send emails?
Imports System.Net.Mail
Imports System.Net.Mime
Public Sub SendThis(ByVal SubjectText As String, _
ByVal BodyText As String, _
ByVal FromAddress As String, _
ByVal ToAddress As String, _
Optional ByVal FileName As Collection = Nothing _
)
Try
Dim email As New Net.Mail.MailMessage(FromAddress, ToAddress)
email.Subject = SubjectText
email.Body = BodyText
If Not FileName Is Nothing Then
For Each Name As String In FileName
Dim attach As New Net.Mail.Attachment(Name) 'Includes Path
email.Attachments.Add(attach)
Next
For Each At As Attachment In email.Attachments
At.TransferEncoding() = Net.Mime.TransferEncoding.Base64
Next
End If
Dim TheSmtp As New SmtpClient(YourSmtpServerName, 587)
TheSmtp.Credentials = New Net.NetworkCredential("abc#gmail.com","MYPASS")
TheSmtp.DeliveryMethod = SmtpDeliveryMethod.Network
TheSmtp.Send(email)
email.Attachments.Clear()
TheSmtp = Nothing
email = Nothing
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, "HFB", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End Try
End Sub
I call the function like:
Private Sub BtnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSend.Click
Dim BodyText As String
Dim SubjectText As String
Dim FromAddress As String
Dim ToAddress As String
Dim Filename As New Collection
If Me.LstBxAttach.Items.Count > 0 Then
For Each TheItem As String In LstBxAttach.Items
Filename.Add(TheItem)
Next
End If
SubjectText = Me.TbSubject.Text
BodyText = Me.TbBody.Text
SendThis(SubjectText, _
BodyText, _
"from#example.com", _
"to#example.com", _
Filename _
)
SubjectText = ""
BodyText = ""
FromAddress = ""
ToAddress = ""
MessageBox.Show("Sent!", "HFB", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
You can use the Outlook object model. The Application object lets you connect to Outlook; to send an e-mail, you will want to create a MailItem object, populate the relevant properties, and call its Send method.