Question

Suppose (using R/gWidgets) we have a simple text window like this:

require(gWidgets)
textwin <- gtext("The camel grazes in the desert.", container=gwindow())

When selecting text with the mouse we can retrieve the selected text.

svalue(textwin, drop=T) # returns text
## [1] "grazes"

Now my question is: Is there a way of replacing the selected text in a gtext?

Was it helpful?

Solution

Retrieve the whole string and the selected string.

all_text <- svalue(textwin, index=0)
selected_text <- svalue(textwin, index=0, drop = TRUE)

Then find the index of the selected substring using regexpr.

rx_match <- regexpr(selected_text, all_text, fixed = TRUE)

Replace that substring with something else.

substring(
  all_text, 
  rx_match, 
  rx_match + attr(rx_match, "match.length") - 1
) <- "monkey"

Update the textbox.

svalue(textwin) <- all_text

Plan B: manipulate the return value from svalue with index = 1. This is nearly right, but I think that there's a bug in gWidgets that stop it from working generally.

# Get the index of the lines/character positions to start and finish
i <- format(svalue(textwin, index = 1, drop = TRUE), digits = 3)
i <- sapply(strsplit(i, "\\."), as.numeric)

# Get all the text as a character vector
all_text <- svalue(textwin, index=0)
all_text <- strsplit(all_text, "\n")[[1]]

# Replace the selected portion
replacement <- "monkey"

if(i[1, 1] == i[1, 2])
{
  svalue(textwin) <- substring(all_text[i[1, 1]], i[2, 1], i[2, 2])
} else
{
    all_text[i[1, 1]] <- paste0(
      substring(all_text[i[1, 1]], 1, i[2, 1]),  
      replacement,
      substring(all_text[i[1, 2]], 1, i[2, 2])
    )
    svalue(textwin) <- all_text[-((i[1, 1] + 1):(i[1, 2]))]
}

The big problem is with the call to format that turns the index numbers into strings. It doesn't play well with positions in single digit versus double digit positions. I'm fairly certain that this is a bug in getMethod(.svalue, signature("gTexttcltk", "guiWidgetsToolkittcltk")) (though there might be problems in other toolkits too).

OTHER TIPS

Since Richie says I'm good about fixing things, here you go:

In gWidgets2 this feature has been added to the development versions on github. Use devtools to install.

I'm trying to only fix bugs in gWidgets and this is a new feature, so I'm not going to add it there. However, here is some code you can easily use within your project:

library(RGtk2)    
replace_selected <- function(gtext_widget, value) {

  view <- gtext_widget@widget@widget

  buffer <- view$getBuffer()

  bnds <- buffer$getSelectionBounds()

  if(bnds$retval) {

    buffer$insert(bnds$start, as.character(value), -1)

    new_bnds <- buffer$getSelectionBounds()

    buffer$delete(new_bnds$start, new_bnds$end)

  }
}

## replace_selected in gWidgetstcltk

replace_selected <- function(gtext_widget, value) {

  widget <- gtext_widget@widget@widget

  range <- as.numeric(tktag.ranges(widget, "sel"))

  if (length(range) > 0)

     tcl(widget,"replace", "sel.first", "sel.last", value)

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top