unit UEditor;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdActns, ActnList, ImgList, ComCtrls, StdCtrls, ToolWin,
  AppEvnts, ExtActns;

type
  TForm1 = class(TForm)
    ToolBar1: TToolBar;
    TBCreate: TToolButton;
    TBOpen: TToolButton;
    TBSave: TToolButton;
    ToolButton4: TToolButton;
    TBPrint: TToolButton;
    ToolButton6: TToolButton;
    TBUndo: TToolButton;
    TBCut: TToolButton;
    TBCopy: TToolButton;
    TBPaste: TToolButton;
    ToolButton11: TToolButton;
    TBFind: TToolButton;
    TBReplace: TToolButton;
    ToolButton14: TToolButton;
    TBFont: TToolButton;
    ToolButton16: TToolButton;
    TBLeft: TToolButton;
    TBCenter: TToolButton;
    TBRight: TToolButton;
    TBBullet: TToolButton;
    RichEdit1: TRichEdit;
    StatusBar1: TStatusBar;
    MainMenu1: TMainMenu;
    MFile1: TMenuItem;
    MNew1: TMenuItem;
    MOpen1: TMenuItem;
    MClose1: TMenuItem;
    N1: TMenuItem;
    MSave1: TMenuItem;
    MSaveAs1: TMenuItem;
    N2: TMenuItem;
    MPrint1: TMenuItem;
    MPrintSetup1: TMenuItem;
    N3: TMenuItem;
    MExit1: TMenuItem;
    MEdit1: TMenuItem;
    MUndo1: TMenuItem;
    N5: TMenuItem;
    MCut1: TMenuItem;
    MCopy1: TMenuItem;
    MPaste1: TMenuItem;
    N6: TMenuItem;
    MFind1: TMenuItem;
    MReplace1: TMenuItem;
    MFormat1: TMenuItem;
    MFont1: TMenuItem;
    MParagr1: TMenuItem;
    MBullet: TMenuItem;
    MWindow1: TMenuItem;
    MNewWind1: TMenuItem;
    N7: TMenuItem;
    MCascad1: TMenuItem;
    MArrange1: TMenuItem;
    MHorizont1: TMenuItem;
    MVert1: TMenuItem;
    MArrIcon1: TMenuItem;
    MHelp1: TMenuItem;
    MCallHelp1: TMenuItem;
    N8: TMenuItem;
    MAbout1: TMenuItem;
    Image1: TImageList;
    ActionList1: TActionList;
    ACut: TEditCut;
    ACopy: TEditCopy;
    APaste: TEditPaste;
    AArrangeIcons: TWindowArrange;
    ACascade: TWindowCascade;
    ATileHorizontally: TWindowTileHorizontal;
    ATileVertically: TWindowTileVertical;
    ACreate: TAction;
    AOpen: TAction;
    ASave: TAction;
    ASaveAs: TAction;
    APrint: TAction;
    APrinterSetup: TAction;
    AExit: TAction;
    AFind: TAction;
    AReplace: TAction;
    AFont: TAction;
    ALeft: TAction;
    ACenter: TAction;
    ARight: TAction;
    ABullet: TAction;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    FontDialog1: TFontDialog;
    PrinterSetupDialog1: TPrinterSetupDialog;
    PrintDialog1: TPrintDialog;
    FindDialog1: TFindDialog;
    ReplaceDialog1: TReplaceDialog;
    PopupMenu1: TPopupMenu;
    N9: TMenuItem;
    N10: TMenuItem;
    N11: TMenuItem;
    N12: TMenuItem;
    N13: TMenuItem;
    N14: TMenuItem;
    N15: TMenuItem;
    N16: TMenuItem;
    N17: TMenuItem;
    AUndo: TEditUndo;
    ApplicationEvents1: TApplicationEvents;
    N18: TMenuItem;
    AParagraph: TAction;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton5: TToolButton;
    ABold: TAction;
    AItalic: TAction;
    AUnderline: TAction;
    AStrike: TAction;
    procedure ACreateExecute(Sender: TObject);
    procedure AFontExecute(Sender: TObject);
    procedure AOpenExecute(Sender: TObject);
    procedure APrinterSetupExecute(Sender: TObject);
    procedure APrintExecute(Sender: TObject);
    procedure ASaveAsExecute(Sender: TObject);
    procedure ASaveExecute(Sender: TObject);
    procedure FontDialog1Apply(Sender: TObject; Wnd: HWND);
    procedure ALeftExecute(Sender: TObject);
    procedure ACenterExecute(Sender: TObject);
    procedure ARightExecute(Sender: TObject);
    procedure ABulletExecute(Sender: TObject);
    procedure StatusExecute(Sender: TObject);
    procedure RichEdit1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure RichEdit1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormCreate(Sender: TObject);
    procedure AFindExecute(Sender: TObject);
    procedure FindDialog1Find(Sender: TObject);
    procedure ReplaceDialog1Replace(Sender: TObject);
    procedure AExitExecute(Sender: TObject);
    procedure ApplicationEvents1Hint(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormDestroy(Sender: TObject);
    procedure AParagraphExecute(Sender: TObject);
    procedure RichEdit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ABoldExecute(Sender: TObject);
    procedure AItalicExecute(Sender: TObject);
    procedure AUnderlineExecute(Sender: TObject);
    procedure AStrikeExecute(Sender: TObject);
    procedure SaveDialog1CanClose(Sender: TObject; var CanClose: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses UCustom;

{$R *.dfm}

type
  TFileOld = class(TMenuItem)
   Procedure Click(); override;
  end;

var SFile: AnsiString = 'Неизвестный';
    SPos:integer;
    NFileMen: word;
    NFiles: word = 10;
    TmpItem: TFileOld;
    Ins: boolean = true;
    Dialog: TFindDialog;

procedure TFileOld.Click();
begin
 Form1.RichEdit1.Lines.LoadFromFile(Caption);
 SFile := ExtractFileName(Caption);
 Form1.RichEdit1.Modified:=false;
end;

procedure FileToMenu(Dialog:TOpenDialog);
begin
 with Form1 do begin
  // Сохранение имени в SFile
  SFile := Dialog.FileName;
  // Удаление раздела, соответствующего тому же файлу
  if (MainMenu1.Items[0].Find(SFile) <> nil)
   then MainMenu1.Items[0].Find(SFile).Free;
  // Создание нового раздела
  TmpItem := TFileOld.Create(MainMenu1);
  TmpItem.Caption := SFile;
  // Вставка в меню нового раздела
  MainMenu1.Items[0].Insert(NFileMen,TmpItem);
  // Если список переполнен, удаление последнего раздела
  if(MainMenu1.Items[0].Count > NFileMen + NFiles + 2)
    then MainMenu1.Items[0].Items[NFileMen+NFiles].Free;
 end;
end;

procedure TForm1.StatusExecute(Sender: TObject);
begin
 StatusBar1.Panels.Items[0].Text:=
                    IntToStr(RichEdit1.CaretPos.y+1) +
                    ': '+IntToStr(RichEdit1.CaretPos.x+1);
 if (RichEdit1.Modified)
  then StatusBar1.Panels.Items[1].Text:='модиф.'
  else StatusBar1.Panels.Items[1].Text:='';
 case (RichEdit1.Paragraph.Alignment) of
  taLeftJustify:   ALeft.Checked:=true;
  taCenter:        ACenter.Checked:=true;
  taRightJustify:  ARight.Checked:=true;
 end;
 ABold.Checked :=  fsBold in RichEdit1.SelAttributes.Style;
 AItalic.Checked :=  fsItalic in RichEdit1.SelAttributes.Style;
 AUnderline.Checked :=  fsUnderline in RichEdit1.SelAttributes.Style;
 AStrike.Checked :=  fsStrikeOut in RichEdit1.SelAttributes.Style;
 ABullet.Checked := (RichEdit1.Paragraph.Numbering = nsBullet);
 if Ins
  then StatusBar1.Panels.Items[2].Text:='вставка'
  else StatusBar1.Panels.Items[2].Text:='замена';
end;

procedure TForm1.ACreateExecute(Sender: TObject);
var res:integer;
begin
 if (RichEdit1.Modified)
 then begin
  res:=Application.MessageBox('Текст в окне был изменен. Сохранить его?',
                              'Подтвердите сохранение файла',
                               MB_YESNOCANCEL);
  case (res) of
   IDYES:    ASaveExecute(Sender);
   IDCANCEL: Exit;
  end;
  RichEdit1.Clear;
  RichEdit1.Modified := false;
  SFile :='Неизвестный';
 end
end;

procedure TForm1.AFontExecute(Sender: TObject);
begin
 if FontDialog1.Execute then
   RichEdit1.SelAttributes.Assign(FontDialog1.Font);
 RichEdit1.SetFocus;
end;

procedure TForm1.AOpenExecute(Sender: TObject);
begin
// OpenDialog1.FileName := SFile;
 if (OpenDialog1.Execute)
  then begin
   SFile := OpenDialog1.FileName;
   RichEdit1.Lines.LoadFromFile(SFile);
   RichEdit1.Modified:=false;
   FileToMenu(OpenDialog1);
  end;
end;

procedure TForm1.APrinterSetupExecute(Sender: TObject);
begin
 PrinterSetupDialog1.Execute;
end;

procedure TForm1.APrintExecute(Sender: TObject);
var i:integer;
begin
 if(PrintDialog1.Execute) then
  for i:=1  to PrintDialog1.Copies do
    RichEdit1.Print('Печать PRichEdit1');
end;

procedure TForm1.ASaveAsExecute(Sender: TObject);
begin
 SaveDialog1.FileName := SFile;
 if (SaveDialog1.Execute)
  then begin
   if (SFile <> SaveDialog1.FileName)
    then FileToMenu(SaveDialog1);
   SFile := SaveDialog1.FileName;
   RichEdit1.Lines.SaveToFile(SaveDialog1.FileName);
   RichEdit1.Modified:=false;
  end;

end;

procedure TForm1.ASaveExecute(Sender: TObject);
begin
 if (SFile = 'Неизвестный')
 then ASaveAsExecute(Sender)
 else RichEdit1.Lines.SaveToFile(SFile);
 RichEdit1.Modified:=false;
end;

procedure TForm1.FontDialog1Apply(Sender: TObject; Wnd: HWND);
begin
  RichEdit1.SelAttributes.Assign(FontDialog1.Font);
end;

procedure TForm1.ALeftExecute(Sender: TObject);
begin
 RichEdit1.Paragraph.Alignment:=taLeftJustify;
 ALeft.Checked:=true;
end;

procedure TForm1.ACenterExecute(Sender: TObject);
begin
 RichEdit1.Paragraph.Alignment:=taCenter;
 ACenter.Checked:=true;
 end;

procedure TForm1.ARightExecute(Sender: TObject);
begin
 RichEdit1.Paragraph.Alignment:=taRightJustify;
 ARight.Checked:=true;
end;

procedure TForm1.ABulletExecute(Sender: TObject);
begin
 if(ABullet.Checked) then
  RichEdit1.Paragraph.Numbering:=nsNone
 else RichEdit1.Paragraph.Numbering:=nsBullet;
 ABullet.Checked:=not ABullet.Checked;
end;

procedure TForm1.RichEdit1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 if (Key = VK_INSERT) and (Shift = [])
   then Ins := not Ins;
 StatusExecute(Sender);
 SPos:=RichEdit1.SelStart;
end;

procedure TForm1.RichEdit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 StatusExecute(Sender);
 SPos:=RichEdit1.SelStart;
end;

procedure TForm1.RichEdit1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  StatusExecute(Sender);
  SPos:=RichEdit1.SelStart;
end;

procedure TForm1.FormCreate(Sender: TObject);
var List: TStringList;
    i: word;
begin
 RichEdit1.Paragraph.FirstIndent:=0;
 RichEdit1.Paragraph.LeftIndent:=- RichEdit1.Paragraph.FirstIndent;
 RichEdit1.Modified:=false;
 NFileMen := MainMenu1.Items[0].Count - 2;
 if FileExists('Menu.cfg')
  then begin
   List := TStringList.Create;
   List.LoadFromFile('Menu.cfg');
   for i := 0 to List.Count-1 do
   begin
    TmpItem := TFileOld.Create(MainMenu1);
    TmpItem.Caption := List.Strings[i];
    MainMenu1.Items[0].Insert(NFileMen,TmpItem);
   end;
   List.Free;
  end;
 StatusExecute(Sender);
end;

procedure TForm1.AFindExecute(Sender: TObject);
begin
// запоминание позиции курсора
 SPos:=RichEdit1.SelStart;
 if (Sender as TAction).Name = 'AFind'
 then Dialog := FindDialog1
 else Dialog := ReplaceDialog1;
 with Dialog do begin
  {начальное значение текста поиска - текст, выделенный в RichEdit1}
  FindText:=RichEdit1.SelText;
  {позиционирование окна диалога внизу RichEdit1}
  Position:=Form1.ClientToScreen(Point(RichEdit1.Left, RichEdit1.Top + RichEdit1.Height));
// Вариант с функцией Pos
  {удаление из диалога кнопок "Вверх", "Вниз",
   "Только  слово целиком"}
//  Options:=Options + [frHideUpDown,frHideWholeWord];
// Вариант с методом FindText
  {удаление из диалога кнопок "Вверх", "Вниз"}
  Options:=Options + [frHideUpDown];
  {выполнение}
  Execute;
 end;
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
var Opt: TSearchTypes;
begin
// Вариант с методом FindText
 with Dialog do begin
 if frMatchCase in Options
  {поиск с учетом регистра}
  then Opt := Opt + [stMatchCase];
 if frWholeWord in Options
  {поиск только слова}
  then Opt := Opt + [stWholeWord];
 SPos:=RichEdit1.FindText(FindText,
                           SPos, Length(RichEdit1.Lines.Text), Opt);
  if SPos >= 0
   then begin
    {выделение найденного текста}
    RichEdit1.SelStart := SPos;
    RichEdit1.SelLength:=Length(FindText);
    Inc(SPos);
    if (Dialog = ReplaceDialog1) and (frReplaceAll in Options)
    then ReplaceDialog1Replace(Sender);
   end
   else
    if MessageDlg(
          'Текст "'+FindText+'" не найден. Продолжать диалог?',
          mtConfirmation,mbYesNoCancel,0) <> mrYes
    then CloseDialog;
 end;
 RichEdit1.SetFocus;
// Вариант с функцией Pos
{
 with Dialog do begin
 if frMatchCase in Options
//  поиск с учетом регистра
  then RichEdit1.SelStart:=Pos(FindText,
                           Copy(RichEdit1.Lines.Text,SPos+1,
                             Length(RichEdit1.Lines.Text)))+Spos-1
//  поиск без учета регистра
  else RichEdit1.SelStart:=Pos(AnsiLowerCase(FindText),
                    AnsiLowerCase(Copy(RichEdit1.Lines.Text,SPos+1,
                    Length(RichEdit1.Lines.Text))))+Spos-1;
  if RichEdit1.SelStart>=Spos
   then begin
//    выделение найденного текста
    RichEdit1.SelLength:=Length(FindText);
//    изменение начальной позиции поиска
    SPos:=RichEdit1.SelStart+RichEdit1.SelLength+1;
    if (Dialog = ReplaceDialog1) and (frReplaceAll in Options)
    then ReplaceDialog1Replace(Sender);
   end
   else
    if MessageDlg(
          'Текст "'+FindText+'" не найден. Продолжать диалог?',
          mtConfirmation,mbYesNoCancel,0) <> mrYes
    then CloseDialog;
 end;
 RichEdit1.SetFocus;
}
end;

procedure TForm1.ReplaceDialog1Replace(Sender: TObject);
begin
 if RichEdit1.SelText<>''
  then RichEdit1.SelText:=ReplaceDialog1.ReplaceText;
 if frReplaceAll in ReplaceDialog1.Options
  then FindDialog1Find(AReplace);
end;

procedure TForm1.AExitExecute(Sender: TObject);
begin
 Close;
end;
procedure TForm1.ApplicationEvents1Hint(Sender: TObject);
begin
 StatusBar1.Panels.Items[3].Text := Application.Hint;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
 if RichEdit1.Modified then
  CanClose := (Application.MessageBox(
               'Текст документа не сохранен.'+
               #13'Действительно хотите закончить работу ?',
               'Подтвердите завершение работы',
               MB_ICONQUESTION+MB_YESNO) = IDYES);
end;

procedure TForm1.FormDestroy(Sender: TObject);
var List: TStringList;
    i: word;
begin
 List := TStringList.Create;
 for i := MainMenu1.Items[0].Count-3 downto NFileMen  do
   List.Add(MainMenu1.Items[0].Items[i].Caption);
 List.SaveToFile(ExtractFileDir(ParamStr(0))+'\Menu.cfg');
   List.Free;
end;

procedure TForm1.AParagraphExecute(Sender: TObject);
begin
 FCustom.ShowModal;
end;

procedure TForm1.ABoldExecute(Sender: TObject);
begin
 ABold.Checked := not ABold.Checked;
 if ABold.Checked
  then RichEdit1.SelAttributes.Style :=
                      RichEdit1.SelAttributes.Style + [fsBold]
  else  RichEdit1.SelAttributes.Style :=
                      RichEdit1.SelAttributes.Style - [fsBold];
end;

procedure TForm1.AItalicExecute(Sender: TObject);
begin
 AItalic.Checked := not AItalic.Checked;
 if AItalic.Checked
  then RichEdit1.SelAttributes.Style :=
                      RichEdit1.SelAttributes.Style + [fsItalic]
  else  RichEdit1.SelAttributes.Style :=
                      RichEdit1.SelAttributes.Style - [fsItalic];
end;

procedure TForm1.AUnderlineExecute(Sender: TObject);
begin
 AUnderline.Checked := not AUnderline.Checked;
 if AUnderline.Checked
  then RichEdit1.SelAttributes.Style :=
                      RichEdit1.SelAttributes.Style + [fsUnderline]
  else  RichEdit1.SelAttributes.Style :=
                      RichEdit1.SelAttributes.Style - [fsUnderline];
end;

procedure TForm1.AStrikeExecute(Sender: TObject);
begin
 AStrike.Checked := not AStrike.Checked;
 if AStrike.Checked
  then RichEdit1.SelAttributes.Style :=
                      RichEdit1.SelAttributes.Style + [fsStrikeOut]
  else  RichEdit1.SelAttributes.Style :=
                      RichEdit1.SelAttributes.Style - [fsStrikeOut];
end;

procedure TForm1.SaveDialog1CanClose(Sender: TObject;
  var CanClose: Boolean);
begin
// Этот обработчик не даст возможности переписать существующий файл

if FileExists(SaveDialog1.FileName)
 then begin
  ShowMessage(
   'Файл "' + SFile +'" существует, надо выбрать другое имя');
  CanClose := false;
 end;

end;

end.
