SciViews / tcltk2

Other
2 stars 1 forks source link

Crashes when loading in RStudio #9

Open josegonzalezpastor opened 3 months ago

josegonzalezpastor commented 3 months ago

Loading the library crashes RStudio.

A quick fix in the setLanguage.R file solved the issue, but I cannot push it. File content is copied here below:

RStudio version: RStudio 2022.07.1+554 "Spotted Wakerobin" Release (7872775ebddc40635780ca1ed238934c3345c5de, 2022-07-22) for Windows Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.12.8 Chrome/69.0.3497.128 Safari/537.36

sessionInfo() R version 4.2.0 (2022-04-22 ucrt) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows Server x64 (build 14393)

Matrix products: default

locale: [1] LC_COLLATE=Dutch_Belgium.1252 LC_CTYPE=Dutch_Belgium.1252 LC_MONETARY=Dutch_Belgium.1252 LC_NUMERIC=C LC_TIME=Dutch_Belgium.1252

attached base packages: [1] stats graphics grDevices utils datasets methods base

loaded via a namespace (and not attached): [1] compiler_4.2.0 tools_4.2.0

R/setLanguage.R with fix:

Management of locales and message translation using msgcat

' Change or get the language used in R and Tcl/Tk, strings translation in Tcl

'

' The function changes dynamically the language used by both R (messages only)

' and Tcl/Tk, retrieves its current value, and manage string translation in

' Tcl.

'

' @param lang An identification for the targeted language, for instance, \"en\"

' for English, \"en_US\" for american English, \"fr\" for French, \"de\" for

' German, \"it\" for Italian, etc. Facultative argument for [tclmclocale()].

' @param msg A single character string with the message to translate.

' @param translation The corresponding version in lang. Substitutions markers

' like \%s for strings, or \%d for numbers are allowed (same syntax as

' [base::gettextf()]). These translations are added in the Tcl catalog in the

' main domain, i.e., you don't need to give a domain name with [tclmc()] to

' retrieve the translation.

' @param fmt A single character vector of format string.

' @param ... Values to be passed into \code{fmt} for the substitution.

' @param domain The 'domain", i;e., Tcl namespace where the translation is

' defined. Use NULL (the default) or "" for the main domain where

' translations using [tclmcset()] are stored.

'

' @return

' [setLanguage()] returns TRUE if language was successfully changed in

' Tcl/Tk, FALSE otherwise. [getLanguage()] returns a string with current

' language in use for R, or an empty string if it cannot determinate which is

' the language currently used, and a tcl.language attribute with the

' different catalogs that are used in priority order (ending with "" for no

' translation, i.e., Tcl translations do not return an error, but the initial

' string if the item is not found in the catalog).

' [tclmclocale()] allows to change and get language for Tcl only, without

' changing anything for R.

'

' The two functions [tclmcset()] and [tclmc()] allow to record and retrieve the

' translation of strings in the main R domain. Moreover, [tclmc()] also allows

' to retrieve translations of Tcl strings in other Tcl namespaces (a.k.a.,

' domains), see the examples.

'

' @note You need the msgcat Tcl package to use this (but it is provided with

' all recent distributions of Tcl/Tk by default).

'

' @author Philippe Grosjean

' @export

' @keywords utilities

' @concept Tcl/Tk language translation

'

' @examples

' # What is the language used by Tcl?

' tclmclocale()

'

' # Define a simple translation in French and German

' tclmcset("de", "Yes", "Ja")

' tclmcset("fr", "Yes", "Oui")

'

' # Determine which language is currently in use in R

' (oldlang <- getLanguage())

' if (oldlang != "") {

' # Switch to English; test a command that issues a warning and a Tcl string

' setLanguage("en_US")

' 1:3 + 1:2

' tclmc("Yes")

'

' # Switch to German and test

' setLanguage("de")

' 1:3 + 1:2

' tclmc("Yes")

'

' # Switch to Belgian French and test

' setLanguage("fr_BE")

' 1:3 + 1:2

' tclmc("Yes")

'

' # A more complex trnaslation message with a substitution

' tclmcset("fr", "Directory contains %d files",

' "Le repertoire contient %d fichiers")

' tclmc("Directory contains %d files", 9)

' # or from a R/Tcl variable...

' nfiles <- tclVar(12)

' tclmc("Directory contains %d files", tclvalue(nfiles))

'

' # Retrieve a translation defined in the "tk" domain

' tclmc("Replace existing file?", domain = "tk")

'

' # Tcl dialog boxes are translated according to the current language

' \dontrun{

' tkgetOpenFile()

' }

'

' # Restore previous language

' setLanguage(oldlang)

' }

setLanguage <- function(lang) {

Change locale for both R and Tcl/Tk

Sys.setenv(language = lang) Sys.setenv(LANG = lang)

try(Sys.setlocale("LC_MESSAGES", lang), silent = TRUE) # Fails on Windows!

res <- tclRequire("msgcat") if (inherits(res, "tclObj")) { .Tcl("namespace import msgcat::*")

If the tcl.language attribute is defined, use it

tcllang <- attr(lang, "tcl.language")
if (!is.null(tcllang) && tcllang[1] != "") {
  lang <- tcllang[1] # Use only first item
} else {
  # Tcl does not accept locales like en_US.UF-8: must be en_us only
  lang <- tolower(sub("^([^.]+)\\..*$", "\\1", lang))
}
tclmclocale(lang)
TRUE

} else { FALSE } }

' @export

' @rdname setLanguage

getLanguage <- function() {

Try to recover current language used for messages and GUI stuff in R

lang <- Sys.getenv("language") if (lang == "") lang <- Sys.getlocale("LC_MESSAGES")

This is a bad hack that probably does not work all the time, but at least,

it works under Windows for getting "fr" for French language

if (lang == "") lang <- tolower(substr(Sys.getlocale("LC_COLLATE"), 1, 2))

Try to get language information from Tcl

tcllang <- try(as.character(tcl("mcpreferences")), silent = TRUE) attr(lang, "tcl.language") <- tcllang

lang }

' @export

' @rdname setLanguage

tclmclocale <- function(lang) { if (missing(lang)) { as.character(tcl("mclocale")) } else {

Make sure lang is made compatible to Tcl

lang <- tolower(sub("^([^.]+)\\..*$", "\\1", lang))
as.character(tcl("mclocale", lang))

} }

' @export

' @rdname setLanguage

tclmcset <- function(lang, msg, translation) invisible(tclvalue(tcl("mcset", lang, msg, translation)))

' @export

' @rdname setLanguage

tclmc <- function(fmt, ..., domain = NULL) { if (is.null(domain) || domain == "") {

Simpler form

tclvalue(tcl("mc", fmt, ...))

} else {

Need to evaluate in 'domain' Tcl namespace

transl <- .Tcl(paste0("namespace eval ", domain, " {set ::Rtransl [mc {",
  fmt, "}]}"))
sprintf(tclvalue(transl), ...)

} }

GegznaV commented 2 months ago

@josegonzalezpastor, can you create a pull request?