fpc/utils/fpmc/frmmain.pp
2005-02-14 17:13:06 +00:00

524 lines
13 KiB
ObjectPascal

{$mode objfpc}
{$h+}
unit frmmain;
interface
uses gdk,gtk,fpgtk,fpgtkext,classes,sysutils;
Type
TMainForm = Class(TFPGtkWindow)
FModified : Boolean;
FFileName : String;
FUnitName : String;
FLanguageID : Integer;
FSubLanguageID : Integer;
FVerbose,
FCreateMsg,
FCreatePas,
FCreateRC,
FEscapePath : Boolean;
FMsgLabel : TFPgtkLabel;
FMsgList : TFPgtkScrollList;
FMsgVBox,
FVBox : TFPGtkVBox;
FVPaned : TFPgtkVPaned;
FFile,
FFileNew,
FFileOpen,
FFileSave,
FFileSaveAs,
FFileExit,
FEdit,
FEditCut,
FEditCopy,
FEditPaste,
FProject,
FProjectCompile,
FProjectOptions,
FHelp,
FHelpAbout : TFPGtkMenuItem;
FMainMenu : TFPGtkMenuBar;
FEditor : TFPGtkScrollText;
Procedure CreateWindow;
Function CheckSaved : Boolean;
Procedure SetCaption;
Function GetFileName(ATitle : String) : String;
// Callback functions.
Procedure DialogSetFilename(Sender : TFPGtkWindow;Data : Pointer; Action : Integer;Initiator : TFPGtkObject);
Procedure SaveOptions(Sender : TFPGtkWindow;Data : Pointer; Action : Integer;Initiator : TFPGtkObject);
Function OnDeleteEvent(Sender:TFPgtkWidget; Event:PGdkEvent; data:pointer): boolean;
Procedure FileNewClick(Sender : TFPGtkObject; Data : Pointer);
Procedure FileSaveClick(Sender : TFPgtkObject; Data : Pointer);
Procedure FileSaveAsClick(Sender : TFPGtkObject; Data : Pointer);
Procedure FileOpenClick(Sender : TFPGtkObject; Data : Pointer);
Procedure FileExitClick(Sender : TFPgtkObject ; Data : Pointer);
Procedure EditCCPClick(Sender : TFPGtkObject; Data : Pointer);
Procedure ProjectCompileClick(Sender : TFPGtkObject; Data : Pointer);
Procedure ProjectOptionsClick(Sender : TFPGtkObject; Data : Pointer);
Procedure HelpAboutClick(Sender : TFPGtkObject; Data : Pointer);
Procedure EditorChanged(Sender : TFPgtkObject; Data : Pointer);
Procedure DoError(Sender : TObject; Msg : String);
Procedure DoVerbose(Sender : TObject; Msg : String);
Public
Constructor Create;
Procedure Compile;
Procedure SetOptions;
Procedure LoadFromFile(FN : String);
Procedure SaveToFile(FN : String);
Procedure NewFile;
Procedure EditCut;
Procedure EditCopy;
Procedure EditPaste;
Property Modified : Boolean Read FModified;
Property FileName : String Read FFileName;
end;
Implementation
uses frmabout,frmoptions,msgcomp;
ResourceString
SMenuFile = '_File';
SMenuFileNew = '_New';
SMenuFileOpen = '_Open';
SMenuFileSave = '_Save';
SMenuFileSaveAs = 'Save _as';
SMenuFileExit = 'E_xit';
SMenuEdit = '_Edit';
SMenuEditCut = 'C_ut';
SMenuEditCopy = '_Copy';
SMenuEditPaste = '_Paste';
SMenuProject = '_Project';
SMenuProjectCompile = '_Compile';
SMenuProjectoptions = '_Options';
SMenuHelp = '_Help';
SMenuHelpAbout = '_About';
SCaption = 'Free Pascal message compiler';
SFileModified = 'File has changed. Save changes ?';
SSaveFile = 'Save file as';
SOpenFile = 'Select file to open';
SModified = '(modified)';
SCompilerMessages = 'Compile messages';
SErrsCompiling = 'Encountered %d errors while compiling.';
SSuccesCompiling = 'Succesfully compiled messages.';
SErrUnexpected = 'The following unexpected error occurred when compiling:%s';
{ ---------------------------------------------------------------------
Form Creation
---------------------------------------------------------------------}
Constructor TMainForm.Create;
begin
Inherited create (gtk_window_dialog);
FCreateMsg:=True;
FCreatePas:=True;
FCreateRC:=True;
FEscapePath:=True;
FVerbose:=True;
Createwindow;
If ParamCount>0 then
LoadFromFile(Paramstr(1));
end;
Procedure TMainForm.CreateWindow;
Var
FAccelGroup : Integer;
begin
FVBox:=TFPgtkVBox.Create;
FAccelGroup:=AccelGroupNew;
FFileNew:=NewMenuItem(SMenuFileNew,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_N,[amcontrol]),@FileNewClick,Nil);
FFileOpen:=NewMenuItem(SMenuFileOpen,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_O,[amcontrol]),@FileOpenClick,Nil);
FFileSave:=NewMenuItem(SMenuFileSave,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_S,[amcontrol]),@FileSaveClick,Nil);
FFileSaveAs:=NewMenuItem(SMenuFileSaveAs,'','', @FileSaveAsClick,Nil);
FFileExit:=NewMenuItem(SMenuFileExit,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_Q,[amcontrol]),@FileExitClick,Nil);
FFile:=NewSubMenu(SmenuFile,'','',[FFileNew,FFileOpen,FFileSave,FFileSaveAs,NewLine,FFileExit]);
FEditCut:=NewMenuItem(SMenuEditCut,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_X,[amcontrol]),@EditCCPClick,Nil);
FEditCopy:=NewMenuItem(SMenuEditCopy,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_C,[amcontrol]),@EditCCPClick,Nil);
FEditPaste:=NewMenuItem(SMenuEditPaste,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_V,[amcontrol]),@EditCCPClick,Nil);
FEdit:=NewSubMenu(SMenuEdit,'','',[FEditCut,FEditCopy,FEditPaste]);
FProjectCompile:=NewMenuItem(SMenuProjectCompile,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_F9,[amcontrol]),@ProjectCompileClick,Nil);
FProjectOptions:=NewMenuItem(SMenuProjectOptions,'','', MakeAccelKeyDef(Self,FaccelGroup,GDK_F11,[amcontrol,amshift]),@ProjectOptionsClick,Nil);
FProject := NewSubMenu(SMenuProject,'','',[FProjectCompile,FProjectoptions]);
FHelpAbout:=NewMenuItem(SMenuHelpAbout ,'','',@HelpAboutClick,Nil);
FHelp := NewSubMenu(SMenuHelp,'','',[FHelpAbout]);
FMainMenu:=NewMenuBar([FFile,FEdit,FProject,FHelp]);
FEditor:=TFPgtkScrollText.Create;
Feditor.TheText.ConnectChanged(@EditorChanged,Nil);
// Compiling messages
FMsgLabel:=TFPgtkLabel.Create(SCompilerMessages);
FMsgList:=TFPgtkScrollList.Create;
FMsgVBox:=TFPgtkVbox.Create;
FMsgVBox.PackStart(FMsgLabel,False,False,0);
FMsgVBox.PackStart(FMsgList,True,True,0);
FVPaned:=TFPgtkVPaned.Create;
FVPaned.Add1(FEditor);
FVPaned.Add2(FMsgVBox);
FVPaned.Position:=350;
FVBox.PackStart(FmainMenu,False,False,0);
FVBox.PackStart(FVPaned,true, true, 0);
ConnectDeleteEvent(@OnDeleteEvent,Nil);
Add(FVBox);
SetUSize(640,480);
SetCaption;
FEditor.TheText.GrabFocus;
end;
{ ---------------------------------------------------------------------
Callback events
---------------------------------------------------------------------}
Procedure TMainForm.FileNewClick(Sender : TFPGtkObject; Data : Pointer);
begin
If CheckSaved then
NewFile;
end;
Function TMainForm.OnDeleteEvent(Sender:TFPgtkWidget; Event:PGdkEvent; data:pointer): boolean;
begin
Result:=Not CheckSaved;
end;
Procedure TMainForm.FileSaveClick(Sender : TFPgtkObject; Data : Pointer);
begin
If (FFileName='') then
FileSaveAsClick(Sender,Data)
else
SaveToFile(FFileName);
end;
Procedure TMainForm.FileSaveAsClick(Sender : TFPGtkObject; Data : Pointer);
Var
FN : String;
begin
FN:=GetFileName(SSaveFile);
If (FN<>'') then
SavetoFile(FN);
end;
Procedure TMainForm.FileOpenClick(Sender : TFPGtkObject; Data : Pointer);
Var
FN : String;
begin
FN:=GetFileName(SOpenFile);
If (FN<>'') then
LoadFromFile(FN);
end;
Procedure TMainForm.EditorChanged(Sender : TFPgtkObject; Data : Pointer);
begin
If FModified<>True then
begin
FModified:=True;
SetCaption;
end;
end;
Procedure TMainForm.EditCCPClick(Sender : TFPGtkObject; Data : Pointer);
begin
If Sender=FEditCut then
EditCut
else if Sender=FEditCopy then
EditCopy
else
EditPaste;
end;
Procedure TMainForm.FileExitClick(Sender : TFPgtkObject; Data : Pointer);
begin
If CheckSaved then
Close;
end;
Procedure TMainForm.HelpAboutClick(Sender : TFPGtkObject; Data : Pointer);
begin
With TAboutForm.Create do
Execute(Nil,Nil,Nil);
end;
Procedure TMainForm.ProjectCompileClick(Sender : TFPGtkObject; Data : Pointer);
begin
Compile;
end;
Procedure TMainForm.ProjectOptionsClick(Sender : TFPGtkObject; Data : Pointer);
begin
SetOptions;
end;
Procedure TMainform.DoError(Sender : TObject; Msg : String);
begin
FMsgList.list.Add(TFPGtkListItem.CreateWithLabel(Msg));
end;
Procedure TMainform.DoVerbose(Sender : TObject; Msg : String);
begin
FMsgList.list.Add(TFPGtkListItem.CreateWithLabel(Msg));
end;
{ ---------------------------------------------------------------------
Auxiliary methods
---------------------------------------------------------------------}
Procedure TMainForm.SetCaption;
Var
S : String;
begin
S:=SCaption;
If (FFileName<>'') then
S:=S+' : '+ExtractFileName(FFileName);
If FModified then
S:=S+' '+SModified;
Title:=S;
end;
Function TMainForm.CheckSaved : Boolean;
begin
Result:=Not FModified;
If Not Result then
Case MessageDlg(SFileModified,mtInformation,mbYesNoCancel,0) of
mrYes : begin
FileSaveClick(Self,Nil);
Result:=True;
end;
mrNo : Result:=True;
mrCancel : Result:=False;
end;
end;
Function TMainForm.GetFileName(ATitle : String) : String;
var
FS : TFPgtkFileSelection;
begin
Result:='';
FS := TFPgtkFileSelection.Create (gtk_window_dialog);
with FS do
begin
Title:=ATitle;
OKButton.ConnectClicked (@(CloseWithResult), inttopointer(drOk));
CancelButton.ConnectClicked (@(CloseWindow), nil);
if Not execute (nil, @Result, @DialogSetFilename) = drOk then
Result:='';
end;
end;
Procedure TMainForm.DialogSetFilename(Sender : TFPGtkWindow;Data : Pointer; Action : Integer;Initiator : TFPGtkObject);
type
PString = ^AnsiString;
begin
PString(Data)^:=(Sender as TFPgtkFileSelection).Filename;
end;
{ ---------------------------------------------------------------------
Public methods
---------------------------------------------------------------------}
Procedure TMainForm.LoadFromFile(FN : String);
Var
S : TStringList;
begin
S:=TStringList.Create;
try
S.LoadFromFile(FN);
FEditor.TheText.Text:=S.Text;
FModified:=False;
Finally
S.Free;
end;
FFileName:=FN;
SetCaption;
end;
Procedure TMainForm.SaveToFile(FN : String);
begin
FFileName:=FN;
FEditor.TheText.Lines.SaveToFile(FN);
FModified:=False;
SetCaption;
end;
Procedure TMainForm.EditCut;
begin
FEditor.TheText.CutClipBoard;
end;
Procedure TMainForm.EditCopy;
begin
FEditor.TheText.CopyCLipBoard;
end;
Procedure TMainForm.EditPaste;
begin
FEditor.TheText.PasteClipBoard;
end;
Procedure TMainForm.NewFile;
begin
Feditor.TheText.Clear;
end;
Procedure TMainForm.Compile;
Var
M,P,R,I : TStream;
S,MsgFileName : String;
Procedure SetupStreams;
begin
I:=TFileStream.Create(FFileName,fmOpenRead);
If FCreatePas then
P:=TFileStream.Create(ChangeFileExt(FFileName,'.pp'),fmCreate);
If FCreateMsg then
begin
MsgFileName:=ChangeFileExt(FFileName,'.msg');
M:=TFileStream.Create(MsgFileName,fmCreate);
end;
If FCreateRC then
R:=TFileStream.Create(ChangeFileExt(FFileName,'.rc'),fmCreate);
end;
Procedure CloseStreams;
begin
M.Free;
P.Free;
R.Free;
I.Free;
end;
begin
FileSaveClick(Self,Nil);
If (FUnitName='') then
FUnitName:=ExtractFileName(FFileName);
FMsgList.List.ClearAll;
Try
SetupStreams;
Try
With TMessageCompiler.Create do
Try
Msg:=M;
MC:=I;
RC:=R;
Pas:=P;
OnError:=@DoError;
If FVerbose then
OnVerbose:=@DoVerbose;
UnitName:=FUnitName;
MessageFileName:=MsgFileName;
EscapeNeeded:=FEscapePath;
If (FLanguageID<>-1) then
LocaleID:=FLanguageID;
If (FSubLanguageID<>-1) then
SubLocaleID:=FSubLanguageID;
If Compile then
DoVerbose(Nil,SSuccesCompiling)
else
begin
S:=Format(SErrsCompiling,[Errors]);
DoVerbose(Nil,S);
MessageDlg(S,mtError,[mbOK],0);
end;
Finally
Free;
end;
Finally
CloseStreams;
end;
except
On E : Exception do
MessageDlg(SErrUnexpected,[E.Message],mtError,[mbOK],0);
end;
end;
Procedure TMainForm.SaveOptions(Sender : TFPGtkWindow;Data : Pointer; Action : Integer;Initiator : TFPGtkObject);
begin
With TOptionsForm(Data) do
begin
FUnitName:=UnitName;
FLanguageID:=StrToIntDef(Trim(Locale),0);
FSubLanguageID:=StrToIntDef(Trim(SubLocale),0);
FVerbose:=Verbose;
FCreateMsg:=CreateMsgFile;
FCreatePas:=CreatePasFile;
FCreateRC:=CreateRCFile;
FEscapePath:=EscapePath;
end;
end;
Procedure TMainForm.SetOptions;
Var
F : TOptionsForm;
begin
If (FUnitName='') and (FFileName<>'') then
FUnitName:=ExtractFileName(FFileName);
F:=TOptionsForm.Create;
With F do
begin
UnitName:=FUnitName;
Locale:=IntToStr(FLanguageID);
SubLocale:=IntToStr(FSubLanguageID);
Verbose:=Fverbose;
CreateMsgFile:=FCreateMsg;
CreatePasFile:=FCreatePas;
CreateRCFile:=FCreateRC;
EscapePath:=FEscapePath;
Execute(Nil,F,@SaveOptions);
end;
end;
end.