Being localization process
This commit is contained in:
parent
bc7d1ec8b2
commit
656c5fc256
|
@ -37,6 +37,7 @@ import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
|
||||||
|
@ -60,25 +61,40 @@ import (
|
||||||
"github.com/AllenDang/giu"
|
"github.com/AllenDang/giu"
|
||||||
|
|
||||||
// Reed-Solomon
|
// Reed-Solomon
|
||||||
"github.com/HACKERALERT/infectious" // v0.0.0-20210730231340-8af02cb9ed0a
|
"github.com/HACKERALERT/infectious" // v0.0.0-20210818221523-92bdec168696
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
"github.com/cloudfoundry-attic/jibber_jabber"
|
||||||
"github.com/HACKERALERT/clipboard" // v0.1.5-0.20210716140604-61d96bf4fc94
|
"github.com/HACKERALERT/clipboard" // v0.1.5-0.20210716140604-61d96bf4fc94
|
||||||
"github.com/HACKERALERT/dialog" // v0.0.0-20210716143851-223edea1d840
|
"github.com/HACKERALERT/dialog" // v0.0.0-20210716143851-223edea1d840
|
||||||
"github.com/HACKERALERT/browser" // v0.0.0-20210730230128-85901a8dd82f
|
"github.com/HACKERALERT/browser" // v0.0.0-20210818221535-991cc324ab76
|
||||||
"github.com/HACKERALERT/zxcvbn-go" // v0.0.0-20210730224720-b29e9dba62c2
|
"github.com/HACKERALERT/zxcvbn-go" // v0.0.0-20210730224720-b29e9dba62c2
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var version = "v1.17"
|
var version = "v1.17"
|
||||||
|
|
||||||
//go:embed NotoSans-Regular.ttf
|
//go:embed font.ttf
|
||||||
var font []byte
|
var font []byte
|
||||||
|
|
||||||
//go:embed sdelete64.exe
|
//go:embed sdelete64.exe
|
||||||
var sdelete64bytes []byte
|
var sdelete64bytes []byte
|
||||||
|
|
||||||
//go:embed icon.png
|
//go:embed icon.png
|
||||||
var iconBytes []byte
|
var iconBytes []byte
|
||||||
|
|
||||||
|
//go:embed strings.json
|
||||||
|
var localeBytes []byte
|
||||||
|
|
||||||
|
type locale struct{
|
||||||
|
iso string
|
||||||
|
data []string
|
||||||
|
}
|
||||||
|
|
||||||
|
var locales []locale
|
||||||
|
var selectedLocale = "en"
|
||||||
|
|
||||||
|
|
||||||
// Languages
|
// Languages
|
||||||
var languages = []string{
|
var languages = []string{
|
||||||
"English",
|
"English",
|
||||||
|
@ -132,7 +148,7 @@ var passwordState = giu.InputTextFlagsPassword
|
||||||
var passwordStateLabel = "Show"
|
var passwordStateLabel = "Show"
|
||||||
var cPassword string // Confirm password text entry string variable
|
var cPassword string // Confirm password text entry string variable
|
||||||
var keyfilePath string
|
var keyfilePath string
|
||||||
var keyfileLabel = "Use a keyfile"
|
var keyfileLabel = "Keyfile"
|
||||||
var metadata string
|
var metadata string
|
||||||
var metadataPrompt = "Metadata (optional):"
|
var metadataPrompt = "Metadata (optional):"
|
||||||
var metadataState = giu.InputTextFlagsNone
|
var metadataState = giu.InputTextFlagsNone
|
||||||
|
@ -205,7 +221,7 @@ func startUI(){
|
||||||
// The tab bar, which contains different tabs for different functions
|
// The tab bar, which contains different tabs for different functions
|
||||||
giu.TabBar().TabItems(
|
giu.TabBar().TabItems(
|
||||||
// Main file encryption/decryption tab
|
// Main file encryption/decryption tab
|
||||||
giu.TabItem("Main").Layout(
|
giu.TabItem(s("Encryption")).Layout(
|
||||||
// Update 'tab' to indicate that this is the active tab
|
// Update 'tab' to indicate that this is the active tab
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if giu.IsItemActive(){
|
if giu.IsItemActive(){
|
||||||
|
@ -216,22 +232,22 @@ func startUI(){
|
||||||
// Password generator modal
|
// Password generator modal
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if showGenpass{
|
if showGenpass{
|
||||||
giu.PopupModal("Generate password:").Layout(
|
giu.PopupModal(s("Generate password:")).Layout(
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Label("Length: "),
|
giu.Label(s("Length:")),
|
||||||
giu.SliderInt("",&genpassLength,4,64).Size(-0.0000001),
|
giu.SliderInt("",&genpassLength,4,64).Size(-0.0000001),
|
||||||
),
|
),
|
||||||
giu.Checkbox("Uppercase",&genpassUpper),
|
giu.Checkbox(s("Uppercase"),&genpassUpper),
|
||||||
giu.Checkbox("Lowercase",&genpassLower),
|
giu.Checkbox(s("Lowercase"),&genpassLower),
|
||||||
giu.Checkbox("Numbers",&genpassNums),
|
giu.Checkbox(s("Numbers"),&genpassNums),
|
||||||
giu.Checkbox("Symbols",&genpassSymbols),
|
giu.Checkbox(s("Symbols"),&genpassSymbols),
|
||||||
giu.Checkbox("Copy to clipboard",&genpassCopy),
|
giu.Checkbox(s("Copy to clipboard"),&genpassCopy),
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Button("Cancel").Size(100,0).OnClick(func(){
|
giu.Button(s("Cancel")).Size(100,0).OnClick(func(){
|
||||||
giu.CloseCurrentPopup()
|
giu.CloseCurrentPopup()
|
||||||
showGenpass = false
|
showGenpass = false
|
||||||
}),
|
}),
|
||||||
giu.Button("Generate").Size(100,0).OnClick(func(){
|
giu.Button(s("Generate")).Size(100,0).OnClick(func(){
|
||||||
tmp := genPassword()
|
tmp := genPassword()
|
||||||
password = tmp
|
password = tmp
|
||||||
cPassword = tmp
|
cPassword = tmp
|
||||||
|
@ -242,7 +258,7 @@ func startUI(){
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).Build()
|
).Build()
|
||||||
giu.OpenPopup("Generate password:")
|
giu.OpenPopup(s("Generate password:"))
|
||||||
giu.Update()
|
giu.Update()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -250,14 +266,14 @@ func startUI(){
|
||||||
// Confirm overwrite with a modal
|
// Confirm overwrite with a modal
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if showConfirmation{
|
if showConfirmation{
|
||||||
giu.PopupModal("Warning:").Layout(
|
giu.PopupModal(s("Warning:")).Layout(
|
||||||
giu.Label("Output already exists. Overwrite?"),
|
giu.Label(s("Output already exists. Overwrite?")),
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Button("No").Size(100,0).OnClick(func(){
|
giu.Button(s("No")).Size(100,0).OnClick(func(){
|
||||||
giu.CloseCurrentPopup()
|
giu.CloseCurrentPopup()
|
||||||
showConfirmation = false
|
showConfirmation = false
|
||||||
}),
|
}),
|
||||||
giu.Button("Yes").Size(100,0).OnClick(func(){
|
giu.Button(s("Yes")).Size(100,0).OnClick(func(){
|
||||||
giu.CloseCurrentPopup()
|
giu.CloseCurrentPopup()
|
||||||
showConfirmation = false
|
showConfirmation = false
|
||||||
showProgress = true
|
showProgress = true
|
||||||
|
@ -272,7 +288,7 @@ func startUI(){
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
).Build()
|
).Build()
|
||||||
giu.OpenPopup("Warning:")
|
giu.OpenPopup(s("Warning:"))
|
||||||
giu.Update()
|
giu.Update()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -290,7 +306,7 @@ func startUI(){
|
||||||
// Progress bar
|
// Progress bar
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.ProgressBar(progress).Size(280,0).Overlay(progressInfo),
|
giu.ProgressBar(progress).Size(280,0).Overlay(progressInfo),
|
||||||
giu.Button("Cancel").Size(58,0).OnClick(func(){
|
giu.Button(s("Cancel")).Size(58,0).OnClick(func(){
|
||||||
working = false
|
working = false
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -303,21 +319,21 @@ func startUI(){
|
||||||
|
|
||||||
// Label listing the input files and a button to clear them
|
// Label listing the input files and a button to clear them
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Label(inputLabel),
|
giu.Label(s(inputLabel)),
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Dummy(-58,0),
|
giu.Dummy(-58,0),
|
||||||
giu.Button("Clear").Size(50,0).OnClick(resetUI),
|
giu.Button(s("Clear")).Size(50,0).OnClick(resetUI),
|
||||||
giu.Tooltip("Clear all input files and reset UI state."),
|
giu.Tooltip(s("Clear all input files and reset UI state.")),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Allow user to choose a custom output path and/or name
|
// Allow user to choose a custom output path and/or name
|
||||||
giu.Label("Save output as:"),
|
giu.Label(s("Save output as:")),
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.InputText(&outputEntry).Size(outputWidth/dpi),
|
giu.InputText(&outputEntry).Size(outputWidth/dpi),
|
||||||
giu.Label(orLabel),
|
giu.Label(orLabel),
|
||||||
giu.Button("Choose").OnClick(func(){
|
giu.Button(s("Choose")).OnClick(func(){
|
||||||
file,_ := dialog.File().Title("Save output as...").Save()
|
file,_ := dialog.File().Title(s("Save output as...")).Save()
|
||||||
|
|
||||||
// Return if user canceled the file dialog
|
// Return if user canceled the file dialog
|
||||||
if file==""{
|
if file==""{
|
||||||
|
@ -338,52 +354,52 @@ func startUI(){
|
||||||
|
|
||||||
outputEntry = file
|
outputEntry = file
|
||||||
}).Size(64,0),
|
}).Size(64,0),
|
||||||
giu.Tooltip("Select a custom name and path to save the output as."),
|
giu.Tooltip(s("Select a custom name and path to save the output as.")),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Prompt for password
|
// Prompt for password
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Label("Password:"),
|
giu.Label(s("Password:")),
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if mode!="decrypt"{
|
if mode!="decrypt"{
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Button("Generate").OnClick(func(){
|
giu.Button(s("Generate")).OnClick(func(){
|
||||||
showGenpass = true
|
showGenpass = true
|
||||||
}),
|
}),
|
||||||
giu.Tooltip("Use this to generate a cryptographically secure password."),
|
giu.Tooltip(s("Use this to generate a cryptographically secure password.")),
|
||||||
|
|
||||||
giu.Button("Copy").OnClick(func(){
|
giu.Button(s("Copy")).OnClick(func(){
|
||||||
clipboard.WriteAll(password)
|
clipboard.WriteAll(password)
|
||||||
}),
|
}),
|
||||||
giu.Tooltip("Copies the contents of the password field into your clipboard."),
|
giu.Tooltip(s("Copies the contents of the password field into your clipboard.")),
|
||||||
).Build()
|
).Build()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
giu.Button("Paste").OnClick(func(){
|
giu.Button(s("Paste")).OnClick(func(){
|
||||||
tmp,_ := clipboard.ReadAll()
|
tmp,_ := clipboard.ReadAll()
|
||||||
password = tmp
|
password = tmp
|
||||||
cPassword = tmp
|
cPassword = tmp
|
||||||
passwordStrength = zxcvbn.PasswordStrength(password,nil).Score
|
passwordStrength = zxcvbn.PasswordStrength(password,nil).Score
|
||||||
giu.Update()
|
giu.Update()
|
||||||
}),
|
}),
|
||||||
giu.Tooltip("Paste your clipboard content into the password fields."),
|
giu.Tooltip(s("Paste your clipboard content into the password fields.")),
|
||||||
|
|
||||||
giu.Button("Clear").OnClick(func(){
|
giu.Button(s("Clear")).OnClick(func(){
|
||||||
password = ""
|
password = ""
|
||||||
cPassword = ""
|
cPassword = ""
|
||||||
}),
|
}),
|
||||||
giu.Tooltip("Clear both password fields."),
|
giu.Tooltip(s("Clear both password fields.")),
|
||||||
|
|
||||||
giu.Button(passwordStateLabel).OnClick(func(){
|
giu.Button(passwordStateLabel).OnClick(func(){
|
||||||
if passwordState==giu.InputTextFlagsPassword{
|
if passwordState==giu.InputTextFlagsPassword{
|
||||||
passwordState = giu.InputTextFlagsNone
|
passwordState = giu.InputTextFlagsNone
|
||||||
passwordStateLabel = "Hide"
|
passwordStateLabel = s("Hide")
|
||||||
}else{
|
}else{
|
||||||
passwordState = giu.InputTextFlagsPassword
|
passwordState = giu.InputTextFlagsPassword
|
||||||
passwordStateLabel = "Show"
|
passwordStateLabel = s("Show")
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
giu.Tooltip("Click to toggle the password state."),
|
giu.Tooltip(s("Click to toggle the password state.")),
|
||||||
),
|
),
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.InputText(&password).Size(300/dpi).Flags(passwordState).OnChange(func(){
|
giu.InputText(&password).Size(300/dpi).Flags(passwordState).OnChange(func(){
|
||||||
|
@ -438,9 +454,9 @@ func startUI(){
|
||||||
}),
|
}),
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if keyfile&&mode=="encrypt"{
|
if keyfile&&mode=="encrypt"{
|
||||||
giu.Button("Clear").OnClick(func(){
|
giu.Button(s("Clear")).OnClick(func(){
|
||||||
keyfile = false
|
keyfile = false
|
||||||
keyfileLabel = "Use keyfile(s)"
|
keyfileLabel = s("Keyfile")
|
||||||
keyfilePath = ""
|
keyfilePath = ""
|
||||||
}).Build()
|
}).Build()
|
||||||
}
|
}
|
||||||
|
@ -451,7 +467,7 @@ func startUI(){
|
||||||
// Prompt to confirm password
|
// Prompt to confirm password
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if mode!="decrypt"{
|
if mode!="decrypt"{
|
||||||
giu.Label("Confirm password:").Build()
|
giu.Label(s("Confirm password:")).Build()
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.InputText(&cPassword).Size(300/dpi).Flags(passwordState),
|
giu.InputText(&cPassword).Size(300/dpi).Flags(passwordState),
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
|
@ -479,42 +495,42 @@ func startUI(){
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Optional metadata
|
// Optional metadata
|
||||||
giu.Label(metadataPrompt),
|
giu.Label(s(metadataPrompt)),
|
||||||
giu.InputText(&metadata).Size(-0.0000001).Flags(metadataState),
|
giu.InputText(&metadata).Size(-0.0000001).Flags(metadataState),
|
||||||
|
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if mode!=""{
|
if mode!=""{
|
||||||
giu.Label("Advanced options:").Build()
|
giu.Label(s("Advanced options:")).Build()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Advanced options can be enabled with checkboxes
|
// Advanced options can be enabled with checkboxes
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if mode=="encrypt"{
|
if mode=="encrypt"{
|
||||||
giu.Checkbox("Shred temporary files",&shredTemp).Build()
|
giu.Checkbox(s("Shred temporary files"),&shredTemp).Build()
|
||||||
giu.Tooltip("Use this to shred temporary zip archives and volumes used by Picocrypt.").Build()
|
giu.Tooltip(s("Use this to shred temporary zip archives and volumes used by Picocrypt.")).Build()
|
||||||
|
|
||||||
giu.Checkbox("Use fast mode",&fast).OnChange(func(){
|
giu.Checkbox(s("Use fast mode"),&fast).OnChange(func(){
|
||||||
paranoid = false
|
paranoid = false
|
||||||
}).Build()
|
}).Build()
|
||||||
giu.Tooltip("Uses BLAKE2b instead of SHA3 with less Argon2; faster, but less secure.").Build()
|
giu.Tooltip(s("Uses BLAKE2b instead of SHA3 with less Argon2; faster, but less secure.")).Build()
|
||||||
|
|
||||||
giu.Checkbox("Use paranoid mode",¶noid).OnChange(func(){
|
giu.Checkbox(s("Use paranoid mode"),¶noid).OnChange(func(){
|
||||||
fast = false
|
fast = false
|
||||||
}).Build()
|
}).Build()
|
||||||
giu.Tooltip("Cascades Serpent with XChaCha20 plus high Argon2; highly secure, but slower.").Build()
|
giu.Tooltip(s("Uses Serpent and high Argon2; highly secure, but slower.")).Build()
|
||||||
|
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Checkbox("Encode with Reed-Solomon",&reedsolo),
|
giu.Checkbox(s("Encode with Reed-Solomon"),&reedsolo),
|
||||||
giu.Tooltip("Reed-Solomon can detect and fix corrupted data."),
|
giu.Tooltip(s("Reed-Solomon can detect and fix corrupted data.")),
|
||||||
giu.Button("?").Size(24,25).OnClick(func(){
|
giu.Button("?").Size(24,25).OnClick(func(){
|
||||||
browser.OpenURL(rsWikipedia)
|
browser.OpenURL(rsWikipedia)
|
||||||
}),
|
}),
|
||||||
).Build()
|
).Build()
|
||||||
|
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Checkbox("Split output into chunks of",&split),
|
giu.Checkbox(s("Split output into chunks of"),&split),
|
||||||
giu.Tooltip("Use this to split the output file into chunks."),
|
giu.Tooltip(s("Use this to split the output file into chunks.")),
|
||||||
giu.InputText(&splitSize).Size(50).Flags(giu.InputTextFlagsCharsDecimal).OnChange(func(){
|
giu.InputText(&splitSize).Size(50).Flags(giu.InputTextFlagsCharsDecimal).OnChange(func(){
|
||||||
if splitSize==""{
|
if splitSize==""{
|
||||||
split = false
|
split = false
|
||||||
|
@ -527,15 +543,15 @@ func startUI(){
|
||||||
|
|
||||||
giu.Dummy(0,1).Build()
|
giu.Dummy(0,1).Build()
|
||||||
}else if mode=="decrypt"{
|
}else if mode=="decrypt"{
|
||||||
giu.Checkbox("Keep decrypted output even if it's corrupted or modified",&keep).Build()
|
giu.Checkbox(s("Keep decrypted output even if it's corrupted or modified"),&keep).Build()
|
||||||
giu.Tooltip("Tells Picocrypt to always keep decrypted outputs.").Build()
|
giu.Tooltip(s("Tells Picocrypt to always keep decrypted outputs.")).Build()
|
||||||
|
|
||||||
giu.Checkbox("Delete the input file(s) after decryption",&deleteEncrypted).Build()
|
giu.Checkbox(s("Delete the input file(s) after decryption"),&deleteEncrypted).Build()
|
||||||
giu.Tooltip("Removes the encrypted Picocrypt volume (and chunks).").Build()
|
giu.Tooltip(s("Removes the encrypted Picocrypt volume (and chunks).")).Build()
|
||||||
giu.Dummy(0,112).Build()
|
giu.Dummy(0,112).Build()
|
||||||
}else{
|
}else{
|
||||||
giu.Dummy(0,67).Build()
|
giu.Dummy(0,67).Build()
|
||||||
giu.Label(" No files selected yet.").Build()
|
giu.Label(s(" No files selected yet.")).Build()
|
||||||
giu.Dummy(0,68).Build()
|
giu.Dummy(0,68).Build()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -543,12 +559,12 @@ func startUI(){
|
||||||
// Start button
|
// Start button
|
||||||
giu.Button("Start").Size(-0.0000001,35).OnClick(func(){
|
giu.Button("Start").Size(-0.0000001,35).OnClick(func(){
|
||||||
if mode=="encrypt"&&password!=cPassword{
|
if mode=="encrypt"&&password!=cPassword{
|
||||||
_status = "Passwords don't match."
|
_status = s("Passwords don't match.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if keyfile&&keyfilePath==""{
|
if keyfile&&keyfilePath==""{
|
||||||
_status = "Please select a keyfile."
|
_status = s("Please select a keyfile.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -584,20 +600,20 @@ func startUI(){
|
||||||
),
|
),
|
||||||
|
|
||||||
// File checksum generator tab
|
// File checksum generator tab
|
||||||
giu.TabItem("Checksum").Layout(
|
giu.TabItem(s("Checksum")).Layout(
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if giu.IsItemActive(){
|
if giu.IsItemActive(){
|
||||||
tab = 1
|
tab = 1
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
giu.Label("Toggle the hashes you would like to generate and drop a file here."),
|
giu.Label(s("Toggle the hashes you would like to generate and drop a file here.")),
|
||||||
|
|
||||||
// MD5
|
// MD5
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Checkbox("MD5:",&md5_selected),
|
giu.Checkbox("MD5:",&md5_selected),
|
||||||
giu.Dummy(-58,0),
|
giu.Dummy(-58,0),
|
||||||
giu.Button("Copy##md5").Size(50,0).OnClick(func(){
|
giu.Button(s("Copy")+"##md5").Size(50,0).OnClick(func(){
|
||||||
clipboard.WriteAll(cs_md5)
|
clipboard.WriteAll(cs_md5)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -609,7 +625,7 @@ func startUI(){
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Checkbox("SHA1:",&sha1_selected),
|
giu.Checkbox("SHA1:",&sha1_selected),
|
||||||
giu.Dummy(-58,0),
|
giu.Dummy(-58,0),
|
||||||
giu.Button("Copy##sha1").Size(50,0).OnClick(func(){
|
giu.Button(s("Copy")+"##sha1").Size(50,0).OnClick(func(){
|
||||||
clipboard.WriteAll(cs_sha1)
|
clipboard.WriteAll(cs_sha1)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -621,7 +637,7 @@ func startUI(){
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Checkbox("SHA256:",&sha256_selected),
|
giu.Checkbox("SHA256:",&sha256_selected),
|
||||||
giu.Dummy(-58,0),
|
giu.Dummy(-58,0),
|
||||||
giu.Button("Copy##sha256").Size(50,0).OnClick(func(){
|
giu.Button(s("Copy")+"##sha256").Size(50,0).OnClick(func(){
|
||||||
clipboard.WriteAll(cs_sha256)
|
clipboard.WriteAll(cs_sha256)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -633,7 +649,7 @@ func startUI(){
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Checkbox("SHA3-256:",&sha3_256_selected),
|
giu.Checkbox("SHA3-256:",&sha3_256_selected),
|
||||||
giu.Dummy(-58,0),
|
giu.Dummy(-58,0),
|
||||||
giu.Button("Copy##sha3_256").Size(50,0).OnClick(func(){
|
giu.Button(s("Copy")+"##sha3_256").Size(50,0).OnClick(func(){
|
||||||
clipboard.WriteAll(cs_sha3_256)
|
clipboard.WriteAll(cs_sha3_256)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -645,7 +661,7 @@ func startUI(){
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Checkbox("BLAKE2b:",&blake2b_selected),
|
giu.Checkbox("BLAKE2b:",&blake2b_selected),
|
||||||
giu.Dummy(-58,0),
|
giu.Dummy(-58,0),
|
||||||
giu.Button("Copy##blake2b").Size(50,0).OnClick(func(){
|
giu.Button(s("Copy")+"##blake2b").Size(50,0).OnClick(func(){
|
||||||
clipboard.WriteAll(cs_blake2b)
|
clipboard.WriteAll(cs_blake2b)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -657,7 +673,7 @@ func startUI(){
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Checkbox("BLAKE2s:",&blake2s_selected),
|
giu.Checkbox("BLAKE2s:",&blake2s_selected),
|
||||||
giu.Dummy(-58,0),
|
giu.Dummy(-58,0),
|
||||||
giu.Button("Copy##blake2s").Size(50,0).OnClick(func(){
|
giu.Button(s("Copy")+"##blake2s").Size(50,0).OnClick(func(){
|
||||||
clipboard.WriteAll(cs_blake2s)
|
clipboard.WriteAll(cs_blake2s)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -666,7 +682,7 @@ func startUI(){
|
||||||
),
|
),
|
||||||
|
|
||||||
// Input entry for validating a checksum
|
// Input entry for validating a checksum
|
||||||
giu.Label("Validate a checksum:"),
|
giu.Label(s("Validate a checksum:")),
|
||||||
giu.InputText(&cs_validate).Size(-0.0000001).OnChange(func(){
|
giu.InputText(&cs_validate).Size(-0.0000001).OnChange(func(){
|
||||||
md5_color = color.RGBA{0x10,0x10,0x10,255}
|
md5_color = color.RGBA{0x10,0x10,0x10,255}
|
||||||
sha1_color = color.RGBA{0x10,0x10,0x10,255}
|
sha1_color = color.RGBA{0x10,0x10,0x10,255}
|
||||||
|
@ -694,25 +710,25 @@ func startUI(){
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// Progress bar
|
// Progress bar
|
||||||
giu.Label("Progress:"),
|
giu.Label(s("Progress:")),
|
||||||
giu.ProgressBar(cs_progress).Size(-0.0000001,0),
|
giu.ProgressBar(cs_progress).Size(-0.0000001,0),
|
||||||
),
|
),
|
||||||
|
|
||||||
// File shredder tab
|
// File shredder tab
|
||||||
giu.TabItem("Shredder").Layout(
|
giu.TabItem(s("Shredder")).Layout(
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if giu.IsItemActive(){
|
if giu.IsItemActive(){
|
||||||
tab = 2
|
tab = 2
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
giu.Label("Drop file(s) and folder(s) here to shred them."),
|
giu.Label(s("Drop file(s) and folder(s) here to shred them.")),
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if runtime.GOOS=="darwin"{
|
if runtime.GOOS=="darwin"{
|
||||||
giu.Label("Number of passes: Not supported on macOS").Build()
|
giu.Label(s("Number of passes: Not supported on macOS")).Build()
|
||||||
}else{
|
}else{
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Label("Number of passes:"),
|
giu.Label(s("Number of passes:")),
|
||||||
giu.InputText(&shredPasses).Size(16).Flags(giu.InputTextFlagsCharsDecimal),
|
giu.InputText(&shredPasses).Size(16).Flags(giu.InputTextFlagsCharsDecimal),
|
||||||
).Build()
|
).Build()
|
||||||
}
|
}
|
||||||
|
@ -720,9 +736,9 @@ func startUI(){
|
||||||
giu.Dummy(0,-50),
|
giu.Dummy(0,-50),
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.ProgressBar(shredProgress).Overlay(shredOverlay).Size(-65,0),
|
giu.ProgressBar(shredProgress).Overlay(shredOverlay).Size(-65,0),
|
||||||
giu.Button("Cancel").Size(58,0).OnClick(func(){
|
giu.Button(s("Cancel")).Size(58,0).OnClick(func(){
|
||||||
stopShredding = true
|
stopShredding = true
|
||||||
shredding = "Ready."
|
shredding = s("Ready.")
|
||||||
shredProgress = 0
|
shredProgress = 0
|
||||||
shredOverlay = ""
|
shredOverlay = ""
|
||||||
}),
|
}),
|
||||||
|
@ -736,29 +752,29 @@ func startUI(){
|
||||||
),
|
),
|
||||||
|
|
||||||
// About tab
|
// About tab
|
||||||
giu.TabItem("About").Layout(
|
giu.TabItem(s("About")).Layout(
|
||||||
giu.Custom(func(){
|
giu.Custom(func(){
|
||||||
if giu.IsItemActive(){
|
if giu.IsItemActive(){
|
||||||
tab = 3
|
tab = 3
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
giu.Label("Picocrypt "+version+", created by Evan Su (https://evansu.cc)."),
|
giu.Label(fmt.Sprintf(s("Picocrypt %s, created by Evan Su (https://evansu.cc/)."),version)),
|
||||||
giu.Label("Released under a GNU GPL v3 License."),
|
giu.Label(s("Released under a GNU GPL v3 License.")),
|
||||||
giu.Label("A warm thank you to all the people listed below."),
|
giu.Label(s("A warm thank you to all the people listed below.")),
|
||||||
giu.Label("Patrons:"),
|
giu.Label(s("Patrons:")),
|
||||||
giu.Label(" - Frederick Doe"),
|
giu.Label(" - Frederick Doe"),
|
||||||
giu.Label("Donators:"),
|
giu.Label(s("Donators:")),
|
||||||
giu.Label(" - jp26"),
|
giu.Label(" - jp26"),
|
||||||
giu.Label(" - W.Graham"),
|
giu.Label(" - W.Graham"),
|
||||||
giu.Label(" - N. Chin"),
|
giu.Label(" - N. Chin"),
|
||||||
giu.Label(" - Manjot"),
|
giu.Label(" - Manjot"),
|
||||||
giu.Label(" - Phil P."),
|
giu.Label(" - Phil P."),
|
||||||
giu.Label(" - E. Zahard"),
|
giu.Label(" - E. Zahard"),
|
||||||
giu.Label("Translators"),
|
giu.Label(s("Translators:")),
|
||||||
giu.Label(" - umitseyhan75 (Turkish)"),
|
giu.Label(" - umitseyhan75 (Turkish)"),
|
||||||
giu.Label(" - digitalblossom (German)"),
|
giu.Label(" - digitalblossom (German)"),
|
||||||
giu.Label(" - maguszeal (Brazilian Portuguese)"),
|
giu.Label(" - maguszeal (Brazilian Portuguese)"),
|
||||||
giu.Label("Other"),
|
giu.Label(s("Other:")),
|
||||||
giu.Label(" - Fuderal for setting up Picocrypt's Discord server"),
|
giu.Label(" - Fuderal for setting up Picocrypt's Discord server"),
|
||||||
giu.Label(" - u/greenreddits for constant feedback and support"),
|
giu.Label(" - u/greenreddits for constant feedback and support"),
|
||||||
giu.Label(" - u/Tall_Escape for helping me test Picocrypt"),
|
giu.Label(" - u/Tall_Escape for helping me test Picocrypt"),
|
||||||
|
@ -771,7 +787,7 @@ func startUI(){
|
||||||
|
|
||||||
// Handle files dropped into Picocrypt by user
|
// Handle files dropped into Picocrypt by user
|
||||||
func onDrop(names []string){
|
func onDrop(names []string){
|
||||||
_status = "Ready."
|
_status = s("Ready.")
|
||||||
recombine = false
|
recombine = false
|
||||||
if tab==0{
|
if tab==0{
|
||||||
// Clear variables
|
// Clear variables
|
||||||
|
@ -784,7 +800,7 @@ func onDrop(names []string){
|
||||||
resetUI()
|
resetUI()
|
||||||
|
|
||||||
// Hide the ".pcv" label
|
// Hide the ".pcv" label
|
||||||
orLabel = "or"
|
orLabel = s("or")
|
||||||
outputWidth = 370
|
outputWidth = 370
|
||||||
|
|
||||||
// There's only one dropped item
|
// There's only one dropped item
|
||||||
|
@ -795,13 +811,13 @@ func onDrop(names []string){
|
||||||
if stat.IsDir(){
|
if stat.IsDir(){
|
||||||
mode = "encrypt"
|
mode = "encrypt"
|
||||||
folders++
|
folders++
|
||||||
inputLabel = "1 folder selected."
|
inputLabel = s("1 folder selected.")
|
||||||
|
|
||||||
// Add the folder
|
// Add the folder
|
||||||
onlyFolders = append(onlyFolders,names[0])
|
onlyFolders = append(onlyFolders,names[0])
|
||||||
|
|
||||||
// Set 'outputEntry' to 'Encrypted'
|
// Set 'outputEntry' to 'Encrypted'
|
||||||
outputEntry = filepath.Join(filepath.Dir(names[0]),"Encrypted")
|
outputEntry = filepath.Join(filepath.Dir(names[0]),s("Encrypted"))
|
||||||
|
|
||||||
// Show the ".zip.pcv" file extension
|
// Show the ".zip.pcv" file extension
|
||||||
orLabel = ".zip.pcv or"
|
orLabel = ".zip.pcv or"
|
||||||
|
@ -823,12 +839,12 @@ func onDrop(names []string){
|
||||||
if strings.HasSuffix(names[0],".pcv")||isSplit{
|
if strings.HasSuffix(names[0],".pcv")||isSplit{
|
||||||
var err error
|
var err error
|
||||||
mode = "decrypt"
|
mode = "decrypt"
|
||||||
inputLabel = name+" (will decrypt)"
|
inputLabel = name+s(" (will decrypt)")
|
||||||
metadataPrompt = "Metadata (read-only):"
|
metadataPrompt = s("Metadata (read-only):")
|
||||||
metadataState = giu.InputTextFlagsReadOnly
|
metadataState = giu.InputTextFlagsReadOnly
|
||||||
|
|
||||||
if isSplit{
|
if isSplit{
|
||||||
inputLabel = name+" (will recombine and decrypt)"
|
inputLabel = name+s(" (will recombine and decrypt)")
|
||||||
ind := strings.Index(names[0],".pcv")
|
ind := strings.Index(names[0],".pcv")
|
||||||
names[0] = names[0][:ind]
|
names[0] = names[0][:ind]
|
||||||
outputEntry = names[0]
|
outputEntry = names[0]
|
||||||
|
@ -850,14 +866,14 @@ func onDrop(names []string){
|
||||||
fin.Read(tmp)
|
fin.Read(tmp)
|
||||||
if string(tmp[:5])=="v1.13"{
|
if string(tmp[:5])=="v1.13"{
|
||||||
resetUI()
|
resetUI()
|
||||||
_status = "Please use Picocrypt v1.13 to decrypt this file."
|
_status = s("Please use Picocrypt v1.13 to decrypt this file.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if valid,_:=regexp.Match(`^v\d\.\d{2}.{10}0?\d+`,tmp);!valid&&!isSplit{
|
if valid,_:=regexp.Match(`^v\d\.\d{2}.{10}0?\d+`,tmp);!valid&&!isSplit{
|
||||||
resetUI()
|
resetUI()
|
||||||
_status = "This doesn't seem to be a Picocrypt volume."
|
_status = s("This doesn't seem to be a Picocrypt volume.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
return
|
return
|
||||||
|
@ -871,7 +887,7 @@ func onDrop(names []string){
|
||||||
tmp,_ = rsDecode(rs5,tmp)
|
tmp,_ = rsDecode(rs5,tmp)
|
||||||
if string(tmp)=="v1.14"||string(tmp)=="v1.15"||string(tmp)=="v1.16"{
|
if string(tmp)=="v1.14"||string(tmp)=="v1.15"||string(tmp)=="v1.16"{
|
||||||
resetUI()
|
resetUI()
|
||||||
_status = "Please use Picocrypt v1.16 to decrypt this file."
|
_status = s("Please use Picocrypt v1.16 to decrypt this file.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
return
|
return
|
||||||
|
@ -889,33 +905,33 @@ func onDrop(names []string){
|
||||||
for i:=0;i<metadataLength*3;i+=3{
|
for i:=0;i<metadataLength*3;i+=3{
|
||||||
t,err := rsDecode(rs1,tmp[i:i+3])
|
t,err := rsDecode(rs1,tmp[i:i+3])
|
||||||
if err!=nil{
|
if err!=nil{
|
||||||
metadata = "Metadata is corrupted."
|
metadata = s("Metadata is corrupted.")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
metadata += string(t)
|
metadata += string(t)
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
metadata = "Metadata is corrupted."
|
metadata = s("Metadata is corrupted.")
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := make([]byte,15)
|
flags := make([]byte,15)
|
||||||
fin.Read(flags)
|
fin.Read(flags)
|
||||||
flags,err = rsDecode(rs5,flags)
|
flags,err = rsDecode(rs5,flags)
|
||||||
if err!=nil{
|
if err!=nil{
|
||||||
_status = "Input file is corrupt and cannot be decrypted."
|
_status = s("Input file is corrupt and cannot be decrypted.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if flags[2]==1{
|
if flags[2]==1{
|
||||||
keyfile = true
|
keyfile = true
|
||||||
keyfileLabel = "Select keyfile"
|
keyfileLabel = s("Select keyfile")
|
||||||
}
|
}
|
||||||
|
|
||||||
fin.Close()
|
fin.Close()
|
||||||
}else{
|
}else{
|
||||||
mode = "encrypt"
|
mode = "encrypt"
|
||||||
inputLabel = name+" (will encrypt)"
|
inputLabel = name+s(" (will encrypt)")
|
||||||
outputEntry = names[0]
|
outputEntry = names[0]
|
||||||
|
|
||||||
// Show the ".pcv" file extension
|
// Show the ".pcv" file extension
|
||||||
|
@ -950,25 +966,25 @@ func onDrop(names []string){
|
||||||
|
|
||||||
if folders==0{
|
if folders==0{
|
||||||
// If folders==0, then there are multiple files
|
// If folders==0, then there are multiple files
|
||||||
inputLabel = fmt.Sprintf("%d files selected.",files)
|
inputLabel = fmt.Sprintf(s("%d files selected."),files)
|
||||||
}else if files==0{
|
}else if files==0{
|
||||||
// If files==0, then there are multiple folders
|
// If files==0, then there are multiple folders
|
||||||
inputLabel = fmt.Sprintf("%d folders selected.",folders)
|
inputLabel = fmt.Sprintf(s("%d folders selected."),folders)
|
||||||
}else{
|
}else{
|
||||||
// There are multiple files and folders
|
// There are multiple files and folders
|
||||||
if files==1&&folders>1{
|
if files==1&&folders>1{
|
||||||
inputLabel = fmt.Sprintf("1 file and %d folders selected.",folders)
|
inputLabel = fmt.Sprintf(s("1 file and %d folders selected."),folders)
|
||||||
}else if folders==1&&files>1{
|
}else if folders==1&&files>1{
|
||||||
inputLabel = fmt.Sprintf("%d files and 1 folder selected.",files)
|
inputLabel = fmt.Sprintf(s("%d files and 1 folder selected."),files)
|
||||||
}else if folders==1&&files==1{
|
}else if folders==1&&files==1{
|
||||||
inputLabel = "1 file and 1 folder selected."
|
inputLabel = s("1 file and 1 folder selected.")
|
||||||
}else{
|
}else{
|
||||||
inputLabel = fmt.Sprintf("%d files and %d folders selected.",files,folders)
|
inputLabel = fmt.Sprintf(s("%d files and %d folders selected."),files,folders)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set 'outputEntry' to 'Encrypted'
|
// Set 'outputEntry' to 'Encrypted'
|
||||||
outputEntry = filepath.Join(filepath.Dir(names[0]),"Encrypted")
|
outputEntry = filepath.Join(filepath.Dir(names[0]),s("Encrypted"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are folders that were dropped, recusively add all files into 'allFiles'
|
// If there are folders that were dropped, recusively add all files into 'allFiles'
|
||||||
|
@ -996,7 +1012,7 @@ func onDrop(names []string){
|
||||||
// Start encryption/decryption
|
// Start encryption/decryption
|
||||||
func work(){
|
func work(){
|
||||||
// Set some variables
|
// Set some variables
|
||||||
status = "Starting..."
|
status = s("Starting...")
|
||||||
working = true
|
working = true
|
||||||
padded := false
|
padded := false
|
||||||
var salt []byte
|
var salt []byte
|
||||||
|
@ -1012,7 +1028,7 @@ func work(){
|
||||||
|
|
||||||
// Set the output file based on mode
|
// Set the output file based on mode
|
||||||
if mode=="encrypt"{
|
if mode=="encrypt"{
|
||||||
status = "Combining files..."
|
status = s("Combining files...")
|
||||||
|
|
||||||
// "Tar" files into a zip archive with a compression level of 0 (store)
|
// "Tar" files into a zip archive with a compression level of 0 (store)
|
||||||
if len(allFiles)>1||len(onlyFolders)>0{
|
if len(allFiles)>1||len(onlyFolders)>0{
|
||||||
|
@ -1033,7 +1049,7 @@ func work(){
|
||||||
w.Close()
|
w.Close()
|
||||||
file.Close()
|
file.Close()
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
_status = "Operation cancelled by user."
|
_status = s("Operation cancelled by user.")
|
||||||
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1066,7 +1082,7 @@ func work(){
|
||||||
}
|
}
|
||||||
|
|
||||||
if recombine{
|
if recombine{
|
||||||
status = "Recombining file..."
|
status = s("Recombining file...")
|
||||||
total := 0
|
total := 0
|
||||||
|
|
||||||
if strings.HasSuffix(inputFile,".pcv"){
|
if strings.HasSuffix(inputFile,".pcv"){
|
||||||
|
@ -1114,7 +1130,7 @@ func work(){
|
||||||
|
|
||||||
// XChaCha20's max message size is 256 GiB
|
// XChaCha20's max message size is 256 GiB
|
||||||
if total>256*1073741824{
|
if total>256*1073741824{
|
||||||
_status = "Total size is larger than 256 GiB, XChaCha20's limit."
|
_status = s("Total size is larger than 256 GiB, XChaCha20's limit.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1125,7 +1141,7 @@ func work(){
|
||||||
|
|
||||||
// If encrypting, generate values; If decrypting, read values from file
|
// If encrypting, generate values; If decrypting, read values from file
|
||||||
if mode=="encrypt"{
|
if mode=="encrypt"{
|
||||||
status = "Generating values..."
|
status = s("Generating values...")
|
||||||
giu.Update()
|
giu.Update()
|
||||||
fout,_ = os.OpenFile(
|
fout,_ = os.OpenFile(
|
||||||
outputFile,
|
outputFile,
|
||||||
|
@ -1215,7 +1231,7 @@ func work(){
|
||||||
var err9 error
|
var err9 error
|
||||||
var err10 error
|
var err10 error
|
||||||
|
|
||||||
status = "Reading values..."
|
status = s("Reading values...")
|
||||||
giu.Update()
|
giu.Update()
|
||||||
version := make([]byte,15)
|
version := make([]byte,15)
|
||||||
fin.Read(version)
|
fin.Read(version)
|
||||||
|
@ -1270,7 +1286,7 @@ func work(){
|
||||||
if keep{
|
if keep{
|
||||||
kept = true
|
kept = true
|
||||||
}else{
|
}else{
|
||||||
_status = "The header is corrupt and the input file cannot be decrypted."
|
_status = s("The header is corrupt and the input file cannot be decrypted.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
return
|
return
|
||||||
|
@ -1278,7 +1294,7 @@ func work(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = "Deriving key..."
|
status = s("Deriving key...")
|
||||||
progress = 0
|
progress = 0
|
||||||
progressInfo = ""
|
progressInfo = ""
|
||||||
giu.Update()
|
giu.Update()
|
||||||
|
@ -1315,7 +1331,7 @@ func work(){
|
||||||
}
|
}
|
||||||
|
|
||||||
if !working{
|
if !working{
|
||||||
_status = "Operation cancelled by user."
|
_status = s("Operation cancelled by user.")
|
||||||
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
|
@ -1370,9 +1386,9 @@ func work(){
|
||||||
}else{
|
}else{
|
||||||
fin.Close()
|
fin.Close()
|
||||||
if !keyCorrect{
|
if !keyCorrect{
|
||||||
_status = "The provided password is incorrect."
|
_status = s("The provided password is incorrect.")
|
||||||
}else{
|
}else{
|
||||||
_status = "The provided keyfile is incorrect."
|
_status = s("The provided keyfile is incorrect.")
|
||||||
}
|
}
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
key = nil
|
key = nil
|
||||||
|
@ -1421,7 +1437,7 @@ func work(){
|
||||||
|
|
||||||
for{
|
for{
|
||||||
if !working{
|
if !working{
|
||||||
_status = "Operation cancelled by user."
|
_status = s("Operation cancelled by user.")
|
||||||
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
|
@ -1491,7 +1507,7 @@ func work(){
|
||||||
if keep{
|
if keep{
|
||||||
kept = true
|
kept = true
|
||||||
}else{
|
}else{
|
||||||
_status = "The input file is too corrupted to decrypt."
|
_status = s("The input file is too corrupted to decrypt.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
|
@ -1513,7 +1529,7 @@ func work(){
|
||||||
if keep{
|
if keep{
|
||||||
kept = true
|
kept = true
|
||||||
}else{
|
}else{
|
||||||
_status = "The input file is too corrupted to decrypt."
|
_status = s("The input file is too corrupted to decrypt.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
|
@ -1529,7 +1545,7 @@ func work(){
|
||||||
if keep{
|
if keep{
|
||||||
kept = true
|
kept = true
|
||||||
}else{
|
}else{
|
||||||
_status = "The input file is too corrupted to decrypt."
|
_status = s("The input file is too corrupted to decrypt.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
|
@ -1570,7 +1586,7 @@ func work(){
|
||||||
}
|
}
|
||||||
|
|
||||||
progressInfo = fmt.Sprintf("%.2f%%",progress*100)
|
progressInfo = fmt.Sprintf("%.2f%%",progress*100)
|
||||||
status = fmt.Sprintf("Working at %.2f MB/s (ETA: %s)",speed,humanize(eta))
|
status = fmt.Sprintf(s("Working at %.2f MB/s (ETA: %s)"),speed,humanize(eta))
|
||||||
giu.Update()
|
giu.Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1600,7 +1616,7 @@ func work(){
|
||||||
// Split files into chunks
|
// Split files into chunks
|
||||||
if split{
|
if split{
|
||||||
var splitted []string
|
var splitted []string
|
||||||
status = "Splitting file..."
|
status = s("Splitting file...")
|
||||||
stat,_ := os.Stat(outputFile)
|
stat,_ := os.Stat(outputFile)
|
||||||
size := stat.Size()
|
size := stat.Size()
|
||||||
finished := 0
|
finished := 0
|
||||||
|
@ -1629,7 +1645,7 @@ func work(){
|
||||||
if !working{
|
if !working{
|
||||||
fin.Close()
|
fin.Close()
|
||||||
fout.Close()
|
fout.Close()
|
||||||
_status = "Operation cancelled by user."
|
_status = s("Operation cancelled by user.")
|
||||||
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
||||||
|
|
||||||
// If user cancels, remove the unfinished files
|
// If user cancels, remove the unfinished files
|
||||||
|
@ -1660,7 +1676,7 @@ func work(){
|
||||||
fin.Close()
|
fin.Close()
|
||||||
if shredTemp{
|
if shredTemp{
|
||||||
progressInfo = ""
|
progressInfo = ""
|
||||||
status = "Shredding temporary files..."
|
status = s("Shredding temporary files...")
|
||||||
shred([]string{outputFile}[:],false)
|
shred([]string{outputFile}[:],false)
|
||||||
}else{
|
}else{
|
||||||
os.Remove(outputFile)
|
os.Remove(outputFile)
|
||||||
|
@ -1676,7 +1692,7 @@ func work(){
|
||||||
if len(allFiles)>1||len(onlyFolders)>0{
|
if len(allFiles)>1||len(onlyFolders)>0{
|
||||||
if shredTemp{
|
if shredTemp{
|
||||||
progressInfo = ""
|
progressInfo = ""
|
||||||
status = "Shredding temporary files..."
|
status = s("Shredding temporary files...")
|
||||||
giu.Update()
|
giu.Update()
|
||||||
shred([]string{outputEntry+".zip"}[:],false)
|
shred([]string{outputEntry+".zip"}[:],false)
|
||||||
}else{
|
}else{
|
||||||
|
@ -1704,10 +1720,10 @@ func work(){
|
||||||
|
|
||||||
// If user chose to keep a corrupted/modified file, let them know
|
// If user chose to keep a corrupted/modified file, let them know
|
||||||
if kept{
|
if kept{
|
||||||
_status = "The input file is corrupted and/or modified. Please be careful."
|
_status = s("The input file is corrupted and/or modified. Please be careful.")
|
||||||
_status_color = color.RGBA{0xff,0xff,0x00,255}
|
_status_color = color.RGBA{0xff,0xff,0x00,255}
|
||||||
}else{
|
}else{
|
||||||
_status = "Completed."
|
_status = s("Completed.")
|
||||||
_status_color = color.RGBA{0x00,0xff,0x00,255}
|
_status_color = color.RGBA{0x00,0xff,0x00,255}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1715,12 +1731,12 @@ func work(){
|
||||||
working = false
|
working = false
|
||||||
kept = false
|
kept = false
|
||||||
key = nil
|
key = nil
|
||||||
status = "Ready."
|
status = s("Ready.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is run if an issue occurs during decryption
|
// This function is run if an issue occurs during decryption
|
||||||
func broken(){
|
func broken(){
|
||||||
_status = "The input file is either corrupted or intentionally modified."
|
_status = s("The input file is either corrupted or intentionally modified.")
|
||||||
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
_status_color = color.RGBA{0xff,0x00,0x00,255}
|
||||||
if recombine{
|
if recombine{
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
|
@ -1749,22 +1765,22 @@ func generateChecksums(file string){
|
||||||
cs_validate = ""
|
cs_validate = ""
|
||||||
|
|
||||||
if md5_selected{
|
if md5_selected{
|
||||||
cs_md5 = "Calculating..."
|
cs_md5 = s("Calculating...")
|
||||||
}
|
}
|
||||||
if sha1_selected{
|
if sha1_selected{
|
||||||
cs_sha1 = "Calculating..."
|
cs_sha1 = s("Calculating...")
|
||||||
}
|
}
|
||||||
if sha256_selected{
|
if sha256_selected{
|
||||||
cs_sha256 = "Calculating..."
|
cs_sha256 = s("Calculating...")
|
||||||
}
|
}
|
||||||
if sha3_256_selected{
|
if sha3_256_selected{
|
||||||
cs_sha3_256 = "Calculating..."
|
cs_sha3_256 = s("Calculating...")
|
||||||
}
|
}
|
||||||
if blake2b_selected{
|
if blake2b_selected{
|
||||||
cs_blake2b = "Calculating..."
|
cs_blake2b = s("Calculating...")
|
||||||
}
|
}
|
||||||
if blake2s_selected{
|
if blake2s_selected{
|
||||||
cs_blake2s = "Calculating..."
|
cs_blake2s = s("Calculating...")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the checksum objects
|
// Create the checksum objects
|
||||||
|
@ -1842,7 +1858,7 @@ func shred(names []string,separate bool){
|
||||||
|
|
||||||
// 'separate' is true if this function is being called from the encryption/decryption tab
|
// 'separate' is true if this function is being called from the encryption/decryption tab
|
||||||
if separate{
|
if separate{
|
||||||
shredOverlay = "Shredding..."
|
shredOverlay = s("Shredding...")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk through directories to get the total number of files for statistics
|
// Walk through directories to get the total number of files for statistics
|
||||||
|
@ -1995,7 +2011,7 @@ func shred(names []string,separate bool){
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear UI state
|
// Clear UI state
|
||||||
shredding = "Completed."
|
shredding = s("Completed.")
|
||||||
shredProgress = 0
|
shredProgress = 0
|
||||||
shredOverlay = ""
|
shredOverlay = ""
|
||||||
}
|
}
|
||||||
|
@ -2015,17 +2031,17 @@ func shredUpdate(separate bool){
|
||||||
// Reset the UI to a clean state with nothing selected or checked
|
// Reset the UI to a clean state with nothing selected or checked
|
||||||
func resetUI(){
|
func resetUI(){
|
||||||
mode = ""
|
mode = ""
|
||||||
inputLabel = "Drag and drop file(s) and folder(s) into this window."
|
inputLabel = s("Drag and drop file(s) and folder(s) into this window.")
|
||||||
outputEntry = ""
|
outputEntry = ""
|
||||||
orLabel = "or"
|
orLabel = s("or")
|
||||||
outputWidth = 370
|
outputWidth = 370
|
||||||
password = ""
|
password = ""
|
||||||
cPassword = ""
|
cPassword = ""
|
||||||
keyfileLabel = "Use a keyfile"
|
keyfileLabel = s("Use a keyfile")
|
||||||
keyfilePath = ""
|
keyfilePath = ""
|
||||||
keyfile = false
|
keyfile = false
|
||||||
metadata = ""
|
metadata = ""
|
||||||
metadataPrompt = "Metadata (optional):"
|
metadataPrompt = s("Metadata (optional):")
|
||||||
metadataState = giu.InputTextFlagsNone
|
metadataState = giu.InputTextFlagsNone
|
||||||
shredTemp = false
|
shredTemp = false
|
||||||
keep = false
|
keep = false
|
||||||
|
@ -2037,7 +2053,7 @@ func resetUI(){
|
||||||
paranoid = false
|
paranoid = false
|
||||||
progress = 0
|
progress = 0
|
||||||
progressInfo = ""
|
progressInfo = ""
|
||||||
_status = "Ready."
|
_status = s("Ready.")
|
||||||
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
_status_color = color.RGBA{0xff,0xff,0xff,255}
|
||||||
giu.Update()
|
giu.Update()
|
||||||
}
|
}
|
||||||
|
@ -2125,7 +2141,56 @@ func genPassword() string{
|
||||||
return string(tmp)
|
return string(tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func s(term string) string{
|
||||||
|
for _,i := range locales{
|
||||||
|
if i.iso==selectedLocale{
|
||||||
|
for _,j := range locales{
|
||||||
|
if j.iso=="en"{
|
||||||
|
for k,l := range j.data{
|
||||||
|
if l==term{
|
||||||
|
return i.data[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return term
|
||||||
|
}
|
||||||
|
|
||||||
func main(){
|
func main(){
|
||||||
|
// Parse locales
|
||||||
|
var obj map[string]json.RawMessage
|
||||||
|
json.Unmarshal(localeBytes,&obj)
|
||||||
|
for i := range obj{
|
||||||
|
var tmp []string
|
||||||
|
json.Unmarshal(obj[i],&tmp)
|
||||||
|
locales = append(locales,locale{
|
||||||
|
iso:i,
|
||||||
|
data:tmp,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check system locale
|
||||||
|
for _,i := range locales{
|
||||||
|
tmp,err := jibber_jabber.DetectIETF()
|
||||||
|
if err==nil{
|
||||||
|
if strings.HasPrefix(tmp,i.iso){
|
||||||
|
selectedLocale = i.iso
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inputLabel = s("Drag and drop file(s) and folder(s) into this window.")
|
||||||
|
orLabel = s("or")
|
||||||
|
status = s("Ready.")
|
||||||
|
_status = s("Ready.")
|
||||||
|
shredding = s("Ready.")
|
||||||
|
passwordStateLabel = s("Show")
|
||||||
|
keyfileLabel = s("Keyfile")
|
||||||
|
metadataPrompt = s("Metadata (optional):")
|
||||||
|
|
||||||
// Create a temporary file to store sdelete64.exe
|
// Create a temporary file to store sdelete64.exe
|
||||||
sdelete64,_ := os.CreateTemp("","sdelete64.*.exe")
|
sdelete64,_ := os.CreateTemp("","sdelete64.*.exe")
|
||||||
sdelete64path = sdelete64.Name()
|
sdelete64path = sdelete64.Name()
|
||||||
|
@ -2143,7 +2208,7 @@ func main(){
|
||||||
v.Body.Close()
|
v.Body.Close()
|
||||||
if err==nil{
|
if err==nil{
|
||||||
if string(body[:5])!=version{
|
if string(body[:5])!=version{
|
||||||
_status = "A newer version is available."
|
_status = s("A newer version is available.")
|
||||||
_status_color = color.RGBA{0,255,0,255}
|
_status_color = color.RGBA{0,255,0,255}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2164,7 +2229,7 @@ func main(){
|
||||||
window.SetDropCallback(onDrop)
|
window.SetDropCallback(onDrop)
|
||||||
window.SetCloseCallback(func() bool{
|
window.SetCloseCallback(func() bool{
|
||||||
// Disable closing window if a Picocrypt is working to prevent temporary files
|
// Disable closing window if a Picocrypt is working to prevent temporary files
|
||||||
if working||(shredding!="Ready."&&shredding!="Completed."){
|
if working||(shredding!=s("Ready.")&&shredding!=s("Completed.")){
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
Loading…
Reference in New Issue