trichview.com

trichview.support




Re: UpperCase and LowerCase


Return to index


Author

Message

Sergey Tkachenko

Posted: 05/22/2003 18:08:48


Sorry for delay.

Create a unit from the code below.


RVChangeCharCase applies LowerCase/UpperCase/WordUpperCase to the selected

text.

This unit will be included in one of the next updates of RichViewActions.


{*******************************************************}

{                                                       }

{       RichView                                        }

{       RVChangeCharCase - procedure for changing       }

{       character case of the selected text             }

{                                                       }

{       Copyright (c) Sergey Tkachenko                  }

{       svt@trichview.com                               }

{       http://www.trichview.com                        }

{                                                       }

{*******************************************************}


unit RVCharCase;


interface

uses Windows, SysUtils,

  RVStyle, RVEdit, RVUni, RVItem;


{

  Limitations:

    - requires WinNT/2k/XP for Unicode text (otherwise, skips Unicode)

    - for non-Unicode text, works correctly only for the main language of

Windows

}


type

  TRVCharCase = (rvccLowerCase, rvccUpperCase, rvccTitleWord);


procedure RVChangeCharCase(rve: TCustomRichViewEdit; CharCase: TRVCharCase);


implementation


{---------------------------------------------------------------------------

---}


function ChangeCharCase(const prevs, s: String; TextStyle: TFontInfo;

  CharCase: TRVCharCase): String;

var unitext: PRVWordArray;

    i: Integer;

    Change: Boolean;

begin

  if Length(s)=0 then begin

    Result := s;

    exit;

  end;

  case CharCase of

    rvccLowerCase:

      if TextStyle.Unicode then

        if RVNT then begin

          SetString(Result, PChar(s), Length(s));

          CharLowerBuffW(Pointer(Result), Length(s) div 2);

          end

        else

          Result := s

      else

       Result := AnsiLowerCase(s);

    rvccUpperCase:

      if TextStyle.Unicode then

        if RVNT then begin

          SetString(Result, PChar(s), Length(s));

          CharUpperBuffW(Pointer(Result), Length(s) div 2);

          end

        else

          Result := s

      else

       Result := AnsiUpperCase(s);

    rvccTitleWord:

      if TextStyle.Unicode then

        if RVNT then begin

          SetString(Result, PChar(s), Length(s));

          CharLowerBuffW(Pointer(Result), Length(s) div 2);

          unitext := PRVWordArray(PChar(Result));

          Change := True;

          if prevs<>'' then

            Change := not IsCharAlphaNumericW(

              WideChar(PWordArray(PChar(prevs))[Length(prevs) div 2-1]));

          for i := 0 to Length(s) div 2 -1 do

            if not IsCharAlphaNumericW(WideChar(unitext[i])) then

              Change := True

            else if Change then begin

              CharUpperBuffW(Pointer(@(unitext[i])), 1);

              Change := False;

            end;

          end

        else

          Result := s

      else begin

        Result := AnsiLowerCase(s);

        Change := True;

        if prevs<>'' then

          Change := not IsCharAlphaNumericA(prevs[Length(prevs)]);

        for i := 1 to Length(Result) do

          if not IsCharAlphaNumericA(Result[i]) then

            Change := True

          else if Change then begin

            CharUpperBuffA(Pointer(@(Result[i])), 1);

            Change := False;

          end;

      end;

  end;

end;


procedure RVChangeCharCase(rve: TCustomRichViewEdit; CharCase: TRVCharCase);

var i, ItemNo1, ItemNo2, Offs1, Offs2: Integer;

    AItemNo1, AItemNo2, AOffs1, AOffs2: Integer;

    TextStyles: TFontInfos;

    ItemOptions: TRVItemOptions;

    s, s1, s2: String;

begin

  TextStyles := rve.Style.TextStyles;

  rve := rve.TopLevelEditor;

  rve.BeginUndoGroup(rvutModifyItem);

  rve.SetUndoGroupMode(True);

  try

    rve.GetSelectionBounds(ItemNo1, Offs1, ItemNo2, Offs2, True);

    rve.GetSelectionBounds(AItemNo1, AOffs1, AItemNo2, AOffs2, False);

    if ItemNo2<>ItemNo1 then begin

      if rve.GetItemStyle(ItemNo1)>=0 then begin

        ItemOptions := rve.GetItem(ItemNo1).ItemOptions;

        s  := rve.GetItemText(ItemNo1);

        s1 := RVU_Copy(s, 1, Offs1-1, ItemOptions);

        s2 := RVU_Copy(s, Offs1, Length(s), ItemOptions);

        if s2<>'' then begin

          s2 := ChangeCharCase(s1, s2,

TextStyles[rve.GetItemStyle(ItemNo1)], CharCase);

          rve.SetItemTextEd(ItemNo1, s1+s2);

        end;

      end;

      for i := ItemNo1+1 to ItemNo2-1 do begin

        s  := rve.GetItemText(i);

        s := ChangeCharCase('', s, TextStyles[rve.GetItemStyle(i)],

CharCase);

        rve.SetItemTextEd(i, s);

      end;

      if rve.GetItemStyle(ItemNo2)>=0 then begin

        ItemOptions := rve.GetItem(ItemNo2).ItemOptions;

        s  := rve.GetItemText(ItemNo2);

        s1 := RVU_Copy(s, 1, Offs2-1, ItemOptions);

        s2 := RVU_Copy(s, Offs2, Length(s), ItemOptions);

        if s1<>'' then begin

          s1 := ChangeCharCase('', s1,

TextStyles[rve.GetItemStyle(ItemNo2)], CharCase);

          rve.SetItemTextEd(ItemNo2, s1+s2);

        end;

      end

      end

    else begin

      ItemOptions := rve.GetItem(ItemNo1).ItemOptions;

      s  := rve.GetItemText(ItemNo1);

      s1 := RVU_Copy(s, 1, Offs1-1, ItemOptions);

      s2 := RVU_Copy(s, Offs2, Length(s), ItemOptions);

      s  := RVU_Copy(s, Offs1, Offs2-Offs1, ItemOptions);

      s := ChangeCharCase(s1, s, TextStyles[rve.GetItemStyle(ItemNo1)],

CharCase);

      rve.SetItemTextEd(ItemNo1, s1+s+s2);

    end;

  finally

    rve.SetUndoGroupMode(False);

    rve.SetSelectionBounds(AItemNo1, AOffs1, AItemNo2, AOffs2);

  end;

end;


end.






Powered by ABC Amber Outlook Express Converter