[Developer] Re-implement Convert-to-character command in web text editor

This commit is contained in:
Marc Durdin 2018-08-30 08:57:05 +10:00
parent 4cee15d20d
commit 57c658d98b
4 changed files with 112 additions and 68 deletions

View file

@ -22,6 +22,8 @@ unit KMDActionInterfaces;
interface
uses
System.Types,
TextFileFormat;
type
@ -74,9 +76,15 @@ type
function GetText: string;
procedure SetText(const Value: string);
function GetSelectedRow: Integer;
function GetSelectedCol: Integer;
function GetSelectedRange: TRect;
function GetEditorFormat: TEditorFormat;
procedure ReplaceSelection(ARange: TRect; const ANewText: string);
property EditorFormat: TEditorFormat read GetEditorFormat;
property SelectedRow: Integer read GetSelectedRow;
property SelectedCol: Integer read GetSelectedCol;
property SelectedRange: TRect read GetSelectedRange;
property Text: string read GetText write SetText;
end;

View file

@ -1,18 +1,18 @@
(*
Name: dmActionsTextEditor
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Documentation:
Description:
Create Date: 23 Aug 2006
Modified Date: 24 Jul 2015
Authors: mcdurdin
Related Files:
Dependencies:
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
Bugs:
Todo:
Notes:
History: 23 Aug 2006 - mcdurdin - Initial version
30 Aug 2006 - mcdurdin - Add Reformat XML action
04 Dec 2006 - mcdurdin - Localize
@ -32,8 +32,10 @@ interface
uses
System.Actions,
System.Character,
System.Classes,
System.SysUtils,
System.Types,
Vcl.ActnList,
Vcl.Menus,
@ -74,57 +76,51 @@ uses
{$R *.dfm}
procedure TmodActionsTextEditor.actTextEditor_ConvertToCharactersExecute(Sender: TObject);
{var
ws: WideString;
x, len: Integer;
memo: TframeTextEditor;
line, seltext: WideString;
i: Integer;
FToCodes: Boolean;
FError: Boolean;
res: string;
FInQuotes: Boolean;}
var
a: IKMDTextEditorActions;
FRange: TRect;
i, len: Integer;
res, ws, FText, newtext, seltext: string;
FError, FInQuotes, FToCodes: Boolean;
begin
{TODO: reimplement in JS probably better
memo := Screen.ActiveControl as TKeymanDeveloperMemo;
line := memo.LinesArray[memo.SelLine];
seltext := memo.SelText;
x := memo.SelCol+1;
len := 0;
a := KMDActions.GetTextEditorController(Screen.ActiveControl);
if memo.SelLength = 0 then // I4797
begin
// Select the token under the cursor
seltext := GetTokenFromCaret(line, x, len);
memo.SelCol := x-1;
memo.SelLength := len;
end;
FText := a.Text;
FRange := a.SelectedRange;
if memo.SelLength < 0 then // I4797
begin
len := -memo.SelLength;
memo.SelStart := memo.SelStart - len;
memo.SelLength := len;
end;
with TStringList.Create do
try
Text := FText;
if (FRange.Left = FRange.Right) and (FRange.Bottom = FRange.Top) then
begin
// No selection
Inc(FRange.Left); // 1-offset instead of 0-offset
seltext := GetTokenFromCaret(Strings[FRange.Top], FRange.Left, len);
FRange.Right := FRange.Left + len;
end
else if FRange.Top = FRange.Bottom then
begin
// Single line selection
seltext := Copy(Strings[FRange.Top], FRange.Left + 1, FRange.Right - FRange.Left);
while (seltext <> '') and (Copy(seltext, 1, 1) = ' ') do
begin
memo.SelStart := memo.SelStart + 1;
memo.SelLength := Length(seltext);
Delete(seltext, 1, 1);
end;
while (seltext <> '') and (Copy(seltext, Length(seltext), 1) = ' ') do
begin
memo.SelLength := memo.SelLength - 1;
Delete(seltext, Length(seltext), 1);
// Adjust selection to remove whitespace
newtext := seltext.TrimLeft;
Inc(FRange.Left, seltext.Length - newtext.Length);
seltext := newtext.TrimRight;
Dec(FRange.Right, newtext.Length - seltext.Length);
end
else
// Cannot convert multi-line selections at this time
Exit;
finally
Free;
end;
if seltext = '' then
Exit;
ws := ExtStringToString(seltext, FError);
if FError then
if FError then
Exit;
FToCodes := (Pos('"', seltext) > 0) or (Pos('''', seltext) > 0);
@ -155,14 +151,12 @@ begin
res := Trim(res);
end;
memo.SelText := res;
memo.SelStart := memo.SelStart - Length(res);
memo.SelLength := Length(res);}
a.ReplaceSelection(FRange, res);
end;
procedure TmodActionsTextEditor.actTextEditor_ConvertToCharactersUpdate(Sender: TObject);
begin
actTextEditor_ConvertToCharacters.Enabled := KMDActions.IsTextEditor(Sender);
actTextEditor_ConvertToCharacters.Enabled := KMDActions.IsTextEditor(Screen.ActiveControl);
end;
procedure TmodActionsTextEditor.actTextEditor_ReformatXMLExecute(Sender: TObject);

View file

@ -46,8 +46,8 @@ type
class var FInitialFilenameIndex: Integer;
private
FSelectedRow: Integer;
FSelectedCol: Integer;
FSelectedRange: TRect;
FSelectedRangeIsBackwards: Boolean;
FCanUndo: Boolean;
FCanRedo: Boolean;
FHasSelection: Boolean;
@ -128,6 +128,9 @@ type
{ IKMDTextEditorActions }
function GetEditorFormat: TEditorFormat;
function GetSelectedRow: Integer;
function GetSelectedCol: Integer;
function GetSelectedRange: TRect;
procedure ReplaceSelection(ARange: TRect; const ANewText: string);
public
{ Public declarations }
@ -192,6 +195,24 @@ begin
//TODO: memo.TabStops := FKeymanDeveloperOptions.IndentSize;
end;
procedure TframeTextEditor.ReplaceSelection(ARange: TRect;
const ANewText: string);
var
j: TJSONObject;
begin
j := TJSONObject.Create;
try
j.AddPair('top', TJSONNumber.Create(ARange.Top));
j.AddPair('left', TJSONNumber.Create(ARange.Left));
j.AddPair('bottom', TJSONNumber.Create(ARange.Bottom));
j.AddPair('right', TJSONNumber.Create(ARange.Right));
j.AddPair('newText', ANewText);
ExecuteCommand('replaceSelection', j);
finally
j.Free;
end;
end;
procedure TframeTextEditor.cefBeforeBrowse(Sender: TObject; const Url: string; out Result: Boolean);
var
params: TStringList;
@ -225,6 +246,7 @@ begin
model.AddItem(TEXTEDITOR_CONTEXTMENU_SHOWCHARACTER, 'S&how Character');
model.SetEnabled(TEXTEDITOR_CONTEXTMENU_SHOWCHARACTER, modActionsTextEditor.actTextEditor_ShowCharacter.Enabled);
model.AddItem(TEXTEDITOR_CONTEXTMENU_CONVERTTOCHARACTERS, 'C&onvert to Characters');
model.SetAccelerator(TEXTEDITOR_CONTEXTMENU_CONVERTTOCHARACTERS, Ord('U'), True, True, False);
model.SetEnabled(TEXTEDITOR_CONTEXTMENU_CONVERTTOCHARACTERS, modActionsTextEditor.actTextEditor_ConvertToCharacters.Enabled);
end;
@ -572,18 +594,25 @@ begin
finally
j.Free;
end;
{TODO:
if (ALine >= EditorMemo.LineCount) or (ALine < 0) then Exit;
EditorMemo.SelLine := ALine;
EditorMemo.SelCol := 0;
EditorMemo.SelLength := Length(EditorMemo.LinesArray[ALine]);
EditorMemo.ScrollInView;
}
end;
function TframeTextEditor.GetSelectedCol: Integer;
begin
if FSelectedRangeIsBackwards
then Result := FSelectedRange.Left
else Result := FSelectedRange.Right;
end;
function TframeTextEditor.GetSelectedRange: TRect;
begin
Result := FSelectedRange;
end;
function TframeTextEditor.GetSelectedRow: Integer;
begin
Result := FSelectedRow;
if FSelectedRangeIsBackwards
then Result := FSelectedRange.Top
else Result := FSelectedRange.Bottom;
end;
procedure TframeTextEditor.SetText(Value: WideString);
@ -624,9 +653,12 @@ begin
begin
if ALocation <> '' then
begin
FSelectedRow := StrToIntDef(StrToken(ALocation, ','),0);
FSelectedCol := StrToIntDef(ALocation,0);
frmKeymanDeveloper.barStatus.Panels[0].Text := Format('Line %d, Col %d', [FSelectedRow+1,FSelectedCol+1]);
FSelectedRange.Top := StrToIntDef(StrToken(ALocation, ','),0);
FSelectedRange.Left := StrToIntDef(StrToken(ALocation, ','),0);
FSelectedRange.Bottom := StrToIntDef(StrToken(ALocation, ','),0);
FSelectedRange.Right := StrToIntDef(StrToken(ALocation, ','),0);
FSelectedRangeIsBackwards := StrToIntDef(StrToken(ALocation, ','),0) > 0;
frmKeymanDeveloper.barStatus.Panels[0].Text := Format('Line %d, Col %d', [FSelectedRange.Top+1,FSelectedRange.Left+1]);
end;
end;
end;

View file

@ -82,6 +82,14 @@ window.editorGlobalContext = {
}
};
context.replaceSelection = function (o) {
let originalRange = new ace.Range(o.top, o.left, o.bottom, o.right);
let end = editor.session.doc.replace(originalRange, o.newText);
let newRange = new ace.Range(o.top, o.left, end.row, end.column);
editor.selection.setSelectionRange(newRange, false);
};
/* Printing */
context.print = function () {
@ -142,9 +150,11 @@ window.editorGlobalContext = {
command(editor.getSelectedText() == '' ? 'no-selection' : 'has-selection');
command(editor.session.getUndoManager().hasUndo() ? 'undo-enable' : 'undo-disable');
command(editor.session.getUndoManager().hasRedo() ? 'redo-enable' : 'redo-disable');
let c = editor.selection.getCursor();
command('location,'+c.row+','+c.column);
command('insert-mode,'+(editor.session.getOption('overwrite') ? 'Overwrite' : 'Insert'));
let r = editor.selection.getRange();
var n = editor.session.doc.getTextRange(editor.selection.getRange()).length;
if (!editor.selection.isBackwards()) n = -n;
command('location,' + r.start.row + ',' + r.start.column + ',' + r.end.row + ',' + r.end.column + ',' + n);
command('insert-mode,' + (editor.session.getOption('overwrite') ? 'Overwrite' : 'Insert'));
// command(editor.session.getUndoManager().isClean() ? 'modified' : 'not-modified');
var s = getTokenAtCursor();
if(s) {