Robin Dunn
Neil Hodgson wrote:
Joseph D. Poirier:
When copying a rectangular selection of text, then pasting it
to a rectangular selection in another part of a file - both rectangular
selections are equal in size - the rectangular paste doesn't seem to
respect the selection boundaries.With Scintilla for Windows, a rectangular selection is represented on the
clipboard by two objects: the text and an empty object of type
"MSDEVColumnSelect" which is compatible with Visual Studio. The paste
operation is performed differently if the rectangular marker
"MSDEVColumnSelect" is present. With Scintilla for GTK+ on X the same effect
is produced by ending the text wth a \n\0 marker.Looks like wxStyledTextControl does not do anything to store or retrieve
a rectangular marker.
I'll add this to my ToDo list, but I wouldn't mind if somebody beat me
to it and submitted a patch.
Thanks for the previous input:
Fortunately the SelectionIsRectangle() flag is being set, and as it turned out
implementing a temporary fix was pretty easy. I've attached the code snippet
below for any one that might be interested.
Notes:
- The code is fairly simple, ie., it's a first run with no tricks or optimizations,
etc., and doesn't seem to get in the way of anything else.
- It works similar to the SciTE editor, where the paste area doesn't actually
have to be a rectangular selection - although I had specified pasting to a
rectangular selection in my original email. The insertion of the rectangular
copied text starts at the current caret position.
- The code includes an EOL check so it should be cross platform.
- Due to the iterative nature of the string insertion for each row, there are an
equal number of "undo" actions required to get back to the starting state.
O'well, I guess you can't have everything!
Joe
···
#=================================================
#=== OnCopy event handler
def OnCopy(self, event):
# Explicitly set the column_edit_flag for each pass.
if self.SelectionIsRectangle():
self.column_edit_flag = True
else:
self.column_edit_flag = False
self.CmdKeyExecute(stc.wxSTC_CMD_COPY)
#=================================================
#=== OnPaste event handler
def OnPaste(self, event):
# Override CndKetExecute if the column_edit_flag is set.
if self.column_edit_flag:
self.ColumnEdit()
else:
self.CmdKeyExecute(stc.wxSTC_CMD_PASTE)
#=================================================
#===
def ColumnEdit(self):
# Create the data object we'll use to store the clipboard data.
data_obj = wx.wxTextDataObject()
wx.wxTheClipboard.Open()
# Continue only if there's data...
if wx.wxTheClipboard.GetData(data_obj):
# Get the actual text...
data = data_obj.GetText()
# What's the EOL format?
current_EOL_mode = self.GetEOLMode()
if current_EOL_mode == stc.wxSTC_EOL_CR:
eol_char = '\r'
elif current_EOL_mode == stc.wxSTC_EOL_LF:
eol_char = '\n'
else: # current_EOL_mode == stc.wxSTC_EOL_CRLF
eol_char = '\r\n'
# ...and create a list with newlines removed. Each item in the list
# is implicitly associated to its own row...it'll make sense later.
data = data.split(eol_char)
# Remove the Null character as well.
del data[len(data)-1]
# Derive some useful info:
total_columns = len(data[0])
start_pos = self.GetCurrentPos()
# The start (and ending) column position remain constant.
start_column = self.GetColumn(start_pos)
# Derive the starting row position.
start_row = self.LineFromPosition(start_pos)
# Now increment through each line, using i to increment the line
# count. It's also used as an index into the data list, where the
# first item in the list goes on the first line, etc...
for i in range(len(data)):
# Calculate the selection start position. Note, that this starts
# before the first character.
sel_start = self.PositionFromLine(start_row + i) + start_column
# Calculate the selection end position. Note, that this ends
# after the last character.
sel_end = sel_start + total_columns
# Set the selection...
self.SetSelection(sel_start, sel_end)
# ...now replace the selection with a list item.
self.ReplaceSelection(data[i])
# For convenience we'll jump back to where we originally started.
self.GotoPos(start_pos)
wx.wxTheClipboard.Close()
Joseph D. Poirier
DSP Software
IMN, Nokia Inc.
6000 Connection Drive
Irving, TX 75039