⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jvunicodeeditor.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  try
    inherited Assign(Source);
    JvEditor.NotUndoable;
    JvEditor.TextAllChanged;
  finally
    JvEditor.EndUpdate;
  end;
end;

procedure TJvEditorWideStrings.AddStrings(Strings: TWStrings);
begin
  JvEditor.BeginUpdate;
  try
    inherited AddStrings(Strings);
    JvEditor.NotUndoable;
  finally
    JvEditor.EndUpdate;
  end;
end;

procedure TJvEditorWideStrings.SetTextStr(const Value: WideString);
begin
  inherited SetTextStr(JvEditor.ExpandTabs(Value));
  if JvEditor.UpdateLock = 0 then
    JvEditor.NotUndoable;
  JvEditor.TextAllChanged;
end;

procedure TJvEditorWideStrings.StringsChanged(Sender: TObject);
begin
  if JvEditor.UpdateLock = 0 then
    JvEditor.TextAllChanged;
end;

procedure TJvEditorWideStrings.SetLockText(const Text: WideString);
begin
  JvEditor.LockUpdate;
  try
    inherited SetTextStr(Text)
  finally
    JvEditor.UnlockUpdate;
  end;
end;

procedure TJvEditorWideStrings.SetInternal(Index: Integer; const Value: WideString);
begin
  JvEditor.LockUpdate;
  try
    InternalPut(Index, Value);
  finally
    JvEditor.UnlockUpdate;
  end;
end;

function TJvEditorWideStrings.Add(const S: WideString): Integer;
begin
  Result := inherited Add(JvEditor.ExpandTabs(S));
end;

procedure TJvEditorWideStrings.Insert(Index: Integer; const S: WideString);
begin
  inherited Insert(Index, JvEditor.ExpandTabs(S));
end;

procedure TJvEditorWideStrings.Put(Index: Integer; const S: WideString);
var
  L: Integer;
begin
  if JvEditor.KeepTrailingBlanks then
    inherited Put(Index, S)
  else
  begin
    L := Length(S) - TrimRightLengthW(S);
    if L = 0 then
      inherited Put(Index, S)
    else
    begin
      {--- UNDO ---}
      TJvDeleteTrailUndo.Create(JvEditor, Length(S), Index, SpacesW(L));
      {--- /UNDO ---}
      inherited Put(Index, TrimRightW(S));
    end;
  end;
end;

procedure TJvEditorWideStrings.ReLine;
var
  L: Integer;
  S: WideString;
begin
  JvEditor.LockUpdate;
  try
    if Count = 0 then
      L := JvEditor.CaretX
    else
      L := Length(Strings[Count - 1]);
    while JvEditor.CaretY > Count - 1 do
    begin
      {--- UNDO ---}
      TJvReLineUndo.Create(JvEditor, L, JvEditor.CaretY, sLineBreak);
      {--- /UNDO ---}
      L := 0;
      Add('');
    end;
    S := Strings[JvEditor.CaretY];
    if JvEditor.CaretX > Length(S) then
    begin
      L := JvEditor.CaretX - Length(S);
      {--- UNDO ---}
{     TJvReLineUndo.Create(JvEditor, Length(S),
        JvEditor.CaretY, SpacesW(L)); } {disabled: moves the caret to wrong undo position }
      {--- /UNDO ---}
      inherited Put(JvEditor.CaretY, S + SpacesW(L));
    end;
  finally
    JvEditor.UnlockUpdate;
  end;
end;

procedure TJvEditorWideStrings.InternalPut(Index: Integer; const Value: WideString);
begin
  if JvEditor.KeepTrailingBlanks then
    inherited Put(Index, JvEditor.ExpandTabs(Value))
  else
    inherited Put(Index, TrimRightW(JvEditor.ExpandTabs(Value)));
end;

procedure TJvEditorWideStrings.DeleteText(BegX, BegY, EndX, EndY: Integer);
{ delete text from [BegX..EndY] [BegY..EndY] all inclusive.
  BegX,EndX: [0..Max_X] }
var
  BegLine, EndLine: WideString;
  I, L: Integer;
begin
  if BegY < 0 then
  begin
    BegY := 0;
    BegX := 0;
  end;
  if BegY >= Count then
    Exit; // nothing to delete
  if EndY >= Count then
  begin
    EndY := Count - 1;
    EndX := MaxInt - 1;
  end;
  if BegX < 0 then
    BegX := 0;

  JvEditor.LockUpdate;
  BeginUpdate;
  try
    BegLine := Strings[BegY];
   // expand BegLine if necessary
    L := (BegX + 1) - Length(BegLine) - 1;
    if L > 0 then
      BegLine := BegLine + SpacesW(L);

    EndLine := Strings[EndY];

    // delete lines between and end line
    for I := EndY downto BegY + 1 do
      Delete(I);

    System.Delete(BegLine, BegX + 1, MaxInt);
    System.Delete(EndLine, 1, EndX + 1);

    Internal[BegY] := BegLine + EndLine;
  finally
    EndUpdate;
    JvEditor.UnlockUpdate;
  end;
end;

procedure TJvEditorWideStrings.InsertText(X, Y: Integer; const Text: WideString);
{ insert text on X:[0..Max_X], Y }
var
  BegLine, EndLine: WideString;
  YStart: Integer;
  F, P: PWideChar;
  S, FirstLine: WideString;
  Len: Integer;
begin
  Inc(X); // increment for WideString functions
  if Y < 0 then
    Y := 0;
  while Y >= Count do
    Add('');

  BegLine := Strings[Y];
  EndLine := System.Copy(BegLine, X, MaxInt);
  System.Delete(BegLine, X, MaxInt);

  // line is too small -> expand it with spaces
  Len := Length(BegLine);
  if Len < X then
  begin
    SetLength(BegLine, X - 1);
    FillChar(BegLine[Len + 1], X - Len - 1, ' ');
  end;

  JvEditor.LockUpdate;
  BeginUpdate;
  try
    P := PWideChar(Text);
    F := P;
    while (P[0] <> #0) and (P[0] <> Lf) and (P[0] <> Cr) do
      Inc(P);

    SetString(S, F, P - F);

    YStart := Y;
    FirstLine := BegLine + S; // set Internal[YStart] later so we keep the trailing spaces for concat EndLine

    while P[0] <> #0 do
    begin
      if P[0] = Cr then
        Inc(P);
      if P[0] = Lf then
        Inc(P);
      F := P;

      while (P[0] <> #0) and (P[0] <> Lf) and (P[0] <> Cr) do
        Inc(P);
      SetString(S, F, P - F);
      Inc(Y);
      Insert(Y, S);
    end;

    if Y = YStart then
      Internal[YStart] := FirstLine + EndLine
    else
    begin
      Internal[YStart] := FirstLine;
      Internal[Y] := Strings[Y] + EndLine;
    end;
  finally
    EndUpdate;
    JvEditor.UnlockUpdate;
  end;
end;

procedure TJvEditorWideStrings.DeleteColumnText(BegX, BegY, EndX, EndY: Integer);
{ delete column text from [BegX..EndY] [BegY..EndY] all inclusive.
  BegX,EndX: [0..Max_X] }
var
  S: WideString;
  I: Integer;
begin
  if BegY < 0 then
  begin
    BegY := 0;
    BegX := 0;
  end;
  if BegY >= Count then
    Exit; // nothing to delete
  if EndY >= Count then
  begin
    EndY := Count - 1;
    EndX := MaxInt - 1;
  end;
  if BegX < 0 then
    BegX := 0;

  JvEditor.LockUpdate;
  BeginUpdate;
  try
    for I := BegY to EndY do
    begin
      S := JvEditor.FLines[I];
      System.Delete(S, BegX + 1, EndX - BegX + 1);
      JvEditor.FLines.Internal[I] := S;
    end;
  finally
    EndUpdate;
    JvEditor.UnlockUpdate;
  end;
end;

procedure TJvEditorWideStrings.InsertColumnText(X, Y: Integer; const Text: WideString);
{ insert column text on X:[0..Max_X], Y }
var
  S, Line: WideString;
  P, F: PWideChar;
  L: Integer;
begin
  Inc(X); // increment for WideString functions
  if Y < 0 then
    Y := 0;

  JvEditor.LockUpdate;
  BeginUpdate;
  try
    P := PWideChar(Text);
    F := P;
    while P[0] <> #0 do
    begin
      while (P[0] <> #0) and (P[0] <> Lf) and (P[0] <> Cr) do
        Inc(P);
      SetString(S, F, P - F);

      while Y >= Count do
        Add('');
      Line := Strings[Y];
      L := (X - 1) - Length(Line);
      if L > 0 then
        Line := Line + SpacesW(L);
      System.Insert(S, Line, X);
      Internal[Y] := Line;

      if P[0] = Cr then
        Inc(P);
      if P[0] = Lf then
        Inc(P);
      F := P;
      Inc(Y);
    end;
  finally
    EndUpdate;
    JvEditor.UnlockUpdate;
  end;
end;

//=== { TJvCustomWideEditor } ================================================

constructor TJvCustomWideEditor.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FLines := TJvEditorWideStrings.Create;
  FLines.FJvEditor := Self;
  FLines.OnChange := DoLinesChange;
  Completion := TJvWideCompletion.Create(Self);
end;

destructor TJvCustomWideEditor.Destroy;
begin
  FLines.Free;
  Completion.Free;
  inherited Destroy;
end;

procedure TJvCustomWideEditor.PaintLineText(Line: Integer; ColBeg, ColEnd: Integer;
  var ColPainted: Integer);
var
  Ch: WideString;
  iC, jC, SL, MX: Integer;
  R: TRect;
  S: WideString;
  LA: TLineAttr;
  jCStart, Len: Integer;
  MyDi: TDynIntArray;
begin
  with EditorClient do
  begin
    S := FLines[Line];

    Len := Max(Length(S), Max_X) + 1;
    if Len > Length(LineAttrs) then
      SetLength(LineAttrs, Len)
    else if Len + 128 < Length(LineAttrs) then
      SetLength(LineAttrs, Len);

    GetLineAttr(S, Line, ColBeg, ColEnd);

    {left line}
    if Canvas.Brush.Color <> LineAttrs[LeftCol + 1].BC then // change GDI object only if necessary
      Canvas.Brush.Color := LineAttrs[LeftCol + 1].BC;

    Canvas.FillRect(Bounds(EditorClient.Left, (Line - TopRow) *
      CellRect.Height, 1, CellRect.Height));
    {optimized, paint group of chars with identical attributes}
    SL := Length(S);
    MX := ColEnd;

    if Length(FMyDi) < MX then
    begin
      SetLength(MyDi, MX);
      for iC := 0 to High(MyDi) do
        MyDi[iC] := CellRect.Width;
     end
    else
      MyDi := FMyDi;

    while ColPainted < MX do
    begin
      with Canvas do
      begin
        iC := ColPainted + 1;
        LA := LineAttrs[iC];
        jC := iC + 1;
        if iC <= SL then
          Ch := S[iC]
        else
          Ch := ' ';
        jCStart := jC;
        while (jC <= MX + 1) and
          CompareMem(@LA, @LineAttrs[jC], SizeOf(LineAttrs[1])) do
            Inc(jC);
        Ch := Copy(S, jCStart - 1, jC - jCStart + 1);
        if jC > SL + 1 then
          Ch := Ch + Spaces(jC - SL - 1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -