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

📄 jveditor.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 3 页
字号:

        if Brush.Color <> LA.BC then // change GDI object only if necessary
          Brush.Color := LA.BC;
        Font.Assign(FontCacheFind(LA));

        R := CalcCellRect(ColPainted - LeftCol, Line - TopRow);
        {bottom line}
        FillRect(Bounds(R.Left, R.Bottom - 1, CellRect.Width * Length(Ch), 1));

        TJvUnicodeCanvas(Canvas).ExtTextOut(R.Left, R.Top, [etoOpaque, etoClipped], nil, Ch, @MyDi[0]);

        if LA.Border <> clNone then
        begin
          Pen.Color := LA.Border;
          R.Right := R.Left + CellRect.Width * Length(Ch);
          Dec(R.Left);
          Brush.Style := bsClear;
          Rectangle(R);
          Brush.Style := bsSolid;
        end;

        ColPainted := jC - 1;
      end;
    end;
  end;
end;

procedure TJvCustomEditor.GetLineAttr(var Str: string; Line, ColBeg, ColEnd: Integer);
var
  I: Integer;
begin
  if ColBeg < 0 then
    ColBeg := 0;
  if ColEnd > Max_X then
    ColEnd := Max_X;
  LineAttrs[ColBeg].Style := Font.Style;
  LineAttrs[ColBeg].FC := Font.Color;
  LineAttrs[ColBeg].BC := Color;
  LineAttrs[ColBeg].Border := clNone;

{  for I := ColBeg + 1 to ColEnd do
    Move(LineAttrs[ColBeg], LineAttrs[I], SizeOf(LineAttrs[1]));}
  for I := ColBeg + 1 to ColEnd do
    LineAttrs[I] := LineAttrs[ColBeg];

  GetAttr(Line, ColBeg, ColEnd);
  if Assigned(FOnGetLineAttr) then
    FOnGetLineAttr(Self, Str, Line, LineAttrs);
  ChangeAttr(Line, ColBeg, ColEnd);
end;

function TJvCustomEditor.GetAnsiTextLine(Y: Integer; out Text: AnsiString): Boolean; 
begin
  if (Y >= 0) and (Y < Lines.Count) then
  begin
    Text := Lines[Y];
    Result := True;
  end
  else
  begin
    Text := '';
    Result := False;
  end;
end;

function TJvCustomEditor.GetAnsiWordOnCaret: AnsiString;
begin
  Result := GetWordOnCaret;
end;

procedure TJvCustomEditor.ReLine;
begin
  FLines.ReLine;
end;

procedure TJvCustomEditor.InsertChar(const Value: Word);
var
  S: string;
  X, Y, iBeg: Integer;
  WasSelected: Boolean;
  Key: Char;
begin
  Key := Char(Value);
  WasSelected := (FSelection.IsSelected) and (not PersistentBlocks);
  if Key in [#32..#255] then
  begin
    if not HasChar(Key, JvEditorCompletionChars) then
      Completion.DoKeyPress(Key);

    RemoveSelectedBlock;

    ReLine; // need ReLine after DeleteSelection
    S := FLines[CaretY];
    if InsertMode then
    begin
      {--- UNDO ---}
      TJvInsertUndo.Create(Self, CaretX, CaretY, Key);
      {--- /UNDO ---}
      Insert(Key, S, CaretX + 1);

      AdjustPersistentBlockSelection(CaretX, CaretY, amInsert, [1]);
    end
    else
    begin
      {--- UNDO ---}
      if CaretX + 1 <= Length(S) then
        TJvOverwriteUndo.Create(Self, CaretX, CaretY, S[CaretX + 1], Key)
      else
        TJvOverwriteUndo.Create(Self, CaretX, CaretY, '', Key);
      {--- /UNDO ---}
      if CaretX + 1 <= Length(S) then
        S[CaretX + 1] := Key
      else
        S := S + Key
    end;
    FLines.Internal[CaretY] := S;
    SetCaretInternal(CaretX + 1, CaretY);
    TextModified(CaretX, CaretY, maInsert, Key);
    PaintLine(CaretY, -1, -1);
    Changed;

    if HasChar(Key, JvEditorCompletionChars) then
      Completion.DoKeyPress(Key);
  end
  else
  case Key of
    Cr:
      begin
        if InsertMode then
        begin
          if WasSelected then // compound only on selection deletion
            BeginCompound;
          LockUpdate;
          try
            RemoveSelectedBlock; // adjusts CaretX, CaretY
            X := CaretX;
            Y := CaretY;
            { --- UNDO --- }
            TJvInsertUndo.Create(Self, CaretX, CaretY, sLineBreak);
            { --- /UNDO --- }
            if FLines.Count = 0 then
              FLines.Add('');
            ReLine;

            S := Copy(FLines[Y], X + 1, MaxInt);
            FLines.Insert(Y + 1, S);
            FLines.Internal[Y] := Copy(FLines[Y], 1, X);
            Inc(Y);
            { auto indent }
            if AutoIndent and
              (((Length(FLines[CaretY]) > 0) and
              (FLines[CaretY][1] = ' ')) or
              ((Trim(FLines[CaretY]) = '') and (X > 0))) then
            begin
              X := GetAutoIndentStop(Y);
              if X > 0 then
              begin
                { --- UNDO --- }
                TJvInsertUndo.Create(Self, 0, Y, Spaces(X));
                { --- /UNDO --- }
                FLines.Internal[Y] := Spaces(X) + FLines[Y];
              end;
            end
            else
              X := 0;

            // persistent blocks: adjust selection
            AdjustPersistentBlockSelection(CaretX, CaretY, amLineBreak, []);

            UpdateEditorSize;
            TextModified(CaretX - 1, CaretY, maInsert, sLineBreak);
          finally
            UnlockUpdate;
            if WasSelected then
              EndCompound;
          end;
          Invalidate;
          Changed;
        end
        else // Overwrite-mode
        begin
          if WasSelected then // compound only on selection deletion
            BeginCompound;
          try
            RemoveSelectedBlock;
            X := CaretX;
            Y := CaretY;
            Inc(Y);
            if Y >= FLines.Count then
            begin
              LockUpdate;
              try
                { --- UNDO --- }
                TJvInsertUndo.Create(Self, CaretX, CaretY, sLineBreak);
                { --- /UNDO --- }
                FLines.Add('');
              finally
                UnlockUpdate;
              end;
              TextModified(0, Y - 1, maInsert, sLineBreak);
              UpdateEditorSize;
              Invalidate;
              Changed;
            end;
            if Y < FLines.Count then
            begin
              S := FLines[Y];
              if Length(S) > 0 then
              begin
                iBeg := FindNotBlankCharPos(S) - 1;
                if iBeg < X then
                  X := iBeg;
              end;
            end;
          finally
            if WasSelected then
              EndCompound;
          end;
        end;
        SetCaretInternal(X, Y);
      end;
  end;
end;

procedure TJvCustomEditor.SelectWordOnCaret;
var
  iBeg, iEnd: Integer;
begin
  if (CaretY >= 0) and (CaretY < LineCount) and (Trim(FLines[CaretY]) <> '') then
  begin
    iEnd := Length(TrimRight(FLines[CaretY]));
    if FCaretX < iEnd then
      while FLines[FCaretY][FCaretX + 1] <= ' ' do
        Inc(FCaretX)
    else
    begin
      FCaretX := iEnd - 1;
      while FLines[FCaretY][FCaretX + 1] <= ' ' do
        Dec(FCaretX);
    end;
    if GetWordOnPosEx(FLines[FCaretY] + ' ', FCaretX + 1, iBeg, iEnd) <> '' then
    begin
      PaintCaret(False);
      SetSel(iBeg - 1, FCaretY);
      SetSel(iEnd - 1, FCaretY);
      SetCaret(iEnd - 1, FCaretY);
      PaintCaret(True);
    end;
  end;
end;

function TJvCustomEditor.DoCommand(ACommand: TEditCommand; var X, Y: Integer;
  var CaretUndo: Boolean): Boolean;

type
  TPr = procedure of object;

  procedure DoAndCorrectXY(Pr: TPr);
  begin
    Pr;
    X := CaretX;
    Y := CaretY;
    CaretUndo := False;
  end;

  procedure SetSel1(X, Y: Integer);
  begin
    SetSel(X, Y);
    CaretUndo := False;
  end;

  procedure SetSelText1(const S: string);
  begin
    SelText := S;
    CaretUndo := False;
  end;

var
  F: Integer;
  S, S2: string;
  B: Boolean;
  iBeg, iEnd: Integer;
begin
  Result := True;
  X := CaretX;
  Y := CaretY;
  case ACommand of
    { caret movements }
    ecPrevWord, ecSelPrevWord, ecBackspaceWord:
      begin
        if (ACommand = ecSelPrevWord) and IsNewSelection then
          SetSel1(CaretX, CaretY);
        if Y >= FLines.Count then
          Exit;

        S := FLines[Y];
        B := False;
        if CaretX > Length(S) then
        begin
          X := Length(S);
          SetSel1(X, Y);
        end
        else
        begin
          for F := X - 1 downto 0 do
          begin
            if B then
            begin
              if CharInSet(S[F + 1], Separators) then
              begin
                X := F + 1;
                Break;
              end;
            end
            else
            if not CharInSet(S[F + 1], Separators) then
              B := True;
          end;

          if X = CaretX then
            X := 0;
          if ACommand = ecSelPrevWord then
            SetSel1(X, Y)
          else
            PersistentBlocksSetUnSelected;

          if (ACommand = ecBackspaceWord) and (Y >= 0) and (X <> CaretX) then
          begin
            if not ReadOnly then
            begin
              BeginCompound;
              try
                SelectRange(X, CaretY, CaretX, CaretY);
                DeleteSelected;
              finally
                EndCompound;
              end;
              ReLine;
            end;
          end;
        end;
      end;
    ecNextWord, ecSelNextWord:
      begin
        if (ACommand = ecSelNextWord) and IsNewSelection then
          SetSel1(CaretX, CaretY);
        if Y >= FLines.Count then
        begin
          Y := FLines.Count - 1;
          if Y < 0 then
            Exit;
          X := Length(FLines[Y]);
        end;
        S := FLines[Y];
        B := False;
        if CaretX >= Length(S) then
        begin
          if Y < FLines.Count - 1 then
          begin
            Y := CaretY + 1;
            X := 0;
            if ACommand = ecSelNextWord then // this code is copied from [ecPrevWord, ecSelPrevWord]
              SetSel1(X, Y)
            else
              PersistentBlocksSetUnSelected;
          end;
        end
        else
        begin
          for F := X to Length(S) - 1 do
            if B then
            begin
              if not CharInSet(S[F + 1], Separators) then
              begin
                X := F;
                Break;
              end
            end
            else
            if CharInSet(S[F + 1], Separators) then
              B := True;
          if X = CaretX then
            X := Length(S);
          if ACommand = ecSelNextWord then
            SetSel1(X, Y)
          else
            PersistentBlocksSetUnSelected;
        end;
      end;
    ecSelWord:
      if IsNewSelection and (GetWordOnPosEx(FLines[Y] + ' ', X + 1, iBeg,
        iEnd) <> '') then
      begin
        SetSel1(iBeg - 1, Y);
        SetSel1(iEnd - 1, Y);
        X := iEnd - 1;
      end;
    ecBackspace:
      if not ReadOnly then
        if X > 0 then
        begin
          // in the middle of line - 

⌨️ 快捷键说明

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