unit MDIEdit;

interface

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  Menus, StdCtrls, ComCtrls, CompOptions, Inifiles, Line, Utils,
  marsCap, Search, ToolWin, ExtCtrls, Buttons, RichEdit,
  SynEdit, SynExportHTML, SynExportRTF, Version,
  ImgList, SynCompletionProposal, SynEditExport, SynEditHighlighter,
  SynEditPrint, SynHighlighterPas;

type
  TEditForm = class(TForm)
    PopupMenu: TPopupMenu;
    CutPopItem: TMenuItem;
    CopyPopItem: TMenuItem;
    PastePopItem: TMenuItem;
    ImageList: TImageList;
    FindDialog: TFindDialog;
    ReplaceDialog: TReplaceDialog;
    Bar: TStatusBar;
    N9: TMenuItem;
    SelectAllPopItem: TMenuItem;
    N10: TMenuItem;
    UndoPopItem: TMenuItem;
    SaveFileDialog: TSaveDialog;
    N1: TMenuItem;
    TogglebookmarksPopItem: TMenuItem;
    GotobookmarksPopItem: TMenuItem;
    Bookmark01: TMenuItem;
    Bookmark11: TMenuItem;
    Bookmark21: TMenuItem;
    Bookmark31: TMenuItem;
    Bookmark41: TMenuItem;
    Bookmark51: TMenuItem;
    Bookmark61: TMenuItem;
    Bookmark71: TMenuItem;
    Bookmark81: TMenuItem;
    Bookmark91: TMenuItem;
    Bookmark02: TMenuItem;
    Bookmark12: TMenuItem;
    Bookmark22: TMenuItem;
    Bookmark32: TMenuItem;
    Bookmark42: TMenuItem;
    Bookmark52: TMenuItem;
    Bookmark62: TMenuItem;
    Bookmark72: TMenuItem;
    Bookmark82: TMenuItem;
    Bookmark92: TMenuItem;
    RedoPopItem: TMenuItem;
    InsertPopItem: TMenuItem;
    CommentheaderPopItem: TMenuItem;
    MainfunctionPopItem: TMenuItem;
    WinMainfunctionPopItem: TMenuItem;
    MessageBoxPopItem: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    ifPopItem: TMenuItem;
    whilePopItem: TMenuItem;
    dowhilePopItem: TMenuItem;
    forPopItem: TMenuItem;
    MarsCaption: TMarsCaption;
    Editor: TSynEdit;
    Completion: TSynCompletionProposal;
    SynExporterRTF: TSynExporterRTF;
    SynExporterHTML: TSynExporterHTML;
    DateandtimePopItem: TMenuItem;
    SynPasSyn: TSynPasSyn;
    Unitbeginend1: TMenuItem;

    procedure New;
    procedure DefaultOpen(const AFileName: string);
    procedure Cut(Sender: TObject);
    procedure Copy(Sender: TObject);
    procedure Paste(Sender: TObject);
    procedure SelectAll(Sender: TObject);
    procedure Save1Click(Sender: TObject);
    procedure Close1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormActivate(Sender: TObject);
    procedure Undo(Sender: TObject);
    procedure Search;
    procedure FindNext;
    procedure Find(Sender : TObject);
    procedure Replace(Sender: TObject);
    procedure EditorKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditorKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure EditorClick(Sender: TObject);
    procedure Gotoline1Click(Sender: TObject);
    procedure Bookmark02Click(Sender: TObject);
    procedure Bookmark01Click(Sender: TObject);
    procedure Redo(Sender: TObject);
    procedure PopupMenuPopup(Sender: TObject);
    procedure WriteCommentHeader;
    procedure WriteWinMainFunction;
    procedure WriteMainFunction;
    procedure WriteIfdef;
    procedure WriteIfndef;
    procedure WriteInclude(s : string);
    procedure WriteIf;
    procedure WriteWhile;
    procedure WriteRepeat;
    procedure WriteFor;
    procedure WriteDateTime;
    procedure WriteUnitFunction;
    procedure WriteMessageBox(Title,Text,Button : string);
    procedure ReadSyntaxColor;
    procedure PrintFile;
    procedure CommentheaderPopItemClick(Sender: TObject);
    procedure MainfunctionPopItemClick(Sender: TObject);
    procedure WinMainfunctionPopItemClick(Sender: TObject);
    procedure ifdefPopItemClick(Sender: TObject);
    procedure MessageBoxPopItemClick(Sender: TObject);
    procedure includePopItemClick(Sender: TObject);
    procedure ifndefPopItemClick(Sender: TObject);
    procedure SaveOneSource;
    procedure ifPopItemClick(Sender: TObject);
    procedure whilePopItemClick(Sender: TObject);
    procedure dowhilePopItemClick(Sender: TObject);
    procedure forPopItemClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure EditorSpecialLineColors(Sender: TObject; Line: Integer;
      var Special: Boolean; var FG, BG: TColor);
    procedure EditorEnter(Sender: TObject);
    procedure OnFindReplace(Sender : TObject);
    function FindReplace : boolean;
    procedure EditorChange(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormDeactivate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure ConvertTabsToSpaces;
    procedure DateAndTimePopItemClick(Sender: TObject);
    procedure FindDialogShow(Sender: TObject);
    procedure FindDialogClose(Sender: TObject);
    procedure EditorDropFiles(Sender: TObject; X, Y: Integer;
      AFiles: TStrings);
    procedure Unitbeginend1Click(Sender: TObject);

  private
    { Private declarations }
    IniFileName : string;
    RestorePos : Boolean;
    BackUpFile : TStringList;

    procedure MenuItemClick(Sender: TObject);
  public
    { Public declarations }
    MenuItem : TMenuItem;   // Window menu item for the editor
    HighlightedLine : integer;
    GetIndex  : integer;
    PathName: string;
    Modified : boolean;
    constructor Create(AOwner : TComponent); override;
    procedure Open(const AFileName: string);
    function Saveas1Click(ProjectFileName : string) : string;
  end;

var
  EditForm: TEditForm;
  SaveOnExit : boolean = True;
  MaxiMode : boolean = False;

const
  DefaultFileName = 'Untitled';

implementation

uses Clipbrd, PrinterFrm, Main, EnvirOpt, About, MsgBox;

{$R *.DFM}

constructor TEditForm.Create(AOwner: TComponent);
begin
  // make the window more 3D
  inherited Create(AOwner);
  SetWindowLong(ClientHandle, GWL_EXSTYLE,
  GetWindowLong(ClientHandle,
    GWL_EXSTYLE) or WS_EX_CLIENTEDGE);
  SetWindowPos(ClientHandle, 0, 0, 0, 0, 0,
    swp_DrawFrame or swp_NoMove or swp_NoSize
    or swp_NoZOrder);
end;

function TEditForm.Saveas1Click(ProjectFileName : string) : string;
var ProjIniFile :TIniFile;
    s : string;
label StartAgain;

  function GetNode(s : string) : TTreeNode;
  var i : integer;
  begin
    Result := nil;
    for i := 0 to MainForm.ProjectView.TopItem.Count-1 do
        if lowercase(MainForm.ProjectView.TopItem.Item[i].Text) = lowercase(s) then begin
           Result := MainForm.ProjectView.TopItem.Item[i];
           break;
        end;
  end;

begin
 IniFileName := ProjectFileName;
 ProjIniFile := TIniFile.Create(IniFileName);

 SaveFileDialog.FileName := Caption;
 s := Caption;

 StartAgain:

 if SaveFileDialog.Execute then
   begin
     if FileExists(SaveFileDialog.FileName) then
        if MessageDlg('File already exists. Overwrite it ?',MtWarning,[MbYes,MbNo],0) = MrNo then Exit;

     if MainForm.Project.FileAlreadyExists(SaveFileDialog.FileName) then begin
        MessageDlg('A file named "'+ExtractFileName(SaveFileDialog.FileName)+'" already exists in '+MainForm.Project.Name+'.'+#13'Please specify another filename.', MtError, [mbOK],0);
        goto StartAgain;
     end
     else if lowercase(ExtractFileName(ChangeFileExt(SaveFileDialog.FileName,'.dp'))) = lowercase(ExtractFileName(ProjectFileName)) then begin
        MessageDlg('A unit file cannot have the same name as the project file.', MtError, [mbOK],0);
        goto StartAgain;
     end;

     PathName := SaveFileDialog.FileName;

     Caption := ExtractFileName(PathName);
     MenuItem.Caption := Self.Caption;
     MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + ' - '+ MainForm.Project.Name + ' - [' + Caption +']';

     Application.ProcessMessages;

     Editor.Lines.SaveToFile(PathName); // Save current file as...

     ProjIniFile.WriteString('Unit'+IntToStr(GetIndex),'FileName',PathName);
     MainForm.Project.Units[GetIndex-1].FileName := PathName;

     if lowercase(s) = lowercase(MainForm.Project.MainUnit) then
        MainForm.Project.SetMainUnit(PathName);

     if (GetNode(s) <> nil) and
        (MainForm.ProjectView.Items.Count > 0) then begin
        GetNode(s).Text := ExtractFileName(PathName);
     end;

     Modified := False;
     ProjInifile.Free;
     Result := PathName;
  end;

{  if NotProject then
     MainForm.Caption := 'Dev-Pascal ' + DevPasVersion +' - '+SaveFileDialog.FileName;}
end;

procedure TEditForm.New;
begin
  MainForm.NewItemClick(Self);
end;

procedure TEditForm.Cut;
begin
  Editor.CutToClipboard;
end;

procedure TEditForm.Copy;
begin
  Editor.CopyToClipboard;
end;

procedure TEditForm.Paste;
begin
  Editor.PasteFromClipboard;
end;

procedure TEditForm.SelectAll;
begin
  Editor.SelectAll;
end;

procedure TEditForm.DefaultOpen(const AFileName: string);
begin
{ Procedure for opening default file }
  try
    with Editor do
     Lines.LoadFromFile(AFileName);
  except
     MessageDlg('Could not open file: '+PathName,MtError,[MbOK],0);
  end;

  Modified := False;

  BackupFile.Clear;
  BackupFile.AddStrings(Editor.Lines);
end;

procedure TEditForm.Open(const AFileName: string);
begin
{ Procedure for opening a file }
  PathName := AFileName;

  if NotProject then
     Caption := PathName
  else Caption := ExtractFileName(PathName);

  try
    with Editor do
     Lines.LoadFromFile(PathName);
  except
     MessageDlg('Could not open file: '+PathName,MtError,[MbOK],0);
  end;

  Modified := False;

  BackupFile.Clear;
  BackupFile.AddStrings(Editor.Lines);

  MainForm.SaveFileHistory(PathName);
end;

procedure TEditForm.Save1Click(Sender: TObject);
var pas_ext : string;
    IniFile : TIniFile;
begin
  Editor.Lines.SaveToFile(PathName); // Save current file

  IniFileName := ExtractFilePath(Application.Exename)+ ChangeFileExt(ExtractFileName(Application.Exename), '.ini');
  IniFile := TIniFile.Create(IniFilename);

  { if the user has select the Backup option, create a backup file }

  if IniFile.ReadBool('Options','Backup',true) then
  begin
     pas_ext := ExtractFileExt(ExtractFileName(Self.Caption));
     if pas_ext = '.pas' then
        BackupFile.SaveToFile(ChangeFileExt(PathName,'.~pa'))
     else
        BackupFile.SaveToFile(ChangeFileExt(PathName,'.~pp'));

     BackupFile.Clear;
     BackupFile.AddStrings(Editor.Lines);
  end;

  Modified := False;
  Bar.Panels[1].Text := '';
end;

procedure TEditForm.Close1Click(Sender: TObject);
begin
  Close;
end;

procedure TEditForm.FormClose(Sender: TObject; var Action: TCloseAction);
const
  SWarningText = 'Save changes to %s?';
var
  SMessageText : string;
  IniFile : TIniFile;
  DoClose : boolean;
begin
  DoClose := True;
  if (Modified = true) or ((PathName = '') and (Editor.Text <> ''))
     and SaveOnExit then
  begin
    SMessageText := Caption;

    case MessageDlg(Format(SWarningText, [Caption]), mtConfirmation,
      [mbYes, mbNo, mbCancel], 0) of
      idYes: begin
               SaveOnExit := False;
               if pos(':\',PathName) <> 0 then
                  Save1Click(Self)
               else MainForm.SaveAsItemClick(self);
             end;
      idNo : begin
               SaveOnExit := False;
             end;
      idCancel: DoClose := False;
    end;
  end;

  IniFileName := ExtractFilePath(Application.Exename)+ ChangeFileExt(ExtractFileName(Application.Exename), '.ini');
  IniFile := TIniFile.Create(IniFilename);

  { Write editor's size to the ini file }
  if WindowState <> wsMaximized then begin
     IniFile.WriteInteger('Position','SizeEditorX',Width);
     IniFile.WriteInteger('Position','SizeEditorY',Height);
  end;

  IniFile.Free;
  WindowState := wsNormal;

  if DoClose then begin
     Action := caFree;
     if (MainForm.Project <> nil) and
        (pos(MainForm.Project.Name + ' - [', MainForm.Caption)<>0) and
        (WindowState <> wsMaximized) then begin
         MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + ' - '+ MainForm.Project.Name;
         MaxiMode := False;
     end
     else if (pos(Caption, MainForm.Caption)<>0) and
        (WindowState <> wsMaximized) then begin
         MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + CompilerString;
         MaxiMode := False;
     end;
  end
  else Action := caNone;
end;

procedure TEditForm.MenuItemClick(Sender: TObject);
begin
  BringToFront;
  if MaxiMode and NotProject then
     MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + ' - ' + Caption
  else if MainForm.Project <> nil then
          MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + ' - ' + MainForm.Project.Name + ' - [' + Caption +']';
end;

procedure TEditForm.FormActivate(Sender: TObject);
var IniFile : TIniFile;
    Style : String;
begin
  IniFileName := ExtractFilePath(Application.Exename)+ ChangeFileExt(ExtractFileName(Application.Exename), '.ini');
  IniFile := TIniFile.Create(IniFilename);

  MenuItem.Checked := True;
  FormPaint(sender);

  with Editor do
  begin
     Visible := False;
     ReadSyntaxColor;

     Font.Size := IniFile.ReadInteger('Options','FontSize', Font.Size);
     Style := IniFile.ReadString('Options','Font', Style);

     if Style = '' then
        Font.Name :=  'Courier New'
     else Font.Name := Style;
        TabWidth := IniFile.ReadInteger('Options','TabIndent',4);

     Gutter.ShowLineNumbers := IniFile.ReadBool('Options','LineNumbers',False);

     if IniFile.ReadBool('Options','ShowScrollHint',True) then
        Options := Options + [eoShowScrollHint]
     else Options := Options - [eoShowScrollHint];

     if IniFile.ReadBool('Options','DontShowScroll',False) = True then
        ScrollBars := ssNone
     else ScrollBars := ssBoth;

     if IniFile.ReadBool('Options','AutoIndent',True) then
        Options := Options + [eoAutoIndent]
     else Options := Options - [eoAutoIndent];

     if IniFile.ReadBool('Options','TabsToSpaces',True) then
        Options := Options + [eoTabsToSpaces]
     else Options := Options - [eoTabsToSpaces];

     if IniFile.ReadBool('Options','SmartTabs',True) then
        Options := Options + [eoSmartTabs]
     else Options := Options - [eoSmartTabs];

     if IniFile.ReadBool('Options','ShowGutter',True) then
        Gutter.Visible := True
     else Gutter.Visible := False;

     Visible := True;
   end;

   if RestorePos and (IniFile.ReadBool('Options','SaveEditor',False)) then begin
      Width  := IniFile.ReadInteger('Position','SizeEditorX', 516);
      Height := IniFile.ReadInteger('Position','SizeEditorY', 326);
   end;

  if not FileExists(MainForm.BinDir+COMPLETION_FILE) then
  try
    MainForm.CreateNewCompletionFile;
  except
    MessageDlg('Could not create Code Completion list file.', mtError, [mbOK], 0);
  end;

  if FileExists((MainForm.BinDir+COMPLETION_FILE)) then
     Completion.ItemList.LoadFromFile(MainForm.BinDir+COMPLETION_FILE);

  if not FileExists(MainForm.BinDir+DEFAULTCODE_FILE) then
  try
    MainForm.CreateNewDefaultFile;
  except
    MessageDlg('Could not create default code file.', mtError, [mbOK], 0);
  end;

  RestorePos := False;
  IniFile.Free;
end;

procedure TEditForm.Undo(Sender: TObject);
begin
  Editor.Undo;
end;

procedure TEditForm.Search;
begin
  FindDialog.Execute;
end;

procedure TEditForm.FindNext;
begin
  Find(Self);
end;

procedure TEditForm.OnFindReplace(Sender : TObject);
begin
  FindReplace;
end;

function TEditForm.FindReplace : boolean;
var rOptions: TSynSearchOptions;
    sSearch: string;
begin
  sSearch := ReplaceDialog.FindText;
  Result := True;

  if Length(sSearch) = 0 then begin
    MessageBeep($7000);
    MessageDlg('Cannot search for empty text',MtWarning,[MbOK],0);
    MainForm.FindNextItem.Enabled := False;
  end else begin
    rOptions := [];
    if not (frDown in ReplaceDialog.Options) then
      Include(rOptions, ssoBackwards);
    if frMatchCase in ReplaceDialog.Options then
      Include(rOptions, ssoMatchCase);
    if frWholeWord in ReplaceDialog.Options then
      Include(rOptions, ssoWholeWord);
    if Editor.SearchReplace(sSearch, '', rOptions) = 0 then begin
      MessageBeep($7000);
      if not (frReplaceAll in ReplaceDialog.Options) then
         MessageDlg('Search text ''' + sSearch + ''' not found', MtInformation, [mbOK],0);
      Result := False;
    end
  end;
end;

procedure TEditForm.Find;
var rOptions: TSynSearchOptions;
    sSearch: string;
begin
  sSearch := FindDialog.FindText;

  if Length(sSearch) = 0 then begin
    MessageBeep($7000);
    MessageDlg('Cannot search for empty text',MtWarning,[MbOK],0);
    MainForm.FindNextItem.Enabled := False;
  end else begin
    rOptions := [];
    if not (frDown in FindDialog.Options) then
      Include(rOptions, ssoBackwards);
    if frMatchCase in FindDialog.Options then
      Include(rOptions, ssoMatchCase);
    if frWholeWord in FindDialog.Options then
      Include(rOptions, ssoWholeWord);
    if Editor.SearchReplace(sSearch, 'df', rOptions) = 0 then begin
      MessageBeep($7000);
      MessageDlg('Search text ''' + sSearch + ''' not found', MtInformation, [mbOK],0);
      MainForm.FindNextItem.Enabled := False;
    end else
      MainForm.FindNextItem.Enabled := True;
  end;
end;

procedure TEditForm.Replace(Sender: TObject);
begin
  if frReplaceAll in ReplaceDialog.Options then begin
     while FindReplace do
           Editor.SelText := ReplaceDialog.ReplaceText;
  end else if Editor.SelText <> '' then
     Editor.SelText := ReplaceDialog.ReplaceText;
end;

procedure TEditForm.Gotoline1Click(Sender: TObject);
begin
  LineForm := TLineForm.Create(self);
  try
    LineForm.ShowModal;
    if LineForm.ModalResult= MrOK then begin
       Editor.CaretY :=StrToInt(LineForm.Line.Text);
       Editor.EnsureCursorPosVisible;
    end;
  finally
    LineForm.Free;
  end;
end;

procedure TEditForm.EditorKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
try
  case Key of
  vk_Insert : if (not (ssCtrl in Shift)) and (not (ssShift in Shift)) then  begin
                if Bar.Panels[2].Text = 'Insertion' then
                   Bar.Panels[2].Text := 'Replacement'
                else
                   Bar.Panels[2].Text := 'Insertion';
                Exit;
              end;

  vk_End, vk_Home, vk_Left, vk_Up, vk_Right, vk_Down,
  vk_Shift, vk_Control, vk_NumLock, vk_Escape, vk_Menu,
  vk_Capital, vk_Prior, vk_Next, vk_Pause, vk_Scroll : exit;
  end;

  //if (ssCtrl in Shift) or (ssAlt in Shift) then
  //   exit;

  Modified := True;
  if not NotProject then
     MainForm.Project.Units[GetIndex-1].Modified := True;

  Bar.Panels[1].Text := 'Modified';
except
end;
end;

procedure TEditForm.EditorKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 Bar.Panels[0].Text := '  '+IntToStr(Editor.CaretX)+': '+IntToStr(Editor.CaretY);
 Bar.Panels[3].Text := IntToStr(Editor.Lines.Count) + ' lines in file';
end;

procedure TEditForm.ConvertTabsToSpaces;
var j : integer;
    CaretPos : TPoint;
    s : string;
begin
  if eoTabsToSpaces in Editor.Options then begin
     s := Editor.Lines.Text;
     j := 0;
     CaretPos := Editor.CaretXY;
     Application.ProcessMessages;

     while pos(#9, s)<>0 do begin
         j := 0;
         repeat
           inc(j);
           Insert(' ',s,pos(#9, s));
         until j = Editor.TabWidth;
         Delete(s,pos(#9, s),1);
         if pos(#9, s) > 32766 then
            break
     end;
     if j > 0 then begin
        Editor.Lines.Text := s;
        Editor.CaretXY := CaretPos;
     end;
  end;
end;

procedure TEditForm.EditorClick(Sender: TObject);
begin
  if Editor.SelectedColor.BackGround <> clHighlight then
     Editor.SelectedColor.BackGround := clHighlight;

  Bar.Panels[0].Text := '  '+IntToStr(Editor.CaretX)+': '+IntToStr(Editor.CaretY);
  Bar.Panels[3].Text := IntToStr(Editor.Lines.Count) + ' lines in file';

  if MainForm.CutItem.ShortCut = 0 then begin
     MainForm.CutItem.ShortCut := TextToShortCut('Ctrl+X');
     MainForm.CopyItem.ShortCut := TextToShortCut('Ctrl+C');
     MainForm.PasteItem.ShortCut := TextToShortCut('Ctrl+V');
  end;
end;

procedure TEditForm.Bookmark02Click(Sender: TObject);
begin
  Editor.GotoBookMark((Sender as TMenuItem).Tag);
end;

procedure TEditForm.Bookmark01Click(Sender: TObject);
var
  BookMark, X, Y: integer;
begin
  (Sender as TMenuItem).Checked:= not (Sender as TMenuItem).Checked;
  if (Sender as TMenuItem).Checked then
  begin
     BookMark:= (Sender as TMenuItem).Tag;
     X:= Editor.CaretX;
     Y:= Editor.CaretY;
     Editor.SetBookMark(BookMark, X, Y);
  end
  else Editor.ClearBookMark((Sender as TMenuItem).Tag);
end;


procedure TEditForm.Redo(Sender: TObject);
begin
  Editor.Redo;
end;

procedure TEditForm.PopupMenuPopup(Sender: TObject);
begin
  UndoPopItem.Enabled := Editor.CanUndo;
  PastePopItem.Enabled := Clipboard.HasFormat(CF_TEXT);
end;

procedure TEditForm.WriteCommentHeader;
begin
  If ThisCompiler = GPC then
  Editor.SelText :=
                   '(* '+#13+
                    '   Name: ' +#13+
                    '   Author: ' +#13+
                    '   Description: ' +#13+
                    '   Date: ' +#13+
                    '   Copyright: ' +#13+
                    '*)' +#13
  else
  Editor.SelText :=
                   '/* '+#13+
                    '   Name: ' +#13+
                    '   Author: ' +#13+
                    '   Description: ' +#13+
                    '   Date: ' +#13+
                    '   Copyright: ' +#13+
                    '*/' +#13;
end;

procedure TEditForm.WriteDateTime;
begin
  Editor.SelText := FormatDateTime('dd/mm/yy hh:nn',Now);
end;

procedure TEditForm.WriteMainFunction;
begin
  Editor.SelText := 'program Untitled;'+#13+
                    'begin'+#13+
                    #13+
                    'end.'+#13;
end;

procedure TEditForm.WriteUnitFunction;
begin
  Editor.SelText := 'unit Untitled;'+#13+
                    'interface'+#13+
                    #13+
                    'implementation'+#13+
                    #13+
                    'begin'+#13+
                    #13+
                    'end.'+#13;
end;

procedure TEditForm.WriteIfdef;
begin
  Editor.SelText := '#ifdef '+#13+
                    #13+
                    #13+
                    '#endif'+#13;
end;

procedure TEditForm.WriteIfndef;
begin
  Editor.SelText := '#ifndef '+#13+
                    #13+
                    #13+
                    '#endif'+#13;
end;

procedure TEditForm.WriteInclude(s : string);
begin
  Editor.SelText := '#include "'+s+'"';
end;

procedure TEditForm.WriteWinMainFunction;
begin
  If ThisCompiler = GPC then
  Editor.SelText :=
   'program Untitled;'+#13+
   'uses Messages, Windows;'+#13
   +#13+
   'begin'+#13+
   #13+
   'end.'
  else
  Editor.SelText :=
   'program Untitled;'+#13+
   '{$APPTYPE GUI}'+#13+
   '{$MODE DELPHI}'+#13+
   'uses Windows;'+#13
   +#13+
   'begin'+#13+
   #13+
   'end.';
end;

procedure TEditForm.WriteMessageBox(Title,Text,Button : string);
begin
  Editor.SelText := 'MessageBox (0, '''+Title+''' , '''+Text +''', '+Button+');'
end;

procedure TEditForm.ReadSyntaxColor;
var IniFile : TIniFile;
    NewColor : string;
    Color_   : TColor;
    i : integer;
begin
  IniFileName := ExtractFilePath(Application.Exename)+ ChangeFileExt(ExtractFileName(Application.Exename), '.ini');
  IniFile := TIniFile.Create(IniFilename);

  with IniFile do
  begin
     NewColor := IniFile.ReadString ('Options','Color', '');
     i := ReturnColorIndex (NewColor);
     Color_ := EditClrInt [i];
     Editor.SelectedColor.Background := clHighlight;
     Editor.SelectedColor.Foreground := clWhite;

     Case Color_ of
          clBlue, clNavy :
          begin
            Editor.SelectedColor.Background := clWhite;
            Editor.SelectedColor.Foreground := clBlack;
          end;
     end; // case

     Editor.Color := Color_;
     Editor.Font.Color := Color_;

     with SynPasSyn do
     begin
           CommentAttri.Background := Color_;
           CommentAttri.Foreground :=
              MakeCommaTextToColor(ReadString('EditorColor','CommentAttri',''), 0, clBlack);

           IdentifierAttri.Background := Color_;
           IdentifierAttri.Foreground :=
              MakeCommaTextToColor(ReadString('EditorColor','IdentifierAttri',''), 0, clBlack);
           KeyAttri.Background := Color_;
           KeyAttri.Foreground :=
              MakeCommaTextToColor(ReadString('EditorColor','KeyAttri',''), 0, clBlack);
           NumberAttri.Background := Color_;
           NumberAttri.Foreground :=
              MakeCommaTextToColor(ReadString('EditorColor','NumberAttri',''), 0, clBlack);
           SpaceAttri.Background := Color_;
           SpaceAttri.Foreground :=
              MakeCommaTextToColor(ReadString('EditorColor','SpaceAttri',''), 0, clBlack);
           StringAttri.Background := Color_;
           StringAttri.Foreground :=
              MakeCommaTextToColor(ReadString('EditorColor','StringAttri',''), 0, clBlack);
           SymbolAttri.Background := Color_;
           SymbolAttri.Foreground :=
              MakeCommaTextToColor(ReadString('EditorColor','SymbolAttri',''), 0, clBlack);
        end;
  end;
end;

procedure TEditForm.PrintFile;
var i : integer;
begin
try
  Printer := TPrinter.Create(self);

  Printer.pUnit.Caption := Self.Caption;

  Printer.PrintEdit.SynEdit := Editor;
  Printer.PrintEdit.Highlighter := SynPasSyn;

  Application.ProcessMessages;

  with Printer do begin
      FromPage.Value := 1;
      FromPage.MaxValue := PrintEdit.PageCount;
      ToPage.MaxValue := PrintEdit.PageCount;
      ToPage.Value := ToPage.MaxValue;
  end;

  if Printer.ShowModal <> mrOK then exit;

  Printer.SetPrintEditConfig;

  try
    for i := 1 to Printer.pCopies.Value do
        Printer.PrintEdit.PrintRange(Printer.FromPage.Value, Printer.ToPage.Value);
  except
    MessageDlg('There was an error while attempting to print.', mtError, [mbOK], 0);
  end;
finally
  Printer.Free;
end;
end;

procedure TEditForm.CommentheaderPopItemClick(Sender: TObject);
begin
  WriteCommentHeader;
end;

procedure TEditForm.MainfunctionPopItemClick(Sender: TObject);
begin
  WriteMainFunction;
end;

procedure TEditForm.WinMainfunctionPopItemClick(Sender: TObject);
begin
  WriteWinMainFunction;
end;

procedure TEditForm.ifdefPopItemClick(Sender: TObject);
begin
  WriteIfdef;
end;

procedure TEditForm.MessageBoxPopItemClick(Sender: TObject);
var
  MsgForm : TMessageBoxForm;
begin
  MsgForm := TMessageBoxForm.Create(Self);
  try
     if MsgForm.ShowModal = mrOk then
        WriteMessageBox(MsgForm.Text, MsgForm.TitleText, MsgForm.Buttons);
  finally
     MsgForm.Free;
  end;
end;

procedure TEditForm.includePopItemClick(Sender: TObject);
var s : string;
begin
  InputQuery('Include directive','Please specify filename: ',s);
  WriteInclude(s);
end;

procedure TEditForm.ifndefPopItemClick(Sender: TObject);
begin
  WriteIfndef;
end;

procedure TEditForm.SaveOneSource;
begin
  SaveFileDialog.FileName := Caption;
  if SaveFileDialog.Execute then begin
     if FileExists(SaveFileDialog.FileName) then
        if MessageDlg('File already exists. Overwrite it ?',MtWarning,[MbYes,MbNo],0) = MrNo then Exit;

     PathName := SaveFileDialog.FileName;

     Caption := PathName;
     MenuItem.Caption := Self.Caption;

     if WindowState = wsMaximized then
        MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + ' - ' + Caption;

     Application.ProcessMessages;

     Editor.Lines.SaveToFile(PathName); // Save current file as...
     Modified := False;

     MainForm.AddHistory(SaveFileDialog.FileName);
     MainForm.SaveFileHistory(SaveFileDialog.FileName);
  end
end;

procedure TEditForm.WriteIf;
begin
  Editor.SelText := 'if  then';
  Editor.CaretX := Editor.CaretX-5
end;

procedure TEditForm.WriteWhile;
begin
  Editor.SelText := 'while  do';
  Editor.CaretX := Editor.CaretX-3
end;

procedure TEditForm.WriteRepeat;
begin
  Editor.SelText := 'repeat '+#13+
                    #13+
                    'until ';
end;

procedure TEditForm.WriteFor;
begin
  Editor.SelText := 'for  :=  to  do';
  Editor.CaretX := Editor.CaretX-11;
end;

procedure TEditForm.ifPopItemClick(Sender: TObject);
begin
  WriteIf;
end;

procedure TEditForm.whilePopItemClick(Sender: TObject);
begin
  WriteWhile;
end;

procedure TEditForm.dowhilePopItemClick(Sender: TObject);
begin
  WriteRepeat;
end;

procedure TEditForm.forPopItemClick(Sender: TObject);
begin
  WriteFor;
end;

procedure TEditForm.FormCreate(Sender: TObject);
begin
  Width := 480;
  Height := 280;
  HighlightedLine := -1;

  MenuItem := TMenuItem.Create(Self);
  MenuItem.OnClick := MenuItemClick;
  MainForm.AddChild(Self);

  BackUpFile := TStringList.Create;

  if MainForm.IniFile.ReadBool('Options','MaxWindow', False) then begin
     RestorePos := False;

     Application.ProcessMessages;
     if WindowState <> wsMaximized then
        PostMessage(Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0)
  end
  else RestorePos := True;
end;

procedure TEditForm.EditorSpecialLineColors(Sender: TObject; Line: Integer;
  var Special: Boolean; var FG, BG: TColor);
begin
  if InvalidateLine and (HighlightedLine = Line) then begin
     Special := True;
     BG := clMaroon;
     FG := clWhite;
     InvalidateLine := True;
  end;
end;

procedure TEditForm.EditorEnter(Sender: TObject);
begin
  if HighlightedLine <> -1 then
     Editor.InvalidateLine(HighlightedLine);
  HighlightedLine := -1;
end;

procedure TEditForm.EditorChange(Sender: TObject);
begin
  Modified := True;
  if not NotProject then
     MainForm.Project.Units[GetIndex-1].Modified := True;

  Bar.Panels[1].Text := 'Modified';
end;

procedure TEditForm.FormDestroy(Sender: TObject);
begin
  MenuItem.Free;
  MainForm.RemoveChild(Self);
end;

procedure TEditForm.FormDeactivate(Sender: TObject);
begin
  MenuItem.Checked := False;
end;

procedure TEditForm.FormPaint(Sender: TObject);
begin
  MenuItem.Caption := Self.Caption;

  if (MainForm.Project <> nil) and
     (pos(MainForm.Project.Name + ' - [', MainForm.Caption)<>0) and
     (WindowState <> wsMaximized) then begin
     MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + ' - ' + MainForm.Project.Name;
     MaxiMode := False;
  end
  else if (pos(Caption, MainForm.Caption)<>0) and
     (WindowState <> wsMaximized) then begin
     MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + CompilerString;
     MaxiMode := False;
  end;

  if WindowState <> wsMaximized then
     MaxiMode := False;

//  if MaxiMode then
 ///    exit
//  else
  if NotProject and (WindowState = wsMaximized) then begin
     MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + ' - ' + Caption;
     MaxiMode := True;
  end
  else if (not NotProject) and (MainForm.Project <> nil) and (WindowState = wsMaximized) then begin
     MainForm.Caption := 'Dev-Pascal ' + DevPasVersion + ' - ' + MainForm.Project.Name + ' - [' + Caption +']';
     MaxiMode := True;
  end;
end;

procedure TEditForm.DateandtimePopItemClick(Sender: TObject);
begin
  WriteDateTime;
end;

procedure TEditForm.FindDialogShow(Sender: TObject);
begin
  MainForm.CutItem.ShortCut := 0;
  MainForm.CopyItem.ShortCut := 0;
  MainForm.PasteItem.ShortCut := 0;
end;

procedure TEditForm.FindDialogClose(Sender: TObject);
begin
  MainForm.CutItem.ShortCut := TextToShortCut('Ctrl+X');
  MainForm.CopyItem.ShortCut := TextToShortCut('Ctrl+C');
  MainForm.PasteItem.ShortCut := TextToShortCut('Ctrl+V');
end;

procedure TEditForm.EditorDropFiles(Sender: TObject; X, Y: Integer;
  AFiles: TStrings);
var i, k : integer;
    s : TStringList;
begin
  s := TStringList.Create;

  for i := 0 to AFiles.Count-1 do begin
      s.LoadFromFile(AFiles[i]);
      for k := 0 to s.Count-1 do
          Editor.Lines.Insert(Editor.CaretY+k, s[k]);
  end;
end;

procedure TEditForm.Unitbeginend1Click(Sender: TObject);
begin
  WriteUnitFunction;
end;

end.
