
{*******************************************************}
{                                                       }
{       RichViewActions                                 }
{       Demo project.                                   }
{       You can use it as a basis for your              }
{       applications.                                   }
{                                                       }
{       Copyright (c) Sergey Tkachenko                  }
{       svt@trichview.com                               }
{       Copyright (c) Ilya Zelenskiy                    }
{       ilya@trichview.com                              }
{       http://www.trichview.com                        }
{                                                       }
{*******************************************************}


unit Unit3Unicode;

interface

{$I RV_Defs.inc}          // contains defines about Delphi compiler versions


uses
  Windows, Messages, SysUtils,
  Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls,
  ActnList, StdActns, ImgList, ToolWin,
  Menus, ShellApi, Printers, ExtCtrls,

  RVUni, RVMisc, RVScroll, RichView, RVEdit,
  RVStyle, CRVFData, RVTable, RVItem, CRVData, RVFuncs,

  RichViewActions, RVFontCombos, Ruler, RVRuler,
  RVALocalize, RVALocRuler,
  // RVAAddictLanguages,

  SRVPageScroll, SclRView, SclRVRuler, SRVToolWindow,
  SRVToolBar, SRVSkinManager, SRVTabSet, SRVActions, SRVALocalize,

  GifImg,
  PngImage,
  RVTypes, XPMan;

type
  TForm3 = class(TForm)
    MainMenu1: TMainMenu;
    mitFile: TMenuItem;
    mitEdit: TMenuItem;
    New1: TMenuItem;
    Load1: TMenuItem;
    N1: TMenuItem;
    mitExit: TMenuItem;
    Cut1: TMenuItem;
    Copy1: TMenuItem;
    n2: TMenuItem;
    mitFont: TMenuItem;
    Bold1: TMenuItem;
    Italic1: TMenuItem;
    Underline1: TMenuItem;
    N3: TMenuItem;
    mitPara: TMenuItem;
    Leftjustify1: TMenuItem;
    N4: TMenuItem;
    Undo1: TMenuItem;
    Redo1: TMenuItem;
    Changefont1: TMenuItem;
    Save1: TMenuItem;
    Strikeout1: TMenuItem;
    mitTable: TMenuItem;
    InsertTable1: TMenuItem;
    N5: TMenuItem;
    SelectAll1: TMenuItem;
    AlignLeft1: TMenuItem;
    AlignCenter1: TMenuItem;
    AlignRight1: TMenuItem;
    N6: TMenuItem;
    DecreaseIndent1: TMenuItem;
    IncreaseIndent1: TMenuItem;
    N7: TMenuItem;
    Justify1: TMenuItem;
    InsertRowAbove1: TMenuItem;
    InsertRowBelow1: TMenuItem;
    N8: TMenuItem;
    InsertColumnLeft1: TMenuItem;
    InsertColumnRight1: TMenuItem;
    N9: TMenuItem;
    N10: TMenuItem;
    DeleteRows1: TMenuItem;
    rvActionTableDeleteCols11: TMenuItem;
    N11: TMenuItem;
    MergeCells1: TMenuItem;
    SplitCells1: TMenuItem;
    N12: TMenuItem;
    mitTableSelect: TMenuItem;
    SelectTable1: TMenuItem;
    SelectColumns1: TMenuItem;
    SelectRows1: TMenuItem;
    SelectCell1: TMenuItem;
    mitFontStyle: TMenuItem;
    mitFontSize: TMenuItem;
    ShrinkFont1: TMenuItem;
    GrowFont1: TMenuItem;
    N13: TMenuItem;
    ShrinkFontByOnePoint1: TMenuItem;
    GrowFontByOnePoint1: TMenuItem;
    N14: TMenuItem;
    AllCapitals1: TMenuItem;
    Overline1: TMenuItem;
    N15: TMenuItem;
    Find1: TMenuItem;
    FindNext1: TMenuItem;
    Replace1: TMenuItem;
    N16: TMenuItem;
    extColor1: TMenuItem;
    extBackgroundColor1: TMenuItem;
    N17: TMenuItem;
    ParagraphBackgroundColor1: TMenuItem;
    mitFormat: TMenuItem;
    BackgroundColor1: TMenuItem;
    DeleteTable1: TMenuItem;
    N18: TMenuItem;
    rvActionParagraph11: TMenuItem;
    RVAControlPanel1: TRVAControlPanel;
    Font1: TMenuItem;
    FillColor1: TMenuItem;
    SaveAs1: TMenuItem;
    Export1: TMenuItem;
    mitInsert: TMenuItem;
    File1: TMenuItem;
    Picture1: TMenuItem;
    PasteSpecial1: TMenuItem;
    N19: TMenuItem;
    SingleLineSpacing1: TMenuItem;
    N15LineSpacing1: TMenuItem;
    DoubleLineSpacing1: TMenuItem;
    N20: TMenuItem;
    InsertPageBreak1: TMenuItem;
    RemovePageBreak1: TMenuItem;
    N21: TMenuItem;
    mitTableAlignCellContents: TMenuItem;
    AlignCellToTheTop1: TMenuItem;
    AlignCellToTheMiddle1: TMenuItem;
    AlignCellToTheBottom1: TMenuItem;
    DefaultCellVerticalAlignment1: TMenuItem;
    ParagraphBorders1: TMenuItem;
    N22: TMenuItem;
    Properties1: TMenuItem;
    HorizontalLine1: TMenuItem;
    HypertextLink1: TMenuItem;
    N23: TMenuItem;
    ableProperties1: TMenuItem;
    N24: TMenuItem;
    ShowGridLines1: TMenuItem;
    N25: TMenuItem;
    BulletsandNumbering1: TMenuItem;
    InsertSymbol1: TMenuItem;
    mitTableCellBorders: TMenuItem;
    LeftBorder1: TMenuItem;
    rvActionTableCellTopBorder11: TMenuItem;
    rvActionTableCellRightBorder11: TMenuItem;
    rvActionTableCellBottomBorder11: TMenuItem;
    rvActionTableCellAllBorders11: TMenuItem;
    rvActionTableCellNoBorders11: TMenuItem;
    Bullets1: TMenuItem;
    Numbering1: TMenuItem;
    RVAPopupMenu1: TRVAPopupMenu;
    Background1: TMenuItem;
    ColorDialog1: TColorDialog;
    N26: TMenuItem;
    CharacterCase1: TMenuItem;
    pmFakeDropDown: TPopupMenu;
    Panel1: TPanel;
    Panel3: TPanel;
    SclRVRuler1: TSclRVRuler;
    Panel4: TPanel;
    RVRulerItemSelector1: TRVRulerItemSelector;
    fd: TFindDialog;
    rd: TReplaceDialog;
    HintTableMenu: TPopupMenu;
    SampleHintTablemenu1: TMenuItem;
    mitPageSetup: TMenuItem;
    mitPrint: TMenuItem;
    N27: TMenuItem;
    rvActionSubscript11: TMenuItem;
    rvActionSuperscript11: TMenuItem;
    SRVPageScroll1: TSRVPageScroll;
    stat1: TStatusBar;
    Button1: TButton;
    SclRVRuler2: TSclRVRuler;
    Splitter1: TSplitter;
    SRVTabSet1: TSRVTabSet;
    SRichViewEdit1: TSRichViewEdit;
    ilDocTypes: TImageList;
    SRVSkinManager1: TSRVSkinManager;
    N28: TMenuItem;
    N29: TMenuItem;
    RemoveHyperlinks1: TMenuItem;
    ObjectPosition1: TMenuItem;
    PasteasText1: TMenuItem;
    N30: TMenuItem;
    mitTextFlow: TMenuItem;
    ClearTextFlowatLeftSide1: TMenuItem;
    ClearTextFlowatRightSide1: TMenuItem;
    ClearTextFlowatBothSides1: TMenuItem;
    NormalTextFlow1: TMenuItem;
    CoolBar1: TCoolBar;
    ToolBar1: TToolBar;
    ToolButton11: TToolButton;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    btnQuickPrint: TToolButton;
    ToolButton4: TToolButton;
    ToolButton32: TToolButton;
    ToolButton33: TToolButton;
    ToolButton34: TToolButton;
    ToolButton17: TToolButton;
    ToolButton18: TToolButton;
    ToolButton19: TToolButton;
    ToolButton5: TToolButton;
    ToolButton20: TToolButton;
    ToolButton21: TToolButton;
    ToolButton10: TToolButton;
    ToolButton46: TToolButton;
    ToolButton12: TToolButton;
    ToolButton47: TToolButton;
    ToolButton62: TToolButton;
    ToolButton63: TToolButton;
    ToolBar2: TToolBar;
    ToolButton41: TToolButton;
    ToolButton42: TToolButton;
    ToolButton43: TToolButton;
    ToolButton44: TToolButton;
    ToolButton29: TToolButton;
    ToolButton64: TToolButton;
    ToolButton13: TToolButton;
    ToolButton22: TToolButton;
    ToolButton6: TToolButton;
    ToolButton30: TToolButton;
    ToolButton31: TToolButton;
    ToolButton35: TToolButton;
    ToolButton36: TToolButton;
    ToolButton38: TToolButton;
    ToolButton37: TToolButton;
    ToolButton49: TToolButton;
    ToolButton50: TToolButton;
    ToolButton51: TToolButton;
    ToolButton8: TToolButton;
    ToolButton7: TToolButton;
    ToolButton57: TToolButton;
    ToolButton61: TToolButton;
    ToolButton60: TToolButton;
    ToolButton53: TToolButton;
    ToolButton54: TToolButton;
    ToolButton40: TToolButton;
    ToolButton39: TToolButton;
    ToolBar3: TToolBar;
    ToolButton9: TToolButton;
    ToolButton14: TToolButton;
    ToolButton15: TToolButton;
    ToolButton16: TToolButton;
    ToolButton27: TToolButton;
    ToolButton23: TToolButton;
    ToolButton24: TToolButton;
    ToolButton45: TToolButton;
    ToolButton28: TToolButton;
    ToolButton25: TToolButton;
    ToolButton26: TToolButton;
    ToolBar4: TToolBar;
    ToolButton48: TToolButton;
    ToolButton52: TToolButton;
    ToolButton55: TToolButton;
    ToolButton56: TToolButton;
    ToolButton58: TToolButton;
    ToolButton59: TToolButton;
    ToolBar5: TToolBar;
    cmbFont: TRVFontComboBox;
    cmbFontSize: TRVFontSizeComboBox;
    ToolButton66: TToolButton;
    ToolButton65: TToolButton;
    btnPageFormat: TToolButton;
    cmbZoom: TComboBox;
    cmbUnits: TComboBox;
    ToolBar6: TToolBar;
    ToolButton71: TToolButton;
    ToolButton72: TToolButton;
    ToolButton75: TToolButton;
    ToolButton76: TToolButton;
    ToolButton77: TToolButton;
    ToolButton78: TToolButton;
    pmPageFormat: TPopupMenu;
    A41: TMenuItem;
    A42: TMenuItem;
    A61: TMenuItem;
    Letter1: TMenuItem;
    Legal1: TMenuItem;
    N1000x1000mm1: TMenuItem;
    N31: TMenuItem;
    PageSetup1: TMenuItem;
    N32: TMenuItem;
    Footnote1: TMenuItem;
    Endnote1: TMenuItem;
    EditNote1: TMenuItem;
    ReturntoNote1: TMenuItem;
    srvtwSearch: TSRVToolWindow;
    ToolButton67: TToolButton;
    ToolButton68: TToolButton;
    Hide1: TMenuItem;
    XPManifest1: TXPManifest;
    ilMenuH: TImageList;
    ilSearchToolWin: TImageList;
    ilMenuV: TImageList;
    procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure mitExitClick(Sender: TObject);
    procedure RichViewEdit1_Jump(Sender: TObject; id: Integer);
    procedure RichViewEdit1_ReadHyperlink(Sender: TCustomRichView;
      const Target, Extras: String; DocFormat: TRVLoadFormat; var StyleNo,
      ItemTag: Integer; var ItemName: TRVRawByteString);
    procedure cmbFontClick(Sender: TObject);
    procedure RichViewEdit1_CurTextStyleChanged(Sender: TObject);
    procedure cmbFontSizeClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure RichViewEdit1_WriteHyperlink(Sender: TCustomRichView;
      id: Integer; RVData: TCustomRVData; ItemNo: Integer;
      SaveFormat: TRVSaveFormat; var Target, Extras: String);
    procedure RVAControlPanel1MarginsChanged(Sender: TrvAction;
      Edit: TCustomRichViewEdit);
    procedure RVAControlPanel1Download(Sender: TrvAction;
      const Source: String);
    procedure RichViewEdit1_KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure pmFakeDropDownPopup(Sender: TObject);
    procedure RichViewEdit1_KeyPress(Sender: TObject; var Key: Char);
    procedure SRichViewEdit1CurrentPageChange(Sender: TObject);
    procedure SRichViewEdit1HMenuClickButton(Sender: TObject;
      ToolButton: TSRVToolButton);
    procedure SRichViewEdit1PageScrolled(Sender: TObject);
    procedure SRichViewEdit1VMenuClickButton(Sender: TObject;
      ToolButton: TSRVToolButton);
    procedure SRichViewEdit1CaretMove(Sender: TObject);
    procedure srvtwSearchClickButton(Sender: TObject;
      ToolButton: TSRVToolButton);
    procedure fdFind(Sender: TObject);
    procedure SclRVRuler1MarginDblClick(Sender: TObject;
      Margin: TMarginType);
    procedure RVAControlPanel1BackgroundChange(Sender: TrvAction;
      Edit: TCustomRichViewEdit);
    procedure SRichViewEdit1TableIconClick(Sender: TSRichViewEdit;
      Button: TMouseButton; Shift: TShiftState; X, Y, PageNo: Integer);
    procedure SRVTabSet1Change(Sender: TObject);
    procedure SRVTabSet1CloseTab(Sender: TSRVTabSet; TabIndex: Integer;
      var CanClose: Boolean);
    procedure SRichViewEdit1Change(Sender: TObject);
    procedure cmbKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SRVTabSet1TabMove(Sender: TSRVTabSet; NewTabIndex,
      OldTabIndex: Integer);
    procedure RVAControlPanel1ViewChanged(Sender: TrvCustomAction;
      Edit: TCustomRichViewEdit);
    procedure cmbZoomChange(Sender: TObject);
    procedure SRichViewEdit1ZoomChanged(Sender: TObject);
    procedure SRichViewEdit1ChangeActiveEditor(Sender: TSRichViewEdit;
      ActiveEditor: TRichViewEdit);
    procedure cmbUnitsClick(Sender: TObject);
  private
    { Private declarations }
    VToolButtonIndex: Integer;
    UpdatingCombos: Boolean;
    Editors : array of TSRichViewEdit;
    ActiveEditor: TSRichViewEdit;
    procedure ColorPickerShow(Sender: TObject);
    procedure ColorPickerHide(Sender: TObject);
    procedure rvActionSave1DocumentFileChange(Sender: TObject;
      Editor: TCustomRichViewEdit; const FileName: String;
      FileFormat: TrvFileSaveFilter; IsNew: Boolean);
    procedure ApplicationHint(Sender: TObject);
    procedure Localize;
    procedure AddEditor;
    procedure SetEditor(Index : Integer);
    procedure RemoveEditor(Index : Integer);
    procedure OnNewEditor(Sender: TObject);
    procedure OnOpenEditor(Sender: TObject);
    function GetIndexOfEditorByRichViewEdit(rve: TCustomRichViewEdit): Integer;
    function GetActiveDocInfo: TrvaDocumentInfo;
    function GetDocInfo(rve: TCustomRichViewEdit): TrvaDocumentInfo;
    function GetIconIndex(IsNew: Boolean; FileFormat: TrvFileSaveFilter; Modified: Boolean): Integer;
    procedure FocusActiveEditor;
    procedure UpdateIcon(Editor: TSRichViewEdit);
    procedure srvActionThumbnails1Executed(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

uses dmActionsSRVAlpha, Math;
{$R *.dfm}


procedure ShowInfo(const msg,cpt: String);
begin
  Application.MessageBox(PChar(msg),PChar(cpt),MB_OK or MB_ICONINFORMATION);
end;
{------------------------------------------------------------------------------}
procedure TForm3.FormCreate(Sender: TObject);
begin
  // Tabbed UI support
  SetLength(Editors, 1);
  Editors[0] := SRichViewEdit1;
  ActiveEditor := SRichViewEdit1;
  SRVTabSet1.TabIndex := 0;

  // Almost all these assignments could be done at design time in the Object Inspector
  // But in this demo we do not want to modify srvActionsResource
  // (and we recommend to use a copy of it in your applications)

  srvActionsResource.rvActionSave1.OnDocumentFileChange := rvActionSave1DocumentFileChange;

  // Code for making color-picking buttons stay pressed while a
  // color-picker window is visible.
  srvActionsResource.rvActionColor1.OnShowColorPicker := ColorPickerShow;
  srvActionsResource.rvActionColor1.OnHideColorPicker := ColorPickerHide;
  srvActionsResource.rvActionParaColor1.OnShowColorPicker := ColorPickerShow;
  srvActionsResource.rvActionParaColor1.OnHideColorPicker := ColorPickerHide;
  srvActionsResource.rvActionFontColor1.OnShowColorPicker := ColorPickerShow;
  srvActionsResource.rvActionFontColor1.OnHideColorPicker := ColorPickerHide;
  srvActionsResource.rvActionFontBackColor1.OnShowColorPicker := ColorPickerShow;
  srvActionsResource.rvActionFontBackColor1.OnHideColorPicker := ColorPickerHide;

  // Delphi 4 and 5 do not have ActionComponent property for actions.
  // Coloring actions have a substitution - CallerControl property
  // It is ignored in Delphi 6+
  srvActionsResource.rvActionParaColor1.CallerControl := ToolButton39;
  srvActionsResource.rvActionFontBackColor1.CallerControl := ToolButton38;
  srvActionsResource.rvActionFontColor1.CallerControl := ToolButton36;

  // Index of the last clicked button in search toolwindow
  VToolButtonIndex := -1;

  // Initializing the action for showing/hiding thumbnails
  srvActionsResource.srvActionThumbnails1.PageScroll := SRVPageScroll1;
  srvActionsResource.srvActionThumbnails1.OnExecuted := srvActionThumbnails1Executed;

  // AutoComplete feature causes OnClick generation when editing combo-box's text.
  // Since in OnClick we move input focus in RichViewEdit1, this effect is
  // undesirable
  cmbFont.AutoComplete := False;
  cmbFontSize.AutoComplete := False;

  // measuring units
  RVA_ConvertToTwips(srvActionsResource);
  RVAControlPanel1.UnitsProgram := rvstuTwips;
  SRichViewEdit1.ConvertToTwips;
  cmbUnits.ItemIndex := ord(SRichViewEdit1.UnitsProgram);
  RVAControlPanel1.UnitsDisplay := SRichViewEdit1.UnitsProgram;

  // Applying the default language
  Localize;

  // Displaying hints on the status bar
  Application.OnHint := ApplicationHint;

  // Loading initial file via ActionOpen (allowing to update user interface)
  srvActionsResource.rvActionOpen1.LoadFile(ActiveEditor.RichViewEdit,
    ExtractFilePath(Application.ExeName)+'readme.rvf', ffiRVF);

  {
  // alternative way to start
    srvActionsResource.rvActionNew1.ExecuteTarget(ActiveEditor.RichViewEdit);
  }

  // Tabbed UI support
  srvActionsResource.rvActionNew1.OnExecute := OnNewEditor;
  srvActionsResource.rvActionOpen1.OnExecute := OnOpenEditor;
  ActiveEditor.RichViewEdit.Modified := False;
  UpdateIcon(ActiveEditor);
  SRichViewEdit1ZoomChanged(ActiveEditor);
end;

{--------------- Working with color-picking buttons ---------------------------}

// Code for making color-picking buttons pressed while
// a color-picker window is visible.
procedure TForm3.ColorPickerShow(Sender: TObject);
begin
  if (Sender as TAction).ActionComponent is TToolButton then
    TToolButton(TAction(Sender).ActionComponent).Down := True;
end;

procedure TForm3.ColorPickerHide(Sender: TObject);
begin
  if (Sender as TAction).ActionComponent is TToolButton then
    TToolButton(TAction(Sender).ActionComponent).Down := False;
end;

{-------------- Set of events for processing hypertext links ------------------}

// Hyperlink click
procedure TForm3.RichViewEdit1_Jump(Sender: TObject; id: Integer);
begin
  srvActionsResource.rvActionInsertHyperlink1.GoToLink(ActiveEditor.ActiveEditor, id);
end;

// Importing hyperlink
procedure TForm3.RichViewEdit1_ReadHyperlink(Sender: TCustomRichView;
  const Target, Extras: String; DocFormat: TRVLoadFormat; var StyleNo,
  ItemTag: Integer; var ItemName: TRVRawByteString);
var URL: String;
begin
  if DocFormat=rvlfURL then
    StyleNo :=
      srvActionsResource.rvActionInsertHyperlink1.GetHyperlinkStyleNo(
        Sender as TCustomRichViewEdit);
  URL := srvActionsResource.rvActionInsertHyperlink1.EncodeTarget(Target);
  ItemTag := Integer(StrNew(PChar(URL)));
end;

// Exporting hyperlink to RTF and HTML
procedure TForm3.RichViewEdit1_WriteHyperlink(Sender: TCustomRichView;
  id: Integer; RVData: TCustomRVData; ItemNo: Integer;
  SaveFormat: TRVSaveFormat; var Target, Extras: String);
begin
  Target := PChar(RVData.GetItemTag(ItemNo));
end;

// URL detection on typing
procedure TForm3.RichViewEdit1_KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key in [VK_SPACE, VK_RETURN, VK_TAB] then begin
    {
      // uncomment if you use Addict3
      RVA_Addict3AutoCorrect(ActiveEditor.ActiveEditor);
    }
    srvActionsResource.rvActionInsertHyperlink1.DetectURL(ActiveEditor.ActiveEditor);
    srvActionsResource.rvActionInsertHyperlink1.TerminateHyperlink(ActiveEditor.ActiveEditor);
  end;
end;

procedure TForm3.RichViewEdit1_KeyPress(Sender: TObject; var Key: Char);
begin
  {
  // uncomment if you use Addict3
  if (Key='''') or ((Key<>' ') and (Pos(Key, ActiveEditor.ActiveEditor.Delimiters)<>0)) then
    RVA_Addict3AutoCorrect(ActiveEditor.ActiveEditor);
  }
end;

{----------------------- Insert table popup      -----------------------------}
{ We use a trick: insert-table button has style tbsDropDown and assigned
  DropDownMenu (pmFakeDropDown). This menu is empty, but shows table size
  popup instead of itself }
procedure TForm3.pmFakeDropDownPopup(Sender: TObject);
begin
  srvActionsResource.rvActionInsertTable1.ShowTableSizeDialog(ActiveEditor.ActiveEditor,
    ToolButton12);
end;

{--------------------- Working with font combo-boxes --------------------------}
// Switching focus to the ActiveEditor without accidental applying combos
// (the apply changes on exiting)
procedure TForm3.FocusActiveEditor;
begin
  if Visible then begin
    UpdatingCombos := True;
    ActiveEditor.SetFocus;
    UpdatingCombos := False;
  end;
end;

// Current font is changed. Updating the combo-boxes.
procedure TForm3.RichViewEdit1_CurTextStyleChanged(Sender: TObject);
var CurStyle: TFontInfo;
    rve: TCustomRichViewEdit;
begin
  UpdatingCombos := True;
  try
    rve := Sender as TCustomRichViewEdit;
    if rve=ActiveEditor.ActiveEditor then begin
      CurStyle := rve.Style.TextStyles[rve.CurTextStyleNo];
      cmbFont.Text := CurStyle.FontName;
      cmbFont.OnClick(Sender);
      cmbFontSize.FontName := CurStyle.FontName;
      cmbFontSize.Text := IntToStr(CurStyle.Size);
    end;
  finally
    UpdatingCombos := False;
  end;
end;

// Applying the font name
procedure TForm3.cmbFontClick(Sender: TObject);
var FontName: String;
begin
  if UpdatingCombos then
    exit;
  if cmbFont.ItemIndex<0 then
    FontName := cmbFont.Text
  else
    FontName := cmbFont.Items[cmbFont.ItemIndex];
  UpdatingCombos := True;
  cmbFontSize.FontName := FontName;
  UpdatingCombos := False;
  if cmbFont.ItemIndex<0 then
    cmbFont.ItemIndex := cmbFont.Items.IndexOf(FontName);
  if cmbFont.ItemIndex<0 then begin
      if Visible then beep
    end
  else
    with srvActionsResource.rvActionFontEx1 do begin
      UserInterface := False;
      ValidProperties := [rvfimFontName];
      Font.Name := FontName;
      ExecuteTarget(ActiveEditor.ActiveEditor);
      UserInterface := True;
    end;
  ActiveEditor.SetFocus;
end;

// Changing the font size
procedure TForm3.cmbFontSizeClick(Sender: TObject);
var FontSize: Integer;
begin
  if UpdatingCombos then
    exit;
  try
    FontSize := StrToInt(cmbFontSize.Text);
    with srvActionsResource.rvActionFontEx1 do begin
      UserInterface := False;
      ValidProperties := [rvfimSize];
      Font.Size := FontSize;
      ExecuteTarget(ActiveEditor.ActiveEditor);
      UserInterface := True;
    end;
  except
    if Visible then beep;
  end;
  ActiveEditor.SetFocus;
end;

procedure TForm3.cmbKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key=VK_RETURN then begin
    Key := 0;
    TComboBox(Sender).OnClick(Sender);
  end;
end;

{---------------------- Zooming combo box -------------------------------------}
// We could implement zooming using only actions, without a combo box

procedure TForm3.SRichViewEdit1ZoomChanged(Sender: TObject);
begin
  if Sender<>ActiveEditor then
    exit;
  UpdatingCombos := True;
  try
    case ActiveEditor.ViewProperty.ZoomMode of
      rvzmPageWidth:
        cmbZoom.ItemIndex := cmbZoom.Items.Count-2;
      rvzmFullPage:
        cmbZoom.ItemIndex := cmbZoom.Items.Count-1;
      rvzmCustom:
        cmbZoom.ItemIndex := cmbZoom.Items.IndexOf(
          IntToStr(Round(ActiveEditor.ViewProperty.ZoomPercent)));
    end;
  finally
    UpdatingCombos := False;
  end;
end;

procedure TForm3.RVAControlPanel1ViewChanged(Sender: TrvCustomAction;
  Edit: TCustomRichViewEdit);
begin
  SRichViewEdit1ZoomChanged(Edit);
end;

// Applying zooming
procedure TForm3.cmbZoomChange(Sender: TObject);
//var Percent : Single;
begin
  if UpdatingCombos then
    exit;
  if cmbZoom.ItemIndex = cmbZoom.Items.Count-1 then
    ActiveEditor.ViewProperty.ZoomMode := rvzmFullPage
  else if cmbZoom.ItemIndex = cmbZoom.Items.Count-2 then
    ActiveEditor.ViewProperty.ZoomMode := rvzmPageWidth
  else if cmbZoom.ItemIndex>=0 then begin
    ActiveEditor.ViewProperty.ZoomPercent := StrToIntDef(cmbZoom.Text, 0);
    ActiveEditor.ViewProperty.ZoomMode := rvzmCustom;
  end;
  {
  // This code will not work, because TsrvActionZoomFullPage and
  // TsrvActionZoomPageWidth are disabled in a web mode

  if cmbZoom.ItemIndex = cmbZoom.Items.Count-1 then
    srvActionsResource.srvActionZoomFullPage1.Execute
  else if cmbZoom.ItemIndex = cmbZoom.Items.Count-2 then
    srvActionsResource.srvActionZoomPageWidth1.Execute
  else if cmbZoom.ItemIndex>=0 then begin
    Percent := srvActionsResource.srvActionZoom1.ZoomPercent;
    srvActionsResource.srvActionZoom1.ZoomPercent := StrToIntDef(cmbZoom.Text, 0);
    srvActionsResource.srvActionZoom1.Execute;
    srvActionsResource.srvActionZoom1.ZoomPercent := Percent;
  end;
  }
end;
{----------------------------- Units combo box --------------------------------}
// Applying units

procedure TForm3.cmbUnitsClick(Sender: TObject);
var i: Integer;
begin
  for i := 0 to High(Editors) do
    Editors[i].UnitsProgram := TRVUnits(cmbUnits.ItemIndex);
  RVAControlPanel1.UnitsDisplay := TRVUnits(cmbUnits.ItemIndex);
  SclRVRuler1.UnitsDisplay := TRulerUnits(cmbUnits.ItemIndex);
  SclRVRuler2.UnitsDisplay := TRulerUnits(cmbUnits.ItemIndex);
end;

{------- Synchronizing ScaleRichView after non-editing operations -------------}

procedure TForm3.RVAControlPanel1MarginsChanged(Sender: TrvAction;
  Edit: TCustomRichViewEdit);
var WasModified: Boolean;
    SRichViewEdit: TSRichViewEdit;
begin
  SRichViewEdit := Editors[GetIndexOfEditorByRichViewEdit(Edit)];
  WasModified := Edit.Modified;

  Edit.RVData.State := Edit.RVData.State + [rvstSkipFormatting];
  SRichViewEdit.SetRVMargins;

  SclRVRuler1.UnitsDisplay := TRulerUnits(ActiveEditor.UnitsProgram);
  SclRVRuler2.UnitsDisplay := TRulerUnits(ActiveEditor.UnitsProgram);
  SclRVRuler1.checkMargin;
  SclRVRuler2.checkMargin;

  Edit.RVData.State := Edit.RVData.State - [rvstSkipFormatting];
  Edit.Modified := WasModified;
  UpdateIcon(SRichViewEdit);
end;

procedure TForm3.RVAControlPanel1BackgroundChange(Sender: TrvAction;
  Edit: TCustomRichViewEdit);
begin
  ActiveEditor.Repaint;
end;

{---------------------------- Localization ------------------------------------}

procedure TForm3.Button1Click(Sender: TObject);
begin
  if RVA_ChooseLanguage then
    Localize;
end;

procedure TForm3.Localize;
var i, Index: Integer;
begin
  // Fonts
  Font.Charset            := RVA_GetCharset;
  stat1.Font.Charset := RVA_GetCharset;
  Screen.HintFont.Charset := RVA_GetCharset;
  Screen.MenuFont.Charset := RVA_GetCharset;
  // Localizing all actions on srvActionsResource
  RVA_LocalizeForm(srvActionsResource);
  // Localizing all actions on this form
  RVA_LocalizeForm(Self);
  // Localizing ruler
  RVALocalizeRuler(SclRVRuler1);
  RVALocalizeRuler(SclRVRuler2);
  // Localizing the editors
  for i := 0 to High(Editors) do begin
    SRVA_LocalizeSRichViewEdit(Editors[i]);
    TSRVToolButton(Editors[i].MenuHButtons.Items[0]).Hint := RVADeleteAmp(SRVA_GetS(srvam_act_Draft));
    TSRVToolButton(Editors[i].MenuHButtons.Items[1]).Hint := RVADeleteAmp(SRVA_GetS(srvam_act_WebLayout));
    TSRVToolButton(Editors[i].MenuHButtons.Items[2]).Hint := RVADeleteAmp(SRVA_GetS(srvam_act_PrintLayout));
  end;
  // Localizing the search tool window
  SRVA_LocalizeToolWindow(srvtwSearch);
  // Localizing menus and tool buttons
  mitFile.Caption := RVA_GetS(rvam_menu_File);
  mitEdit.Caption := RVA_GetS(rvam_menu_Edit);
  mitFont.Caption := RVA_GetS(rvam_menu_Font);
  mitPara.Caption := RVA_GetS(rvam_menu_Para);
  mitFormat.Caption := RVA_GetS(rvam_menu_Format);
  mitInsert.Caption := RVA_GetS(rvam_menu_Insert);
  mitTable.Caption := RVA_GetS(rvam_menu_Table);
  mitExit.Caption := RVA_GetS(rvam_menu_Exit);

  mitFontSize.Caption := RVA_GetS(rvam_menu_FontSize);
  mitFontStyle.Caption := RVA_GetS(rvam_menu_FontStyle);
  mitTextFlow.Caption := RVA_GetS(rvam_menu_TextFlow);

  mitTableSelect.Caption := RVA_GetS(rvam_menu_TableSelect);
  mitTableCellBorders.Caption := RVA_GetS(rvam_menu_TableCellBorders);
  mitTableAlignCellContents.Caption := RVA_GetS(rvam_menu_TableCellAlign);

  btnPageFormat.Caption := SRVA_GetS(srvam_menu_PageSize);
  btnPageFormat.Hint := RVADeleteAmp(btnPageFormat.Caption);
  // In your application, you can use either TrvActionFonts or TrvActionFontEx
  srvActionsResource.rvActionFonts1.Caption := srvActionsResource.rvActionFonts1.Caption+' (Standard)';
  srvActionsResource.rvActionFontEx1.Caption := srvActionsResource.rvActionFontEx1.Caption+' (Advanced)';

  // Localizing measuring units
  Index := cmbUnits.ItemIndex;
  RVA_TranslateUnits(cmbUnits.Items);
  cmbUnits.ItemIndex := Index;

  // Localizing the zoom combo box

  Index := cmbZoom.ItemIndex;
  cmbZoom.Items[cmbZoom.Items.Count-2] := RVA_GetS(rvam_pp_PageWidth);
  cmbZoom.Items[cmbZoom.Items.Count-1] := RVA_GetS(rvam_pp_FullPage);
  cmbZoom.ItemIndex := Index;


  // Localizing text on the status bar
  SRichViewEdit1CurrentPageChange(ActiveEditor);
  SRichViewEdit1PageScrolled(ActiveEditor);
  SRichViewEdit1CaretMove(ActiveEditor);

  {
  // uncomment if you use Addict3. It's assumed that RVAddictSpell31
  // and RVThesaurus31 are on this form.
  RVAddictSpell31.UILanguage := GetAddictSpellLanguage(RVA_GetLanguageName);
  RVThesaurus31.UILanguage := GetAddictThesLanguage(RVA_GetLanguageName);
  }
end;

{---------------------- Live spelling with Addict 3 ---------------------------}
(*
// Add these events if you use Addict3
// (Assuming that you have RVAddictSpell31: TRVAddictSpell3 on the form)

// RichViewEdit1.OnSpellingCheck event
procedure TForm3.RichViewEdit1SpellingCheck(Sender: TCustomRichView;
  const AWord: String; StyleNo: Integer; var Misspelled: Boolean);
begin
  Misspelled := not RVAddictSpell31.WordAcceptable(AWord);
end;

// RVAddictSpell31.OnParserIgnoreWord: if Ignore All or Add buttons were pressed
// in spellchecker dialog, removing underlines from the ignored word
procedure TForm3.RVAddictSpell31ParserIgnoreWord(Sender: TObject;
  Before: Boolean; State: Integer);
begin
  if not Before and (State in [IgnoreState_IgnoreAll, IgnoreState_Add]) then
    ActiveEditor.RichViewEdit.LiveSpellingValidateWord(RVAddictSpell31.CurrentWord);
end;

// Besides, if you want spelling check starting when loading document, call
// ActiveEditor.RichViewEdit.StartLiveSpelling in rvActionFileOpen.OnOpenFile event
*)

{------------------------------ Status bar ------------------------------------}
// Displaying the index of the edited page
procedure TForm3.SRichViewEdit1CurrentPageChange(Sender: TObject);
begin
  if Sender=ActiveEditor then
    stat1.Panels.Items[1].Text := Format(SRVA_GetS(srvam_PageMofN),
      [ActiveEditor.CurrentPage, ActiveEditor.PageCount]);
end;
// Displaying the index of the visible page
procedure TForm3.SRichViewEdit1PageScrolled(Sender: TObject);
begin
  if Sender=ActiveEditor then
    stat1.Panels.Items[0].Text  := Format(SRVA_GetS(srvam_ViewPageX),
      [ActiveEditor.ScrolledPage]);
end;

// Displaying the current line and column
procedure TForm3.SRichViewEdit1CaretMove(Sender: TObject);
var Line, Column : Integer;
begin
  if (ActiveEditor<>nil) and (Sender=ActiveEditor.ActiveEditor) then begin
    ActiveEditor.GetCurrentLineCol(Line, Column);
    stat1.Panels.Items[2].Text := Format(SRVA_GetS(srvam_LineX), [Line]);
    stat1.Panels.Items[3].Text := Format(SRVA_GetS(srvam_ColX), [Column]);
  end;
end;

// switching to header/footer/main
procedure TForm3.SRichViewEdit1ChangeActiveEditor(Sender: TSRichViewEdit;
  ActiveEditor: TRichViewEdit);
begin
  SRichViewEdit1CaretMove(ActiveEditor);
end;

// Displaying hints
procedure TForm3.ApplicationHint(Sender: TObject);
var s: String;
begin
  s := GetLongHint(Application.Hint);
  stat1.SimplePanel := s<>'';
  stat1.SimpleText := s;
  stat1.Repaint;
end;
{--------------------- Buttons on scroll-bars ---------------------------------}
// On horizontal scroll bar (view modes)
procedure TForm3.SRichViewEdit1HMenuClickButton(Sender: TObject;
  ToolButton: TSRVToolButton);
begin
  if ToolButton = nil then Exit;
  ActiveEditor.CanUpdate := False;
  case (ToolButton.Index) of
    0 : srvActionsResource.srvActionLayoutDraft1.Execute;
    1 : srvActionsResource.srvActionLayoutWeb1.Execute;
    2 : srvActionsResource.srvActionLayoutPrint1.Execute;
  end;
  ActiveEditor.CanUpdate := True;
end;
// On vertical scroll bar
procedure TForm3.SRichViewEdit1VMenuClickButton(Sender: TObject;
  ToolButton: TSRVToolButton);
var
     sbX, sbY : Integer;
     p : TPoint;
begin
  if ToolButton = nil then Exit;
  case ToolButton.Index of
    0 :  // "Up arrows" button, performs search to the top
      begin
          case VToolButtonIndex of
            SRV_TOOLWIN_PAGE, -1 : ActiveEditor.PriorCurPage;
            SRV_TOOLWIN_TABLE : ActiveEditor.PriorCurItem([rvsTable]);
            SRV_TOOLWIN_PICTURE : ActiveEditor.PriorCurItem([rvsPicture, rvsHotspot, rvsHotPicture]);
            SRV_TOOLWIN_HEADLINE : ActiveEditor.PriorCurHeading;
            SRV_TOOLWIN_HYPERLINK : ActiveEditor.PriorCurHyperlink;
            SRV_TOOLWIN_TEXT :
              begin
                fd.Options := fd.Options - [frDown];
                fdFind(nil);
              end;
          end;
      end;
    1 : // "Circle" button, shows tool window
      begin
        sbX := ActiveEditor.MenuVertical.SRVToolBar.Width;
        sbY := ActiveEditor.MenuVertical.SRVToolBar.Height div 3;

        p := ActiveEditor.MenuVertical.SRVToolBar.ClientToScreen(Point(0, 0));
        p.Y := p.Y + sbY;

        srvtwSearch.Execute(Bounds(p.x, p.y, sbX, sbY));
      end;
    2 : // "Down arrows" button, performs search to the bottom
      begin
          case VToolButtonIndex of
            SRV_TOOLWIN_PAGE, -1 : ActiveEditor.NextCurPage;
            SRV_TOOLWIN_TABLE : ActiveEditor.NextCurItem([rvsTable]);
            SRV_TOOLWIN_PICTURE : ActiveEditor.NextCurItem([rvsPicture, rvsHotspot, rvsHotPicture]);
            SRV_TOOLWIN_HEADLINE : ActiveEditor.NextCurHeading;
            SRV_TOOLWIN_HYPERLINK : ActiveEditor.NextCurHyperlink;
            SRV_TOOLWIN_TEXT :
              begin
                fd.Options := fd.Options + [frDown];
                fdFind(nil);
              end;
          end;
      end;
  end;
end;
// Button on the tool window is clicked
procedure TForm3.srvtwSearchClickButton(Sender: TObject;
  ToolButton: TSRVToolButton);
var
     s: String;
     posit: Integer;
begin
  if ToolButton = nil then begin
    VToolButtonIndex := -1;
    Exit;
    end
  else
    VToolButtonIndex := ToolButton.Index;
  if ToolButton.Index = SRV_TOOLWIN_TEXT then // starting text search
    begin
      ActiveEditor.SetFocus;
      fd.CloseDialog;
      if ActiveEditor.RichViewEdit.SelectionExists then
        begin
          s := ActiveEditor.RichViewEdit.GetSelText;
          posit := Pos(#13,s);
          if posit<>0 then
            s := Copy(s,1,posit-1);
          fd.FindText := s;
        end;
      fd.Execute;
    end
  else // starting search
    SRichViewEdit1VMenuClickButton(Sender,
      TSRVToolButton(ActiveEditor.MenuVButtons.Items[2]));
end;
// text search
procedure TForm3.fdFind(Sender: TObject);
begin
  if not ActiveEditor.RichViewEdit.SearchText(fd.FindText,GetRVESearchOptions(fd.Options)) then
    ShowInfo(Format(RVA_GetS(rvam_src_NotFound), [fd.FindText]), RVA_GetS(rvam_src_Complete));
  ActiveEditor.Repaint;
end;
{-------------------------------- Misc. ---------------------------------------}
// On dowloading image
procedure TForm3.RVAControlPanel1Download(Sender: TrvAction;
  const Source: String);
begin
  if Source='' then
    Application.Hint := ''
  else
    Application.Hint := 'Downloading '+Source+'...';
end;
// On clicking a table icon
procedure TForm3.SRichViewEdit1TableIconClick(Sender: TSRichViewEdit;
  Button: TMouseButton; Shift: TShiftState; X, Y, PageNo: Integer);
begin
  Sender.GetTableIconItem.SelectRows(0, Sender.GetTableIconItem.RowCount);
  Sender.Repaint;
end;
//  Double clicking on the rulers' margins shows the page setup dialog
procedure TForm3.SclRVRuler1MarginDblClick(Sender: TObject;
  Margin: TMarginType);
begin
   srvActionsResource.srvActionPageSetup1.ExecuteTarget(ActiveEditor);
end;
// After TsrvActionThumbnails is executed
procedure TForm3.srvActionThumbnails1Executed(Sender: TObject);
begin
  Splitter1.Visible := TsrvActionThumbnails(Sender).Checked;
  SRVPageScroll1.Visible := TsrvActionThumbnails(Sender).Checked;
end;
{-------------------------- Tabbed User Interface -----------------------------}
{
  Main variables:
  Editors[] - array of opened editors, in the order of tabs
  ActiveEditor - focused editor (on the active tab). This editor is visible,
    others are hidden.
}

// Returns the index of tab icon depending on IsNew (document was created
// but never saved), FileFormat, Modified (document has unsaved changes)
function TForm3.GetIconIndex(IsNew: Boolean; FileFormat: TrvFileSaveFilter; Modified: Boolean): Integer;
begin
  Result := 0;
  if not IsNew then
    case FileFormat of
      ffeRVF:
        Result := 1;
      ffeRTF:
        Result := 2;
      ffeTextANSI, ffeTextUnicode:
        Result := 3;
    end;
  if Modified then
    inc(Result, 4);
end;

// rvActionSave1.OnDocumentFileChange: occurs when document is created, saved, loaded...
// This event occurs on New, SaveAs, Open actions
procedure TForm3.rvActionSave1DocumentFileChange(Sender: TObject;
  Editor: TCustomRichViewEdit; const FileName: String;
  FileFormat: TrvFileSaveFilter; IsNew: Boolean);
var
     s: String;
     TI : TSRVTabItem;
     Index: Integer;
begin
  s := ExtractFileName(FileName);

  srvActionsResource.srvActionPrint1.Title := s;
  srvActionsResource.srvActionQuickPrint1.Title := s;

  Index := GetIndexOfEditorByRichViewEdit(Editor);
  If Index >= 0 then begin
    TI := SRVTabSet1.Tabs[Index];
    TI.Text := s;
    TI.ImageIndex := GetIconIndex(IsNew, FileFormat, False);
  end;
end;

// Prompt for saving when the form closes
procedure TForm3.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  While SRVTabSet1.Tabs.Count > 0 do begin
    CanClose := srvActionsResource.rvActionSave1.CanCloseDoc(ActiveEditor.RichViewEdit);
    If CanClose then
      If SRVTabSet1.Tabs.Count > 1 then begin
        RemoveEditor(SRVTabSet1.TabIndex);
        SRVTabSet1.Tabs[SRVTabSet1.TabIndex].Free;
        SetEditor(SRVTabSet1.Tabs.Count-1);
      end else
        Break
    else
      Break;
  end;
end;

// exiting
procedure TForm3.mitExitClick(Sender: TObject);
begin
  Close;
end;

// Returns the index of TSRichViewEdit in Editors[] by its RichViewEdit
function TForm3.GetIndexOfEditorByRichViewEdit(rve: TCustomRichViewEdit): Integer;
var i: Integer;
begin
  for i:=0 to High(Editors) do
    If Editors[i].RichViewEdit=rve then begin
      Result := i;
      Exit;
    end;
  Result := -1;
end;

// Returns information about document opened in TRichViewEdit
function TForm3.GetDocInfo(rve: TCustomRichViewEdit): TrvaDocumentInfo;
var DocIndex: Integer;
begin
  DocIndex := srvActionsResource.rvActionSave1.FindDoc(rve);
  if DocIndex>=0 then
    Result := TrvaDocumentInfo(srvActionsResource.rvActionSave1.Documents[DocIndex])
  else
    Result := nil;
end;

// Returns information about the active document (opened in ActiveEditor)
function TForm3.GetActiveDocInfo: TrvaDocumentInfo;
begin
  Result := GetDocInfo(ActiveEditor.RichViewEdit);
end;

// Adds a new tab with editor, making it active
procedure TForm3.AddEditor;
var
     srve : TSRichViewEdit;
begin
  SetLength(Editors, Length(Editors)+1);

  srve := TSRichViewEdit.Create(ActiveEditor.Owner);
  srve.Hide;
  srve.Parent := ActiveEditor.Parent;
  srve.Align := alClient;
  srve.BackgroundProperty.Assign(ActiveEditor.BackgroundProperty);
  srve.MenuHorizontal.Assign(ActiveEditor.MenuHorizontal);
  srve.MenuVertical.Assign(ActiveEditor.MenuVertical);
  srve.UnitsProgram := ActiveEditor.UnitsProgram;
  srve.PopupMenu := ActiveEditor.PopupMenu;
  srve.SkinManager := ActiveEditor.SkinManager;
  srve.ViewProperty.MarginsRectVisible := ActiveEditor.ViewProperty.MarginsRectVisible;
  srve.HScrollBarSchemeIndex := ActiveEditor.HScrollBarSchemeIndex;
  srve.VScrollBarSchemeIndex := ActiveEditor.VScrollBarSchemeIndex;
  srve.OnCaretMove := SRichViewEdit1CaretMove;
  srve.OnCurrentPageChange := SRichViewEdit1CurrentPageChange;
  srve.OnCurTextStyleChanged := RichViewEdit1_CurTextStyleChanged;
  srve.OnHMenuClickButton := SRichViewEdit1HMenuClickButton;
  srve.OnJump := RichViewEdit1_Jump;
  srve.OnKeyDown := RichViewEdit1_KeyDown;
  srve.OnCurrentPageChange := SRichViewEdit1CurrentPageChange;
  srve.OnPageScrolled := SRichViewEdit1PageScrolled;
  srve.OnTableIconClick := SRichViewEdit1TableIconClick;
  srve.OnVMenuClickButton := SRichViewEdit1VMenuClickButton;
  srve.OnWriteHyperlink := RichViewEdit1_WriteHyperlink;
  srve.OnReadHyperlink := RichViewEdit1_ReadHyperlink;  
  srve.OnChange := SRichViewEdit1Change;
  srve.OnZoomChanged := SRichViewEdit1ZoomChanged;
  srve.OnZoomViewChanged := SRichViewEdit1ZoomChanged;
  srve.Loaded;
  SRVA_LocalizeSRichViewEdit(srve);
  srve.ConvertToTwips;
  srve.Show;
  ActiveEditor.Hide;
  ActiveEditor := srve;

  srve.ResetEventRuler;
  SclRVRuler1.SRichViewEdit := srve;
  SclRVRuler2.SRichViewEdit := srve;
  SRVPageScroll1.SRichViewEdit := srve;



  Editors[High(Editors)] := srve;

  SRVTabSet1.Tabs.Add;
  SRVTabSet1.TabIndex := High(Editors); // calls SetEditor
  // Some assignments may set Modified flag, resetting
  srve.RichViewEdit.Modified := False;
  UpdateIcon(srve);  
  FocusActiveEditor;
end;

// Makes Editors[Index] active
procedure TForm3.SetEditor(Index : Integer);
var DocInfo: TrvaDocumentInfo;
begin
  Index := Min(Max(Index, 0), SRVTabSet1.Tabs.Count-1);

  If SRVTabSet1.TabIndex <> Index then
    SRVTabSet1.TabIndex := Index;

  If ActiveEditor <> Editors[Index] then begin
    if ActiveEditor<>nil then
      ActiveEditor.Hide;
    ActiveEditor := Editors[Index];
    ActiveEditor.Show;
  end;
  RVAControlPanel1.DefaultControl := ActiveEditor.RichViewEdit;  
  ActiveEditor.ResetEventRuler;
  SclRVRuler1.SRichViewEdit := ActiveEditor;
  SclRVRuler2.SRichViewEdit := ActiveEditor;
  SRVPageScroll1.SRichViewEdit := ActiveEditor;
  DocInfo := GetActiveDocInfo;
  if DocInfo<>nil then begin
    srvActionsResource.srvActionPrint1.Title := ExtractFileName(DocInfo.FileName);
    srvActionsResource.srvActionQuickPrint1.Title := ExtractFileName(DocInfo.FileName);
  end;
  RVAControlPanel1MarginsChanged(nil, ActiveEditor.RichViewEdit);
  RVAControlPanel1ViewChanged(nil, ActiveEditor.RichViewEdit);
  SRichViewEdit1CurrentPageChange(ActiveEditor);
  SRichViewEdit1PageScrolled(ActiveEditor);
  FocusActiveEditor;
end;

// Deletes Editors[Index] (but does not deletes its tab)
// Usually this function is used to close the active editor
procedure TForm3.RemoveEditor(Index : Integer);
var i: Integer;
begin
  i := srvActionsResource.rvActionSave1.FindDoc(Editors[Index].RichViewEdit);
  if i>=0 then
    srvActionsResource.rvActionSave1.Documents.Delete(i);
  if Editors[Index]=ActiveEditor then begin
    SclRVRuler1.SRichViewEdit := nil;
    SclRVRuler2.SRichViewEdit := nil;
    SRVPageScroll1.SRichViewEdit := nil;
    ActiveEditor := nil;
  end;
  Editors[Index].Free;
  for i := Index to High(Editors)-1 do
    Editors[i] := Editors[i+1];
  SetLength(Editors, Length(Editors)-1);
end;

// SRVTabSet1.OnChange: another tab became active
procedure TForm3.SRVTabSet1Change(Sender: TObject);
begin
  SetEditor(SRVTabSet1.TabIndex);
end;

// SRVTabSet1.OnCloseTab: checking if we can close this tab
procedure TForm3.SRVTabSet1CloseTab(Sender: TSRVTabSet; TabIndex: Integer;
  var CanClose: Boolean);
begin
  CanClose := srvActionsResource.rvActionSave1.CanCloseDoc(Editors[TabIndex].RichViewEdit);
  If CanClose then
    RemoveEditor(TabIndex);
end;
// srvActionsResource.rvActionNew1.OnExecute: "File | New" command
procedure TForm3.OnNewEditor(Sender: TObject);
begin
  // Instead of applying to the active editor,
  // we creating a new editor, making it active,
  AddEditor;
  // then execute rvActionNew for this new editor
  srvActionsResource.rvActionNew1.ExecuteTarget(ActiveEditor.RichViewEdit);
  // Some assignments may set Modified flag, resetting
  ActiveEditor.RichViewEdit.Modified := False;
  UpdateIcon(ActiveEditor);  
end;

// srvActionsResource.rvActionOpen1.OnExecute: "File | Open..." command
procedure TForm3.OnOpenEditor(Sender: TObject);
var DocInfo: TrvaDocumentInfo;
begin
  // Instead of applying to the active editor,
  // we creating a new editor, making it active,
  AddEditor;
  // then execute rvActionOpen for this new editor
  srvActionsResource.rvActionOpen1.ExecuteTarget(ActiveEditor.RichViewEdit);
  // Some assignments may set Modified flag, resetting
  ActiveEditor.RichViewEdit.Modified := False;
  UpdateIcon(ActiveEditor);  
  // But may be the user pressed "Cancel" in the file opening dialog.
  // In this case, we closing the new tab.
  DocInfo := GetActiveDocInfo;
  if (DocInfo=nil) or not DocInfo.Defined then begin
    RemoveEditor(SRVTabSet1.TabIndex);
    SRVTabSet1.Tabs[SRVTabSet1.TabIndex].Free;
    SetEditor(Max(SRVTabSet1.TabIndex-1, 0));
  end;
end;
// updating tab icon depending on Editor.RichViewEdit.Modified
procedure TForm3.UpdateIcon(Editor: TSRichViewEdit);
var EditIndex: Integer;
    TI : TSRVTabItem;
    DocInfo: TrvaDocumentInfo;
begin
  // Updating the tab icon to show a "modified" state
  DocInfo := GetDocInfo(Editor.RichViewEdit);
  if DocInfo=nil then
    exit;
  EditIndex := GetIndexOfEditorByRichViewEdit(DocInfo.rve);
  If EditIndex >= 0 then begin
    TI := SRVTabSet1.Tabs[EditIndex];
    TI.ImageIndex := GetIconIndex(not DocInfo.Defined, DocInfo.FileFormat,
      Editor.RichViewEdit.Modified);
  end;
end;

// OnChange event (usually called for the ActiveEditor)
procedure TForm3.SRichViewEdit1Change(Sender: TObject);
begin
  UpdateIcon(Sender as TSRichViewEdit);
end;

procedure TForm3.SRVTabSet1TabMove(Sender: TSRVTabSet; NewTabIndex,
  OldTabIndex: Integer);
var
  tmp : TSRichViewEdit;
begin
  tmp := Editors[OldTabIndex];
  Editors[OldTabIndex] := Editors[NewTabIndex];
  Editors[NewTabIndex] := tmp;
end;

initialization

// Initializing graphics

  RegisterClass(TGifImage);
  RV_RegisterHTMLGraphicFormat(TGifImage);
  // RegisterClass(TPngImage); - not necessary, because RegisterClassAlias registers
  RV_RegisterHTMLGraphicFormat(TPngImage);
  RV_RegisterPngGraphic(TPngImage);
  // allows loading old RVF files saved with TPNGObject instead of TPngImage
  RegisterClassAlias(TPngImage, 'TPNGObject');

// IMPORTANT: allowing RichViewActions and TRVAPopupMenu working with TSRichViewEdit
  RVA_GetRichViewEditFromPopupComponent :=
   SRVGetRichViewEditFromPopupComponent;
  RVA_GetRichViewEdit := SRVGetRichViewEdit;

end.