This commit is contained in:
Stanislav Nikitin 2018-11-10 20:58:15 +05:00
parent 39ac02dfc5
commit 2b3c9ef9ea
25 changed files with 1054 additions and 1022 deletions

View File

@ -10,105 +10,105 @@
package clipboardwatcher package clipboardwatcher
import ( import (
// stdlib // stdlib
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
// other // other
"github.com/mattn/go-gtk/gdk" "github.com/mattn/go-gtk/gdk"
"github.com/mattn/go-gtk/gtk" "github.com/mattn/go-gtk/gtk"
) )
type ClipboardWatcher struct { type ClipboardWatcher struct {
// Clipboard. // Clipboard.
clipboard *gtk.Clipboard clipboard *gtk.Clipboard
// PRIMARY clipboard. // PRIMARY clipboard.
prim_clipboard *gtk.Clipboard prim_clipboard *gtk.Clipboard
// Flags. // Flags.
// We have just copy connect string to clipboard. // We have just copy connect string to clipboard.
// Used to ignore clipboard data in check*Input() // Used to ignore clipboard data in check*Input()
just_set bool just_set bool
} }
func (cw *ClipboardWatcher) checkInput() { func (cw *ClipboardWatcher) checkInput() {
if !cw.just_set { if !cw.just_set {
text := cw.clipboard.WaitForText() text := cw.clipboard.WaitForText()
cw.parseData(text) cw.parseData(text)
} else { } else {
cw.just_set = false cw.just_set = false
} }
} }
func (cw *ClipboardWatcher) checkPrimaryInput() { func (cw *ClipboardWatcher) checkPrimaryInput() {
if !cw.just_set { if !cw.just_set {
text := cw.prim_clipboard.WaitForText() text := cw.prim_clipboard.WaitForText()
cw.parseData(text) cw.parseData(text)
} else { } else {
cw.just_set = false cw.just_set = false
} }
} }
func (cw *ClipboardWatcher) CopyServerData(server_address string) error { func (cw *ClipboardWatcher) CopyServerData(server_address string) error {
server, ok := Cache.Servers[server_address] server, ok := Cache.Servers[server_address]
if !ok { if !ok {
// ToDo: show message box? // ToDo: show message box?
return errors.New("Server wasn't selected") return errors.New("Server wasn't selected")
} }
// Composing connection string. // Composing connection string.
var connect_string string = "" var connect_string string = ""
connect_string += "/connect " + server.Server.Ip + ":" + server.Server.Port connect_string += "/connect " + server.Server.Ip + ":" + server.Server.Port
if len(server.Server.Password) >= 1 { if len(server.Server.Password) >= 1 {
connect_string += ";password " + server.Server.Password connect_string += ";password " + server.Server.Password
} }
fmt.Println("Connect string: ", connect_string) fmt.Println("Connect string: ", connect_string)
cw.just_set = true cw.just_set = true
cw.clipboard.SetText(connect_string) cw.clipboard.SetText(connect_string)
return nil return nil
} }
func (cw *ClipboardWatcher) Initialize() { func (cw *ClipboardWatcher) Initialize() {
fmt.Println("Initializing clipboard watcher...") fmt.Println("Initializing clipboard watcher...")
cw.just_set = false cw.just_set = false
cw.clipboard = gtk.NewClipboardGetForDisplay(gdk.DisplayGetDefault(), gdk.SELECTION_CLIPBOARD) cw.clipboard = gtk.NewClipboardGetForDisplay(gdk.DisplayGetDefault(), gdk.SELECTION_CLIPBOARD)
cw.clipboard.Connect("owner-change", cw.checkInput) cw.clipboard.Connect("owner-change", cw.checkInput)
cw.prim_clipboard = gtk.NewClipboardGetForDisplay(gdk.DisplayGetDefault(), gdk.SELECTION_PRIMARY) cw.prim_clipboard = gtk.NewClipboardGetForDisplay(gdk.DisplayGetDefault(), gdk.SELECTION_PRIMARY)
cw.prim_clipboard.Connect("owner-change", cw.checkPrimaryInput) cw.prim_clipboard.Connect("owner-change", cw.checkPrimaryInput)
} }
func (cw *ClipboardWatcher) parseData(data string) { func (cw *ClipboardWatcher) parseData(data string) {
// We should check only first string. // We should check only first string.
data = strings.Split(data, "\n")[0] data = strings.Split(data, "\n")[0]
// Checking if we have connection string here. // Checking if we have connection string here.
if strings.Contains(data, "ct ") { if strings.Contains(data, "ct ") {
fmt.Println("Connection string detected!") fmt.Println("Connection string detected!")
var server string = "" var server string = ""
var password string = "" var password string = ""
conn_string := strings.Split(data, ";") conn_string := strings.Split(data, ";")
if len(conn_string) > 0 { if len(conn_string) > 0 {
srv_string := strings.Split(data, ";")[0] srv_string := strings.Split(data, ";")[0]
srv_splitted := strings.Split(srv_string, "ct ") srv_splitted := strings.Split(srv_string, "ct ")
if len(srv_splitted) > 1 { if len(srv_splitted) > 1 {
server_raw := strings.Split(srv_splitted[1], " ")[0] server_raw := strings.Split(srv_splitted[1], " ")[0]
// Get rid of spaces. // Get rid of spaces.
server = strings.TrimSpace(server_raw) server = strings.TrimSpace(server_raw)
} }
} }
if len(conn_string) > 1 && strings.Contains(data, "password") { if len(conn_string) > 1 && strings.Contains(data, "password") {
pw_string := strings.Split(data, ";")[1] pw_string := strings.Split(data, ";")[1]
pw_splitted := strings.Split(pw_string, "password ") pw_splitted := strings.Split(pw_string, "password ")
if len(pw_splitted) > 1 { if len(pw_splitted) > 1 {
password_raw := strings.Split(pw_splitted[1], " ")[0] password_raw := strings.Split(pw_splitted[1], " ")[0]
// Get rid of spaces. // Get rid of spaces.
password = strings.TrimSpace(password_raw) password = strings.TrimSpace(password_raw)
} }
} }
Eventer.LaunchEvent("setQuickConnectDetails", map[string]string{"server": server, "password": password}) Eventer.LaunchEvent("setQuickConnectDetails", map[string]string{"server": server, "password": password})
} }
} }

View File

@ -10,76 +10,76 @@
package colorizer package colorizer
import ( import (
// stdlib // stdlib
"fmt" "fmt"
"html" "html"
"strings" "strings"
) )
type Colorizer struct { type Colorizer struct {
// RAW colors to Pango relation. // RAW colors to Pango relation.
colors map[string]string colors map[string]string
} }
func (c *Colorizer) ClearFromMarkup(data string) string { func (c *Colorizer) ClearFromMarkup(data string) string {
var result string = "" var result string = ""
data = html.EscapeString(data) data = html.EscapeString(data)
data_splitted := strings.Split(data, ">") data_splitted := strings.Split(data, ">")
if len(data_splitted) > 1 { if len(data_splitted) > 1 {
for item := range data_splitted { for item := range data_splitted {
if len(data_splitted[item]) > 0 { if len(data_splitted[item]) > 0 {
result += strings.Split(data_splitted[item], "<")[0] result += strings.Split(data_splitted[item], "<")[0]
} }
} }
} else { } else {
result = data_splitted[0] result = data_splitted[0]
} }
return result return result
} }
func (c *Colorizer) Fix(data string) string { func (c *Colorizer) Fix(data string) string {
var result string = "" var result string = ""
data = html.EscapeString(data) data = html.EscapeString(data)
data_splitted := strings.Split(data, "^") data_splitted := strings.Split(data, "^")
if len(data_splitted) > 1 { if len(data_splitted) > 1 {
for item := range data_splitted { for item := range data_splitted {
if len(data_splitted[item]) > 0 { if len(data_splitted[item]) > 0 {
colorcode_raw := string([]rune(data_splitted[item])[0]) colorcode_raw := string([]rune(data_splitted[item])[0])
colorcode, ok := c.colors[colorcode_raw] colorcode, ok := c.colors[colorcode_raw]
if !ok { if !ok {
colorcode = "#000000" colorcode = "#000000"
} }
result += "<span foreground=\"" + colorcode + "\">" + string([]rune(data_splitted[item])[1:]) + "</span>" result += "<span foreground=\"" + colorcode + "\">" + string([]rune(data_splitted[item])[1:]) + "</span>"
} else { } else {
result += data_splitted[item] result += data_splitted[item]
} }
} }
} else { } else {
result = data_splitted[0] result = data_splitted[0]
} }
return "<markup>" + result + "</markup>" return "<markup>" + result + "</markup>"
} }
func (c *Colorizer) Initialize() { func (c *Colorizer) Initialize() {
fmt.Println("Initializing colorizer...") fmt.Println("Initializing colorizer...")
c.initializeStorages() c.initializeStorages()
} }
func (c *Colorizer) initializeStorages() { func (c *Colorizer) initializeStorages() {
c.colors = map[string]string{ c.colors = map[string]string{
"1": "#cc0000", "1": "#cc0000",
"2": "#00cc00", "2": "#00cc00",
"3": "#eeee00", "3": "#eeee00",
"4": "#1c86ee", "4": "#1c86ee",
"5": "#00eeee", "5": "#00eeee",
"6": "#ee00ee", "6": "#ee00ee",
"7": "#000000", "7": "#000000",
"8": "#000000", "8": "#000000",
} }
} }

View File

@ -10,6 +10,6 @@
package colorizer package colorizer
func New() *Colorizer { func New() *Colorizer {
c := Colorizer {} c := Colorizer{}
return &c return &c
} }

View File

@ -10,85 +10,85 @@
package configuration package configuration
import ( import (
// stdlib // stdlib
"fmt" "fmt"
"os" "os"
"path" "path"
"runtime" "runtime"
) )
type Config struct { type Config struct {
// Configuration from database. // Configuration from database.
Cfg map[string]string Cfg map[string]string
// Temporary (or runtime) configuration things. // Temporary (or runtime) configuration things.
TEMP map[string]string TEMP map[string]string
} }
func (c *Config) initializePathsMac() { func (c *Config) initializePathsMac() {
fmt.Println("Initializing configuration paths...") fmt.Println("Initializing configuration paths...")
home_path := os.Getenv("HOME") home_path := os.Getenv("HOME")
data_path := path.Join(home_path, "Library", "Application Support", "URTrator") data_path := path.Join(home_path, "Library", "Application Support", "URTrator")
fmt.Println("Will use data path: " + data_path) fmt.Println("Will use data path: " + data_path)
c.TEMP["DATA"] = data_path c.TEMP["DATA"] = data_path
profile_path := path.Join(home_path, "Library", "Application Support", "Quake3", "q3ut4") profile_path := path.Join(home_path, "Library", "Application Support", "Quake3", "q3ut4")
c.TEMP["DEFAULT_PROFILE_PATH"] = profile_path c.TEMP["DEFAULT_PROFILE_PATH"] = profile_path
if _, err := os.Stat(data_path); os.IsNotExist(err) { if _, err := os.Stat(data_path); os.IsNotExist(err) {
os.MkdirAll(data_path, 0755) os.MkdirAll(data_path, 0755)
} }
} }
func (c *Config) initializePathsNix() { func (c *Config) initializePathsNix() {
fmt.Println("Initializing configuration paths...") fmt.Println("Initializing configuration paths...")
// Get storage path. By default we will use ~/.config/urtrator // Get storage path. By default we will use ~/.config/urtrator
// directory. // directory.
home_path := os.Getenv("HOME") home_path := os.Getenv("HOME")
data_path := path.Join(home_path, ".config", "urtrator") data_path := path.Join(home_path, ".config", "urtrator")
fmt.Println("Will use data path: " + data_path) fmt.Println("Will use data path: " + data_path)
c.TEMP["DATA"] = data_path c.TEMP["DATA"] = data_path
profile_path := path.Join(home_path, ".q3a", "q3ut4") profile_path := path.Join(home_path, ".q3a", "q3ut4")
c.TEMP["DEFAULT_PROFILE_PATH"] = profile_path c.TEMP["DEFAULT_PROFILE_PATH"] = profile_path
if _, err := os.Stat(data_path); os.IsNotExist(err) { if _, err := os.Stat(data_path); os.IsNotExist(err) {
os.MkdirAll(data_path, 0755) os.MkdirAll(data_path, 0755)
} }
} }
func (c *Config) initializePathsWin() { func (c *Config) initializePathsWin() {
fmt.Println("Initializing configuration paths...") fmt.Println("Initializing configuration paths...")
homepath_without_drive := os.Getenv("HOMEPATH") homepath_without_drive := os.Getenv("HOMEPATH")
homedrive := os.Getenv("HOMEDRIVE") homedrive := os.Getenv("HOMEDRIVE")
data_path := path.Join(homedrive, homepath_without_drive, "AppData", "Roaming", "URTrator") data_path := path.Join(homedrive, homepath_without_drive, "AppData", "Roaming", "URTrator")
c.TEMP["DATA"] = data_path c.TEMP["DATA"] = data_path
// Verify it! // Verify it!
profile_path := path.Join(homedrive, homepath_without_drive, "AppData", "UrbanTerror43", "q3ut4") profile_path := path.Join(homedrive, homepath_without_drive, "AppData", "UrbanTerror43", "q3ut4")
c.TEMP["DEFAULT_PROFILE_PATH"] = profile_path c.TEMP["DEFAULT_PROFILE_PATH"] = profile_path
if _, err := os.Stat(data_path); os.IsNotExist(err) { if _, err := os.Stat(data_path); os.IsNotExist(err) {
os.MkdirAll(data_path, 0755) os.MkdirAll(data_path, 0755)
} }
} }
func (c *Config) initializeStorages() { func (c *Config) initializeStorages() {
c.TEMP = make(map[string]string) c.TEMP = make(map[string]string)
c.Cfg = make(map[string]string) c.Cfg = make(map[string]string)
} }
func (c *Config) Initialize() { func (c *Config) Initialize() {
fmt.Println("Initializing configuration storage...") fmt.Println("Initializing configuration storage...")
c.initializeStorages() c.initializeStorages()
if runtime.GOOS == "linux" { if runtime.GOOS == "linux" {
c.initializePathsNix() c.initializePathsNix()
} else if runtime.GOOS == "darwin" { } else if runtime.GOOS == "darwin" {
c.initializePathsMac() c.initializePathsMac()
} else if runtime.GOOS == "windows" { } else if runtime.GOOS == "windows" {
c.initializePathsWin() c.initializePathsWin()
} else { } else {
panic("We're not ready for other OSes yet!") panic("We're not ready for other OSes yet!")
} }
} }

View File

@ -10,6 +10,6 @@
package configuration package configuration
func New() *Config { func New() *Config {
c := Config{} c := Config{}
return &c return &c
} }

View File

@ -10,6 +10,6 @@
package context package context
func New() *Context { func New() *Context {
c := Context{} c := Context{}
return &c return &c
} }

View File

@ -10,8 +10,8 @@
package database package database
import ( import (
// stdlib // stdlib
"fmt" "fmt"
) )
var start_schema = ` var start_schema = `
@ -39,95 +39,128 @@ INSERT INTO database (version) VALUES (1);
// Migrate database to latest version. // Migrate database to latest version.
// ToDo: make it more good :). // ToDo: make it more good :).
func migrate_full(db *Database, version int) { func migrate_full(db *Database, version int) {
if version < 1 {start_to_one(db); version = 1} if version < 1 {
if version == 1 {one_to_two(db); version = 2} start_to_one(db)
if version == 2 {two_to_three(db); version = 3} version = 1
if version == 3 {three_to_four(db); version = 4} }
if version == 4 {four_to_five(db); version = 5} if version == 1 {
if version == 5 {five_to_six(db); version = 6 } one_to_two(db)
if version == 6 {six_to_seven(db); version = 7} version = 2
if version == 7 {seven_to_eight(db); version = 8} }
if version == 8 {eight_to_nine(db); version = 9} if version == 2 {
if version == 9 {nine_to_ten(db); version = 10} two_to_three(db)
if version == 10 {ten_to_eleven(db); version = 11} version = 3
}
if version == 3 {
three_to_four(db)
version = 4
}
if version == 4 {
four_to_five(db)
version = 5
}
if version == 5 {
five_to_six(db)
version = 6
}
if version == 6 {
six_to_seven(db)
version = 7
}
if version == 7 {
seven_to_eight(db)
version = 8
}
if version == 8 {
eight_to_nine(db)
version = 9
}
if version == 9 {
nine_to_ten(db)
version = 10
}
if version == 10 {
ten_to_eleven(db)
version = 11
}
} }
// Initial database structure. // Initial database structure.
func start_to_one(db *Database) { func start_to_one(db *Database) {
fmt.Println("Upgrading database from 0 to 1...") fmt.Println("Upgrading database from 0 to 1...")
db.Db.MustExec(start_schema) db.Db.MustExec(start_schema)
} }
// Favorite server mark. // Favorite server mark.
func one_to_two(db *Database) { func one_to_two(db *Database) {
fmt.Println("Upgrading database from 1 to 2...") fmt.Println("Upgrading database from 1 to 2...")
db.Db.MustExec("ALTER TABLE servers ADD favorite VARCHAR(1) DEFAULT '0'") db.Db.MustExec("ALTER TABLE servers ADD favorite VARCHAR(1) DEFAULT '0'")
db.Db.MustExec("UPDATE database SET version=2") db.Db.MustExec("UPDATE database SET version=2")
} }
// URTRator settings and Urban Terror profiles. // URTRator settings and Urban Terror profiles.
func two_to_three(db *Database) { func two_to_three(db *Database) {
fmt.Println("Upgrading database from 2 to 3...") fmt.Println("Upgrading database from 2 to 3...")
db.Db.MustExec("DROP TABLE IF EXISTS settings") db.Db.MustExec("DROP TABLE IF EXISTS settings")
db.Db.MustExec("CREATE TABLE settings (show_tray_icon VARCHAR(1) NOT NULL DEFAULT '0', enable_autoupdate VARCHAR(1) NOT NULL DEFAULT '0')") db.Db.MustExec("CREATE TABLE settings (show_tray_icon VARCHAR(1) NOT NULL DEFAULT '0', enable_autoupdate VARCHAR(1) NOT NULL DEFAULT '0')")
db.Db.MustExec("DROP TABLE IF EXISTS urt_profiles") db.Db.MustExec("DROP TABLE IF EXISTS urt_profiles")
db.Db.MustExec("CREATE TABLE urt_profiles (name VARCHAR(128) NOT NULL, version VARCHAR(5) NOT NULL DEFAULT '4.3', binary VARCHAR(1024) NOT NULL, second_x_session VARCHAR(1) NOT NULL DEFAULT '0', additional_parameters VARCHAR(1024) NOT NULL DEFAULT '')") db.Db.MustExec("CREATE TABLE urt_profiles (name VARCHAR(128) NOT NULL, version VARCHAR(5) NOT NULL DEFAULT '4.3', binary VARCHAR(1024) NOT NULL, second_x_session VARCHAR(1) NOT NULL DEFAULT '0', additional_parameters VARCHAR(1024) NOT NULL DEFAULT '')")
db.Db.MustExec("UPDATE database SET version=3") db.Db.MustExec("UPDATE database SET version=3")
} }
// UrT version inconsistency. // UrT version inconsistency.
func three_to_four(db *Database) { func three_to_four(db *Database) {
fmt.Println("Upgrading database from 3 to 4...") fmt.Println("Upgrading database from 3 to 4...")
db.Db.MustExec("UPDATE urt_profiles SET version='4.3.0' WHERE version='4.3.000'") db.Db.MustExec("UPDATE urt_profiles SET version='4.3.0' WHERE version='4.3.000'")
db.Db.MustExec("UPDATE database SET version=4") db.Db.MustExec("UPDATE database SET version=4")
} }
// Server's passwords. // Server's passwords.
func four_to_five(db *Database) { func four_to_five(db *Database) {
fmt.Println("Upgrading database from 4 to 5...") fmt.Println("Upgrading database from 4 to 5...")
db.Db.MustExec("ALTER TABLE servers ADD password VARCHAR(64) DEFAULT ''") db.Db.MustExec("ALTER TABLE servers ADD password VARCHAR(64) DEFAULT ''")
db.Db.MustExec("UPDATE database SET version=5") db.Db.MustExec("UPDATE database SET version=5")
} }
// Profile for server. // Profile for server.
func five_to_six(db *Database) { func five_to_six(db *Database) {
fmt.Println("Upgrading database from 5 to 6...") fmt.Println("Upgrading database from 5 to 6...")
db.Db.MustExec("ALTER TABLE servers ADD profile_to_use VARCHAR(128) DEFAULT ''") db.Db.MustExec("ALTER TABLE servers ADD profile_to_use VARCHAR(128) DEFAULT ''")
db.Db.MustExec("UPDATE database SET version=6") db.Db.MustExec("UPDATE database SET version=6")
} }
// Configuration storage. // Configuration storage.
func six_to_seven(db *Database) { func six_to_seven(db *Database) {
fmt.Println("Upgrading database from 6 to 7...") fmt.Println("Upgrading database from 6 to 7...")
db.Db.MustExec("CREATE TABLE configuration (key VARCHAR(128) NOT NULL, value VARCHAR(1024) NOT NULL)") db.Db.MustExec("CREATE TABLE configuration (key VARCHAR(128) NOT NULL, value VARCHAR(1024) NOT NULL)")
db.Db.MustExec("UPDATE database SET version=7") db.Db.MustExec("UPDATE database SET version=7")
} }
// Server's extended information. // Server's extended information.
func seven_to_eight(db *Database) { func seven_to_eight(db *Database) {
fmt.Println("Upgrading database from 7 to 8...") fmt.Println("Upgrading database from 7 to 8...")
db.Db.MustExec("ALTER TABLE servers ADD extended_config VARCHAR(4096) NOT NULL DEFAULT ''") db.Db.MustExec("ALTER TABLE servers ADD extended_config VARCHAR(4096) NOT NULL DEFAULT ''")
db.Db.MustExec("ALTER TABLE servers ADD players_info VARCHAR(8192) NOT NULL DEFAULT ''") db.Db.MustExec("ALTER TABLE servers ADD players_info VARCHAR(8192) NOT NULL DEFAULT ''")
db.Db.MustExec("UPDATE database SET version=8") db.Db.MustExec("UPDATE database SET version=8")
} }
// Is server private flag. // Is server private flag.
func eight_to_nine(db *Database) { func eight_to_nine(db *Database) {
fmt.Println("Upgrading database from 8 to 9...") fmt.Println("Upgrading database from 8 to 9...")
db.Db.MustExec("ALTER TABLE servers ADD is_private VARCHAR(1) NOT NULL DEFAULT '0'") db.Db.MustExec("ALTER TABLE servers ADD is_private VARCHAR(1) NOT NULL DEFAULT '0'")
db.Db.MustExec("UPDATE database SET version=9") db.Db.MustExec("UPDATE database SET version=9")
} }
// Bots count. // Bots count.
func nine_to_ten(db *Database) { func nine_to_ten(db *Database) {
fmt.Println("Upgrading database from 9 to 10...") fmt.Println("Upgrading database from 9 to 10...")
db.Db.MustExec("ALTER TABLE servers ADD bots VARCHAR(2) NOT NULL DEFAULT '0'") db.Db.MustExec("ALTER TABLE servers ADD bots VARCHAR(2) NOT NULL DEFAULT '0'")
db.Db.MustExec("UPDATE database SET version=10") db.Db.MustExec("UPDATE database SET version=10")
} }
// Urban terror's profile path. // Urban terror's profile path.
func ten_to_eleven(db *Database) { func ten_to_eleven(db *Database) {
fmt.Println("Upgrading database from 10 to 11...") fmt.Println("Upgrading database from 10 to 11...")
db.Db.MustExec("ALTER TABLE urt_profiles ADD profile_path VARCHAR(4096) NOT NULL DEFAULT '~/.q3ut4'") db.Db.MustExec("ALTER TABLE urt_profiles ADD profile_path VARCHAR(4096) NOT NULL DEFAULT '~/.q3ut4'")
db.Db.MustExec("UPDATE database SET version=11") db.Db.MustExec("UPDATE database SET version=11")
} }

View File

@ -10,6 +10,6 @@
package datamodels package datamodels
type Configuration struct { type Configuration struct {
Key string `db:"key"` Key string `db:"key"`
Value string `db:"value"` Value string `db:"value"`
} }

View File

@ -10,5 +10,5 @@
package datamodels package datamodels
type Database struct { type Database struct {
Version string `db:"version"` Version string `db:"version"`
} }

View File

@ -10,16 +10,16 @@
package datamodels package datamodels
type Profile struct { type Profile struct {
// Profile name. // Profile name.
Name string `db:"name"` Name string `db:"name"`
// Game version. // Game version.
Version string `db:"version"` Version string `db:"version"`
// Binary path. // Binary path.
Binary string `db:"binary"` Binary string `db:"binary"`
// Will we use second X session? // Will we use second X session?
Second_x_session string `db:"second_x_session"` Second_x_session string `db:"second_x_session"`
// Additional game parameters we will pass. // Additional game parameters we will pass.
Additional_params string `db:"additional_parameters"` Additional_params string `db:"additional_parameters"`
// Profile path. // Profile path.
Profile_path string `db:"profile_path"` Profile_path string `db:"profile_path"`
} }

View File

@ -10,36 +10,36 @@
package datamodels package datamodels
type Server struct { type Server struct {
// Server's address // Server's address
Ip string `db:"ip"` Ip string `db:"ip"`
// Server's port // Server's port
Port string `db:"port"` Port string `db:"port"`
// Server's name // Server's name
Name string `db:"name"` Name string `db:"name"`
// Current players count // Current players count
Players string `db:"players"` Players string `db:"players"`
// Bots count // Bots count
Bots string `db:"bots"` Bots string `db:"bots"`
// Maximum players // Maximum players
Maxplayers string `db:"maxplayers"` Maxplayers string `db:"maxplayers"`
// Ping // Ping
Ping string `db:"ping"` Ping string `db:"ping"`
// Gametype. See Urban Terror documentation on relationship. // Gametype. See Urban Terror documentation on relationship.
Gamemode string `db:"gamemode"` Gamemode string `db:"gamemode"`
// Current map // Current map
Map string `db:"map"` Map string `db:"map"`
// Server's software version // Server's software version
Version string `db:"version"` Version string `db:"version"`
// Is server was favorited? // Is server was favorited?
Favorite string `db:"favorite"` Favorite string `db:"favorite"`
// Server's password. // Server's password.
Password string `db:"password"` Password string `db:"password"`
// Profile to use with server. // Profile to use with server.
ProfileToUse string `db:"profile_to_use"` ProfileToUse string `db:"profile_to_use"`
// Extended server's configuration. // Extended server's configuration.
ExtendedConfig string `db:"extended_config"` ExtendedConfig string `db:"extended_config"`
// Players information. // Players information.
PlayersInfo string `db:"players_info"` PlayersInfo string `db:"players_info"`
// Is server private? // Is server private?
IsPrivate string `db:"is_private"` IsPrivate string `db:"is_private"`
} }

View File

@ -10,66 +10,66 @@
package eventer package eventer
import ( import (
crand "crypto/rand" crand "crypto/rand"
"errors" "errors"
"fmt" "fmt"
//"reflect" //"reflect"
// github // github
"github.com/mattn/go-gtk/glib" "github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk" "github.com/mattn/go-gtk/gtk"
) )
type Eventer struct { type Eventer struct {
// Events // Events
events map[string]map[string]func(data map[string]string) events map[string]map[string]func(data map[string]string)
} }
func (e *Eventer) AddEventHandler(event string, handler func(data map[string]string)) { func (e *Eventer) AddEventHandler(event string, handler func(data map[string]string)) {
_, ok := e.events[event] _, ok := e.events[event]
if !ok { if !ok {
e.events[event] = make(map[string]func(data map[string]string)) e.events[event] = make(map[string]func(data map[string]string))
} }
event_id_raw := make([]byte, 16) event_id_raw := make([]byte, 16)
crand.Read(event_id_raw) crand.Read(event_id_raw)
event_id := fmt.Sprintf("%x", event_id_raw) event_id := fmt.Sprintf("%x", event_id_raw)
e.events[event][event_id] = handler e.events[event][event_id] = handler
} }
func (e *Eventer) Initialize() { func (e *Eventer) Initialize() {
e.initializeStorage() e.initializeStorage()
} }
func (e *Eventer) initializeStorage() { func (e *Eventer) initializeStorage() {
e.events = make(map[string]map[string]func(data map[string]string)) e.events = make(map[string]map[string]func(data map[string]string))
} }
func (e *Eventer) LaunchEvent(event string, data map[string]string) error { func (e *Eventer) LaunchEvent(event string, data map[string]string) error {
_, ok := e.events[event] _, ok := e.events[event]
if !ok { if !ok {
return errors.New("Event " + event + " not found!") return errors.New("Event " + event + " not found!")
} }
fmt.Println("Launching event " + event) fmt.Println("Launching event " + event)
glib.IdleAdd(func() bool { glib.IdleAdd(func() bool {
e.reallyLaunchEvent(event, data) e.reallyLaunchEvent(event, data)
return false return false
}) })
for { for {
if gtk.EventsPending() { if gtk.EventsPending() {
gtk.MainIteration() gtk.MainIteration()
} else { } else {
break break
} }
} }
return nil return nil
} }
func (e *Eventer) reallyLaunchEvent(event string, data map[string]string) { func (e *Eventer) reallyLaunchEvent(event string, data map[string]string) {
fmt.Println("Really launching event " + event + "...") fmt.Println("Really launching event " + event + "...")
for _, val := range e.events[event] { for _, val := range e.events[event] {
val(data) val(data)
} }
} }

View File

@ -10,6 +10,6 @@
package eventer package eventer
func New() *Eventer { func New() *Eventer {
e := Eventer{} e := Eventer{}
return &e return &e
} }

View File

@ -10,39 +10,39 @@
package ioq3dataparser package ioq3dataparser
import ( import (
// stdlib // stdlib
"strings" "strings"
) )
func ParseInfoToMap(data string) map[string]string { func ParseInfoToMap(data string) map[string]string {
parsed_data := make(map[string]string) parsed_data := make(map[string]string)
srv_config := strings.Split(data, "\\") srv_config := strings.Split(data, "\\")
srv_config = srv_config[1:] srv_config = srv_config[1:]
// Parse server configuration into passed server's datamodel. // Parse server configuration into passed server's datamodel.
for i := 0; i < len(srv_config[1:]); i = i + 2 { for i := 0; i < len(srv_config[1:]); i = i + 2 {
parsed_data[srv_config[i]] = srv_config[i + 1] parsed_data[srv_config[i]] = srv_config[i+1]
} }
return parsed_data return parsed_data
} }
func ParsePlayersInfoToMap(data string) map[string]map[string]string { func ParsePlayersInfoToMap(data string) map[string]map[string]string {
parsed_data := make(map[string]map[string]string) parsed_data := make(map[string]map[string]string)
// Structure: frags|ping|nick // Structure: frags|ping|nick
raw_data := strings.Split(data, "\\") raw_data := strings.Split(data, "\\")
for i := range raw_data { for i := range raw_data {
raw_player_data := strings.Split(raw_data[i], " ") raw_player_data := strings.Split(raw_data[i], " ")
player_data := make(map[string]string) player_data := make(map[string]string)
if len(raw_player_data) > 1 { if len(raw_player_data) > 1 {
nickname := strings.Join(raw_player_data[2:], " ") nickname := strings.Join(raw_player_data[2:], " ")
player_data["nick"] = string([]byte(nickname)[1:len(nickname)-1]) player_data["nick"] = string([]byte(nickname)[1 : len(nickname)-1])
player_data["ping"] = raw_player_data[1] player_data["ping"] = raw_player_data[1]
player_data["frags"] = raw_player_data[0] player_data["frags"] = raw_player_data[0]
parsed_data[player_data["nick"]] = player_data parsed_data[player_data["nick"]] = player_data
} }
} }
return parsed_data return parsed_data
} }

View File

@ -10,6 +10,6 @@
package launcher package launcher
func New() *Launcher { func New() *Launcher {
l := Launcher{} l := Launcher{}
return &l return &l
} }

View File

@ -10,121 +10,121 @@
package timer package timer
import ( import (
// stdlib // stdlib
"errors" "errors"
"fmt" "fmt"
"strconv" "strconv"
"sync" "sync"
"time" "time"
) )
type Timer struct { type Timer struct {
// Tasks. // Tasks.
tasks map[string]*TimerTask tasks map[string]*TimerTask
// Tasks map mutex. // Tasks map mutex.
tasksMutex sync.Mutex tasksMutex sync.Mutex
} }
func (t *Timer) AddTask(task *TimerTask) error { func (t *Timer) AddTask(task *TimerTask) error {
fmt.Println("Adding task '" + task.Name + "'...") fmt.Println("Adding task '" + task.Name + "'...")
_, ok := t.tasks[task.Name] _, ok := t.tasks[task.Name]
if ok { if ok {
error_text := "Task '" + task.Name + "' already exist! Ignoring..." error_text := "Task '" + task.Name + "' already exist! Ignoring..."
fmt.Println(error_text) fmt.Println(error_text)
return errors.New(error_text) return errors.New(error_text)
} }
task.InProgress = false task.InProgress = false
curtime := time.Now() curtime := time.Now()
nextlaunch := curtime.Add(time.Duration(task.Timeout) * time.Second) nextlaunch := curtime.Add(time.Duration(task.Timeout) * time.Second)
task.NextLaunch = nextlaunch task.NextLaunch = nextlaunch
t.tasksMutex.Lock() t.tasksMutex.Lock()
t.tasks[task.Name] = task t.tasks[task.Name] = task
t.tasksMutex.Unlock() t.tasksMutex.Unlock()
fmt.Println("Added task '" + task.Name + "' with " + strconv.Itoa(task.Timeout) + " seconds timeout") fmt.Println("Added task '" + task.Name + "' with " + strconv.Itoa(task.Timeout) + " seconds timeout")
return nil return nil
} }
func (t *Timer) executeTasks() { func (t *Timer) executeTasks() {
t.tasksMutex.Lock() t.tasksMutex.Lock()
for task_name, task := range t.tasks { for task_name, task := range t.tasks {
// Check if task should be run. // Check if task should be run.
curtime := time.Now() curtime := time.Now()
diff := curtime.Sub(task.NextLaunch) diff := curtime.Sub(task.NextLaunch)
//fmt.Println(diff) //fmt.Println(diff)
if diff > 0 { if diff > 0 {
fmt.Println("Checking task '" + task_name + "'...") fmt.Println("Checking task '" + task_name + "'...")
// Check if task is already running. // Check if task is already running.
if task.InProgress { if task.InProgress {
fmt.Println("Already executing, skipping...") fmt.Println("Already executing, skipping...")
continue continue
} }
fmt.Println("Launching task '" + task_name + "'...") fmt.Println("Launching task '" + task_name + "'...")
task.InProgress = true task.InProgress = true
Eventer.LaunchEvent(task.Callee, map[string]string{}) Eventer.LaunchEvent(task.Callee, map[string]string{})
curtime = time.Now() curtime = time.Now()
nextlaunch := curtime.Add(time.Duration(task.Timeout) * time.Second) nextlaunch := curtime.Add(time.Duration(task.Timeout) * time.Second)
task.NextLaunch = nextlaunch task.NextLaunch = nextlaunch
} }
} }
t.tasksMutex.Unlock() t.tasksMutex.Unlock()
} }
func (t *Timer) GetTaskStatus(task_name string) bool { func (t *Timer) GetTaskStatus(task_name string) bool {
t.tasksMutex.Lock() t.tasksMutex.Lock()
task, ok := t.tasks[task_name] task, ok := t.tasks[task_name]
t.tasksMutex.Unlock() t.tasksMutex.Unlock()
if !ok { if !ok {
return false return false
} }
return task.InProgress return task.InProgress
} }
func (t *Timer) Initialize() { func (t *Timer) Initialize() {
fmt.Println("Initializing timer...") fmt.Println("Initializing timer...")
t.initializeStorage() t.initializeStorage()
Eventer.AddEventHandler("taskDone", t.SetTaskNotInProgress) Eventer.AddEventHandler("taskDone", t.SetTaskNotInProgress)
ticker := time.NewTicker(time.Second * 1) ticker := time.NewTicker(time.Second * 1)
go func() { go func() {
for _ = range ticker.C { for _ = range ticker.C {
go t.executeTasks() go t.executeTasks()
} }
}() }()
} }
func (t *Timer) initializeStorage() { func (t *Timer) initializeStorage() {
t.tasks = make(map[string]*TimerTask) t.tasks = make(map[string]*TimerTask)
} }
func (t *Timer) RemoveTask(task_name string) { func (t *Timer) RemoveTask(task_name string) {
t.tasksMutex.Lock() t.tasksMutex.Lock()
_, ok := t.tasks[task_name] _, ok := t.tasks[task_name]
t.tasksMutex.Unlock() t.tasksMutex.Unlock()
if !ok { if !ok {
return return
} }
t.tasksMutex.Lock() t.tasksMutex.Lock()
delete(t.tasks, task_name) delete(t.tasks, task_name)
t.tasksMutex.Unlock() t.tasksMutex.Unlock()
} }
func (t *Timer) SetTaskNotInProgress(data map[string]string) { func (t *Timer) SetTaskNotInProgress(data map[string]string) {
t.tasksMutex.Lock() t.tasksMutex.Lock()
_, ok := t.tasks[data["task_name"]] _, ok := t.tasks[data["task_name"]]
if !ok { if !ok {
return return
} }
t.tasks[data["task_name"]].InProgress = false t.tasks[data["task_name"]].InProgress = false
t.tasksMutex.Unlock() t.tasksMutex.Unlock()
} }

View File

@ -10,25 +10,25 @@
package timer package timer
import ( import (
// stdlib // stdlib
"time" "time"
) )
type TimerTask struct { type TimerTask struct {
// Task name. // Task name.
Name string Name string
// Task timeout, in seconds. // Task timeout, in seconds.
Timeout int Timeout int
// What we should call? // What we should call?
// This should be an event name. // This should be an event name.
Callee string Callee string
// Internal variables, used by Timer. // Internal variables, used by Timer.
// These variables can be defined, but they will be most likely // These variables can be defined, but they will be most likely
// overrided after first task launch. // overrided after first task launch.
// Next task launch time. // Next task launch time.
NextLaunch time.Time NextLaunch time.Time
// Is task currently executed? // Is task currently executed?
// Kinda alternative to mutex. // Kinda alternative to mutex.
InProgress bool InProgress bool
} }

View File

@ -14,23 +14,23 @@
package translator package translator
import ( import (
// stdlib // stdlib
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"strings" "strings"
) )
type Translator struct { type Translator struct {
// Accepted languages. // Accepted languages.
AcceptedLanguages map[string]string AcceptedLanguages map[string]string
// Currently active language. // Currently active language.
Language string Language string
// Translations. // Translations.
translations map[string]map[string]string translations map[string]map[string]string
// Path to translations files. // Path to translations files.
translationsPath string translationsPath string
} }
// Formats string from passed map. // Formats string from passed map.
@ -50,73 +50,73 @@ type Translator struct {
// Also note that we will replace ALL occurences of "{{ VAR }}" within string! // Also note that we will replace ALL occurences of "{{ VAR }}" within string!
// All untranslated variables will not be touched at all. // All untranslated variables will not be touched at all.
func (t *Translator) formatFromMap(data string, params map[string]string) string { func (t *Translator) formatFromMap(data string, params map[string]string) string {
new_data := data new_data := data
for k, v := range params { for k, v := range params {
new_data = strings.Replace(new_data, "{{ " + k + " }}", v, -1) new_data = strings.Replace(new_data, "{{ "+k+" }}", v, -1)
} }
return new_data return new_data
} }
// Translator initialization. // Translator initialization.
func (t *Translator) Initialize() { func (t *Translator) Initialize() {
fmt.Println("Initializing translations...") fmt.Println("Initializing translations...")
t.AcceptedLanguages = map[string]string{ t.AcceptedLanguages = map[string]string{
"System's default language": "default", "System's default language": "default",
"English": "en_US", "English": "en_US",
"French": "fr_FR", "French": "fr_FR",
"Russian": "ru_RU", "Russian": "ru_RU",
} }
// Initialize storages. // Initialize storages.
t.translations = make(map[string]map[string]string) t.translations = make(map[string]map[string]string)
t.translationsPath = "" t.translationsPath = ""
// Getting locale name from environment. // Getting locale name from environment.
// ToDo: Windows compatability. Possible reference: // ToDo: Windows compatability. Possible reference:
// https://github.com/cloudfoundry-attic/jibber_jabber/blob/master/jibber_jabber_windows.go // https://github.com/cloudfoundry-attic/jibber_jabber/blob/master/jibber_jabber_windows.go
t.detectLanguage() t.detectLanguage()
fmt.Println("Using translations for '" + t.Language + "'") fmt.Println("Using translations for '" + t.Language + "'")
err := t.detectTranslationsDirectory() err := t.detectTranslationsDirectory()
if err == nil { if err == nil {
t.loadTranslations() t.loadTranslations()
} else { } else {
fmt.Println("Skipping translations loading due to missing translations directory.") fmt.Println("Skipping translations loading due to missing translations directory.")
} }
} }
// Load translations into memory. // Load translations into memory.
func (t *Translator) loadTranslations() { func (t *Translator) loadTranslations() {
fmt.Println("Loading translations for language " + t.Language) fmt.Println("Loading translations for language " + t.Language)
fmt.Println("Translations directory: " + t.translationsPath) fmt.Println("Translations directory: " + t.translationsPath)
t.translations[t.Language] = make(map[string]string) t.translations[t.Language] = make(map[string]string)
if t.translationsPath != "" { if t.translationsPath != "" {
// Check if language was selected in options dialog. In that // Check if language was selected in options dialog. In that
// case it will overwrite autodetected language. // case it will overwrite autodetected language.
var translationsDir string = "" var translationsDir string = ""
if cfg.Cfg["/general/language"] != "" { if cfg.Cfg["/general/language"] != "" {
translationsDir = filepath.Join(t.translationsPath, cfg.Cfg["/general/language"]) translationsDir = filepath.Join(t.translationsPath, cfg.Cfg["/general/language"])
t.Language = cfg.Cfg["/general/language"] t.Language = cfg.Cfg["/general/language"]
} else { } else {
translationsDir = filepath.Join(t.translationsPath, t.Language) translationsDir = filepath.Join(t.translationsPath, t.Language)
} }
files_list, _ := ioutil.ReadDir(translationsDir) files_list, _ := ioutil.ReadDir(translationsDir)
if len(files_list) > 0 { if len(files_list) > 0 {
for i := range files_list { for i := range files_list {
// Read file. // Read file.
file_path := filepath.Join(translationsDir, files_list[i].Name()) file_path := filepath.Join(translationsDir, files_list[i].Name())
file_data, _ := ioutil.ReadFile(file_path) file_data, _ := ioutil.ReadFile(file_path)
var trans map[string]string var trans map[string]string
json.Unmarshal(file_data, &trans) json.Unmarshal(file_data, &trans)
// Assign parsed translations to language code. // Assign parsed translations to language code.
t.translations[t.Language] = trans t.translations[t.Language] = trans
} }
} }
} }
} }
// Actual translation function. // Actual translation function.
@ -129,18 +129,18 @@ func (t *Translator) loadTranslations() {
// Translates passed data from loaded translations file. // Translates passed data from loaded translations file.
// Returns passed data without changes if translation wasn't found. // Returns passed data without changes if translation wasn't found.
func (t *Translator) Translate(data string, params map[string]string) string { func (t *Translator) Translate(data string, params map[string]string) string {
val, ok := t.translations[t.Language][data] val, ok := t.translations[t.Language][data]
if !ok { if !ok {
if params != nil && len(params) > 0 { if params != nil && len(params) > 0 {
return t.formatFromMap(data, params) return t.formatFromMap(data, params)
} else { } else {
return data return data
} }
} }
if params != nil && len(params) > 0 { if params != nil && len(params) > 0 {
return t.formatFromMap(val, params) return t.formatFromMap(val, params)
} }
return val return val
} }

View File

@ -22,64 +22,64 @@
package translator package translator
import ( import (
// stdlib // stdlib
"errors" "errors"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
) )
// Detect language on Unices. // Detect language on Unices.
func (t *Translator) detectLanguage() { func (t *Translator) detectLanguage() {
// Use LC_ALL first. // Use LC_ALL first.
t.Language = os.Getenv("LC_ALL") t.Language = os.Getenv("LC_ALL")
// If LC_ALL is empty - use LANG. // If LC_ALL is empty - use LANG.
if t.Language == "" { if t.Language == "" {
t.Language = os.Getenv("LANG") t.Language = os.Getenv("LANG")
} }
// If still nothing - force "en_US" as default locale. Otherwise // If still nothing - force "en_US" as default locale. Otherwise
// split language string by "." and take first part. // split language string by "." and take first part.
// Note: en_US is a default thing, so you will not found anything // Note: en_US is a default thing, so you will not found anything
// in "translations" directory! // in "translations" directory!
if t.Language == "" { if t.Language == "" {
fmt.Println("No locale data for current user found, using default (en_US)...") fmt.Println("No locale data for current user found, using default (en_US)...")
t.Language = "en_US" t.Language = "en_US"
} else { } else {
t.Language = strings.Split(t.Language, ".")[0] t.Language = strings.Split(t.Language, ".")[0]
} }
} }
func (t *Translator) detectTranslationsDirectory() error { func (t *Translator) detectTranslationsDirectory() error {
// Try to use directory near binary. // Try to use directory near binary.
dir, _ := filepath.Abs(filepath.Dir(os.Args[0])) dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
// ..which can be overriden by URTRATOR_BINDIR environment variable. // ..which can be overriden by URTRATOR_BINDIR environment variable.
// Useful for developers. // Useful for developers.
envdir := os.Getenv("URTRATOR_BINDIR") envdir := os.Getenv("URTRATOR_BINDIR")
if envdir != "" { if envdir != "" {
dir = envdir dir = envdir
} }
translations_dir := filepath.Join(dir, "translations") translations_dir := filepath.Join(dir, "translations")
_, err := os.Stat(translations_dir) _, err := os.Stat(translations_dir)
if err != nil { if err != nil {
fmt.Println("Translations wasn't found near binary!") fmt.Println("Translations wasn't found near binary!")
// As we're using JSON translation storage, it should be // As we're using JSON translation storage, it should be
// put in /usr/share/urtrator/translations by package // put in /usr/share/urtrator/translations by package
// maintainers in distros. // maintainers in distros.
fmt.Println("Trying /usr/share/urtrator/translations...") fmt.Println("Trying /usr/share/urtrator/translations...")
_, err := os.Stat("/usr/share/urtrator/translations") _, err := os.Stat("/usr/share/urtrator/translations")
if err != nil { if err != nil {
t.Language = "en_US" t.Language = "en_US"
fmt.Println("Translations unavailable, forcing en_US language code") fmt.Println("Translations unavailable, forcing en_US language code")
return errors.New("No translations directory was detected!") return errors.New("No translations directory was detected!")
} else { } else {
t.translationsPath = "/usr/share/urtrator/translations" t.translationsPath = "/usr/share/urtrator/translations"
} }
} else { } else {
t.translationsPath = translations_dir t.translationsPath = translations_dir
} }
return nil return nil
} }

View File

@ -22,23 +22,23 @@
package translator package translator
import ( import (
// stdlib // stdlib
"fmt" "fmt"
"path/filepath" "os"
"os" "path/filepath"
) )
// Detect language on Windows. // Detect language on Windows.
func (t *Translator) detectLanguage() { func (t *Translator) detectLanguage() {
fmt.Println("ToDo! Forcing en_US for now!") fmt.Println("ToDo! Forcing en_US for now!")
t.Language = "en_US" t.Language = "en_US"
} }
func (t *Translator) detectTranslationsDirectory() error { func (t *Translator) detectTranslationsDirectory() error {
// Translations MUST reside in directory neear binary! // Translations MUST reside in directory neear binary!
// ToDo: more checks. // ToDo: more checks.
dir, _ := filepath.Abs(filepath.Dir(os.Args[0])) dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
t.translationsPath = filepath.Join(dir, "translations") t.translationsPath = filepath.Join(dir, "translations")
return nil return nil
} }

View File

@ -1,47 +1,47 @@
package ui package ui
import ( import (
// stdlib // stdlib
"strings" "strings"
// other // other
"github.com/mattn/go-gtk/glib" "github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk" "github.com/mattn/go-gtk/gtk"
) )
func (m *MainWindow) getGameModeName(name string) string { func (m *MainWindow) getGameModeName(name string) string {
val, ok := m.gamemodes[name] val, ok := m.gamemodes[name]
if !ok { if !ok {
return "Unknown or custom" return "Unknown or custom"
} }
return val return val
} }
func (m *MainWindow) getIpFromServersList(current_tab string) string { func (m *MainWindow) getIpFromServersList(current_tab string) string {
// Getting server's address from list. // Getting server's address from list.
// Assuming that we're on "Servers" tab by default. // Assuming that we're on "Servers" tab by default.
sel := m.all_servers.GetSelection() sel := m.all_servers.GetSelection()
model := m.all_servers.GetModel() model := m.all_servers.GetModel()
if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) { if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
sel = m.fav_servers.GetSelection() sel = m.fav_servers.GetSelection()
model = m.fav_servers.GetModel() model = m.fav_servers.GetModel()
} }
iter := new(gtk.TreeIter) iter := new(gtk.TreeIter)
_ = sel.GetSelected(iter) _ = sel.GetSelected(iter)
// Getting server address. // Getting server address.
var srv_addr string var srv_addr string
srv_addr_gval := glib.ValueFromNative(srv_addr) srv_addr_gval := glib.ValueFromNative(srv_addr)
if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) { if strings.Contains(current_tab, ctx.Translator.Translate("Servers", nil)) {
model.GetValue(iter, m.column_pos["Servers"]["IP"], srv_addr_gval) model.GetValue(iter, m.column_pos["Servers"]["IP"], srv_addr_gval)
} else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) { } else if strings.Contains(current_tab, ctx.Translator.Translate("Favorites", nil)) {
model.GetValue(iter, m.column_pos["Favorites"]["IP"], srv_addr_gval) model.GetValue(iter, m.column_pos["Favorites"]["IP"], srv_addr_gval)
} }
server_address := srv_addr_gval.GetString() server_address := srv_addr_gval.GetString()
return server_address return server_address
} }

View File

@ -10,16 +10,16 @@
package ui package ui
import ( import (
// local // local
"github.com/pztrn/urtrator/context" "github.com/pztrn/urtrator/context"
) )
var ( var (
ctx *context.Context ctx *context.Context
) )
func NewMainWindow(c *context.Context) *MainWindow { func NewMainWindow(c *context.Context) *MainWindow {
ctx = c ctx = c
m := MainWindow{} m := MainWindow{}
return &m return &m
} }

View File

@ -10,109 +10,108 @@
package ui package ui
import ( import (
// stdlib // stdlib
"fmt" "fmt"
//"runtime" //"runtime"
//"sort" //"sort"
//"strconv" //"strconv"
//"strings" //"strings"
// Local // Local
//"github.com/pztrn/urtrator/datamodels" //"github.com/pztrn/urtrator/datamodels"
//"github.com/pztrn/urtrator/ioq3dataparser" //"github.com/pztrn/urtrator/ioq3dataparser"
// github // github
"github.com/therecipe/qt/widgets" "github.com/therecipe/qt/widgets"
) )
type MainWindow struct { type MainWindow struct {
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Main widgets and pointers. // Main widgets and pointers.
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Application. // Application.
app *widgets.QApplication app *widgets.QApplication
// Main window. // Main window.
window *widgets.QMainWindow window *widgets.QMainWindow
// Main menu. // Main menu.
mainmenu *widgets.QMenuBar mainmenu *widgets.QMenuBar
// Main vertical box. // Main vertical box.
vbox *widgets.QVBoxLayout vbox *widgets.QVBoxLayout
// Toolbar. // Toolbar.
toolbar *widgets.QToolBar toolbar *widgets.QToolBar
// Splitter. // Splitter.
splitter *widgets.QSplitter splitter *widgets.QSplitter
// Tabs widget. // Tabs widget.
tabs *widgets.QTabWidget tabs *widgets.QTabWidget
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Servers lists and related. // Servers lists and related.
////////////////////////////////////////////////// //////////////////////////////////////////////////
// "Servers" tab list. // "Servers" tab list.
all_servers *widgets.QTreeView all_servers *widgets.QTreeView
// Hide offline servers checkbox. // Hide offline servers checkbox.
all_servers_hide_offline *widgets.QCheckBox all_servers_hide_offline *widgets.QCheckBox
// Hide private servers? // Hide private servers?
all_servers_hide_private *widgets.QCheckBox all_servers_hide_private *widgets.QCheckBox
// Server's version. // Server's version.
all_servers_version *widgets.QComboBox all_servers_version *widgets.QComboBox
// Game mode. // Game mode.
all_servers_gamemode *widgets.QComboBox all_servers_gamemode *widgets.QComboBox
// Favorites tab list. // Favorites tab list.
fav_servers *widgets.QTreeView fav_servers *widgets.QTreeView
// Hide offline servers checkbox. // Hide offline servers checkbox.
fav_servers_hide_offline *widgets.QCheckBox fav_servers_hide_offline *widgets.QCheckBox
// Hide private servers? // Hide private servers?
fav_servers_hide_private *widgets.QCheckBox fav_servers_hide_private *widgets.QCheckBox
// Server's version. // Server's version.
fav_servers_version *widgets.QComboBox fav_servers_version *widgets.QComboBox
// Game mode. // Game mode.
fav_servers_gamemode *widgets.QComboBox fav_servers_gamemode *widgets.QComboBox
// Sidebar's server's information widget. // Sidebar's server's information widget.
sidebar_server_info *widgets.QTreeView sidebar_server_info *widgets.QTreeView
// Sidebar's server's players widget. // Sidebar's server's players widget.
sidebar_server_players *widgets.QTreeView sidebar_server_players *widgets.QTreeView
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Datas. // Datas.
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Window size. // Window size.
window_width int window_width int
window_height int window_height int
// Window position. // Window position.
window_pos_x int window_pos_x int
window_pos_y int window_pos_y int
// Supported game modes. // Supported game modes.
gamemodes map[string]string gamemodes map[string]string
// Columns names for servers tabs. // Columns names for servers tabs.
column_names map[string]string column_names map[string]string
// Real columns positions on servers tabs. // Real columns positions on servers tabs.
column_pos map[string]map[string]int column_pos map[string]map[string]int
} }
func (m *MainWindow) close(a bool) { func (m *MainWindow) close(a bool) {
fmt.Println("Closing URTrator...") fmt.Println("Closing URTrator...")
m.app.Quit() m.app.Quit()
} }
func (m *MainWindow) dropDatabasesData(bool) { func (m *MainWindow) dropDatabasesData(bool) {
fmt.Println("About to drop databases data...") fmt.Println("About to drop databases data...")
} }
func (m *MainWindow) showAboutDialog(a bool) { func (m *MainWindow) showAboutDialog(a bool) {
fmt.Println("Showing about dialog...") fmt.Println("Showing about dialog...")
} }
func (m *MainWindow) showAboutQtDialog(a bool) { func (m *MainWindow) showAboutQtDialog(a bool) {
fmt.Println("Showing about Qt dialog...") fmt.Println("Showing about Qt dialog...")
widgets.QMessageBox_AboutQt(m.window, "About Qt") widgets.QMessageBox_AboutQt(m.window, "About Qt")
} }
func (m *MainWindow) showOptionsDialog(a bool) { func (m *MainWindow) showOptionsDialog(a bool) {
fmt.Println("Showing options dialog...") fmt.Println("Showing options dialog...")
} }
func (m *MainWindow) splitterMoved(pos int, index int) { func (m *MainWindow) splitterMoved(pos int, index int) {
fmt.Println("Splitter moved!") fmt.Println("Splitter moved!")
fmt.Println(index, pos) fmt.Println(index, pos)
} }

View File

@ -10,336 +10,336 @@
package ui package ui
import ( import (
// stdlib // stdlib
"fmt" "fmt"
"os" "os"
//"runtime" //"runtime"
"sort" "sort"
"strconv" "strconv"
// local // local
"github.com/pztrn/urtrator/common" "github.com/pztrn/urtrator/common"
// Qt5 // Qt5
"github.com/therecipe/qt/core" "github.com/therecipe/qt/core"
"github.com/therecipe/qt/widgets" "github.com/therecipe/qt/widgets"
) )
func (m *MainWindow) Initialize() { func (m *MainWindow) Initialize() {
fmt.Println("Initializing main window...") fmt.Println("Initializing main window...")
m.app = widgets.NewQApplication(len(os.Args), os.Args) m.app = widgets.NewQApplication(len(os.Args), os.Args)
m.initializeStorages() m.initializeStorages()
m.window = widgets.NewQMainWindow(nil, 0) m.window = widgets.NewQMainWindow(nil, 0)
m.window.SetWindowTitle("URTrator") m.window.SetWindowTitle("URTrator")
// Restoring window position. // Restoring window position.
var win_pos_x_str string = "0" var win_pos_x_str string = "0"
var win_pos_y_str string = "0" var win_pos_y_str string = "0"
saved_win_pos_x_str, ok := ctx.Cfg.Cfg["/mainwindow/position_x"] saved_win_pos_x_str, ok := ctx.Cfg.Cfg["/mainwindow/position_x"]
if ok { if ok {
win_pos_x_str = saved_win_pos_x_str win_pos_x_str = saved_win_pos_x_str
} }
saved_win_pos_y_str, ok := ctx.Cfg.Cfg["/mainwindow/position_y"] saved_win_pos_y_str, ok := ctx.Cfg.Cfg["/mainwindow/position_y"]
if ok { if ok {
win_pos_y_str = saved_win_pos_y_str win_pos_y_str = saved_win_pos_y_str
} }
win_pos_x, _ := strconv.Atoi(win_pos_x_str) win_pos_x, _ := strconv.Atoi(win_pos_x_str)
win_pos_y, _ := strconv.Atoi(win_pos_y_str) win_pos_y, _ := strconv.Atoi(win_pos_y_str)
// Restoring window size. // Restoring window size.
var win_size_width_str string = "1000" var win_size_width_str string = "1000"
var win_size_height_str string = "600" var win_size_height_str string = "600"
saved_win_size_width_str, ok := ctx.Cfg.Cfg["/mainwindow/width"] saved_win_size_width_str, ok := ctx.Cfg.Cfg["/mainwindow/width"]
if ok { if ok {
win_size_width_str = saved_win_size_width_str win_size_width_str = saved_win_size_width_str
} }
saved_win_size_height_str, ok := ctx.Cfg.Cfg["/mainwindow/height"] saved_win_size_height_str, ok := ctx.Cfg.Cfg["/mainwindow/height"]
if ok { if ok {
win_size_height_str = saved_win_size_height_str win_size_height_str = saved_win_size_height_str
} }
m.window_width, _ = strconv.Atoi(win_size_width_str) m.window_width, _ = strconv.Atoi(win_size_width_str)
m.window_height, _ = strconv.Atoi(win_size_height_str) m.window_height, _ = strconv.Atoi(win_size_height_str)
m.window.SetGeometry2(win_pos_x, win_pos_y, m.window_width, m.window_height) m.window.SetGeometry2(win_pos_x, win_pos_y, m.window_width, m.window_height)
m.initializeMenu() m.initializeMenu()
// Central widget. // Central widget.
cv := widgets.NewQWidget(nil, core.Qt__Widget) cv := widgets.NewQWidget(nil, core.Qt__Widget)
//cv_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Expanding, widgets.QSizePolicy__Expanding, widgets.QSizePolicy__DefaultType) //cv_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Expanding, widgets.QSizePolicy__Expanding, widgets.QSizePolicy__DefaultType)
//cv.SetSizePolicy(cv_policy) //cv.SetSizePolicy(cv_policy)
m.window.SetCentralWidget(cv) m.window.SetCentralWidget(cv)
// Main vertical box. // Main vertical box.
m.vbox = widgets.NewQVBoxLayout() m.vbox = widgets.NewQVBoxLayout()
m.vbox.SetContentsMargins(4, 4, 4, 4) m.vbox.SetContentsMargins(4, 4, 4, 4)
cv.SetLayout(m.vbox) cv.SetLayout(m.vbox)
m.initializeToolbar() m.initializeToolbar()
m.initializeTabs() m.initializeTabs()
m.initializeSidebar() m.initializeSidebar()
m.window.Show() m.window.Show()
// Restore splitter position. // Restore splitter position.
// We will restore saved thing, or will use "window_width - 150". // We will restore saved thing, or will use "window_width - 150".
saved_pane_pos, ok := ctx.Cfg.Cfg["/mainwindow/pane_negative_position"] saved_pane_pos, ok := ctx.Cfg.Cfg["/mainwindow/pane_negative_position"]
if ok { if ok {
pane_negative_pos, _ := strconv.Atoi(saved_pane_pos) pane_negative_pos, _ := strconv.Atoi(saved_pane_pos)
new_splitter_pos := m.window_width - pane_negative_pos new_splitter_pos := m.window_width - pane_negative_pos
fmt.Println(new_splitter_pos) fmt.Println(new_splitter_pos)
m.splitter.MoveSplitter(new_splitter_pos, 1) m.splitter.MoveSplitter(new_splitter_pos, 1)
fmt.Println(m.splitter.ClosestLegalPosition(1, new_splitter_pos)) fmt.Println(m.splitter.ClosestLegalPosition(1, new_splitter_pos))
} else { } else {
g := m.window.Geometry() g := m.window.Geometry()
w := g.Width() w := g.Width()
m.splitter.MoveSplitter(w - 150, 1) m.splitter.MoveSplitter(w-150, 1)
} }
m.splitter.ConnectSplitterMoved(m.splitterMoved) m.splitter.ConnectSplitterMoved(m.splitterMoved)
widgets.QApplication_Exec() widgets.QApplication_Exec()
} }
func (m *MainWindow) initializeSidebar() { func (m *MainWindow) initializeSidebar() {
sidebar_widget := widgets.NewQWidget(nil, core.Qt__Widget) sidebar_widget := widgets.NewQWidget(nil, core.Qt__Widget)
m.splitter.AddWidget(sidebar_widget) m.splitter.AddWidget(sidebar_widget)
sidebar_layout := widgets.NewQVBoxLayout() sidebar_layout := widgets.NewQVBoxLayout()
sidebar_layout.SetContentsMargins(4, 4, 4, 4) sidebar_layout.SetContentsMargins(4, 4, 4, 4)
sidebar_widget.SetLayout(sidebar_layout) sidebar_widget.SetLayout(sidebar_layout)
// Server's information list. // Server's information list.
m.sidebar_server_info = widgets.NewQTreeView(nil) m.sidebar_server_info = widgets.NewQTreeView(nil)
sidebar_layout.AddWidget(m.sidebar_server_info, 0, core.Qt__AlignHCenter & core.Qt__AlignTop) sidebar_layout.AddWidget(m.sidebar_server_info, 0, core.Qt__AlignHCenter&core.Qt__AlignTop)
// Server's players widget. // Server's players widget.
m.sidebar_server_players = widgets.NewQTreeView(nil) m.sidebar_server_players = widgets.NewQTreeView(nil)
sidebar_layout.AddWidget(m.sidebar_server_players, 0, core.Qt__AlignHCenter & core.Qt__AlignTop) sidebar_layout.AddWidget(m.sidebar_server_players, 0, core.Qt__AlignHCenter&core.Qt__AlignTop)
// Add spacer. // Add spacer.
spacer := widgets.NewQSpacerItem(6, 6, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Expanding) spacer := widgets.NewQSpacerItem(6, 6, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Expanding)
sidebar_layout.AddSpacerItem(spacer) sidebar_layout.AddSpacerItem(spacer)
} }
func (m *MainWindow) initializeStorages() { func (m *MainWindow) initializeStorages() {
m.gamemodes = make(map[string]string) m.gamemodes = make(map[string]string)
m.gamemodes = map[string]string{ m.gamemodes = map[string]string{
"1": "Last Man Standing", "1": "Last Man Standing",
"2": "Free For All", "2": "Free For All",
"3": "Team DM", "3": "Team DM",
"4": "Team Survivor", "4": "Team Survivor",
"5": "Follow The Leader", "5": "Follow The Leader",
"6": "Cap'n'Hold", "6": "Cap'n'Hold",
"7": "Capture The Flag", "7": "Capture The Flag",
"8": "Bomb", "8": "Bomb",
"9": "Jump", "9": "Jump",
"10": "Freeze Tag", "10": "Freeze Tag",
"11": "Gun Game", "11": "Gun Game",
"12": "Instagib", "12": "Instagib",
} }
// Columns names. // Columns names.
// Key - default position in lists. // Key - default position in lists.
m.column_names = map[string]string{ m.column_names = map[string]string{
"2": "Name", "2": "Name",
"3": "Mode", "3": "Mode",
"4": "Map", "4": "Map",
"5": "Players", "5": "Players",
"6": "Ping", "6": "Ping",
"7": "Version", "7": "Version",
"8": "IP", "8": "IP",
} }
// Real columns positions. // Real columns positions.
m.column_pos = make(map[string]map[string]int) m.column_pos = make(map[string]map[string]int)
m.column_pos["Servers"] = make(map[string]int) m.column_pos["Servers"] = make(map[string]int)
m.column_pos["Favorites"] = make(map[string]int) m.column_pos["Favorites"] = make(map[string]int)
} }
func (m *MainWindow) initializeTabs() { func (m *MainWindow) initializeTabs() {
m.splitter = widgets.NewQSplitter(nil) m.splitter = widgets.NewQSplitter(nil)
m.splitter.SetOrientation(core.Qt__Horizontal) m.splitter.SetOrientation(core.Qt__Horizontal)
m.vbox.AddWidget(m.splitter, 0, core.Qt__AlignHCenter & core.Qt__AlignTop) m.vbox.AddWidget(m.splitter, 0, core.Qt__AlignHCenter&core.Qt__AlignTop)
m.tabs = widgets.NewQTabWidget(nil) m.tabs = widgets.NewQTabWidget(nil)
m.splitter.AddWidget(m.tabs) m.splitter.AddWidget(m.tabs)
// Default size policy for filters widget. // Default size policy for filters widget.
filters_size_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__DefaultType) filters_size_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__DefaultType)
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Servers page. // Servers page.
////////////////////////////////////////////////// //////////////////////////////////////////////////
serverspagewidget := widgets.NewQWidget(nil, core.Qt__Widget) serverspagewidget := widgets.NewQWidget(nil, core.Qt__Widget)
serverspagewidget_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Expanding, widgets.QSizePolicy__Expanding, widgets.QSizePolicy__DefaultType) serverspagewidget_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Expanding, widgets.QSizePolicy__Expanding, widgets.QSizePolicy__DefaultType)
serverspagewidget.SetSizePolicy(serverspagewidget_policy) serverspagewidget.SetSizePolicy(serverspagewidget_policy)
m.tabs.AddTab(serverspagewidget, ctx.Translator.Translate("Servers", nil)) m.tabs.AddTab(serverspagewidget, ctx.Translator.Translate("Servers", nil))
serverspagewidget_layout := widgets.NewQHBoxLayout() serverspagewidget_layout := widgets.NewQHBoxLayout()
serverspagewidget_layout.SetContentsMargins(4, 4, 4, 4) serverspagewidget_layout.SetContentsMargins(4, 4, 4, 4)
serverspagewidget.SetLayout(serverspagewidget_layout) serverspagewidget.SetLayout(serverspagewidget_layout)
// Servers list. // Servers list.
m.all_servers = widgets.NewQTreeView(nil) m.all_servers = widgets.NewQTreeView(nil)
serverspagewidget_layout.AddWidget(m.all_servers, 0, core.Qt__AlignLeft & core.Qt__AlignTop) serverspagewidget_layout.AddWidget(m.all_servers, 0, core.Qt__AlignLeft&core.Qt__AlignTop)
// Servers list filters widget. // Servers list filters widget.
serverspagewidget_filters_widget := widgets.NewQWidget(nil, core.Qt__Widget) serverspagewidget_filters_widget := widgets.NewQWidget(nil, core.Qt__Widget)
serverspagewidget_filters_widget_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__DefaultType) serverspagewidget_filters_widget_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__DefaultType)
serverspagewidget_filters_widget.SetSizePolicy(serverspagewidget_filters_widget_policy) serverspagewidget_filters_widget.SetSizePolicy(serverspagewidget_filters_widget_policy)
serverspagewidget_layout.AddWidget(serverspagewidget_filters_widget, 0, core.Qt__AlignRight & core.Qt__AlignTop) serverspagewidget_layout.AddWidget(serverspagewidget_filters_widget, 0, core.Qt__AlignRight&core.Qt__AlignTop)
// Servers list filters layout. // Servers list filters layout.
serverspagewidget_filters_layout := widgets.NewQVBoxLayout() serverspagewidget_filters_layout := widgets.NewQVBoxLayout()
serverspagewidget_filters_widget.SetLayout(serverspagewidget_filters_layout) serverspagewidget_filters_widget.SetLayout(serverspagewidget_filters_layout)
serverspagewidget_filters_layout.SetContentsMargins(4, 4, 4, 4) serverspagewidget_filters_layout.SetContentsMargins(4, 4, 4, 4)
// Filters itself. // Filters itself.
// Hide offline servers checkbox. // Hide offline servers checkbox.
m.all_servers_hide_offline = widgets.NewQCheckBox(nil) m.all_servers_hide_offline = widgets.NewQCheckBox(nil)
m.all_servers_hide_offline.SetText(ctx.Translator.Translate("Hide offline servers", nil)) m.all_servers_hide_offline.SetText(ctx.Translator.Translate("Hide offline servers", nil))
m.all_servers_hide_offline.SetSizePolicy(filters_size_policy) m.all_servers_hide_offline.SetSizePolicy(filters_size_policy)
serverspagewidget_filters_layout.AddWidget(m.all_servers_hide_offline, 0, core.Qt__AlignTop) serverspagewidget_filters_layout.AddWidget(m.all_servers_hide_offline, 0, core.Qt__AlignTop)
// Restore value of hide offline servers checkbox. // Restore value of hide offline servers checkbox.
// Set to checked for new installations. // Set to checked for new installations.
all_servers_hide_offline_cb_val, ok := ctx.Cfg.Cfg["/serverslist/all_servers/hide_offline"] all_servers_hide_offline_cb_val, ok := ctx.Cfg.Cfg["/serverslist/all_servers/hide_offline"]
if !ok { if !ok {
m.all_servers_hide_offline.SetCheckState(2) m.all_servers_hide_offline.SetCheckState(2)
} else { } else {
if all_servers_hide_offline_cb_val == "1" { if all_servers_hide_offline_cb_val == "1" {
m.all_servers_hide_offline.SetCheckState(2) m.all_servers_hide_offline.SetCheckState(2)
} }
} }
// Hide private servers. // Hide private servers.
m.all_servers_hide_private = widgets.NewQCheckBox(nil) m.all_servers_hide_private = widgets.NewQCheckBox(nil)
m.all_servers_hide_private.SetText(ctx.Translator.Translate("Hide private servers", nil)) m.all_servers_hide_private.SetText(ctx.Translator.Translate("Hide private servers", nil))
m.all_servers_hide_private.SetSizePolicy(filters_size_policy) m.all_servers_hide_private.SetSizePolicy(filters_size_policy)
serverspagewidget_filters_layout.AddWidget(m.all_servers_hide_private, 0, core.Qt__AlignTop) serverspagewidget_filters_layout.AddWidget(m.all_servers_hide_private, 0, core.Qt__AlignTop)
// Restore checkbox value. // Restore checkbox value.
all_servers_hide_private_cb_val, ok := ctx.Cfg.Cfg["/serverslist/all_servers/hide_private"] all_servers_hide_private_cb_val, ok := ctx.Cfg.Cfg["/serverslist/all_servers/hide_private"]
if !ok { if !ok {
m.all_servers_hide_private.SetCheckState(2) m.all_servers_hide_private.SetCheckState(2)
} else { } else {
if all_servers_hide_private_cb_val == "1" { if all_servers_hide_private_cb_val == "1" {
m.all_servers_hide_private.SetCheckState(2) m.all_servers_hide_private.SetCheckState(2)
} }
} }
// Game version. // Game version.
m.all_servers_version = widgets.NewQComboBox(nil) m.all_servers_version = widgets.NewQComboBox(nil)
m.all_servers_version.SetSizePolicy(filters_size_policy) m.all_servers_version.SetSizePolicy(filters_size_policy)
serverspagewidget_filters_layout.AddWidget(m.all_servers_version, 0, core.Qt__AlignTop) serverspagewidget_filters_layout.AddWidget(m.all_servers_version, 0, core.Qt__AlignTop)
// Fill game version combobox with supported versions. // Fill game version combobox with supported versions.
m.all_servers_version.AddItems(common.SUPPORTED_URT_VERSIONS) m.all_servers_version.AddItems(common.SUPPORTED_URT_VERSIONS)
// Game mode. // Game mode.
m.all_servers_gamemode = widgets.NewQComboBox(nil) m.all_servers_gamemode = widgets.NewQComboBox(nil)
m.all_servers_gamemode.SetSizePolicy(filters_size_policy) m.all_servers_gamemode.SetSizePolicy(filters_size_policy)
serverspagewidget_filters_layout.AddWidget(m.all_servers_gamemode, 0, core.Qt__AlignTop) serverspagewidget_filters_layout.AddWidget(m.all_servers_gamemode, 0, core.Qt__AlignTop)
// Fill game mode with supported gamemodes. // Fill game mode with supported gamemodes.
// First - create sorted gamemodes keys slice. // First - create sorted gamemodes keys slice.
gm_keys := make([]int, 0, len(m.gamemodes)) gm_keys := make([]int, 0, len(m.gamemodes))
for k, _ := range m.gamemodes { for k, _ := range m.gamemodes {
ki, _ := strconv.Atoi(k) ki, _ := strconv.Atoi(k)
gm_keys = append(gm_keys, ki) gm_keys = append(gm_keys, ki)
} }
sort.Ints(gm_keys) sort.Ints(gm_keys)
// Create a strings slice with gamemodes, using sorted keys. // Create a strings slice with gamemodes, using sorted keys.
gmodes := make([]string, 0, len(m.gamemodes)) gmodes := make([]string, 0, len(m.gamemodes))
// Add "All gamemodes" as first gamemode :) // Add "All gamemodes" as first gamemode :)
gmodes = append(gmodes, ctx.Translator.Translate("All gamemodes", nil)) gmodes = append(gmodes, ctx.Translator.Translate("All gamemodes", nil))
for i := range gm_keys { for i := range gm_keys {
ks := strconv.Itoa(gm_keys[i]) ks := strconv.Itoa(gm_keys[i])
gmodes = append(gmodes, m.gamemodes[ks]) gmodes = append(gmodes, m.gamemodes[ks])
} }
m.all_servers_gamemode.AddItems(gmodes) m.all_servers_gamemode.AddItems(gmodes)
// After creating filters - add spacer to move them on top of widget. // After creating filters - add spacer to move them on top of widget.
all_servers_filters_spacer := widgets.NewQSpacerItem(6, 6, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Expanding) all_servers_filters_spacer := widgets.NewQSpacerItem(6, 6, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Expanding)
serverspagewidget_filters_layout.AddSpacerItem(all_servers_filters_spacer) serverspagewidget_filters_layout.AddSpacerItem(all_servers_filters_spacer)
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Favorites page. // Favorites page.
////////////////////////////////////////////////// //////////////////////////////////////////////////
favoritespagewidget := widgets.NewQWidget(nil, core.Qt__Widget) favoritespagewidget := widgets.NewQWidget(nil, core.Qt__Widget)
favoritespagewidget_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Expanding, widgets.QSizePolicy__Expanding, widgets.QSizePolicy__DefaultType) favoritespagewidget_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Expanding, widgets.QSizePolicy__Expanding, widgets.QSizePolicy__DefaultType)
favoritespagewidget.SetSizePolicy(favoritespagewidget_policy) favoritespagewidget.SetSizePolicy(favoritespagewidget_policy)
m.tabs.AddTab(favoritespagewidget, ctx.Translator.Translate("Favorites", nil)) m.tabs.AddTab(favoritespagewidget, ctx.Translator.Translate("Favorites", nil))
favoritespagewidget_layout := widgets.NewQHBoxLayout() favoritespagewidget_layout := widgets.NewQHBoxLayout()
favoritespagewidget_layout.SetContentsMargins(4, 4, 4, 4) favoritespagewidget_layout.SetContentsMargins(4, 4, 4, 4)
favoritespagewidget.SetLayout(favoritespagewidget_layout) favoritespagewidget.SetLayout(favoritespagewidget_layout)
// Favorites list. // Favorites list.
m.fav_servers = widgets.NewQTreeView(nil) m.fav_servers = widgets.NewQTreeView(nil)
favoritespagewidget_layout.AddWidget(m.fav_servers, 0, core.Qt__AlignHCenter & core.Qt__AlignTop) favoritespagewidget_layout.AddWidget(m.fav_servers, 0, core.Qt__AlignHCenter&core.Qt__AlignTop)
// Favorites list filters widget. // Favorites list filters widget.
favoritespagewidget_filters_widget := widgets.NewQWidget(nil, core.Qt__Widget) favoritespagewidget_filters_widget := widgets.NewQWidget(nil, core.Qt__Widget)
favoritespagewidget_filters_widget_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__DefaultType) favoritespagewidget_filters_widget_policy := widgets.NewQSizePolicy2(widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__DefaultType)
favoritespagewidget_filters_widget.SetSizePolicy(favoritespagewidget_filters_widget_policy) favoritespagewidget_filters_widget.SetSizePolicy(favoritespagewidget_filters_widget_policy)
favoritespagewidget_layout.AddWidget(favoritespagewidget_filters_widget, 0, core.Qt__AlignRight & core.Qt__AlignTop) favoritespagewidget_layout.AddWidget(favoritespagewidget_filters_widget, 0, core.Qt__AlignRight&core.Qt__AlignTop)
// Favorites list filters layout. // Favorites list filters layout.
favoritespagewidget_filters_layout := widgets.NewQVBoxLayout() favoritespagewidget_filters_layout := widgets.NewQVBoxLayout()
favoritespagewidget_filters_widget.SetLayout(favoritespagewidget_filters_layout) favoritespagewidget_filters_widget.SetLayout(favoritespagewidget_filters_layout)
favoritespagewidget_filters_layout.SetContentsMargins(4, 4, 4, 4) favoritespagewidget_filters_layout.SetContentsMargins(4, 4, 4, 4)
// Filters itself. // Filters itself.
// Hide offline servers checkbox. // Hide offline servers checkbox.
m.fav_servers_hide_offline = widgets.NewQCheckBox(nil) m.fav_servers_hide_offline = widgets.NewQCheckBox(nil)
m.fav_servers_hide_offline.SetText(ctx.Translator.Translate("Hide offline servers", nil)) m.fav_servers_hide_offline.SetText(ctx.Translator.Translate("Hide offline servers", nil))
m.fav_servers_hide_offline.SetSizePolicy(filters_size_policy) m.fav_servers_hide_offline.SetSizePolicy(filters_size_policy)
favoritespagewidget_filters_layout.AddWidget(m.fav_servers_hide_offline, 0, core.Qt__AlignTop) favoritespagewidget_filters_layout.AddWidget(m.fav_servers_hide_offline, 0, core.Qt__AlignTop)
// Restore it's value. // Restore it's value.
favorite_servers_hide_offline_cb_val, ok := ctx.Cfg.Cfg["/serverslist/favorite/hide_offline"] favorite_servers_hide_offline_cb_val, ok := ctx.Cfg.Cfg["/serverslist/favorite/hide_offline"]
if !ok { if !ok {
m.fav_servers_hide_offline.SetCheckState(2) m.fav_servers_hide_offline.SetCheckState(2)
} else { } else {
if favorite_servers_hide_offline_cb_val == "1" { if favorite_servers_hide_offline_cb_val == "1" {
m.fav_servers_hide_offline.SetCheckState(2) m.fav_servers_hide_offline.SetCheckState(2)
} }
} }
// Hide private servers. // Hide private servers.
m.fav_servers_hide_private = widgets.NewQCheckBox(nil) m.fav_servers_hide_private = widgets.NewQCheckBox(nil)
m.fav_servers_hide_private.SetText(ctx.Translator.Translate("Hide private servers", nil)) m.fav_servers_hide_private.SetText(ctx.Translator.Translate("Hide private servers", nil))
m.fav_servers_hide_private.SetSizePolicy(filters_size_policy) m.fav_servers_hide_private.SetSizePolicy(filters_size_policy)
favoritespagewidget_filters_layout.AddWidget(m.fav_servers_hide_private, 0, core.Qt__AlignTop) favoritespagewidget_filters_layout.AddWidget(m.fav_servers_hide_private, 0, core.Qt__AlignTop)
fav_servers_hide_private_cb_val, ok := ctx.Cfg.Cfg["/serverslist/favorite/hide_private"] fav_servers_hide_private_cb_val, ok := ctx.Cfg.Cfg["/serverslist/favorite/hide_private"]
if !ok { if !ok {
m.fav_servers_hide_private.SetCheckState(2) m.fav_servers_hide_private.SetCheckState(2)
} else { } else {
if fav_servers_hide_private_cb_val == "1" { if fav_servers_hide_private_cb_val == "1" {
m.fav_servers_hide_private.SetCheckState(2) m.fav_servers_hide_private.SetCheckState(2)
} }
} }
// Game version. // Game version.
m.fav_servers_version = widgets.NewQComboBox(nil) m.fav_servers_version = widgets.NewQComboBox(nil)
m.fav_servers_version.SetSizePolicy(filters_size_policy) m.fav_servers_version.SetSizePolicy(filters_size_policy)
favoritespagewidget_filters_layout.AddWidget(m.fav_servers_version, 0, core.Qt__AlignTop) favoritespagewidget_filters_layout.AddWidget(m.fav_servers_version, 0, core.Qt__AlignTop)
// Fill game version combobox with supported versions. // Fill game version combobox with supported versions.
m.fav_servers_version.AddItems(common.SUPPORTED_URT_VERSIONS) m.fav_servers_version.AddItems(common.SUPPORTED_URT_VERSIONS)
// Game mode. // Game mode.
m.fav_servers_gamemode = widgets.NewQComboBox(nil) m.fav_servers_gamemode = widgets.NewQComboBox(nil)
m.fav_servers_gamemode.SetSizePolicy(filters_size_policy) m.fav_servers_gamemode.SetSizePolicy(filters_size_policy)
favoritespagewidget_filters_layout.AddWidget(m.fav_servers_gamemode, 0, core.Qt__AlignTop) favoritespagewidget_filters_layout.AddWidget(m.fav_servers_gamemode, 0, core.Qt__AlignTop)
// Fill game mode with supported gamemodes. // Fill game mode with supported gamemodes.
// As we have previously created this list - reuse it. // As we have previously created this list - reuse it.
m.fav_servers_gamemode.AddItems(gmodes) m.fav_servers_gamemode.AddItems(gmodes)
// After creating filters - add spacer to move them on top of widget. // After creating filters - add spacer to move them on top of widget.
fav_servers_filters_spacer := widgets.NewQSpacerItem(6, 6, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Expanding) fav_servers_filters_spacer := widgets.NewQSpacerItem(6, 6, widgets.QSizePolicy__Minimum, widgets.QSizePolicy__Expanding)
favoritespagewidget_filters_layout.AddSpacerItem(fav_servers_filters_spacer) favoritespagewidget_filters_layout.AddSpacerItem(fav_servers_filters_spacer)
} }
func (m *MainWindow) initializeToolbar() { func (m *MainWindow) initializeToolbar() {
m.toolbar = widgets.NewQToolBar("Main Toolbar", m.window) m.toolbar = widgets.NewQToolBar("Main Toolbar", m.window)
m.window.AddToolBar(core.Qt__TopToolBarArea, m.toolbar) m.window.AddToolBar(core.Qt__TopToolBarArea, m.toolbar)
} }

View File

@ -12,61 +12,61 @@
package ui package ui
import ( import (
// stdlib // stdlib
//"fmt" //"fmt"
//"os" //"os"
//"runtime" //"runtime"
// Qt5 // Qt5
"github.com/therecipe/qt/widgets" "github.com/therecipe/qt/widgets"
) )
func (m *MainWindow) initializeMenu() { func (m *MainWindow) initializeMenu() {
m.mainmenu = widgets.NewQMenuBar(nil) m.mainmenu = widgets.NewQMenuBar(nil)
////////////////////////////////////////////////// //////////////////////////////////////////////////
// File menu. // File menu.
////////////////////////////////////////////////// //////////////////////////////////////////////////
filemenu := widgets.NewQMenu2("&File", nil) filemenu := widgets.NewQMenu2("&File", nil)
// Options action. // Options action.
file_options := filemenu.AddAction("&Options") file_options := filemenu.AddAction("&Options")
file_options.SetMenuRole(widgets.QAction__PreferencesRole) file_options.SetMenuRole(widgets.QAction__PreferencesRole)
file_options.ConnectTriggered(m.showOptionsDialog) file_options.ConnectTriggered(m.showOptionsDialog)
// Separator :) // Separator :)
filemenu.AddSeparator() filemenu.AddSeparator()
// Exit URTrator. // Exit URTrator.
file_exit := filemenu.AddAction("&Exit") file_exit := filemenu.AddAction("&Exit")
file_exit.SetMenuRole(widgets.QAction__QuitRole) file_exit.SetMenuRole(widgets.QAction__QuitRole)
file_exit.ConnectTriggered(m.close) file_exit.ConnectTriggered(m.close)
m.mainmenu.AddMenu(filemenu) m.mainmenu.AddMenu(filemenu)
////////////////////////////////////////////////// //////////////////////////////////////////////////
// About menu // About menu
////////////////////////////////////////////////// //////////////////////////////////////////////////
aboutmenu := widgets.NewQMenu2("&Help", nil) aboutmenu := widgets.NewQMenu2("&Help", nil)
// About URTrator. // About URTrator.
about_about := aboutmenu.AddAction("&About URTrator...") about_about := aboutmenu.AddAction("&About URTrator...")
about_about.SetMenuRole(widgets.QAction__AboutRole) about_about.SetMenuRole(widgets.QAction__AboutRole)
about_about.ConnectTriggered(m.showAboutDialog) about_about.ConnectTriggered(m.showAboutDialog)
// About Qt. // About Qt.
about_about_qt := aboutmenu.AddAction("About &Qt...") about_about_qt := aboutmenu.AddAction("About &Qt...")
about_about_qt.SetMenuRole(widgets.QAction__AboutQtRole) about_about_qt.SetMenuRole(widgets.QAction__AboutQtRole)
about_about_qt.ConnectTriggered(m.showAboutQtDialog) about_about_qt.ConnectTriggered(m.showAboutQtDialog)
// Separator :) // Separator :)
aboutmenu.AddSeparator() aboutmenu.AddSeparator()
// Drop database data. // Drop database data.
about_drop_database := aboutmenu.AddAction("&Drop database...") about_drop_database := aboutmenu.AddAction("&Drop database...")
//about_drop_database.SetMenuRole(widgets.QAction__ApplicationSpecificRole) //about_drop_database.SetMenuRole(widgets.QAction__ApplicationSpecificRole)
about_drop_database.ConnectTriggered(m.dropDatabasesData) about_drop_database.ConnectTriggered(m.dropDatabasesData)
m.mainmenu.AddMenu(aboutmenu) m.mainmenu.AddMenu(aboutmenu)
m.window.SetMenuBar(m.mainmenu) m.window.SetMenuBar(m.mainmenu)
} }